diff --git a/.devcontainer/Readme.md b/.devcontainer/Readme.md new file mode 100644 index 0000000000..00acbb5786 --- /dev/null +++ b/.devcontainer/Readme.md @@ -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. diff --git a/.devcontainer/cortex-m/devcontainer.json b/.devcontainer/cortex-m/devcontainer.json new file mode 100644 index 0000000000..ee8aeb1ea0 --- /dev/null +++ b/.devcontainer/cortex-m/devcontainer.json @@ -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" +} diff --git a/.devcontainer/cortex-m/on-create.sh b/.devcontainer/cortex-m/on-create.sh new file mode 100755 index 0000000000..8c4bd0cfed --- /dev/null +++ b/.devcontainer/cortex-m/on-create.sh @@ -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 diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 7b6a53dbba..c81bf63123 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -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 diff --git a/.github/actions/deps/external/action.yml b/.github/actions/deps/external/action.yml new file mode 100644 index 0000000000..9e32e733a2 --- /dev/null +++ b/.github/actions/deps/external/action.yml @@ -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 diff --git a/.github/actions/deps/ports/action.yml b/.github/actions/deps/ports/action.yml new file mode 100644 index 0000000000..8125de2acc --- /dev/null +++ b/.github/actions/deps/ports/action.yml @@ -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 diff --git a/.github/actions/deps/ports/broadcom/action.yml b/.github/actions/deps/ports/broadcom/action.yml new file mode 100644 index 0000000000..bd76c78262 --- /dev/null +++ b/.github/actions/deps/ports/broadcom/action.yml @@ -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 diff --git a/.github/actions/deps/ports/espressif/action.yml b/.github/actions/deps/ports/espressif/action.yml new file mode 100644 index 0000000000..aa1e98f8a0 --- /dev/null +++ b/.github/actions/deps/ports/espressif/action.yml @@ -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 diff --git a/.github/actions/deps/ports/litex/action.yml b/.github/actions/deps/ports/litex/action.yml new file mode 100644 index 0000000000..a89a222505 --- /dev/null +++ b/.github/actions/deps/ports/litex/action.yml @@ -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 diff --git a/.github/actions/deps/ports/nrf/action.yml b/.github/actions/deps/ports/nrf/action.yml new file mode 100644 index 0000000000..d977c937b3 --- /dev/null +++ b/.github/actions/deps/ports/nrf/action.yml @@ -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 diff --git a/.github/actions/deps/python/action.yml b/.github/actions/deps/python/action.yml new file mode 100644 index 0000000000..9b3732c9e0 --- /dev/null +++ b/.github/actions/deps/python/action.yml @@ -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 diff --git a/.github/actions/deps/submodules/action.yml b/.github/actions/deps/submodules/action.yml new file mode 100644 index 0000000000..bca76b204c --- /dev/null +++ b/.github/actions/deps/submodules/action.yml @@ -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 diff --git a/.github/actions/mpy_cross/action.yml b/.github/actions/mpy_cross/action.yml new file mode 100644 index 0000000000..d9fe54fdc7 --- /dev/null +++ b/.github/actions/mpy_cross/action.yml @@ -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 diff --git a/.github/actions/upload_aws/action.yml b/.github/actions/upload_aws/action.yml new file mode 100644 index 0000000000..643dd00342 --- /dev/null +++ b/.github/actions/upload_aws/action.yml @@ -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 diff --git a/.github/workflows/build-boards.yml b/.github/workflows/build-boards.yml new file mode 100644 index 0000000000..85e789bf87 --- /dev/null +++ b/.github/workflows/build-boards.yml @@ -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 }} diff --git a/.github/workflows/build-mpy-cross.yml b/.github/workflows/build-mpy-cross.yml new file mode 100644 index 0000000000..10c4498bc8 --- /dev/null +++ b/.github/workflows/build-mpy-cross.yml @@ -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 }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8dc31a3ff6..bee5afdd6a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 + runs-on: macos-11 + needs: scheduler + if: needs.scheduler.outputs.ports != '{}' + env: + CP_VERSION: ${{ needs.scheduler.outputs.cp-version }} steps: - - name: Dump 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 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 - 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')) + - 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: + boards: ${{ toJSON(fromJSON(needs.scheduler.outputs.ports)[matrix.port]) }} + cp-version: ${{ needs.scheduler.outputs.cp-version }} diff --git a/.github/workflows/create_website_pr.yml b/.github/workflows/create-website-pr.yml similarity index 54% rename from .github/workflows/create_website_pr.yml rename to .github/workflows/create-website-pr.yml index 2367b6c475..eeae8c8299 100644 --- a/.github/workflows/create_website_pr.yml +++ b/.github/workflows/create-website-pr.yml @@ -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') diff --git a/.github/workflows/custom-board-build.yml b/.github/workflows/custom-board-build.yml new file mode 100644 index 0000000000..aa8044b0d2 --- /dev/null +++ b/.github/workflows/custom-board-build.yml @@ -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.* diff --git a/.github/workflows/notify-on-issue-label.yml b/.github/workflows/notify-on-issue-label.yml new file mode 100644 index 0000000000..da1ac0a18e --- /dev/null +++ b/.github/workflows/notify-on-issue-label.yml @@ -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. diff --git a/.github/workflows/notify.yml b/.github/workflows/notify.yml deleted file mode 100644 index 4cfb22298f..0000000000 --- a/.github/workflows/notify.yml +++ /dev/null @@ -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 diff --git a/.github/workflows/ports_windows.yml b/.github/workflows/ports_windows.yml deleted file mode 100644 index bc5f837745..0000000000 --- a/.github/workflows/ports_windows.yml +++ /dev/null @@ -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 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 52e2d2b714..c0dff33564 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -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 diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000000..44146662f2 --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -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 diff --git a/.gitignore b/.gitignore index 2fdfe207a2..9cb1e9ea5e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ !atmel-samd/asf/**/*.a *.elf *.bin +!*.toml.bin *.map *.hex *.dis diff --git a/.gitmodules b/.gitmodules index 0177e5a2ea..2ba84b4305 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bcf7f8da2b..1905b233cf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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 diff --git a/.readthedocs.yml b/.readthedocs.yml index 94ba8750b0..29a915766f 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -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 diff --git a/BUILDING.md b/BUILDING.md index 37800e689f..4793824cf1 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -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. diff --git a/LICENSE b/LICENSE index 2b9a64b89a..5b8797814f 100644 --- a/LICENSE +++ b/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. diff --git a/LICENSE_MicroPython b/LICENSE_MicroPython new file mode 100644 index 0000000000..2b9a64b89a --- /dev/null +++ b/LICENSE_MicroPython @@ -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) diff --git a/Makefile b/Makefile index b35b5c66b9..91d842231f 100644 --- a/Makefile +++ b/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' diff --git a/README.rst b/README.rst index 66ad78f6eb..1a6dc2c33e 100644 --- a/README.rst +++ b/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" `_ repo. This way we can update any custom code as we update the CircuitPython internals. -* Your product is listed on `circuitpython.org `__ (source +- Your product is listed on `circuitpython.org `__ (source `here `_). 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 `__" 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 `__" 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 diff --git a/conf.py b/conf.py index 145bed4d7b..7b3b4ca585 100644 --- a/conf.py +++ b/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", diff --git a/data/nvm.toml b/data/nvm.toml index 2d292ad4e6..73fafcbe4c 160000 --- a/data/nvm.toml +++ b/data/nvm.toml @@ -1 +1 @@ -Subproject commit 2d292ad4e67890d4b85b027431ba9fef7bf561fd +Subproject commit 73fafcbe4c66b23df63be31e9227353b695abb08 diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.c b/devices/ble_hci/common-hal/_bleio/Adapter.c index 8c7b8f67eb..f558d66d40 100644 --- a/devices/ble_hci/common-hal/_bleio/Adapter.c +++ b/devices/ble_hci/common-hal/_bleio/Adapter.c @@ -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)); diff --git a/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c b/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c index 0d87f03ae3..5c8c659e36 100644 --- a/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c +++ b/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c @@ -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); } } diff --git a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c index 7380d7ed4f..b690909029 100644 --- a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c +++ b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c @@ -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); } } diff --git a/license.rst b/docs/LICENSE.md similarity index 78% rename from license.rst rename to docs/LICENSE.md index 7e97341cda..a63dd7c965 100644 --- a/license.rst +++ b/docs/LICENSE.md @@ -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. diff --git a/docs/design_guide.rst b/docs/design_guide.rst index fdb8f9b019..784284892c 100644 --- a/docs/design_guide.rst +++ b/docs/design_guide.rst @@ -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__ = "" + 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 `_ is +a foundational library that manages packing and unpacking data from I2C device +registers. There is also `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 `_. + +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 -------------------------------------------------------------------------------- diff --git a/docs/drivers.rst b/docs/drivers.rst deleted file mode 100644 index 8855abbd2d..0000000000 --- a/docs/drivers.rst +++ /dev/null @@ -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 `_. - - -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: . - -- Documentation for the bundle, which includes links to documentation for all - libraries, is available here: . - - -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: . - -- Documentation is not available on ReadTheDocs at this time. See each library for any - included documentation. diff --git a/docs/environment.rst b/docs/environment.rst index 4d12009848..58ada402c6 100644 --- a/docs/environment.rst +++ b/docs/environment.rst @@ -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 `_ -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. diff --git a/docs/index.rst b/docs/index.rst index a200a5238b..e49b74b4e3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -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 diff --git a/docs/libraries.rst b/docs/libraries.rst new file mode 100644 index 0000000000..2d34ccbe3f --- /dev/null +++ b/docs/libraries.rst @@ -0,0 +1,31 @@ +Adafruit CircuitPython Libraries +================================ + +Documentation for all Adafruit-sponsored CircuitPython libraries is at: +. + + +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 . + +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: . +The Community bundles are available at: . + +More detailed information about the bundles, and download links for the latest bundles +are at . + +Documentation about bundle construction is at: . + +Documentation for Community Libraries is not available on ReadTheDocs at this time. See the GitHub repository +for each library for any included documentation. diff --git a/docs/library/asyncio.rst b/docs/library/asyncio.rst deleted file mode 100644 index 87417f55e2..0000000000 --- a/docs/library/asyncio.rst +++ /dev/null @@ -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 `_ - -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'``. diff --git a/docs/library/builtins.rst b/docs/library/builtins.rst index a3be5ae16e..3a675e7ec1 100644 --- a/docs/library/builtins.rst +++ b/docs/library/builtins.rst @@ -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 diff --git a/docs/library/collections.rst b/docs/library/collections.rst index b7a5fb1765..2cc1a215d1 100644 --- a/docs/library/collections.rst +++ b/docs/library/collections.rst @@ -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) diff --git a/docs/library/hashlib.rst b/docs/library/hashlib.rst deleted file mode 100644 index 061f9fd1e0..0000000000 --- a/docs/library/hashlib.rst +++ /dev/null @@ -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. diff --git a/docs/library/index.rst b/docs/library/index.rst index 5d8dd3118f..2a8e37a8f4 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -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 ------------------------------------------- diff --git a/docs/library/micropython.rst b/docs/library/micropython.rst index 2623aab582..dddb813d34 100644 --- a/docs/library/micropython.rst +++ b/docs/library/micropython.rst @@ -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 diff --git a/docs/library/zlib.rst b/docs/library/zlib.rst deleted file mode 100644 index 514b787bc4..0000000000 --- a/docs/library/zlib.rst +++ /dev/null @@ -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 `_ -(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. diff --git a/docs/porting.rst b/docs/porting.rst index 07a2b1e9c4..f4ed2ab4cc 100644 --- a/docs/porting.rst +++ b/docs/porting.rst @@ -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 diff --git a/docs/redirects.txt b/docs/redirects.txt index 2817bb14e5..b8282635ab 100644 --- a/docs/redirects.txt +++ b/docs/redirects.txt @@ -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 diff --git a/docs/shared_bindings_matrix.py b/docs/shared_bindings_matrix.py index 961b38370d..761e3e29f2 100644 --- a/docs/shared_bindings_matrix.py +++ b/docs/shared_bindings_matrix.py @@ -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"): - frozen_modules.append((sub.name[:-3], url_repository)) + 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 - frozen_modules.append((sub.name, url_repository)) + 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 diff --git a/docs/workflows.md b/docs/workflows.md index 2196d1111a..29229bd00e 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -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 diff --git a/extmod/moduasyncio.c b/extmod/moduasyncio.c index c4c4d36ad8..1e1c5de7e7 100644 --- a/extmod/moduasyncio.c +++ b/extmod/moduasyncio.c @@ -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)) { - // Task finished, raise return value to caller so it can continue. - nlr_raise(self->data); + 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)); diff --git a/extmod/moduselect.c b/extmod/moduselect.c index c8f5e57363..d388438313 100644 --- a/extmod/moduselect.c +++ b/extmod/moduselect.c @@ -9,13 +9,14 @@ #include -#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; diff --git a/extmod/uasyncio/task.py b/extmod/uasyncio/task.py index cd75a14a09..7a80b25208 100644 --- a/extmod/uasyncio/task.py +++ b/extmod/uasyncio/task.py @@ -141,8 +141,12 @@ class Task: def __next__(self): if not self.state: - # Task finished, raise return value to caller so it can continue. - raise self.data + 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: # Put calling task on waiting queue. self.state.push_head(core.cur_task) diff --git a/extmod/ulab b/extmod/ulab index 346c936e14..f2dd2230c4 160000 --- a/extmod/ulab +++ b/extmod/ulab @@ -1 +1 @@ -Subproject commit 346c936e14c6ea3a8d3d65cb1fa46202dc92999d +Subproject commit f2dd2230c4fdf1aa5c7a160782efdde18e8204bb diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index d19a53a9ef..0a9737e53a 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -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 diff --git a/frozen/Adafruit_CircuitPython_APDS9960 b/frozen/Adafruit_CircuitPython_APDS9960 index 13856be616..9ddd596505 160000 --- a/frozen/Adafruit_CircuitPython_APDS9960 +++ b/frozen/Adafruit_CircuitPython_APDS9960 @@ -1 +1 @@ -Subproject commit 13856be616eee2eb84280b7c4914951c1ddbfd36 +Subproject commit 9ddd59650598b7a0641d70aabcc8aab71799cb93 diff --git a/frozen/Adafruit_CircuitPython_BLE b/frozen/Adafruit_CircuitPython_BLE index 7d9635ba1d..e07e1853d7 160000 --- a/frozen/Adafruit_CircuitPython_BLE +++ b/frozen/Adafruit_CircuitPython_BLE @@ -1 +1 @@ -Subproject commit 7d9635ba1dda31ce45b84519c4da76ff86d0debe +Subproject commit e07e1853d7e995b9797a064c098bccc5c384632e diff --git a/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center b/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center index e5cf8206c0..b06b47037a 160000 --- a/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center +++ b/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center @@ -1 +1 @@ -Subproject commit e5cf8206c0173228252ae74367cab85b0531488e +Subproject commit b06b47037aed97475b1676b104d1f4b05c3f5e86 diff --git a/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice index 9addf6a26f..9ace770b04 160000 --- a/frozen/Adafruit_CircuitPython_BusDevice +++ b/frozen/Adafruit_CircuitPython_BusDevice @@ -1 +1 @@ -Subproject commit 9addf6a26fef3a32c78d574c66452b6210eca5c5 +Subproject commit 9ace770b048be9ab0da4a154af279dbb643bbdb0 diff --git a/frozen/Adafruit_CircuitPython_CircuitPlayground b/frozen/Adafruit_CircuitPython_CircuitPlayground index 843def7dae..47f848f13f 160000 --- a/frozen/Adafruit_CircuitPython_CircuitPlayground +++ b/frozen/Adafruit_CircuitPython_CircuitPlayground @@ -1 +1 @@ -Subproject commit 843def7daee741c8fb04fe21c3c7b98f22862471 +Subproject commit 47f848f13f75d2f62d16407edaaf6dd0ec1fc3cc diff --git a/frozen/Adafruit_CircuitPython_Crickit b/frozen/Adafruit_CircuitPython_Crickit index 0a045871d3..a37c7cc836 160000 --- a/frozen/Adafruit_CircuitPython_Crickit +++ b/frozen/Adafruit_CircuitPython_Crickit @@ -1 +1 @@ -Subproject commit 0a045871d3da681d1c9c9578f09174bfc6d84f1d +Subproject commit a37c7cc83685f2ff84a171a519207567a75d0947 diff --git a/frozen/Adafruit_CircuitPython_DRV2605 b/frozen/Adafruit_CircuitPython_DRV2605 index 6a429bcd0e..ab0ffa938d 160000 --- a/frozen/Adafruit_CircuitPython_DRV2605 +++ b/frozen/Adafruit_CircuitPython_DRV2605 @@ -1 +1 @@ -Subproject commit 6a429bcd0e6b22ee181197ce0477ae70f5adb80d +Subproject commit ab0ffa938dfa7eb1fd7260353a7a4e28f55e537a diff --git a/frozen/Adafruit_CircuitPython_DS3231 b/frozen/Adafruit_CircuitPython_DS3231 index 22931594bc..e6a9a0140e 160000 --- a/frozen/Adafruit_CircuitPython_DS3231 +++ b/frozen/Adafruit_CircuitPython_DS3231 @@ -1 +1 @@ -Subproject commit 22931594bc52ab259eaf313d26219a507703c315 +Subproject commit e6a9a0140ed44ef5f15d8040fce35b5319c1f216 diff --git a/frozen/Adafruit_CircuitPython_Display_Shapes b/frozen/Adafruit_CircuitPython_Display_Shapes index cdef09114d..cf2b173d0f 160000 --- a/frozen/Adafruit_CircuitPython_Display_Shapes +++ b/frozen/Adafruit_CircuitPython_Display_Shapes @@ -1 +1 @@ -Subproject commit cdef09114d2b43d2e461d066a5b56697ab567abc +Subproject commit cf2b173d0fc3ac2cd961754c6adf8f614a1c7c39 diff --git a/frozen/Adafruit_CircuitPython_Display_Text b/frozen/Adafruit_CircuitPython_Display_Text index bb9cb75e15..911201504a 160000 --- a/frozen/Adafruit_CircuitPython_Display_Text +++ b/frozen/Adafruit_CircuitPython_Display_Text @@ -1 +1 @@ -Subproject commit bb9cb75e15b4bfce3063a94b40dfad2375d5605e +Subproject commit 911201504a269dbfc49b04ca59bc54adabd4716a diff --git a/frozen/Adafruit_CircuitPython_DotStar b/frozen/Adafruit_CircuitPython_DotStar index f9469d26ed..187279a95e 160000 --- a/frozen/Adafruit_CircuitPython_DotStar +++ b/frozen/Adafruit_CircuitPython_DotStar @@ -1 +1 @@ -Subproject commit f9469d26ed9eb95d43982de88c035ac3862dd258 +Subproject commit 187279a95e5cdd634d233af59352558cea4c1227 diff --git a/frozen/Adafruit_CircuitPython_ESP32SPI b/frozen/Adafruit_CircuitPython_ESP32SPI index f3d504be1d..ee6bfcf9e6 160000 --- a/frozen/Adafruit_CircuitPython_ESP32SPI +++ b/frozen/Adafruit_CircuitPython_ESP32SPI @@ -1 +1 @@ -Subproject commit f3d504be1dc82cc4a8e4ea9b38bd5c2ce74d59ba +Subproject commit ee6bfcf9e676eb435c8890db37f07719984a60a1 diff --git a/frozen/Adafruit_CircuitPython_FakeRequests b/frozen/Adafruit_CircuitPython_FakeRequests index 2ea025b1b6..8eedf860be 160000 --- a/frozen/Adafruit_CircuitPython_FakeRequests +++ b/frozen/Adafruit_CircuitPython_FakeRequests @@ -1 +1 @@ -Subproject commit 2ea025b1b68b0be95a0514732d4bc623f313fd75 +Subproject commit 8eedf860beca0d32219189b72ea6fc8eea7e66db diff --git a/frozen/Adafruit_CircuitPython_FocalTouch b/frozen/Adafruit_CircuitPython_FocalTouch index b637c47423..3d7d404a1c 160000 --- a/frozen/Adafruit_CircuitPython_FocalTouch +++ b/frozen/Adafruit_CircuitPython_FocalTouch @@ -1 +1 @@ -Subproject commit b637c47423eb85233ba614424aadadace37fcfb1 +Subproject commit 3d7d404a1cafc02f6c3391b100157490132e5c5f diff --git a/frozen/Adafruit_CircuitPython_HID b/frozen/Adafruit_CircuitPython_HID index 47cc914748..93c7e0ed55 160000 --- a/frozen/Adafruit_CircuitPython_HID +++ b/frozen/Adafruit_CircuitPython_HID @@ -1 +1 @@ -Subproject commit 47cc91474823677218239b5b37901590755cac4c +Subproject commit 93c7e0ed55e7ed011908ac9a1c0f8228f0f4323b diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote index a2491a806b..340c62ef6c 160000 --- a/frozen/Adafruit_CircuitPython_IRRemote +++ b/frozen/Adafruit_CircuitPython_IRRemote @@ -1 +1 @@ -Subproject commit a2491a806b636f66caf670527c49b864923f125c +Subproject commit 340c62ef6ce867b3924d166afc3d2a171680f799 diff --git a/frozen/Adafruit_CircuitPython_IS31FL3731 b/frozen/Adafruit_CircuitPython_IS31FL3731 index b4a0461889..5433ba3760 160000 --- a/frozen/Adafruit_CircuitPython_IS31FL3731 +++ b/frozen/Adafruit_CircuitPython_IS31FL3731 @@ -1 +1 @@ -Subproject commit b4a0461889ead5da69f4ed6d0118276b01613981 +Subproject commit 5433ba3760ca605267223de883a44cb8394f40a5 diff --git a/frozen/Adafruit_CircuitPython_LC709203F b/frozen/Adafruit_CircuitPython_LC709203F index 72367f37cd..38bd02f014 160000 --- a/frozen/Adafruit_CircuitPython_LC709203F +++ b/frozen/Adafruit_CircuitPython_LC709203F @@ -1 +1 @@ -Subproject commit 72367f37cd221c7af7822ba3a9cd21cd3cd70292 +Subproject commit 38bd02f014403954ab52154e3877e502d83862dc diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH index a06c8a116e..240fe51935 160000 --- a/frozen/Adafruit_CircuitPython_LIS3DH +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -1 +1 @@ -Subproject commit a06c8a116e5767a8481b9018239fe729e01760a6 +Subproject commit 240fe51935f4a9def33ef347d40b13862a60b7ac diff --git a/frozen/Adafruit_CircuitPython_LSM6DS b/frozen/Adafruit_CircuitPython_LSM6DS index 5acf8a850d..d689ca77c6 160000 --- a/frozen/Adafruit_CircuitPython_LSM6DS +++ b/frozen/Adafruit_CircuitPython_LSM6DS @@ -1 +1 @@ -Subproject commit 5acf8a850d98789a79fe37836b2ac7b623d95913 +Subproject commit d689ca77c67806484037e00110c669cf55846b6e diff --git a/frozen/Adafruit_CircuitPython_MIDI b/frozen/Adafruit_CircuitPython_MIDI index d3f9adce6e..e38bf1f9cf 160000 --- a/frozen/Adafruit_CircuitPython_MIDI +++ b/frozen/Adafruit_CircuitPython_MIDI @@ -1 +1 @@ -Subproject commit d3f9adce6e48d37222ef171a280cfa3122faf15b +Subproject commit e38bf1f9cf1e8faeb7d15a1d10674fb2c0a81e72 diff --git a/frozen/Adafruit_CircuitPython_Motor b/frozen/Adafruit_CircuitPython_Motor index df61e7b0be..9c3de3abce 160000 --- a/frozen/Adafruit_CircuitPython_Motor +++ b/frozen/Adafruit_CircuitPython_Motor @@ -1 +1 @@ -Subproject commit df61e7b0be9dc0c6a1bbe60f526fbdc01b6c2819 +Subproject commit 9c3de3abce00b50ba936f4f8daad0a8a6bee34a6 diff --git a/frozen/Adafruit_CircuitPython_NeoPixel b/frozen/Adafruit_CircuitPython_NeoPixel index 015eb1ccd5..9516aa97e9 160000 --- a/frozen/Adafruit_CircuitPython_NeoPixel +++ b/frozen/Adafruit_CircuitPython_NeoPixel @@ -1 +1 @@ -Subproject commit 015eb1ccd5eb5364d8e1cf20358e7dcda9f12efc +Subproject commit 9516aa97e9216eac2b229fbb7dac34fa60c347c4 diff --git a/frozen/Adafruit_CircuitPython_PortalBase b/frozen/Adafruit_CircuitPython_PortalBase index 217af2bc7d..759c5c3488 160000 --- a/frozen/Adafruit_CircuitPython_PortalBase +++ b/frozen/Adafruit_CircuitPython_PortalBase @@ -1 +1 @@ -Subproject commit 217af2bc7de658ff2f6380a066d99a149e69693e +Subproject commit 759c5c348878932adc5fcc9e4f3b3f570b43e17f diff --git a/frozen/Adafruit_CircuitPython_ProgressBar b/frozen/Adafruit_CircuitPython_ProgressBar index 1c39469bac..74a1c26110 160000 --- a/frozen/Adafruit_CircuitPython_ProgressBar +++ b/frozen/Adafruit_CircuitPython_ProgressBar @@ -1 +1 @@ -Subproject commit 1c39469bac98eea022af695ac42e5096dae6130c +Subproject commit 74a1c261103cda43172053ff2370777255b9bf8d diff --git a/frozen/Adafruit_CircuitPython_RFM69 b/frozen/Adafruit_CircuitPython_RFM69 index 74ea48f7a5..af1cba8a7e 160000 --- a/frozen/Adafruit_CircuitPython_RFM69 +++ b/frozen/Adafruit_CircuitPython_RFM69 @@ -1 +1 @@ -Subproject commit 74ea48f7a5d85591f5af804cacb57e9cfaab46c6 +Subproject commit af1cba8a7e4e3950fcc5367e9c55a024d9ab9f64 diff --git a/frozen/Adafruit_CircuitPython_RFM9x b/frozen/Adafruit_CircuitPython_RFM9x index 13cdb9912b..c46c59e300 160000 --- a/frozen/Adafruit_CircuitPython_RFM9x +++ b/frozen/Adafruit_CircuitPython_RFM9x @@ -1 +1 @@ -Subproject commit 13cdb9912ba31f6e267f1afb9f71fddf5b1c139c +Subproject commit c46c59e3004817c708c78c59d247b02161c6bf06 diff --git a/frozen/Adafruit_CircuitPython_Register b/frozen/Adafruit_CircuitPython_Register index d1e8ac7ad9..46a49205f3 160000 --- a/frozen/Adafruit_CircuitPython_Register +++ b/frozen/Adafruit_CircuitPython_Register @@ -1 +1 @@ -Subproject commit d1e8ac7ad9dcd65ab83749db3e5c96ffee80ebb7 +Subproject commit 46a49205f3f14546273dd1267e66cad82f03986c diff --git a/frozen/Adafruit_CircuitPython_Requests b/frozen/Adafruit_CircuitPython_Requests index b168b28fc5..558fff7223 160000 --- a/frozen/Adafruit_CircuitPython_Requests +++ b/frozen/Adafruit_CircuitPython_Requests @@ -1 +1 @@ -Subproject commit b168b28fc58973cf20269cc87a655d7812659fd0 +Subproject commit 558fff7223178eae6228e5262f3a08d3a4101394 diff --git a/frozen/Adafruit_CircuitPython_SD b/frozen/Adafruit_CircuitPython_SD index 332143d4ca..eb17bffa75 160000 --- a/frozen/Adafruit_CircuitPython_SD +++ b/frozen/Adafruit_CircuitPython_SD @@ -1 +1 @@ -Subproject commit 332143d4ca5762d2d351ceb170c0b4e37dd42793 +Subproject commit eb17bffa757dc8c0a53fe9e61c45246c06418099 diff --git a/frozen/Adafruit_CircuitPython_SSD1680 b/frozen/Adafruit_CircuitPython_SSD1680 new file mode 160000 index 0000000000..91b6867aca --- /dev/null +++ b/frozen/Adafruit_CircuitPython_SSD1680 @@ -0,0 +1 @@ +Subproject commit 91b6867aca2b0511571fed14ab051d37f1f1544c diff --git a/frozen/Adafruit_CircuitPython_ST7789 b/frozen/Adafruit_CircuitPython_ST7789 index 995959d5dc..e23c487145 160000 --- a/frozen/Adafruit_CircuitPython_ST7789 +++ b/frozen/Adafruit_CircuitPython_ST7789 @@ -1 +1 @@ -Subproject commit 995959d5dca23fbe49590700d1aa26a96dca1df7 +Subproject commit e23c4871456cdf0ef1bfb59d1c2f6e38b7b640ee diff --git a/frozen/Adafruit_CircuitPython_SimpleIO b/frozen/Adafruit_CircuitPython_SimpleIO index d238fe99e2..eac33b430b 160000 --- a/frozen/Adafruit_CircuitPython_SimpleIO +++ b/frozen/Adafruit_CircuitPython_SimpleIO @@ -1 +1 @@ -Subproject commit d238fe99e24ea4cdb472f1d8a9c99dd189b0aeca +Subproject commit eac33b430b0cbe1f6f583000f6b29f75bfe8507e diff --git a/frozen/Adafruit_CircuitPython_SimpleMath b/frozen/Adafruit_CircuitPython_SimpleMath index 632655b8f5..dc605bb229 160000 --- a/frozen/Adafruit_CircuitPython_SimpleMath +++ b/frozen/Adafruit_CircuitPython_SimpleMath @@ -1 +1 @@ -Subproject commit 632655b8f5f6f62e3b4d0b6161213634e0ae74e9 +Subproject commit dc605bb22914d77d80c5342cbb4c10f773aede95 diff --git a/frozen/Adafruit_CircuitPython_Thermistor b/frozen/Adafruit_CircuitPython_Thermistor index 3816a4f4c9..43a4f15d60 160000 --- a/frozen/Adafruit_CircuitPython_Thermistor +++ b/frozen/Adafruit_CircuitPython_Thermistor @@ -1 +1 @@ -Subproject commit 3816a4f4c997b03d4a7ebfe35a617d1e50124b04 +Subproject commit 43a4f15d604919d6e143e975a85abf7b96a4061d diff --git a/frozen/Adafruit_CircuitPython_Ticks b/frozen/Adafruit_CircuitPython_Ticks index 6757c5b37c..2634ca0163 160000 --- a/frozen/Adafruit_CircuitPython_Ticks +++ b/frozen/Adafruit_CircuitPython_Ticks @@ -1 +1 @@ -Subproject commit 6757c5b37cf26458448930042cb0a41f8ad0a5ef +Subproject commit 2634ca0163020bebec300fcca6e0b5afcdc655b8 diff --git a/frozen/Adafruit_CircuitPython_UC8151D b/frozen/Adafruit_CircuitPython_UC8151D new file mode 160000 index 0000000000..b6d9f852f5 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_UC8151D @@ -0,0 +1 @@ +Subproject commit b6d9f852f50b489615f3f357f9758d0073335334 diff --git a/frozen/Adafruit_CircuitPython_asyncio b/frozen/Adafruit_CircuitPython_asyncio index c496cfb576..596cc896e5 160000 --- a/frozen/Adafruit_CircuitPython_asyncio +++ b/frozen/Adafruit_CircuitPython_asyncio @@ -1 +1 @@ -Subproject commit c496cfb5768cd506d61100284fdab94dd439ec3b +Subproject commit 596cc896e5c8815caa2a6f405560833193848149 diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw index 148345d232..d4ff0388f3 160000 --- a/frozen/Adafruit_CircuitPython_seesaw +++ b/frozen/Adafruit_CircuitPython_seesaw @@ -1 +1 @@ -Subproject commit 148345d232c83133de3649fb70b471f11501b3d2 +Subproject commit d4ff0388f3e3af2745864f2c3e5926f500673a40 diff --git a/frozen/circuitpython-stage b/frozen/circuitpython-stage index 3bdd335452..4124dfbdaa 160000 --- a/frozen/circuitpython-stage +++ b/frozen/circuitpython-stage @@ -1 +1 @@ -Subproject commit 3bdd335452ff14a53d1e840de043e3159cb3b829 +Subproject commit 4124dfbdaadce1966f457d7d6c6984e9832999bf diff --git a/frozen/mixgo_cp_lib b/frozen/mixgo_cp_lib index 4ba6956d49..d5e3e809d7 160000 --- a/frozen/mixgo_cp_lib +++ b/frozen/mixgo_cp_lib @@ -1 +1 @@ -Subproject commit 4ba6956d49752f2d0cdc73903b86a34c225934ef +Subproject commit d5e3e809d7aa938b233b49526c55bfd2e314272c diff --git a/lib/AnimatedGIF/AnimatedGIF.cpp b/lib/AnimatedGIF/AnimatedGIF.cpp new file mode 100644 index 0000000000..ad79b212b8 --- /dev/null +++ b/lib/AnimatedGIF/AnimatedGIF.cpp @@ -0,0 +1,236 @@ +// +// GIF Animator +// written by Larry Bank +// bitbank@pobox.com +// Arduino port started 7/5/2020 +// Original GIF code written 20+ years ago :) +// The goal of this code is to decode images up to 480x320 +// using no more than 22K of RAM (if sent directly to an LCD display) +// +// Copyright 2020 BitBank Software, Inc. All Rights Reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//=========================================================================== +#include "AnimatedGIF.h" + +// Here is all of the actual code... +#include "gif.inl" + +// +// Memory initialization +// +int AnimatedGIF::open(uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw) +{ + _gif.iError = GIF_SUCCESS; + _gif.pfnRead = readMem; + _gif.pfnSeek = seekMem; + _gif.pfnDraw = pfnDraw; + _gif.pfnOpen = NULL; + _gif.pfnClose = NULL; + _gif.GIFFile.iSize = iDataSize; + _gif.GIFFile.pData = pData; + return GIFInit(&_gif); +} /* open() */ + +int AnimatedGIF::openFLASH(uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw) +{ + _gif.iError = GIF_SUCCESS; + _gif.pfnRead = readFLASH; + _gif.pfnSeek = seekMem; + _gif.pfnDraw = pfnDraw; + _gif.pfnOpen = NULL; + _gif.pfnClose = NULL; + _gif.GIFFile.iSize = iDataSize; + _gif.GIFFile.pData = pData; + return GIFInit(&_gif); +} /* openFLASH() */ + +// +// Returns the first comment block found (if any) +// +int AnimatedGIF::getComment(char *pDest) +{ +int32_t iOldPos; + + iOldPos = _gif.GIFFile.iPos; // keep old position + (*_gif.pfnSeek)(&_gif.GIFFile, _gif.iCommentPos); + (*_gif.pfnRead)(&_gif.GIFFile, (uint8_t *)pDest, _gif.sCommentLen); + (*_gif.pfnSeek)(&_gif.GIFFile, iOldPos); + pDest[_gif.sCommentLen] = 0; // zero terminate the string + return (int)_gif.sCommentLen; +} /* getComment() */ + +// +// Allocate a block of memory to hold the entire canvas (as 8-bpp) +// +int AnimatedGIF::allocFrameBuf(GIF_ALLOC_CALLBACK *pfnAlloc) +{ + if (_gif.iCanvasWidth > 0 && _gif.iCanvasHeight > 0 && _gif.pFrameBuffer == NULL) + { + // Allocate a little extra space for the current line + // as RGB565 or RGB888 + int iCanvasSize = _gif.iCanvasWidth * (_gif.iCanvasHeight+3); + _gif.pFrameBuffer = (unsigned char *)(*pfnAlloc)(iCanvasSize); + if (_gif.pFrameBuffer == NULL) + return GIF_ERROR_MEMORY; + return GIF_SUCCESS; + } + return GIF_INVALID_PARAMETER; +} /* allocFrameBuf() */ +// +// Set the DRAW callback behavior to RAW (default) +// or COOKED (requires allocating a frame buffer) +// +int AnimatedGIF::setDrawType(int iType) +{ + if (iType != GIF_DRAW_RAW && iType != GIF_DRAW_COOKED) + return GIF_INVALID_PARAMETER; // invalid drawing mode + _gif.ucDrawType = (uint8_t)iType; + return GIF_SUCCESS; +} /* setDrawType() */ +// +// Release the memory used by the frame buffer +// +int AnimatedGIF::freeFrameBuf(GIF_FREE_CALLBACK *pfnFree) +{ + if (_gif.pFrameBuffer) + { + (*pfnFree)(_gif.pFrameBuffer); + _gif.pFrameBuffer = NULL; + return GIF_SUCCESS; + } + return GIF_INVALID_PARAMETER; +} /* freeFrameBuf() */ +// +// Return a pointer to the frame buffer (if it was allocated) +// +uint8_t * AnimatedGIF::getFrameBuf() +{ + return _gif.pFrameBuffer; +} /* getFrameBuf() */ + +int AnimatedGIF::getCanvasWidth() +{ + return _gif.iCanvasWidth; +} /* getCanvasWidth() */ + +int AnimatedGIF::getCanvasHeight() +{ + return _gif.iCanvasHeight; +} /* getCanvasHeight() */ + +int AnimatedGIF::getLoopCount() +{ + return _gif.iRepeatCount; +} /* getLoopCount() */ + +int AnimatedGIF::getInfo(GIFINFO *pInfo) +{ + return GIF_getInfo(&_gif, pInfo); +} /* getInfo() */ + +int AnimatedGIF::getLastError() +{ + return _gif.iError; +} /* getLastError() */ + +// +// File (SD/MMC) based initialization +// +int AnimatedGIF::open(const char *szFilename, GIF_OPEN_CALLBACK *pfnOpen, GIF_CLOSE_CALLBACK *pfnClose, GIF_READ_CALLBACK *pfnRead, GIF_SEEK_CALLBACK *pfnSeek, GIF_DRAW_CALLBACK *pfnDraw) +{ + _gif.iError = GIF_SUCCESS; + _gif.pfnRead = pfnRead; + _gif.pfnSeek = pfnSeek; + _gif.pfnDraw = pfnDraw; + _gif.pfnOpen = pfnOpen; + _gif.pfnClose = pfnClose; + _gif.GIFFile.fHandle = (*pfnOpen)(szFilename, &_gif.GIFFile.iSize); + if (_gif.GIFFile.fHandle == NULL) { + _gif.iError = GIF_FILE_NOT_OPEN; + return 0; + } + return GIFInit(&_gif); + +} /* open() */ + +void AnimatedGIF::close() +{ + if (_gif.pfnClose) + (*_gif.pfnClose)(_gif.GIFFile.fHandle); +} /* close() */ + +void AnimatedGIF::reset() +{ + (*_gif.pfnSeek)(&_gif.GIFFile, 0); +} /* reset() */ + +void AnimatedGIF::begin(unsigned char ucPaletteType) +{ + memset(&_gif, 0, sizeof(_gif)); + if (ucPaletteType != GIF_PALETTE_RGB565_LE && ucPaletteType != GIF_PALETTE_RGB565_BE && ucPaletteType != GIF_PALETTE_RGB888) + _gif.iError = GIF_INVALID_PARAMETER; + _gif.ucPaletteType = ucPaletteType; + _gif.ucDrawType = GIF_DRAW_RAW; // assume RAW pixel handling + _gif.pFrameBuffer = NULL; +} /* begin() */ +// +// Play a single frame +// returns: +// 1 = good result and more frames exist +// 0 = no more frames exist, a frame may or may not have been played: use getLastError() and look for GIF_SUCCESS to know if a frame was played +// -1 = error +int AnimatedGIF::playFrame(bool bSync, int *delayMilliseconds, void *pUser) +{ +int rc; +#if !defined( __MACH__ ) && !defined( __LINUX__ ) +long lTime = millis(); +#endif + + if (_gif.GIFFile.iPos >= _gif.GIFFile.iSize-1) // no more data exists + { + (*_gif.pfnSeek)(&_gif.GIFFile, 0); // seek to start + } + if (GIFParseInfo(&_gif, 0)) + { + _gif.pUser = pUser; + if (_gif.iError == GIF_EMPTY_FRAME) // don't try to decode it + return 0; + rc = DecodeLZW(&_gif, 0); + if (rc != 0) // problem + return -1; + } + else + { + // The file is "malformed" in that there is a bunch of non-image data after + // the last frame. Return as if all is well, though if needed getLastError() + // can be used to see if a frame was actually processed: + // GIF_SUCCESS -> frame processed, GIF_EMPTY_FRAME -> no frame processed + if (_gif.iError == GIF_EMPTY_FRAME) + { + if (delayMilliseconds) + *delayMilliseconds = 0; + return 0; + } + return -1; // error parsing the frame info, we may be at the end of the file + } + // Return 1 for more frames or 0 if this was the last frame + if (bSync) + { +#if !defined( __MACH__ ) && !defined( __LINUX__ ) + lTime = millis() - lTime; + if (lTime < _gif.iFrameDelay) // need to pause a bit + delay(_gif.iFrameDelay - lTime); +#endif // __LINUX__ + } + if (delayMilliseconds) // if not NULL, return the frame delay time + *delayMilliseconds = _gif.iFrameDelay; + return (_gif.GIFFile.iPos < _gif.GIFFile.iSize-10); +} /* playFrame() */ diff --git a/lib/AnimatedGIF/AnimatedGIF.h b/lib/AnimatedGIF/AnimatedGIF.h new file mode 100644 index 0000000000..e1868bb6cd --- /dev/null +++ b/lib/AnimatedGIF/AnimatedGIF.h @@ -0,0 +1,216 @@ +// Copyright 2020 BitBank Software, Inc. All Rights Reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//=========================================================================== + +#ifndef __ANIMATEDGIF__ +#define __ANIMATEDGIF__ +#if defined( PICO_BUILD ) || defined( __MACH__ ) || defined( __LINUX__ ) || defined( __MCUXPRESSO ) +#include +#include +#include +#include +#define memcpy_P memcpy +#define PROGMEM +#else +#include +#endif +// +// GIF Animator +// Written by Larry Bank +// Copyright (c) 2020 BitBank Software, Inc. +// bitbank@pobox.com +// +// Designed to decode images up to 480x320 +// using less than 22K of RAM +// + +/* GIF Defines and variables */ +#define MAX_CHUNK_SIZE 255 +#define LZW_BUF_SIZE (6*MAX_CHUNK_SIZE) +#define LZW_HIGHWATER (4*MAX_CHUNK_SIZE) +#ifdef __LINUX__ +#define MAX_WIDTH 2048 +#else +#define MAX_WIDTH 320 +#endif // __LINUX__ +#define FILE_BUF_SIZE 4096 + +#define PIXEL_FIRST 0 +#define PIXEL_LAST 4096 +#define LINK_UNUSED 5911 // 0x1717 to use memset +#define LINK_END 5912 +#define MAX_HASH 5003 +#define MAXMAXCODE 4096 + +enum { + GIF_PALETTE_RGB565_LE = 0, // little endian (default) + GIF_PALETTE_RGB565_BE, // big endian + GIF_PALETTE_RGB888 // original 24-bpp entries +}; +// for compatibility with older code +#define LITTLE_ENDIAN_PIXELS GIF_PALETTE_RGB565_LE +#define BIG_ENDIAN_PIXELS GIF_PALETTE_RGB565_BE +// +// Draw callback pixel type +// RAW = 8-bit palettized pixels requiring transparent pixel handling +// COOKED = 16 or 24-bpp fully rendered pixels ready for display +// +enum { + GIF_DRAW_RAW = 0, + GIF_DRAW_COOKED +}; + +enum { + GIF_SUCCESS = 0, + GIF_DECODE_ERROR, + GIF_TOO_WIDE, + GIF_INVALID_PARAMETER, + GIF_UNSUPPORTED_FEATURE, + GIF_FILE_NOT_OPEN, + GIF_EARLY_EOF, + GIF_EMPTY_FRAME, + GIF_BAD_FILE, + GIF_ERROR_MEMORY +}; + +typedef struct gif_file_tag +{ + int32_t iPos; // current file position + int32_t iSize; // file size + uint8_t *pData; // memory file pointer + void * fHandle; // class pointer to File/SdFat or whatever you want +} GIFFILE; + +typedef struct gif_info_tag +{ + int32_t iFrameCount; // total frames in file + int32_t iDuration; // duration of animation in milliseconds + int32_t iMaxDelay; // maximum frame delay + int32_t iMinDelay; // minimum frame delay +} GIFINFO; + +typedef struct gif_draw_tag +{ + int iX, iY; // Corner offset of this frame on the canvas + int y; // current line being drawn (0 = top line of image) + int iWidth, iHeight; // size of this frame + void *pUser; // user supplied pointer + uint8_t *pPixels; // 8-bit source pixels for this line + uint16_t *pPalette; // little or big-endian RGB565 palette entries (default) + uint8_t *pPalette24; // RGB888 palette (optional) + uint8_t ucTransparent; // transparent color + uint8_t ucHasTransparency; // flag indicating the transparent color is in use + uint8_t ucDisposalMethod; // frame disposal method + uint8_t ucBackground; // background color + uint8_t ucIsGlobalPalette; // Flag to indicate that a global palette, rather than a local palette is being used +} GIFDRAW; + +// Callback function prototypes +typedef int32_t (GIF_READ_CALLBACK)(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen); +typedef int32_t (GIF_SEEK_CALLBACK)(GIFFILE *pFile, int32_t iPosition); +typedef void (GIF_DRAW_CALLBACK)(GIFDRAW *pDraw); +typedef void * (GIF_OPEN_CALLBACK)(const char *szFilename, int32_t *pFileSize); +typedef void (GIF_CLOSE_CALLBACK)(void *pHandle); +typedef void * (GIF_ALLOC_CALLBACK)(uint32_t iSize); +typedef void (GIF_FREE_CALLBACK)(void *buffer); +// +// our private structure to hold a GIF image decode state +// +typedef struct gif_image_tag +{ + int iWidth, iHeight, iCanvasWidth, iCanvasHeight; + int iX, iY; // GIF corner offset + int iBpp; + int iError; // last error + int iFrameDelay; // delay in milliseconds for this frame + int iRepeatCount; // NETSCAPE animation repeat count. 0=forever + int iXCount, iYCount; // decoding position in image (countdown values) + int iLZWOff; // current LZW data offset + int iLZWSize; // current quantity of data in the LZW buffer + int iCommentPos; // file offset of start of comment data + short sCommentLen; // length of comment + GIF_READ_CALLBACK *pfnRead; + GIF_SEEK_CALLBACK *pfnSeek; + GIF_DRAW_CALLBACK *pfnDraw; + GIF_OPEN_CALLBACK *pfnOpen; + GIF_CLOSE_CALLBACK *pfnClose; + GIFFILE GIFFile; + void *pUser; + unsigned char *pFrameBuffer; + unsigned char *pPixels, *pOldPixels; + unsigned char ucLineBuf[MAX_WIDTH]; // current line + unsigned char ucFileBuf[FILE_BUF_SIZE]; // holds temp data and pixel stack + unsigned short pPalette[384]; // can hold RGB565 or RGB888 - set in begin() + unsigned short pLocalPalette[384]; // color palettes for GIF images + unsigned char ucLZW[LZW_BUF_SIZE]; // holds 6 chunks (6x255) of GIF LZW data packed together + unsigned short usGIFTable[4096]; + unsigned char ucGIFPixels[8192]; + unsigned char bEndOfFrame; + unsigned char ucGIFBits, ucBackground, ucTransparent, ucCodeStart, ucMap, bUseLocalPalette; + unsigned char ucPaletteType; // RGB565 or RGB888 + unsigned char ucDrawType; // RAW or COOKED +} GIFIMAGE; + +#ifdef __cplusplus +// +// The GIF class wraps portable C code which does the actual work +// +class AnimatedGIF +{ + public: + int open(uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw); + int openFLASH(uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw); + int open(const char *szFilename, GIF_OPEN_CALLBACK *pfnOpen, GIF_CLOSE_CALLBACK *pfnClose, GIF_READ_CALLBACK *pfnRead, GIF_SEEK_CALLBACK *pfnSeek, GIF_DRAW_CALLBACK *pfnDraw); + void close(); + void reset(); + void begin(unsigned char ucPaletteType = GIF_PALETTE_RGB565_LE); + void begin(int iEndian, unsigned char ucPaletteType) { begin(ucPaletteType); }; + int playFrame(bool bSync, int *delayMilliseconds, void *pUser = NULL); + int getCanvasWidth(); + int allocFrameBuf(GIF_ALLOC_CALLBACK *pfnAlloc); + int setDrawType(int iType); + int freeFrameBuf(GIF_FREE_CALLBACK *pfnFree); + uint8_t *getFrameBuf(); + int getCanvasHeight(); + int getLoopCount(); + int getInfo(GIFINFO *pInfo); + int getLastError(); + int getComment(char *destBuffer); + + private: + GIFIMAGE _gif; +}; +#else +// C interface + int GIF_openRAM(GIFIMAGE *pGIF, uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw); + int GIF_openFile(GIFIMAGE *pGIF, const char *szFilename, GIF_DRAW_CALLBACK *pfnDraw); + void GIF_close(GIFIMAGE *pGIF); + void GIF_begin(GIFIMAGE *pGIF, unsigned char ucPaletteType); + void GIF_reset(GIFIMAGE *pGIF); + int GIF_playFrame(GIFIMAGE *pGIF, int *delayMilliseconds, void *pUser); + int GIF_getCanvasWidth(GIFIMAGE *pGIF); + int GIF_getCanvasHeight(GIFIMAGE *pGIF); + int GIF_getComment(GIFIMAGE *pGIF, char *destBuffer); + int GIF_getInfo(GIFIMAGE *pGIF, GIFINFO *pInfo); + int GIF_getLastError(GIFIMAGE *pGIF); + int GIF_getLoopCount(GIFIMAGE *pGIF); +#endif // __cplusplus + +// Due to unaligned memory causing an exception, we have to do these macros the slow way +#define INTELSHORT(p) ((*p) + (*(p+1)<<8)) +#define INTELLONG(p) ((*p) + (*(p+1)<<8) + (*(p+2)<<16) + (*(p+3)<<24)) +#define MOTOSHORT(p) (((*(p))<<8) + (*(p+1))) +#define MOTOLONG(p) (((*p)<<24) + ((*(p+1))<<16) + ((*(p+2))<<8) + (*(p+3))) + +// Must be a 32-bit target processor +#define REGISTER_WIDTH 32 + +#endif // __ANIMATEDGIF__ diff --git a/lib/AnimatedGIF/AnimatedGIF_circuitpy.h b/lib/AnimatedGIF/AnimatedGIF_circuitpy.h new file mode 100644 index 0000000000..c1f359194f --- /dev/null +++ b/lib/AnimatedGIF/AnimatedGIF_circuitpy.h @@ -0,0 +1,182 @@ +// Copyright 2020 BitBank Software, Inc. All Rights Reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// =========================================================================== +// +// Modified 2023 by Mark Komus to work for CircuitPython +// + +#ifndef __ANIMATEDGIF__ +#define __ANIMATEDGIF__ +#include +#include +#include +#include +// +// GIF Animator +// Written by Larry Bank +// Copyright (c) 2020 BitBank Software, Inc. +// bitbank@pobox.com +// +// Designed to decode images up to 480x320 +// using less than 22K of RAM +// + +/* GIF Defines and variables */ +#define MAX_CHUNK_SIZE 255 +#define LZW_BUF_SIZE (6 * MAX_CHUNK_SIZE) +#define LZW_HIGHWATER (4 * MAX_CHUNK_SIZE) +#define MAX_WIDTH 320 +#define FILE_BUF_SIZE 4096 + +#define PIXEL_FIRST 0 +#define PIXEL_LAST 4096 +#define LINK_UNUSED 5911 // 0x1717 to use memset +#define LINK_END 5912 +#define MAX_HASH 5003 +#define MAXMAXCODE 4096 + +enum { + GIF_PALETTE_RGB565_LE = 0, // little endian (default) + GIF_PALETTE_RGB565_BE, // big endian + GIF_PALETTE_RGB888 // original 24-bpp entries +}; +// for compatibility with older code +#define LITTLE_ENDIAN_PIXELS GIF_PALETTE_RGB565_LE +#define BIG_ENDIAN_PIXELS GIF_PALETTE_RGB565_BE +// +// Draw callback pixel type +// RAW = 8-bit palettized pixels requiring transparent pixel handling +// COOKED = 16 or 24-bpp fully rendered pixels ready for display +// +enum { + GIF_DRAW_RAW = 0, + GIF_DRAW_COOKED +}; + +enum { + GIF_SUCCESS = 0, + GIF_DECODE_ERROR, + GIF_TOO_WIDE, + GIF_INVALID_PARAMETER, + GIF_UNSUPPORTED_FEATURE, + GIF_FILE_NOT_OPEN, + GIF_EARLY_EOF, + GIF_EMPTY_FRAME, + GIF_BAD_FILE, + GIF_ERROR_MEMORY +}; + +typedef struct gif_file_tag +{ + int32_t iPos; // current file position + int32_t iSize; // file size + uint8_t *pData; // memory file pointer + void *fHandle; // class pointer to File/SdFat or whatever you want +} GIFFILE; + +typedef struct gif_info_tag +{ + int32_t iFrameCount; // total frames in file + int32_t iDuration; // duration of animation in milliseconds + int32_t iMaxDelay; // maximum frame delay + int32_t iMinDelay; // minimum frame delay +} GIFINFO; + +typedef struct gif_draw_tag +{ + int iX, iY; // Corner offset of this frame on the canvas + int y; // current line being drawn (0 = top line of image) + int iWidth, iHeight; // size of this frame + void *pUser; // user supplied pointer + uint8_t *pPixels; // 8-bit source pixels for this line + uint16_t *pPalette; // little or big-endian RGB565 palette entries (default) + uint8_t *pPalette24; // RGB888 palette (optional) + uint8_t ucTransparent; // transparent color + uint8_t ucHasTransparency; // flag indicating the transparent color is in use + uint8_t ucDisposalMethod; // frame disposal method + uint8_t ucBackground; // background color + uint8_t ucIsGlobalPalette; // Flag to indicate that a global palette, rather than a local palette is being used +} GIFDRAW; + +// Callback function prototypes +typedef int32_t (GIF_READ_CALLBACK)(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen); +typedef int32_t (GIF_SEEK_CALLBACK)(GIFFILE *pFile, int32_t iPosition); +typedef void (GIF_DRAW_CALLBACK)(GIFDRAW *pDraw); +typedef void * (GIF_OPEN_CALLBACK)(const char *szFilename, int32_t *pFileSize); +typedef void (GIF_CLOSE_CALLBACK)(void *pHandle); +typedef void * (GIF_ALLOC_CALLBACK)(uint32_t iSize); +typedef void (GIF_FREE_CALLBACK)(void *buffer); +// +// our private structure to hold a GIF image decode state +// +typedef struct gif_image_tag +{ + int iWidth, iHeight, iCanvasWidth, iCanvasHeight; + int iX, iY; // GIF corner offset + int iBpp; + int iError; // last error + int iFrameDelay; // delay in milliseconds for this frame + int iRepeatCount; // NETSCAPE animation repeat count. 0=forever + int iXCount, iYCount; // decoding position in image (countdown values) + int iLZWOff; // current LZW data offset + int iLZWSize; // current quantity of data in the LZW buffer + int iCommentPos; // file offset of start of comment data + short sCommentLen; // length of comment + GIF_READ_CALLBACK *pfnRead; + GIF_SEEK_CALLBACK *pfnSeek; + GIF_DRAW_CALLBACK *pfnDraw; + GIF_OPEN_CALLBACK *pfnOpen; + GIF_CLOSE_CALLBACK *pfnClose; + GIFFILE GIFFile; + void *pUser; + //unsigned char *pFrameBuffer; + unsigned int *pFrameBuffer; + unsigned char *pPixels, *pOldPixels; + unsigned char ucLineBuf[MAX_WIDTH]; // current line + unsigned char ucFileBuf[FILE_BUF_SIZE]; // holds temp data and pixel stack + unsigned short pPalette[384]; // can hold RGB565 or RGB888 - set in begin() + unsigned short pLocalPalette[384]; // color palettes for GIF images + unsigned char ucLZW[LZW_BUF_SIZE]; // holds 6 chunks (6x255) of GIF LZW data packed together + unsigned short usGIFTable[4096]; + unsigned char ucGIFPixels[8192]; + unsigned char bEndOfFrame; + unsigned char ucGIFBits, ucBackground, ucTransparent, ucCodeStart, ucMap, bUseLocalPalette; + unsigned char ucPaletteType; // RGB565 or RGB888 + unsigned char ucDrawType; // RAW or COOKED +} GIFIMAGE; + +// C interface +int GIF_openRAM(GIFIMAGE *pGIF, uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw); +int GIF_openFile(GIFIMAGE *pGIF, const char *szFilename, GIF_DRAW_CALLBACK *pfnDraw); +void GIF_close(GIFIMAGE *pGIF); +void GIF_begin(GIFIMAGE *pGIF, unsigned char ucPaletteType); +void GIF_reset(GIFIMAGE *pGIF); +int GIF_playFrame(GIFIMAGE *pGIF, int *delayMilliseconds, void *pUser); +int GIF_getCanvasWidth(GIFIMAGE *pGIF); +int GIF_getCanvasHeight(GIFIMAGE *pGIF); +int GIF_getComment(GIFIMAGE *pGIF, char *destBuffer); +int GIF_getInfo(GIFIMAGE *pGIF, GIFINFO *pInfo); +int GIF_getLastError(GIFIMAGE *pGIF); +int GIF_getLoopCount(GIFIMAGE *pGIF); +int GIF_init(GIFIMAGE *pGIF); +void GIF_setDrawCallback(GIFIMAGE *pGIF, GIF_DRAW_CALLBACK *pfnDraw); +void GIF_scaleHalf(uint16_t *pCurrent, uint16_t *pPrev, int iWidth, int bBigEndian); + +// Due to unaligned memory causing an exception, we have to do these macros the slow way +#define INTELSHORT(p) ((*p) + (*(p + 1) << 8)) +#define INTELLONG(p) ((*p) + (*(p + 1) << 8) + (*(p + 2) << 16) + (*(p + 3) << 24)) +#define MOTOSHORT(p) (((*(p)) << 8) + (*(p + 1))) +#define MOTOLONG(p) (((*p) << 24) + ((*(p + 1)) << 16) + ((*(p + 2)) << 8) + (*(p + 3))) + +// Must be a 32-bit target processor +#define REGISTER_WIDTH 32 + +#endif // __ANIMATEDGIF__ diff --git a/lib/AnimatedGIF/README.md b/lib/AnimatedGIF/README.md new file mode 100644 index 0000000000..25b8cd59b7 --- /dev/null +++ b/lib/AnimatedGIF/README.md @@ -0,0 +1,5 @@ +This library is from the AnimatedGIF Arduino GIF decoder by Larry Bank. +Released under the Apache License 2.0 +[AnimatedGIF](https://github.com/bitbank2/AnimatedGIF) + +It has been modified for use in CircuitPython by Mark Komus. diff --git a/lib/AnimatedGIF/gif.c b/lib/AnimatedGIF/gif.c new file mode 100644 index 0000000000..0822b608c1 --- /dev/null +++ b/lib/AnimatedGIF/gif.c @@ -0,0 +1,1043 @@ +// +// GIF Animator +// written by Larry Bank +// bitbank@pobox.com +// Arduino port started 7/5/2020 +// Original GIF code written 20+ years ago :) +// The goal of this code is to decode images up to 480x320 +// using no more than 22K of RAM (if sent directly to an LCD display) +// +// Copyright 2020 BitBank Software, Inc. All Rights Reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//=========================================================================== +// +// Modified 2023 by Mark Komus to work for CircuitPython +// +#include "AnimatedGIF_circuitpy.h" + +#ifdef HAL_ESP32_HAL_H_ +#define memcpy_P memcpy +#endif + +static const unsigned char cGIFBits[9] = {1,4,4,4,8,8,8,8,8}; // convert odd bpp values to ones we can handle + +// forward references +static int GIFInit(GIFIMAGE *pGIF); +static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly); +static int GIFGetMoreData(GIFIMAGE *pPage); +static void GIFMakePels(GIFIMAGE *pPage, unsigned int code); +static int DecodeLZW(GIFIMAGE *pImage, int iOptions); +static int32_t readMem(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen); +static int32_t seekMem(GIFFILE *pFile, int32_t iPosition); +int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo); + +#if defined ( __LINUX__ ) || defined( __MCUXPRESSO ) +static int32_t readFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen); +static int32_t seekFile(GIFFILE *pFile, int32_t iPosition); +static void closeFile(void *handle); +#endif + +// C API +int GIF_openRAM(GIFIMAGE *pGIF, uint8_t *pData, int iDataSize, GIF_DRAW_CALLBACK *pfnDraw) +{ + pGIF->iError = GIF_SUCCESS; + pGIF->pfnRead = readMem; + pGIF->pfnSeek = seekMem; + pGIF->pfnDraw = pfnDraw; + pGIF->pfnOpen = NULL; + pGIF->pfnClose = NULL; + pGIF->GIFFile.iSize = iDataSize; + pGIF->GIFFile.pData = pData; + return GIFInit(pGIF); +} /* GIF_openRAM() */ + +#ifdef __LINUX__ +int GIF_openFile(GIFIMAGE *pGIF, const char *szFilename, GIF_DRAW_CALLBACK *pfnDraw) +{ + pGIF->iError = GIF_SUCCESS; + pGIF->pfnRead = readFile; + pGIF->pfnSeek = seekFile; + pGIF->pfnDraw = pfnDraw; + pGIF->pfnOpen = NULL; + pGIF->pfnClose = closeFile; + pGIF->GIFFile.fHandle = fopen(szFilename, "r+b"); + if (pGIF->GIFFile.fHandle == NULL) + return 0; + fseek((FILE *)pGIF->GIFFile.fHandle, 0, SEEK_END); + pGIF->GIFFile.iSize = (int)ftell((FILE *)pGIF->GIFFile.fHandle); + fseek((FILE *)pGIF->GIFFile.fHandle, 0, SEEK_SET); + return GIFInit(pGIF); +} /* GIF_openFile() */ +#endif + +void GIF_close(GIFIMAGE *pGIF) +{ + if (pGIF->pfnClose) + (*pGIF->pfnClose)(pGIF->GIFFile.fHandle); +} /* GIF_close() */ + +void GIF_begin(GIFIMAGE *pGIF, unsigned char ucPaletteType) +{ + memset(pGIF, 0, sizeof(GIFIMAGE)); + pGIF->ucPaletteType = ucPaletteType; +} /* GIF_begin() */ + +void GIF_reset(GIFIMAGE *pGIF) +{ + (*pGIF->pfnSeek)(&pGIF->GIFFile, 0); +} /* GIF_reset() */ + +// +// Return value: +// 1 = good decode, more frames exist +// 0 = good decode, no more frames +// -1 = error +// +int GIF_playFrame(GIFIMAGE *pGIF, int *delayMilliseconds, void *pUser) +{ +int rc; + + if (delayMilliseconds) + *delayMilliseconds = 0; // clear any old valid + if (pGIF->GIFFile.iPos >= pGIF->GIFFile.iSize-1) // no more data exists + { + (*pGIF->pfnSeek)(&pGIF->GIFFile, 0); // seek to start + } + if (GIFParseInfo(pGIF, 0)) + { + pGIF->pUser = pUser; + if (pGIF->iError == GIF_EMPTY_FRAME) // don't try to decode it + return 0; + rc = DecodeLZW(pGIF, 0); + if (rc != 0) // problem + return 0; + } + else + { + return 0; // error parsing the frame info, we may be at the end of the file + } + // Return 1 for more frames or 0 if this was the last frame + if (delayMilliseconds) // if not NULL, return the frame delay time + *delayMilliseconds = pGIF->iFrameDelay; + return (pGIF->GIFFile.iPos < pGIF->GIFFile.iSize-1); +} /* GIF_playFrame() */ + +int GIF_getCanvasWidth(GIFIMAGE *pGIF) +{ + return pGIF->iCanvasWidth; +} /* GIF_getCanvasWidth() */ + +int GIF_getCanvasHeight(GIFIMAGE *pGIF) +{ + return pGIF->iCanvasHeight; +} /* GIF_getCanvasHeight() */ + +int GIF_getLoopCount(GIFIMAGE *pGIF) +{ + return pGIF->iRepeatCount; +} /* GIF_getLoopCount() */ + +int GIF_getComment(GIFIMAGE *pGIF, char *pDest) +{ +int32_t iOldPos; + + iOldPos = pGIF->GIFFile.iPos; // keep old position + (*pGIF->pfnSeek)(&pGIF->GIFFile, pGIF->iCommentPos); + (*pGIF->pfnRead)(&pGIF->GIFFile, (uint8_t *)pDest, pGIF->sCommentLen); + (*pGIF->pfnSeek)(&pGIF->GIFFile, iOldPos); + pDest[pGIF->sCommentLen] = 0; // zero terminate the string + return (int)pGIF->sCommentLen; + +} /* GIF_getComment() */ + +int GIF_getLastError(GIFIMAGE *pGIF) +{ + return pGIF->iError; +} /* GIF_getLastError() */ + +int GIF_init(GIFIMAGE *pGIF) { + return GIFInit(pGIF); +} + +// +// Helper functions for memory based images +// +static int32_t readMem(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) +{ + int32_t iBytesRead; + + iBytesRead = iLen; + if ((pFile->iSize - pFile->iPos) < iLen) + iBytesRead = pFile->iSize - pFile->iPos; + if (iBytesRead <= 0) + return 0; + memmove(pBuf, &pFile->pData[pFile->iPos], iBytesRead); + pFile->iPos += iBytesRead; + return iBytesRead; +} /* readMem() */ + +#ifndef CIRCUITPY +static int32_t readFLASH(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) +{ + int32_t iBytesRead; + + iBytesRead = iLen; + if ((pFile->iSize - pFile->iPos) < iLen) + iBytesRead = pFile->iSize - pFile->iPos; + if (iBytesRead <= 0) + return 0; + memcpy_P(pBuf, &pFile->pData[pFile->iPos], iBytesRead); + pFile->iPos += iBytesRead; + return iBytesRead; +} /* readFLASH() */ +#endif + +static int32_t seekMem(GIFFILE *pFile, int32_t iPosition) +{ + if (iPosition < 0) iPosition = 0; + else if (iPosition >= pFile->iSize) iPosition = pFile->iSize-1; + pFile->iPos = iPosition; + return iPosition; +} /* seekMem() */ + +#if defined ( __LINUX__ ) || defined( __MCUXPRESSO ) +static void closeFile(void *handle) +{ + fclose((FILE *)handle); +} /* closeFile() */ + +static int32_t seekFile(GIFFILE *pFile, int32_t iPosition) +{ + if (iPosition < 0) iPosition = 0; + else if (iPosition >= pFile->iSize) iPosition = pFile->iSize-1; + pFile->iPos = iPosition; + fseek((FILE *)pFile->fHandle, iPosition, SEEK_SET); + return iPosition; +} /* seekMem() */ + +static int32_t readFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) +{ + int32_t iBytesRead; + + iBytesRead = iLen; + if ((pFile->iSize - pFile->iPos) < iLen) + iBytesRead = pFile->iSize - pFile->iPos; + if (iBytesRead <= 0) + return 0; + iBytesRead = (int)fread(pBuf, 1, iBytesRead, (FILE *)pFile->fHandle); + pFile->iPos += iBytesRead; + return iBytesRead; +} /* readFile() */ + +#endif // __LINUX__ +// +// The following functions are written in plain C and have no +// 3rd party dependencies, not even the C runtime library +// +// +// Initialize a GIF file and callback access from a file on SD or memory +// returns 1 for success, 0 for failure +// Fills in the canvas size of the GIFIMAGE structure +// +static int GIFInit(GIFIMAGE *pGIF) +{ + pGIF->GIFFile.iPos = 0; // start at beginning of file + if (!GIFParseInfo(pGIF, 1)) // gather info for the first frame + return 0; // something went wrong; not a GIF file? + (*pGIF->pfnSeek)(&pGIF->GIFFile, 0); // seek back to start of the file + if (pGIF->iCanvasWidth > MAX_WIDTH) { // need to allocate more space + pGIF->iError = GIF_TOO_WIDE; + return 0; + } + return 1; +} /* GIFInit() */ + +// +// Parse the GIF header, gather the size and palette info +// If called with bInfoOnly set to true, it will test for a valid file +// and return the canvas size only +// Returns 1 for success, 0 for failure +// +static int GIFParseInfo(GIFIMAGE *pPage, int bInfoOnly) +{ + int i, j, iColorTableBits; + int iBytesRead; + unsigned char c, *p; + int32_t iOffset = 0; + int32_t iStartPos = pPage->GIFFile.iPos; // starting file position + int iReadSize; + + pPage->bUseLocalPalette = 0; // assume no local palette + pPage->bEndOfFrame = 0; // we're just getting started + pPage->iFrameDelay = 0; // may not have a gfx extension block + pPage->iRepeatCount = -1; // assume NETSCAPE loop count is not specified + iReadSize = (bInfoOnly) ? 12 : MAX_CHUNK_SIZE; + // If you try to read past the EOF, the SD lib will return garbage data + if (iStartPos + iReadSize > pPage->GIFFile.iSize) + iReadSize = (pPage->GIFFile.iSize - iStartPos - 1); + p = pPage->ucFileBuf; + iBytesRead = (*pPage->pfnRead)(&pPage->GIFFile, pPage->ucFileBuf, iReadSize); // 255 is plenty for now + + if (iBytesRead != iReadSize) // we're at the end of the file + { + pPage->iError = GIF_EARLY_EOF; + return 0; + } + if (iStartPos == 0) // start of the file + { // canvas size + if (memcmp(p, "GIF89", 5) != 0 && memcmp(p, "GIF87", 5) != 0) // not a GIF file + { + pPage->iError = GIF_BAD_FILE; + return 0; + } + pPage->iCanvasWidth = pPage->iWidth = INTELSHORT(&p[6]); + pPage->iCanvasHeight = pPage->iHeight = INTELSHORT(&p[8]); + pPage->iBpp = ((p[10] & 0x70) >> 4) + 1; + if (bInfoOnly) + return 1; // we've got the info we needed, leave + iColorTableBits = (p[10] & 7) + 1; // Log2(size) of the color table + pPage->ucBackground = p[11]; // background color + pPage->ucGIFBits = 0; + iOffset = 13; + if (p[10] & 0x80) // global color table? + { // by default, convert to byte-reversed RGB565 for immediate use + // Read enough additional data for the color table + iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], 3*(1<ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE) + { + for (i=0; i<(1<> 3) << 11); // R + usRGB565 |= ((p[iOffset+1] >> 2) << 5); // G + usRGB565 |= (p[iOffset+2] >> 3); // B + if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE) + pPage->pPalette[i] = usRGB565; + else + pPage->pPalette[i] = __builtin_bswap16(usRGB565); // SPI wants MSB first + iOffset += 3; + } + } + else // just copy it as-is + { + memcpy(pPage->pPalette, &p[iOffset], (1<ucGIFBits = p[iOffset+1]; // packed fields + pPage->iFrameDelay = (INTELSHORT(&p[iOffset+2]))*10; // delay in ms + if (pPage->iFrameDelay <= 1) // 0-1 is going to make it run at 60fps; use 100 (10fps) as a reasonable substitute + pPage->iFrameDelay = 100; + if (pPage->ucGIFBits & 1) // transparent color is used + pPage->ucTransparent = p[iOffset+4]; // transparent color index + iOffset += 6; + } + // else // error + break; + case 0xff: /* App extension */ + c = 1; + while (c) /* Skip all data sub-blocks */ + { + c = p[iOffset++]; /* Block length */ + if ((iBytesRead - iOffset) < (c+32)) // need to read more data first + { + memmove(pPage->ucFileBuf, &pPage->ucFileBuf[iOffset], (iBytesRead-iOffset)); // move existing data down + iBytesRead -= iOffset; + iStartPos += iOffset; + iOffset = 0; + iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], c+32); + } + if (c == 11) // fixed block length + { // Netscape app block contains the repeat count + if (memcmp(&p[iOffset], "NETSCAPE2.0", 11) == 0) + { + if (p[iOffset+11] == 3 && p[iOffset+12] == 1) // loop count + pPage->iRepeatCount = INTELSHORT(&p[iOffset+13]); + } + } + iOffset += (int)c; /* Skip to next sub-block */ + } + break; + case 0x01: /* Text extension */ + c = 1; + j = 0; + while (c) /* Skip all data sub-blocks */ + { + c = p[iOffset++]; /* Block length */ + if (j == 0) // use only first block + { + j = c; + if (j > 127) // max comment length = 127 + j = 127; + // memcpy(pPage->szInfo1, &p[iOffset], j); + // pPage->szInfo1[j] = '\0'; + j = 1; + } + iOffset += (int)c; /* Skip this sub-block */ + } + break; + case 0xfe: /* Comment */ + c = 1; + while (c) /* Skip all data sub-blocks */ + { + c = p[iOffset++]; /* Block length */ + if ((iBytesRead - iOffset) < (c+32)) // need to read more data first + { + memmove(pPage->ucFileBuf, &pPage->ucFileBuf[iOffset], (iBytesRead-iOffset)); // move existing data down + iBytesRead -= iOffset; + iStartPos += iOffset; + iOffset = 0; + iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], c+32); + } + if (pPage->iCommentPos == 0) // Save first block info + { + pPage->iCommentPos = iStartPos + iOffset; + pPage->sCommentLen = c; + } + iOffset += (int)c; /* Skip this sub-block */ + } + break; + default: + /* Bad header info */ + pPage->iError = GIF_DECODE_ERROR; + return 0; + } /* switch */ + } + else // invalid byte, stop decoding + { + if (pPage->GIFFile.iSize - iStartPos < 32) // non-image bytes at end of file? + pPage->iError = GIF_EMPTY_FRAME; + else + /* Bad header info */ + pPage->iError = GIF_DECODE_ERROR; + return 0; + } + } /* while */ + if (p[iOffset] == ';') { // end of file, quit and return a correct error code + pPage->iError = GIF_EMPTY_FRAME; + return 1; + } + + if (p[iOffset] == ',') + iOffset++; + // This particular frame's size and position on the main frame (if animated) + pPage->iX = INTELSHORT(&p[iOffset]); + pPage->iY = INTELSHORT(&p[iOffset+2]); + pPage->iWidth = INTELSHORT(&p[iOffset+4]); + pPage->iHeight = INTELSHORT(&p[iOffset+6]); + iOffset += 8; + + /* Image descriptor + 7 6 5 4 3 2 1 0 M=0 - use global color map, ignore pixel + M I 0 0 0 pixel M=1 - local color map follows, use pixel + I=0 - Image in sequential order + I=1 - Image in interlaced order + pixel+1 = # bits per pixel for this image + */ + pPage->ucMap = p[iOffset++]; + if (pPage->ucMap & 0x80) // local color table? + {// by default, convert to byte-reversed RGB565 for immediate use + j = (1<<((pPage->ucMap & 7)+1)); + // Read enough additional data for the color table + iBytesRead += (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucFileBuf[iBytesRead], j*3); + if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE) + { + for (i=0; i> 3) << 11); // R + usRGB565 |= ((p[iOffset+1] >> 2) << 5); // G + usRGB565 |= (p[iOffset+2] >> 3); // B + if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE) + pPage->pLocalPalette[i] = usRGB565; + else + pPage->pLocalPalette[i] = __builtin_bswap16(usRGB565); // SPI wants MSB first + iOffset += 3; + } + } + else // just copy it as-is + { + memcpy(pPage->pLocalPalette, &p[iOffset], j * 3); + iOffset += j*3; + } + pPage->bUseLocalPalette = 1; + } + pPage->ucCodeStart = p[iOffset++]; /* initial code size */ + /* Since GIF can be 1-8 bpp, we only allow 1,4,8 */ + pPage->iBpp = cGIFBits[pPage->ucCodeStart]; + // we are re-using the same buffer turning GIF file data + // into "pure" LZW + pPage->iLZWSize = 0; // we're starting with no LZW data yet + c = 1; // get chunk length + while (c && iOffset < iBytesRead) + { +// Serial.printf("iOffset=%d, iBytesRead=%d\n", iOffset, iBytesRead); + c = p[iOffset++]; // get chunk length +// Serial.printf("Chunk size = %d\n", c); + if (c <= (iBytesRead - iOffset)) + { + memcpy(&pPage->ucLZW[pPage->iLZWSize], &p[iOffset], c); + pPage->iLZWSize += c; + iOffset += c; + } + else // partial chunk in our buffer + { + int iPartialLen = (iBytesRead - iOffset); + memcpy(&pPage->ucLZW[pPage->iLZWSize], &p[iOffset], iPartialLen); + pPage->iLZWSize += iPartialLen; + iOffset += iPartialLen; + (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucLZW[pPage->iLZWSize], c - iPartialLen); + pPage->iLZWSize += (c - iPartialLen); + } + if (c == 0) + pPage->bEndOfFrame = 1; // signal not to read beyond the end of the frame + } +// seeking on an SD card is VERY VERY SLOW, so use the data we've already read by de-chunking it +// in this case, there's too much data, so we have to seek backwards a bit + if (iOffset < iBytesRead) + { +// Serial.printf("Need to seek back %d bytes\n", iBytesRead - iOffset); + (*pPage->pfnSeek)(&pPage->GIFFile, iStartPos + iOffset); // position file to new spot + } + return 1; // we are now at the start of the chunk data +} /* GIFParseInfo() */ +// +// Gather info about an animated GIF file +// +int GIF_getInfo(GIFIMAGE *pPage, GIFINFO *pInfo) +{ + int iOff, iNumFrames; + int iDelay, iMaxDelay, iMinDelay, iTotalDelay; + int iReadAmount; + int iDataAvailable = 0; + int iDataRemaining = 0; + uint32_t lFileOff = 0; + int bDone = 0; + int bExt; + uint8_t c, *cBuf; + + iMaxDelay = iTotalDelay = 0; + iMinDelay = 10000; + iNumFrames = 1; + iDataRemaining = pPage->GIFFile.iSize; + cBuf = (uint8_t *) pPage->ucFileBuf; + (*pPage->pfnSeek)(&pPage->GIFFile, 0); + iDataAvailable = (*pPage->pfnRead)(&pPage->GIFFile, cBuf, FILE_BUF_SIZE); + iDataRemaining -= iDataAvailable; + lFileOff += iDataAvailable; + iOff = 10; + c = cBuf[iOff]; // get info bits + iOff += 3; /* Skip flags, background color & aspect ratio */ + if (c & 0x80) /* Deal with global color table */ + { + c &= 7; /* Get the number of colors defined */ + iOff += (2<pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE-iDataAvailable); + iDataAvailable += iReadAmount; + iDataRemaining -= iReadAmount; + lFileOff += iReadAmount; + } + switch(cBuf[iOff]) + { + case 0x3b: /* End of file */ + /* we were fooled into thinking there were more pages */ + iNumFrames--; + goto gifpagesz; + // F9 = Graphic Control Extension (fixed length of 4 bytes) + // FE = Comment Extension + // FF = Application Extension + // 01 = Plain Text Extension + case 0x21: /* Extension block */ + if (cBuf[iOff+1] == 0xf9 && cBuf[iOff+2] == 4) // Graphic Control Extension + { + //cBuf[iOff+3]; // page disposition flags + iDelay = cBuf[iOff+4]; // delay low byte + iDelay |= ((uint16_t)(cBuf[iOff+5]) << 8); // delay high byte + if (iDelay < 2) // too fast, provide a default + iDelay = 2; + iDelay *= 10; // turn JIFFIES into milliseconds + iTotalDelay += iDelay; + if (iDelay > iMaxDelay) iMaxDelay = iDelay; + else if (iDelay < iMinDelay) iMinDelay = iDelay; + // (cBuf[iOff+6]; // transparent color index + } + iOff += 2; /* skip to length */ + iOff += (int)cBuf[iOff]; /* Skip the data block */ + iOff++; + // block terminator or optional sub blocks + c = cBuf[iOff++]; /* Skip any sub-blocks */ + while (c) + { + iOff += (int)c; + c = cBuf[iOff++]; + if ((iDataAvailable - iOff) < (c+258)) // need to read more data first + { + memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down + iDataAvailable -= iOff; + iOff = 0; + iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE-iDataAvailable); + iDataAvailable += iReadAmount; + iDataRemaining -= iReadAmount; + lFileOff += iReadAmount; + } + } + if (c != 0) // problem, we went past the end + { + iNumFrames--; // possible corrupt data; stop + goto gifpagesz; + } + break; + case 0x2c: /* Start of image data */ + bExt = 0; /* Stop doing extension blocks */ + break; + default: + /* Corrupt data, stop here */ + iNumFrames--; + goto gifpagesz; + } // switch + } // while + if (iOff >= iDataAvailable) // problem + { + iNumFrames--; // possible corrupt data; stop + goto gifpagesz; + } + /* Start of image data */ + c = cBuf[iOff+9]; /* Get the flags byte */ + iOff += 10; /* Skip image position and size */ + if (c & 0x80) /* Local color table */ + { + c &= 7; + iOff += (2<pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], FILE_BUF_SIZE-iDataAvailable); + iDataAvailable += iReadAmount; + iDataRemaining -= iReadAmount; + lFileOff += iReadAmount; + } + c = cBuf[iOff++]; + while (c) /* While there are more data blocks */ + { + if (iOff > (3*FILE_BUF_SIZE/4) && iDataRemaining > 0) /* Near end of buffer, re-align */ + { + memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down + iDataAvailable -= iOff; + iOff = 0; + iReadAmount = (FILE_BUF_SIZE - iDataAvailable); + if (iReadAmount > iDataRemaining) + iReadAmount = iDataRemaining; + iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], iReadAmount); + iDataAvailable += iReadAmount; + iDataRemaining -= iReadAmount; + lFileOff += iReadAmount; + } + iOff += (int)c; /* Skip this data block */ +// if ((int)lFileOff + iOff > pPage->GIFFile.iSize) // past end of file, stop +// { +// iNumFrames--; // don't count this page +// break; // last page is corrupted, don't use it +// } + c = cBuf[iOff++]; /* Get length of next */ + } + /* End of image data, check for more pages... */ + if (cBuf[iOff] == 0x3b || (iDataRemaining == 0 && (iDataAvailable - iOff) < 32)) + { + bDone = 1; /* End of file has been reached */ + } + else /* More pages to scan */ + { + iNumFrames++; + // read new page data starting at this offset + if (pPage->GIFFile.iSize > FILE_BUF_SIZE && iDataRemaining > 0) // since we didn't read the whole file in one shot + { + memmove(cBuf, &cBuf[iOff], (iDataAvailable-iOff)); // move existing data down + iDataAvailable -= iOff; + iOff = 0; + iReadAmount = (FILE_BUF_SIZE - iDataAvailable); + if (iReadAmount > iDataRemaining) + iReadAmount = iDataRemaining; + iReadAmount = (*pPage->pfnRead)(&pPage->GIFFile, &cBuf[iDataAvailable], iReadAmount); + iDataAvailable += iReadAmount; + iDataRemaining -= iReadAmount; + lFileOff += iReadAmount; + } + } + } /* while !bDone */ +gifpagesz: + pInfo->iFrameCount = iNumFrames; + pInfo->iMaxDelay = iMaxDelay; + pInfo->iMinDelay = iMinDelay; + pInfo->iDuration = iTotalDelay; + return 1; +} /* GIF_getInfo() */ + +// +// Unpack more chunk data for decoding +// returns 1 to signify more data available for this image +// 0 indicates there is no more data +// +static int GIFGetMoreData(GIFIMAGE *pPage) +{ + int iDelta = (pPage->iLZWSize - pPage->iLZWOff); + unsigned char c = 1; + // move any existing data down + if (pPage->bEndOfFrame || iDelta >= (LZW_BUF_SIZE - MAX_CHUNK_SIZE) || iDelta <= 0) + return 1; // frame is finished or buffer is already full; no need to read more data + if (pPage->iLZWOff != 0) + { +// NB: memcpy() fails on some systems because the src and dest ptrs overlap +// so copy the bytes in a simple loop to avoid problems + for (int i=0; iiLZWSize - pPage->iLZWOff; i++) { + pPage->ucLZW[i] = pPage->ucLZW[i + pPage->iLZWOff]; + } + pPage->iLZWSize -= pPage->iLZWOff; + pPage->iLZWOff = 0; + } + while (c && pPage->GIFFile.iPos < pPage->GIFFile.iSize && pPage->iLZWSize < (LZW_BUF_SIZE-MAX_CHUNK_SIZE)) + { + (*pPage->pfnRead)(&pPage->GIFFile, &c, 1); // current length + (*pPage->pfnRead)(&pPage->GIFFile, &pPage->ucLZW[pPage->iLZWSize], c); + pPage->iLZWSize += c; + } + if (c == 0) // end of frame + pPage->bEndOfFrame = 1; + return (c != 0 && pPage->GIFFile.iPos < pPage->GIFFile.iSize); // more data available? +} /* GIFGetMoreData() */ +// +// Handle transparent pixels and disposal method +// Used only when a frame buffer is allocated +// +static void DrawNewPixels(GIFIMAGE *pPage, GIFDRAW *pDraw) +{ + uint8_t *d, *s; + int x, iPitch = pPage->iCanvasWidth; + + s = pDraw->pPixels; + d = (uint8_t*)&pPage->pFrameBuffer[pDraw->iX + (pDraw->y + pDraw->iY) * iPitch]; // dest pointer in our complete canvas buffer + if (pDraw->ucDisposalMethod == 2) // restore to background color + { + memset(d, pDraw->ucBackground, pDraw->iWidth); + } + // Apply the new pixels to the main image + if (pDraw->ucHasTransparency) // if transparency used + { + uint8_t c, ucTransparent = pDraw->ucTransparent; + for (x=0; xiWidth; x++) + { + c = *s++; + if (c != ucTransparent) + *d = c; + d++; + } + } + else + { + memcpy(d, s, pDraw->iWidth); // just overwrite the old pixels + } +} /* DrawNewPixels() */ +// +// Convert current line of pixels through the palette +// to either RGB565 or RGB888 output +// Used only when a frame buffer has been allocated +// +static void ConvertNewPixels(GIFIMAGE *pPage, GIFDRAW *pDraw) +{ + uint8_t *d, *s; + int x; + + s = (uint8_t*)&pPage->pFrameBuffer[(pPage->iCanvasWidth * (pDraw->iY + pDraw->y)) + pDraw->iX]; + d = (uint8_t*)&pPage->pFrameBuffer[pPage->iCanvasHeight * pPage->iCanvasWidth]; // point past bottom of frame buffer + if (pPage->ucPaletteType == GIF_PALETTE_RGB565_LE || pPage->ucPaletteType == GIF_PALETTE_RGB565_BE) + { + uint16_t *pPal, *pu16; + pPal = (uint16_t *)pDraw->pPalette; + pu16 = (uint16_t *)&pPage->pFrameBuffer[pPage->iCanvasHeight * pPage->iCanvasWidth]; + for (x=0; xiWidth; x++) + { + *pu16++ = pPal[*s++]; // convert to RGB565 pixels + } + } + else + { + uint8_t *pPal; + int pixel; + pPal = (uint8_t *)pDraw->pPalette; + for (x=0; xiWidth; x++) + { + pixel = *s++; + *d++ = pPal[(pixel * 3) + 0]; // convert to RGB888 pixels + *d++ = pPal[(pixel * 3) + 1]; + *d++ = pPal[(pixel * 3) + 2]; + } + } +} /* ConvertNewPixels() */ + +// +// GIFMakePels +// +static void GIFMakePels(GIFIMAGE *pPage, unsigned int code) +{ + int iPixCount; + unsigned short *giftabs; + unsigned char *buf, *s, *pEnd, *gifpels; + unsigned char ucNeedMore = 0; + /* Copy this string of sequential pixels to output buffer */ + // iPixCount = 0; + s = pPage->ucFileBuf + FILE_BUF_SIZE; /* Pixels will come out in reversed order */ + buf = pPage->ucLineBuf + (pPage->iWidth - pPage->iXCount); + giftabs = pPage->usGIFTable; + gifpels = &pPage->ucGIFPixels[PIXEL_LAST]; + while (code < LINK_UNUSED) + { + if (s == pPage->ucFileBuf) /* Houston, we have a problem */ + { + return; /* Exit with error */ + } + *(--s) = gifpels[code]; + code = giftabs[code]; + } + iPixCount = (int)(intptr_t)(pPage->ucFileBuf + FILE_BUF_SIZE - s); + + while (iPixCount && pPage->iYCount > 0) + { + if (pPage->iXCount > iPixCount) /* Pixels fit completely on the line */ + { + // memcpy(buf, s, iPixCount); + // buf += iPixCount; + pEnd = buf + iPixCount; + while (buf < pEnd) + { + *buf++ = *s++; + } + pPage->iXCount -= iPixCount; + // iPixCount = 0; + if (ucNeedMore) + GIFGetMoreData(pPage); // check if we need to read more LZW data every 4 lines + return; + } + else /* Pixels cross into next line */ + { + GIFDRAW gd; + pEnd = buf + pPage->iXCount; + while (buf < pEnd) + { + *buf++ = *s++; + } + iPixCount -= pPage->iXCount; + pPage->iXCount = pPage->iWidth; /* Reset pixel count */ + // Prepare GIDRAW structure for callback + gd.iX = pPage->iX; + gd.iY = pPage->iY; + gd.iWidth = pPage->iWidth; + gd.iHeight = pPage->iHeight; + gd.pPixels = pPage->ucLineBuf; + gd.pPalette = (pPage->bUseLocalPalette) ? pPage->pLocalPalette : pPage->pPalette; + gd.pPalette24 = (uint8_t *)gd.pPalette; // just cast the pointer for RGB888 + gd.ucIsGlobalPalette = pPage->bUseLocalPalette==1?0:1; + gd.y = pPage->iHeight - pPage->iYCount; + // Ugly logic to handle the interlaced line position, but it + // saves having to have another set of state variables + if (pPage->ucMap & 0x40) { // interlaced? + int height = pPage->iHeight-1; + if (gd.y > height / 2) + gd.y = gd.y * 2 - (height | 1); + else if (gd.y > height / 4) + gd.y = gd.y * 4 - ((height & ~1) | 2); + else if (gd.y > height / 8) + gd.y = gd.y * 8 - ((height & ~3) | 4); + else + gd.y = gd.y * 8; + } + gd.ucDisposalMethod = (pPage->ucGIFBits & 0x1c)>>2; + gd.ucTransparent = pPage->ucTransparent; + gd.ucHasTransparency = pPage->ucGIFBits & 1; + gd.ucBackground = pPage->ucBackground; + gd.pUser = pPage->pUser; + if (pPage->pFrameBuffer) // update the frame buffer + { + DrawNewPixels(pPage, &gd); + if (pPage->ucDrawType == GIF_DRAW_COOKED) + { + ConvertNewPixels(pPage, &gd); // prepare for output + gd.pPixels = (uint8_t*)&pPage->pFrameBuffer[pPage->iCanvasWidth * pPage->iCanvasHeight]; + } + } + (*pPage->pfnDraw)(&gd); // callback to handle this line + pPage->iYCount--; + buf = pPage->ucLineBuf; + if ((pPage->iYCount & 3) == 0) // since we support only small images... + ucNeedMore = 1; + } + } /* while */ + if (ucNeedMore) + GIFGetMoreData(pPage); // check if we need to read more LZW data every 4 lines + return; +} /* GIFMakePels() */ +// +// Macro to extract a variable length code +// +#define GET_CODE if (bitnum > (REGISTER_WIDTH - codesize)) { pImage->iLZWOff += (bitnum >> 3); \ + bitnum &= 7; ulBits = INTELLONG(&p[pImage->iLZWOff]); } \ + code = (unsigned short) (ulBits >> bitnum); /* Read a 32-bit chunk */ \ + code &= sMask; bitnum += codesize; + +// +// Decode LZW into an image +// +static int DecodeLZW(GIFIMAGE *pImage, int iOptions) +{ + int i, bitnum; + unsigned short oldcode, codesize, nextcode, nextlim; + unsigned short *giftabs, cc, eoi; + signed short sMask; + unsigned char *gifpels, *p; + // int iStripSize; + //unsigned char **index; + uint32_t ulBits; + unsigned short code; + (void)iOptions; // not used for now + // if output can be used for string table, do it faster + // if (bGIF && (OutPage->cBitsperpixel == 8 && ((OutPage->iWidth & 3) == 0))) + // return PILFastLZW(InPage, OutPage, bGIF, iOptions); + p = pImage->ucLZW; // un-chunked LZW data + sMask = 0xffff << (pImage->ucCodeStart + 1); + sMask = 0xffff - sMask; + cc = (sMask >> 1) + 1; /* Clear code */ + eoi = cc + 1; + giftabs = pImage->usGIFTable; + gifpels = pImage->ucGIFPixels; + pImage->iYCount = pImage->iHeight; // count down the lines + pImage->iXCount = pImage->iWidth; + bitnum = 0; + pImage->iLZWOff = 0; // Offset into compressed data + GIFGetMoreData(pImage); // Read some data to start + + // Initialize code table + // this part only needs to be initialized once + for (i = 0; i < cc; i++) + { + gifpels[PIXEL_FIRST + i] = gifpels[PIXEL_LAST + i] = (unsigned short) i; + giftabs[i] = LINK_END; + } +init_codetable: + codesize = pImage->ucCodeStart + 1; + sMask = 0xffff << (pImage->ucCodeStart + 1); + sMask = 0xffff - sMask; + nextcode = cc + 2; + nextlim = (unsigned short) ((1 << codesize)); + // This part of the table needs to be reset multiple times + memset(&giftabs[cc], LINK_UNUSED, (4096 - cc)*sizeof(short)); + ulBits = INTELLONG(&p[pImage->iLZWOff]); // start by reading 4 bytes of LZW data + GET_CODE + if (code == cc) // we just reset the dictionary, so get another code + { + GET_CODE + } + oldcode = code; + GIFMakePels(pImage, code); // first code is output as the first pixel + // Main decode loop + while (code != eoi && pImage->iYCount > 0) // && y < pImage->iHeight+1) /* Loop through all lines of the image (or strip) */ + { + GET_CODE + if (code == cc) /* Clear code?, and not first code */ + goto init_codetable; + if (code != eoi) + { + if (nextcode < nextlim) // for deferred cc case, don't let it overwrite the last entry (fff) + { + giftabs[nextcode] = oldcode; + gifpels[PIXEL_FIRST + nextcode] = gifpels[PIXEL_FIRST + oldcode]; + if (giftabs[code] == LINK_UNUSED) /* Old code */ + gifpels[PIXEL_LAST + nextcode] = gifpels[PIXEL_FIRST + oldcode]; + else + gifpels[PIXEL_LAST + nextcode] = gifpels[PIXEL_FIRST + code]; + } + nextcode++; + if (nextcode >= nextlim && codesize < 12) + { + codesize++; + nextlim <<= 1; + sMask = (sMask << 1) | 1; + } + GIFMakePels(pImage, code); + oldcode = code; + } + } /* while not end of LZW code stream */ + return 0; +//gif_forced_error: +// free(pImage->pPixels); +// pImage->pPixels = NULL; +// return -1; +} /* DecodeLZW() */ + +void GIF_setDrawCallback(GIFIMAGE *pGIF, GIF_DRAW_CALLBACK *pfnDraw) +{ + pGIF->pfnDraw = pfnDraw; +} /* GIF_setDrawCallback() */ +// +// Scale 2 scanlines down by 50% with pixel averaging +// writes new values over previous line +// expects RGB565 little endian pixels as input +// +void GIF_scaleHalf(uint16_t *pCurrent, uint16_t *pPrev, int iWidth, int bBigEndian) +{ +int x; +uint16_t *d = pPrev; +uint32_t gSum, rbSum, pix0,pix1,pix2,pix3; +const uint32_t RBMask = 0xf81f, GMask = 0x7e0; + + for (x=0; x> 2) & GMask; // for rounding towards 1 + rbSum = (pix0 & RBMask) + (pix1 & RBMask) + (pix2 & RBMask) + (pix3 & RBMask); + rbSum = ((rbSum + 0x1002) >> 2) & RBMask; + if (bBigEndian) + *d++ = __builtin_bswap16((uint16_t)(gSum + rbSum)); + else + *d++ = (uint16_t)(gSum + rbSum); // store finished pixel + } // for x +} /* GIF_scaleHalf() */ diff --git a/ports/espressif/certificates/README.md b/lib/certificates/README.md similarity index 100% rename from ports/espressif/certificates/README.md rename to lib/certificates/README.md diff --git a/ports/espressif/certificates/nina-fw b/lib/certificates/nina-fw similarity index 100% rename from ports/espressif/certificates/nina-fw rename to lib/certificates/nina-fw diff --git a/lib/mbedtls b/lib/mbedtls new file mode 160000 index 0000000000..1bc2c9cb8b --- /dev/null +++ b/lib/mbedtls @@ -0,0 +1 @@ +Subproject commit 1bc2c9cb8b8fe4659bd94b8ebba5a4c02029b7fa diff --git a/lib/mbedtls_errors/README.md b/lib/mbedtls_errors/README.md new file mode 100644 index 0000000000..0e13021eb1 --- /dev/null +++ b/lib/mbedtls_errors/README.md @@ -0,0 +1,42 @@ +MBEDTLS Error Strings for MicroPython +===================================== + +This directory contains source code and tools to rework the Mbedtls error strings for +micropython to use less space. In short, instead of storing and printing something like +"SSL - Our own certificate(s) is/are too large to send in an SSL message" it prints +the name of the error #define, which would be "MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE" in +this case, and only stores `SSL_CERTIFICATE_TOO_LARGE` in flash. The exact Mbedtls error +defines are used because they're easy to search for to find more detailed information. + +Mbedtls defines a specific format for error value #defines and +includes a Perl script to gather all `MBEDTLS_ERR` defines from includes files together with +english error text. From that the Perl script generates `mbedtls_strerror()`. The files in this +directory modify this process to produce a more space efficient error lookup table with +shorter error strings. + +The files are as follows: +- `generate_errors.diff` - diff for original mbedtls perl script +- `error.fmt` - modified code template for MicroPython +- `mp_mbedtls_errors.c` - source file with `mbedtls_strerror` this is built using the include + files in `../mbedtls` +- `do-mp.sh` - shell script to produce `mp_mbedtls_errors.c` +- `tester.c` - simple C main to test `mp_mbedtls_errors.c` locally on a dev box +- `do-test.sh` - shell script to produce `mp_mbedtls_errors.c` and compile the `tester` app +- `do-esp32.sh` - shell script to produce `esp32_mbedtls_errors.c` -- see below + +In order not to store multiple copies of `mbedtls_errors.c` +([https://github.com/micropython/micropython/pull/5819#discussion_r445528006](see)) +it is assumed that all ports use the same version of mbedtls with the same error #defines. +This is true as of MP v1.13, and ESP-IDF versions 3.3.2 and 4.0.1. If anything changes in the +future the `do-esp32.sh` script can be used to generate an esp32-specific version. + +### How-to + +- To build MicroPython all that is needed is to include the `mp_mbedtls_errors.c` into the build + (the Makefiles do this automatically). Note that Perl is not needed for routine MicroPython + builds. +- When a new version of Mbedtls is pulled-in the `do-mp.sh` script should be run to + re-generate `mp_mbedtls_errors.c`. +- The `tester` app should be run if changes to the string handling in `error.fmt` are made: + it tests that there is not an off-by-one error in the string copying/appending, etc. +- To include `mbedtls_strerror` error strings define `MBEDTLS_ERROR_C` in the build. diff --git a/lib/mbedtls_errors/do-esp32.sh b/lib/mbedtls_errors/do-esp32.sh new file mode 100755 index 0000000000..6fd4682415 --- /dev/null +++ b/lib/mbedtls_errors/do-esp32.sh @@ -0,0 +1,7 @@ +#! /bin/bash -e +# Generate esp32_mbedtls_errors.c for use in the Esp32 port, with the ESP-IDF version of mbedtls +# The IDF_PATH env var must be set to the top-level dir of ESPIDF +echo "IDF_PATH=$IDF_PATH" +MBEDTLS=$IDF_PATH/components/mbedtls/mbedtls +patch -o esp32_generate_errors.pl $MBEDTLS/scripts/generate_errors.pl +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_snprintf snprintf +#define mbedtls_time_t time_t +#endif + +#if defined(MBEDTLS_ERROR_C) + +#include + +HEADER_INCLUDED + +// Error code table type +struct ssl_errs { + int16_t errnum; + const char *errstr; +}; + +// Table of high level error codes +static const struct ssl_errs mbedtls_high_level_error_tab[] = { +// BEGIN generated code +HIGH_LEVEL_CODE_CHECKS +// END generated code +}; + +static const struct ssl_errs mbedtls_low_level_error_tab[] = { +// Low level error codes +// +// BEGIN generated code +LOW_LEVEL_CODE_CHECKS +// END generated code +}; + +static const char *mbedtls_err_prefix = "MBEDTLS_ERR_"; +#define MBEDTLS_ERR_PREFIX_LEN ( sizeof("MBEDTLS_ERR_")-1 ) + +// copy error text into buffer, ensure null termination, return strlen of result +static size_t mbedtls_err_to_str(int err, const struct ssl_errs tab[], int tab_len, char *buf, size_t buflen) { + if (buflen == 0) return 0; + + // prefix for all error names + strncpy(buf, mbedtls_err_prefix, buflen); + if (buflen <= MBEDTLS_ERR_PREFIX_LEN+1) { + buf[buflen-1] = 0; + return buflen-1; + } + + // append error name from table + for (int i = 0; i < tab_len; i++) { + if (tab[i].errnum == err) { + strncpy(buf+MBEDTLS_ERR_PREFIX_LEN, tab[i].errstr, buflen-MBEDTLS_ERR_PREFIX_LEN); + buf[buflen-1] = 0; + return strlen(buf); + } + } + + mbedtls_snprintf(buf+MBEDTLS_ERR_PREFIX_LEN, buflen-MBEDTLS_ERR_PREFIX_LEN, "UNKNOWN (0x%04X)", + err); + return strlen(buf); +} + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +void mbedtls_strerror(int ret, char *buf, size_t buflen) { + int use_ret; + + if (buflen == 0) return; + + buf[buflen-1] = 0; + + if (ret < 0) ret = -ret; + + // + // High-level error codes + // + uint8_t got_hl = (ret & 0xFF80) != 0; + if (got_hl) { + use_ret = ret & 0xFF80; + + // special case +#if defined(MBEDTLS_SSL_TLS_C) + if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) { + strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen); + buf[buflen-1] = 0; + return; + } +#endif + + size_t len = mbedtls_err_to_str(use_ret, mbedtls_high_level_error_tab, + ARRAY_SIZE(mbedtls_high_level_error_tab), buf, buflen); + + buf += len; + buflen -= len; + if (buflen == 0) return; + } + + // + // Low-level error codes + // + use_ret = ret & ~0xFF80; + + if (use_ret == 0) return; + + // If high level code is present, make a concatenation between both error strings. + if (got_hl) { + if (buflen < 2) return; + *buf++ = '+'; + buflen--; + } + + mbedtls_err_to_str(use_ret, mbedtls_low_level_error_tab, + ARRAY_SIZE(mbedtls_low_level_error_tab), buf, buflen); +} + +#else /* MBEDTLS_ERROR_C */ + +#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) + +/* + * Provide an non-function in case MBEDTLS_ERROR_C is not defined + */ +void mbedtls_strerror( int ret, char *buf, size_t buflen ) +{ + ((void) ret); + + if( buflen > 0 ) + buf[0] = '\0'; +} + +#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ + +#endif /* MBEDTLS_ERROR_C */ diff --git a/lib/mbedtls_errors/generate_errors.diff b/lib/mbedtls_errors/generate_errors.diff new file mode 100644 index 0000000000..ad24c372fa --- /dev/null +++ b/lib/mbedtls_errors/generate_errors.diff @@ -0,0 +1,22 @@ +--- generate_errors_orig.pl 2020-06-20 08:40:38.819060379 -0700 ++++ generate_errors.pl 2020-06-20 08:47:26.511163591 -0700 +@@ -162,16 +162,12 @@ + + if ($error_name eq "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE") + { +- ${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n". +- "${white_space}\{\n". +- "${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n". +- "${white_space} return;\n". +- "${white_space}}\n" ++ # no-op, this case is hard-coded in error.fmt + } + else + { +- ${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n". +- "${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n" ++ my $error_text = $error_name =~ s/^MBEDTLS_ERR_//r; ++ ${$code_check} .= "${white_space}{ -($error_name), \"$error_text\" },\n" + } + }; + diff --git a/lib/mbedtls_errors/mp_mbedtls_errors.c b/lib/mbedtls_errors/mp_mbedtls_errors.c new file mode 100644 index 0000000000..03a91f0dc9 --- /dev/null +++ b/lib/mbedtls_errors/mp_mbedtls_errors.c @@ -0,0 +1,705 @@ +/* + * Error message information + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) +#include "mbedtls/error.h" +#include +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_snprintf snprintf +#define mbedtls_time_t time_t +#endif + +#if defined(MBEDTLS_ERROR_C) + +#include + +#if defined(MBEDTLS_AES_C) +#include "mbedtls/aes.h" +#endif + +#if defined(MBEDTLS_ARC4_C) +#include "mbedtls/arc4.h" +#endif + +#if defined(MBEDTLS_ARIA_C) +#include "mbedtls/aria.h" +#endif + +#if defined(MBEDTLS_BASE64_C) +#include "mbedtls/base64.h" +#endif + +#if defined(MBEDTLS_BIGNUM_C) +#include "mbedtls/bignum.h" +#endif + +#if defined(MBEDTLS_BLOWFISH_C) +#include "mbedtls/blowfish.h" +#endif + +#if defined(MBEDTLS_CAMELLIA_C) +#include "mbedtls/camellia.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_CHACHA20_C) +#include "mbedtls/chacha20.h" +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) +#include "mbedtls/chachapoly.h" +#endif + +#if defined(MBEDTLS_CIPHER_C) +#include "mbedtls/cipher.h" +#endif + +#if defined(MBEDTLS_CMAC_C) +#include "mbedtls/cmac.h" +#endif + +#if defined(MBEDTLS_CTR_DRBG_C) +#include "mbedtls/ctr_drbg.h" +#endif + +#if defined(MBEDTLS_DES_C) +#include "mbedtls/des.h" +#endif + +#if defined(MBEDTLS_DHM_C) +#include "mbedtls/dhm.h" +#endif + +#if defined(MBEDTLS_ECP_C) +#include "mbedtls/ecp.h" +#endif + +#if defined(MBEDTLS_ENTROPY_C) +#include "mbedtls/entropy.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "mbedtls/gcm.h" +#endif + +#if defined(MBEDTLS_HKDF_C) +#include "mbedtls/hkdf.h" +#endif + +#if defined(MBEDTLS_HMAC_DRBG_C) +#include "mbedtls/hmac_drbg.h" +#endif + +#if defined(MBEDTLS_MD_C) +#include "mbedtls/md.h" +#endif + +#if defined(MBEDTLS_MD2_C) +#include "mbedtls/md2.h" +#endif + +#if defined(MBEDTLS_MD4_C) +#include "mbedtls/md4.h" +#endif + +#if defined(MBEDTLS_MD5_C) +#include "mbedtls/md5.h" +#endif + +#if defined(MBEDTLS_NET_C) +#include "mbedtls/net_sockets.h" +#endif + +#if defined(MBEDTLS_OID_C) +#include "mbedtls/oid.h" +#endif + +#if defined(MBEDTLS_PADLOCK_C) +#include "mbedtls/padlock.h" +#endif + +#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) +#include "mbedtls/pem.h" +#endif + +#if defined(MBEDTLS_PK_C) +#include "mbedtls/pk.h" +#endif + +#if defined(MBEDTLS_PKCS12_C) +#include "mbedtls/pkcs12.h" +#endif + +#if defined(MBEDTLS_PKCS5_C) +#include "mbedtls/pkcs5.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#endif + +#if defined(MBEDTLS_POLY1305_C) +#include "mbedtls/poly1305.h" +#endif + +#if defined(MBEDTLS_RIPEMD160_C) +#include "mbedtls/ripemd160.h" +#endif + +#if defined(MBEDTLS_RSA_C) +#include "mbedtls/rsa.h" +#endif + +#if defined(MBEDTLS_SHA1_C) +#include "mbedtls/sha1.h" +#endif + +#if defined(MBEDTLS_SHA256_C) +#include "mbedtls/sha256.h" +#endif + +#if defined(MBEDTLS_SHA512_C) +#include "mbedtls/sha512.h" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) +#include "mbedtls/ssl.h" +#endif + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) +#include "mbedtls/x509.h" +#endif + +#if defined(MBEDTLS_XTEA_C) +#include "mbedtls/xtea.h" +#endif + + +// Error code table type +struct ssl_errs { + int16_t errnum; + const char *errstr; +}; + +// Table of high level error codes +static const struct ssl_errs mbedtls_high_level_error_tab[] = { +// BEGIN generated code +#if defined(MBEDTLS_CIPHER_C) + { -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE), "CIPHER_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA), "CIPHER_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED), "CIPHER_ALLOC_FAILED" }, + { -(MBEDTLS_ERR_CIPHER_INVALID_PADDING), "CIPHER_INVALID_PADDING" }, + { -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED), "CIPHER_FULL_BLOCK_EXPECTED" }, + { -(MBEDTLS_ERR_CIPHER_AUTH_FAILED), "CIPHER_AUTH_FAILED" }, + { -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT), "CIPHER_INVALID_CONTEXT" }, + { -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED), "CIPHER_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_CIPHER_C */ + +#if defined(MBEDTLS_DHM_C) + { -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA), "DHM_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED), "DHM_READ_PARAMS_FAILED" }, + { -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED), "DHM_MAKE_PARAMS_FAILED" }, + { -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED), "DHM_READ_PUBLIC_FAILED" }, + { -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED), "DHM_MAKE_PUBLIC_FAILED" }, + { -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED), "DHM_CALC_SECRET_FAILED" }, + { -(MBEDTLS_ERR_DHM_INVALID_FORMAT), "DHM_INVALID_FORMAT" }, + { -(MBEDTLS_ERR_DHM_ALLOC_FAILED), "DHM_ALLOC_FAILED" }, + { -(MBEDTLS_ERR_DHM_FILE_IO_ERROR), "DHM_FILE_IO_ERROR" }, + { -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED), "DHM_HW_ACCEL_FAILED" }, + { -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED), "DHM_SET_GROUP_FAILED" }, +#endif /* MBEDTLS_DHM_C */ + +#if defined(MBEDTLS_ECP_C) + { -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA), "ECP_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL), "ECP_BUFFER_TOO_SMALL" }, + { -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE), "ECP_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_ECP_VERIFY_FAILED), "ECP_VERIFY_FAILED" }, + { -(MBEDTLS_ERR_ECP_ALLOC_FAILED), "ECP_ALLOC_FAILED" }, + { -(MBEDTLS_ERR_ECP_RANDOM_FAILED), "ECP_RANDOM_FAILED" }, + { -(MBEDTLS_ERR_ECP_INVALID_KEY), "ECP_INVALID_KEY" }, + { -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH), "ECP_SIG_LEN_MISMATCH" }, + { -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED), "ECP_HW_ACCEL_FAILED" }, + { -(MBEDTLS_ERR_ECP_IN_PROGRESS), "ECP_IN_PROGRESS" }, +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_MD_C) + { -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE), "MD_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_MD_BAD_INPUT_DATA), "MD_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_MD_ALLOC_FAILED), "MD_ALLOC_FAILED" }, + { -(MBEDTLS_ERR_MD_FILE_IO_ERROR), "MD_FILE_IO_ERROR" }, + { -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED), "MD_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_MD_C */ + +#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) + { -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT), "PEM_NO_HEADER_FOOTER_PRESENT" }, + { -(MBEDTLS_ERR_PEM_INVALID_DATA), "PEM_INVALID_DATA" }, + { -(MBEDTLS_ERR_PEM_ALLOC_FAILED), "PEM_ALLOC_FAILED" }, + { -(MBEDTLS_ERR_PEM_INVALID_ENC_IV), "PEM_INVALID_ENC_IV" }, + { -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG), "PEM_UNKNOWN_ENC_ALG" }, + { -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED), "PEM_PASSWORD_REQUIRED" }, + { -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH), "PEM_PASSWORD_MISMATCH" }, + { -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE), "PEM_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA), "PEM_BAD_INPUT_DATA" }, +#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ + +#if defined(MBEDTLS_PK_C) + { -(MBEDTLS_ERR_PK_ALLOC_FAILED), "PK_ALLOC_FAILED" }, + { -(MBEDTLS_ERR_PK_TYPE_MISMATCH), "PK_TYPE_MISMATCH" }, + { -(MBEDTLS_ERR_PK_BAD_INPUT_DATA), "PK_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_PK_FILE_IO_ERROR), "PK_FILE_IO_ERROR" }, + { -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION), "PK_KEY_INVALID_VERSION" }, + { -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT), "PK_KEY_INVALID_FORMAT" }, + { -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG), "PK_UNKNOWN_PK_ALG" }, + { -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED), "PK_PASSWORD_REQUIRED" }, + { -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH), "PK_PASSWORD_MISMATCH" }, + { -(MBEDTLS_ERR_PK_INVALID_PUBKEY), "PK_INVALID_PUBKEY" }, + { -(MBEDTLS_ERR_PK_INVALID_ALG), "PK_INVALID_ALG" }, + { -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE), "PK_UNKNOWN_NAMED_CURVE" }, + { -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE), "PK_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH), "PK_SIG_LEN_MISMATCH" }, + { -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED), "PK_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_PK_C */ + +#if defined(MBEDTLS_PKCS12_C) + { -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA), "PKCS12_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE), "PKCS12_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT), "PKCS12_PBE_INVALID_FORMAT" }, + { -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH), "PKCS12_PASSWORD_MISMATCH" }, +#endif /* MBEDTLS_PKCS12_C */ + +#if defined(MBEDTLS_PKCS5_C) + { -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA), "PKCS5_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT), "PKCS5_INVALID_FORMAT" }, + { -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE), "PKCS5_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH), "PKCS5_PASSWORD_MISMATCH" }, +#endif /* MBEDTLS_PKCS5_C */ + +#if defined(MBEDTLS_RSA_C) + { -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA), "RSA_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_RSA_INVALID_PADDING), "RSA_INVALID_PADDING" }, + { -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED), "RSA_KEY_GEN_FAILED" }, + { -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED), "RSA_KEY_CHECK_FAILED" }, + { -(MBEDTLS_ERR_RSA_PUBLIC_FAILED), "RSA_PUBLIC_FAILED" }, + { -(MBEDTLS_ERR_RSA_PRIVATE_FAILED), "RSA_PRIVATE_FAILED" }, + { -(MBEDTLS_ERR_RSA_VERIFY_FAILED), "RSA_VERIFY_FAILED" }, + { -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE), "RSA_OUTPUT_TOO_LARGE" }, + { -(MBEDTLS_ERR_RSA_RNG_FAILED), "RSA_RNG_FAILED" }, + { -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION), "RSA_UNSUPPORTED_OPERATION" }, + { -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED), "RSA_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_SSL_TLS_C) + { -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE), "SSL_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA), "SSL_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_SSL_INVALID_MAC), "SSL_INVALID_MAC" }, + { -(MBEDTLS_ERR_SSL_INVALID_RECORD), "SSL_INVALID_RECORD" }, + { -(MBEDTLS_ERR_SSL_CONN_EOF), "SSL_CONN_EOF" }, + { -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER), "SSL_UNKNOWN_CIPHER" }, + { -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN), "SSL_NO_CIPHER_CHOSEN" }, + { -(MBEDTLS_ERR_SSL_NO_RNG), "SSL_NO_RNG" }, + { -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE), "SSL_NO_CLIENT_CERTIFICATE" }, + { -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE), "SSL_CERTIFICATE_TOO_LARGE" }, + { -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED), "SSL_CERTIFICATE_REQUIRED" }, + { -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED), "SSL_PRIVATE_KEY_REQUIRED" }, + { -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED), "SSL_CA_CHAIN_REQUIRED" }, + { -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE), "SSL_UNEXPECTED_MESSAGE" }, + { -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED), "SSL_PEER_VERIFY_FAILED" }, + { -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY), "SSL_PEER_CLOSE_NOTIFY" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO), "SSL_BAD_HS_CLIENT_HELLO" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO), "SSL_BAD_HS_SERVER_HELLO" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE), "SSL_BAD_HS_CERTIFICATE" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST), "SSL_BAD_HS_CERTIFICATE_REQUEST" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE), "SSL_BAD_HS_SERVER_KEY_EXCHANGE" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE), "SSL_BAD_HS_SERVER_HELLO_DONE" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY), "SSL_BAD_HS_CERTIFICATE_VERIFY" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC), "SSL_BAD_HS_CHANGE_CIPHER_SPEC" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED), "SSL_BAD_HS_FINISHED" }, + { -(MBEDTLS_ERR_SSL_ALLOC_FAILED), "SSL_ALLOC_FAILED" }, + { -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED), "SSL_HW_ACCEL_FAILED" }, + { -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH), "SSL_HW_ACCEL_FALLTHROUGH" }, + { -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED), "SSL_COMPRESSION_FAILED" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION), "SSL_BAD_HS_PROTOCOL_VERSION" }, + { -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET), "SSL_BAD_HS_NEW_SESSION_TICKET" }, + { -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED), "SSL_SESSION_TICKET_EXPIRED" }, + { -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH), "SSL_PK_TYPE_MISMATCH" }, + { -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY), "SSL_UNKNOWN_IDENTITY" }, + { -(MBEDTLS_ERR_SSL_INTERNAL_ERROR), "SSL_INTERNAL_ERROR" }, + { -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING), "SSL_COUNTER_WRAPPING" }, + { -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO), "SSL_WAITING_SERVER_HELLO_RENEGO" }, + { -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED), "SSL_HELLO_VERIFY_REQUIRED" }, + { -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL), "SSL_BUFFER_TOO_SMALL" }, + { -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE), "SSL_NO_USABLE_CIPHERSUITE" }, + { -(MBEDTLS_ERR_SSL_WANT_READ), "SSL_WANT_READ" }, + { -(MBEDTLS_ERR_SSL_WANT_WRITE), "SSL_WANT_WRITE" }, + { -(MBEDTLS_ERR_SSL_TIMEOUT), "SSL_TIMEOUT" }, + { -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT), "SSL_CLIENT_RECONNECT" }, + { -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD), "SSL_UNEXPECTED_RECORD" }, + { -(MBEDTLS_ERR_SSL_NON_FATAL), "SSL_NON_FATAL" }, + { -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH), "SSL_INVALID_VERIFY_HASH" }, + { -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING), "SSL_CONTINUE_PROCESSING" }, + { -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS), "SSL_ASYNC_IN_PROGRESS" }, + { -(MBEDTLS_ERR_SSL_EARLY_MESSAGE), "SSL_EARLY_MESSAGE" }, + { -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS), "SSL_CRYPTO_IN_PROGRESS" }, +#endif /* MBEDTLS_SSL_TLS_C */ + +#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) + { -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE), "X509_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_X509_UNKNOWN_OID), "X509_UNKNOWN_OID" }, + { -(MBEDTLS_ERR_X509_INVALID_FORMAT), "X509_INVALID_FORMAT" }, + { -(MBEDTLS_ERR_X509_INVALID_VERSION), "X509_INVALID_VERSION" }, + { -(MBEDTLS_ERR_X509_INVALID_SERIAL), "X509_INVALID_SERIAL" }, + { -(MBEDTLS_ERR_X509_INVALID_ALG), "X509_INVALID_ALG" }, + { -(MBEDTLS_ERR_X509_INVALID_NAME), "X509_INVALID_NAME" }, + { -(MBEDTLS_ERR_X509_INVALID_DATE), "X509_INVALID_DATE" }, + { -(MBEDTLS_ERR_X509_INVALID_SIGNATURE), "X509_INVALID_SIGNATURE" }, + { -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS), "X509_INVALID_EXTENSIONS" }, + { -(MBEDTLS_ERR_X509_UNKNOWN_VERSION), "X509_UNKNOWN_VERSION" }, + { -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG), "X509_UNKNOWN_SIG_ALG" }, + { -(MBEDTLS_ERR_X509_SIG_MISMATCH), "X509_SIG_MISMATCH" }, + { -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED), "X509_CERT_VERIFY_FAILED" }, + { -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT), "X509_CERT_UNKNOWN_FORMAT" }, + { -(MBEDTLS_ERR_X509_BAD_INPUT_DATA), "X509_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_X509_ALLOC_FAILED), "X509_ALLOC_FAILED" }, + { -(MBEDTLS_ERR_X509_FILE_IO_ERROR), "X509_FILE_IO_ERROR" }, + { -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL), "X509_BUFFER_TOO_SMALL" }, + { -(MBEDTLS_ERR_X509_FATAL_ERROR), "X509_FATAL_ERROR" }, +#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ +// END generated code +}; + +static const struct ssl_errs mbedtls_low_level_error_tab[] = { +// Low level error codes +// +// BEGIN generated code +#if defined(MBEDTLS_AES_C) + { -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH), "AES_INVALID_KEY_LENGTH" }, + { -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH), "AES_INVALID_INPUT_LENGTH" }, + { -(MBEDTLS_ERR_AES_BAD_INPUT_DATA), "AES_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE), "AES_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED), "AES_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_ARC4_C) + { -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED), "ARC4_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_ARIA_C) + { -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA), "ARIA_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH), "ARIA_INVALID_INPUT_LENGTH" }, + { -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE), "ARIA_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED), "ARIA_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_ARIA_C */ + +#if defined(MBEDTLS_ASN1_PARSE_C) + { -(MBEDTLS_ERR_ASN1_OUT_OF_DATA), "ASN1_OUT_OF_DATA" }, + { -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG), "ASN1_UNEXPECTED_TAG" }, + { -(MBEDTLS_ERR_ASN1_INVALID_LENGTH), "ASN1_INVALID_LENGTH" }, + { -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH), "ASN1_LENGTH_MISMATCH" }, + { -(MBEDTLS_ERR_ASN1_INVALID_DATA), "ASN1_INVALID_DATA" }, + { -(MBEDTLS_ERR_ASN1_ALLOC_FAILED), "ASN1_ALLOC_FAILED" }, + { -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL), "ASN1_BUF_TOO_SMALL" }, +#endif /* MBEDTLS_ASN1_PARSE_C */ + +#if defined(MBEDTLS_BASE64_C) + { -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL), "BASE64_BUFFER_TOO_SMALL" }, + { -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER), "BASE64_INVALID_CHARACTER" }, +#endif /* MBEDTLS_BASE64_C */ + +#if defined(MBEDTLS_BIGNUM_C) + { -(MBEDTLS_ERR_MPI_FILE_IO_ERROR), "MPI_FILE_IO_ERROR" }, + { -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA), "MPI_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_MPI_INVALID_CHARACTER), "MPI_INVALID_CHARACTER" }, + { -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL), "MPI_BUFFER_TOO_SMALL" }, + { -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE), "MPI_NEGATIVE_VALUE" }, + { -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO), "MPI_DIVISION_BY_ZERO" }, + { -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE), "MPI_NOT_ACCEPTABLE" }, + { -(MBEDTLS_ERR_MPI_ALLOC_FAILED), "MPI_ALLOC_FAILED" }, +#endif /* MBEDTLS_BIGNUM_C */ + +#if defined(MBEDTLS_BLOWFISH_C) + { -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA), "BLOWFISH_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH), "BLOWFISH_INVALID_INPUT_LENGTH" }, + { -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED), "BLOWFISH_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + { -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA), "CAMELLIA_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH), "CAMELLIA_INVALID_INPUT_LENGTH" }, + { -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED), "CAMELLIA_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_CCM_C) + { -(MBEDTLS_ERR_CCM_BAD_INPUT), "CCM_BAD_INPUT" }, + { -(MBEDTLS_ERR_CCM_AUTH_FAILED), "CCM_AUTH_FAILED" }, + { -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED), "CCM_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_CCM_C */ + +#if defined(MBEDTLS_CHACHA20_C) + { -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA), "CHACHA20_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE), "CHACHA20_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED), "CHACHA20_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_CHACHA20_C */ + +#if defined(MBEDTLS_CHACHAPOLY_C) + { -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE), "CHACHAPOLY_BAD_STATE" }, + { -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED), "CHACHAPOLY_AUTH_FAILED" }, +#endif /* MBEDTLS_CHACHAPOLY_C */ + +#if defined(MBEDTLS_CMAC_C) + { -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED), "CMAC_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_CMAC_C */ + +#if defined(MBEDTLS_CTR_DRBG_C) + { -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED), "CTR_DRBG_ENTROPY_SOURCE_FAILED" }, + { -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG), "CTR_DRBG_REQUEST_TOO_BIG" }, + { -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG), "CTR_DRBG_INPUT_TOO_BIG" }, + { -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR), "CTR_DRBG_FILE_IO_ERROR" }, +#endif /* MBEDTLS_CTR_DRBG_C */ + +#if defined(MBEDTLS_DES_C) + { -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH), "DES_INVALID_INPUT_LENGTH" }, + { -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED), "DES_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ENTROPY_C) + { -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED), "ENTROPY_SOURCE_FAILED" }, + { -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES), "ENTROPY_MAX_SOURCES" }, + { -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED), "ENTROPY_NO_SOURCES_DEFINED" }, + { -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE), "ENTROPY_NO_STRONG_SOURCE" }, + { -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR), "ENTROPY_FILE_IO_ERROR" }, +#endif /* MBEDTLS_ENTROPY_C */ + +#if defined(MBEDTLS_GCM_C) + { -(MBEDTLS_ERR_GCM_AUTH_FAILED), "GCM_AUTH_FAILED" }, + { -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED), "GCM_HW_ACCEL_FAILED" }, + { -(MBEDTLS_ERR_GCM_BAD_INPUT), "GCM_BAD_INPUT" }, +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_HKDF_C) + { -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA), "HKDF_BAD_INPUT_DATA" }, +#endif /* MBEDTLS_HKDF_C */ + +#if defined(MBEDTLS_HMAC_DRBG_C) + { -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG), "HMAC_DRBG_REQUEST_TOO_BIG" }, + { -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG), "HMAC_DRBG_INPUT_TOO_BIG" }, + { -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR), "HMAC_DRBG_FILE_IO_ERROR" }, + { -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED), "HMAC_DRBG_ENTROPY_SOURCE_FAILED" }, +#endif /* MBEDTLS_HMAC_DRBG_C */ + +#if defined(MBEDTLS_MD2_C) + { -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED), "MD2_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_MD2_C */ + +#if defined(MBEDTLS_MD4_C) + { -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED), "MD4_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_MD4_C */ + +#if defined(MBEDTLS_MD5_C) + { -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED), "MD5_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_MD5_C */ + +#if defined(MBEDTLS_NET_C) + { -(MBEDTLS_ERR_NET_SOCKET_FAILED), "NET_SOCKET_FAILED" }, + { -(MBEDTLS_ERR_NET_CONNECT_FAILED), "NET_CONNECT_FAILED" }, + { -(MBEDTLS_ERR_NET_BIND_FAILED), "NET_BIND_FAILED" }, + { -(MBEDTLS_ERR_NET_LISTEN_FAILED), "NET_LISTEN_FAILED" }, + { -(MBEDTLS_ERR_NET_ACCEPT_FAILED), "NET_ACCEPT_FAILED" }, + { -(MBEDTLS_ERR_NET_RECV_FAILED), "NET_RECV_FAILED" }, + { -(MBEDTLS_ERR_NET_SEND_FAILED), "NET_SEND_FAILED" }, + { -(MBEDTLS_ERR_NET_CONN_RESET), "NET_CONN_RESET" }, + { -(MBEDTLS_ERR_NET_UNKNOWN_HOST), "NET_UNKNOWN_HOST" }, + { -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL), "NET_BUFFER_TOO_SMALL" }, + { -(MBEDTLS_ERR_NET_INVALID_CONTEXT), "NET_INVALID_CONTEXT" }, + { -(MBEDTLS_ERR_NET_POLL_FAILED), "NET_POLL_FAILED" }, + { -(MBEDTLS_ERR_NET_BAD_INPUT_DATA), "NET_BAD_INPUT_DATA" }, +#endif /* MBEDTLS_NET_C */ + +#if defined(MBEDTLS_OID_C) + { -(MBEDTLS_ERR_OID_NOT_FOUND), "OID_NOT_FOUND" }, + { -(MBEDTLS_ERR_OID_BUF_TOO_SMALL), "OID_BUF_TOO_SMALL" }, +#endif /* MBEDTLS_OID_C */ + +#if defined(MBEDTLS_PADLOCK_C) + { -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED), "PADLOCK_DATA_MISALIGNED" }, +#endif /* MBEDTLS_PADLOCK_C */ + +#if defined(MBEDTLS_PLATFORM_C) + { -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED), "PLATFORM_HW_ACCEL_FAILED" }, + { -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED), "PLATFORM_FEATURE_UNSUPPORTED" }, +#endif /* MBEDTLS_PLATFORM_C */ + +#if defined(MBEDTLS_POLY1305_C) + { -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA), "POLY1305_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE), "POLY1305_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED), "POLY1305_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_POLY1305_C */ + +#if defined(MBEDTLS_RIPEMD160_C) + { -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED), "RIPEMD160_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_RIPEMD160_C */ + +#if defined(MBEDTLS_SHA1_C) + { -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED), "SHA1_HW_ACCEL_FAILED" }, + { -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA), "SHA1_BAD_INPUT_DATA" }, +#endif /* MBEDTLS_SHA1_C */ + +#if defined(MBEDTLS_SHA256_C) + { -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED), "SHA256_HW_ACCEL_FAILED" }, + { -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA), "SHA256_BAD_INPUT_DATA" }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED), "SHA512_HW_ACCEL_FAILED" }, + { -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA), "SHA512_BAD_INPUT_DATA" }, +#endif /* MBEDTLS_SHA512_C */ + +#if defined(MBEDTLS_THREADING_C) + { -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE), "THREADING_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA), "THREADING_BAD_INPUT_DATA" }, + { -(MBEDTLS_ERR_THREADING_MUTEX_ERROR), "THREADING_MUTEX_ERROR" }, +#endif /* MBEDTLS_THREADING_C */ + +#if defined(MBEDTLS_XTEA_C) + { -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH), "XTEA_INVALID_INPUT_LENGTH" }, + { -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED), "XTEA_HW_ACCEL_FAILED" }, +#endif /* MBEDTLS_XTEA_C */ +// END generated code +}; + +static const char *mbedtls_err_prefix = "MBEDTLS_ERR_"; +#define MBEDTLS_ERR_PREFIX_LEN ( sizeof("MBEDTLS_ERR_")-1 ) + +// copy error text into buffer, ensure null termination, return strlen of result +static size_t mbedtls_err_to_str(int err, const struct ssl_errs tab[], int tab_len, char *buf, size_t buflen) { + if (buflen == 0) return 0; + + // prefix for all error names + strncpy(buf, mbedtls_err_prefix, buflen); + if (buflen <= MBEDTLS_ERR_PREFIX_LEN+1) { + buf[buflen-1] = 0; + return buflen-1; + } + + // append error name from table + for (int i = 0; i < tab_len; i++) { + if (tab[i].errnum == err) { + strncpy(buf+MBEDTLS_ERR_PREFIX_LEN, tab[i].errstr, buflen-MBEDTLS_ERR_PREFIX_LEN); + buf[buflen-1] = 0; + return strlen(buf); + } + } + + mbedtls_snprintf(buf+MBEDTLS_ERR_PREFIX_LEN, buflen-MBEDTLS_ERR_PREFIX_LEN, "UNKNOWN (0x%04X)", + err); + return strlen(buf); +} + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +void mbedtls_strerror(int ret, char *buf, size_t buflen) { + int use_ret; + + if (buflen == 0) return; + + buf[buflen-1] = 0; + + if (ret < 0) ret = -ret; + + // + // High-level error codes + // + uint8_t got_hl = (ret & 0xFF80) != 0; + if (got_hl) { + use_ret = ret & 0xFF80; + + // special case +#if defined(MBEDTLS_SSL_TLS_C) + if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) { + strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen); + buf[buflen-1] = 0; + return; + } +#endif + + size_t len = mbedtls_err_to_str(use_ret, mbedtls_high_level_error_tab, + ARRAY_SIZE(mbedtls_high_level_error_tab), buf, buflen); + + buf += len; + buflen -= len; + if (buflen == 0) return; + } + + // + // Low-level error codes + // + use_ret = ret & ~0xFF80; + + if (use_ret == 0) return; + + // If high level code is present, make a concatenation between both error strings. + if (got_hl) { + if (buflen < 2) return; + *buf++ = '+'; + buflen--; + } + + mbedtls_err_to_str(use_ret, mbedtls_low_level_error_tab, + ARRAY_SIZE(mbedtls_low_level_error_tab), buf, buflen); +} + +#else /* MBEDTLS_ERROR_C */ + +#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) + +/* + * Provide an non-function in case MBEDTLS_ERROR_C is not defined + */ +void mbedtls_strerror( int ret, char *buf, size_t buflen ) +{ + ((void) ret); + + if( buflen > 0 ) + buf[0] = '\0'; +} + +#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ + +#endif /* MBEDTLS_ERROR_C */ diff --git a/lib/mbedtls_errors/tester.c b/lib/mbedtls_errors/tester.c new file mode 100644 index 0000000000..6f1c788f50 --- /dev/null +++ b/lib/mbedtls_errors/tester.c @@ -0,0 +1,58 @@ +#include "mbedtls/error.h" +#include +#include + +// test_code checks that the provided code results in the provided error string for any size +// buffer. It calls mbedtls_strerror() to fill a buffer that is from 1 to 100 bytes in length +// and then checks that the buffer contents is OK and that a few guard bytes before and after +// the buffer were not overwritten. +int test_code(int code, char *str) { + char buf[100]; + int ok = 1; + int res; + + // test zero-length buffer + memset(buf, -3, 100); + mbedtls_strerror(code, buf + 4, 0); + for (int i = 0; i < 10; i++) { + if (buf[i] != -3) { + printf("Error: guard overwritten buflen=0 i=%d buf[i]=%d\n", i, buf[i]); + ok = 0; + } + } + + // test + for (size_t buflen = 1; buflen < 90; buflen++) { + memset(buf, -3, 100); + mbedtls_strerror(code, buf + 4, buflen); + for (int i = 0; i < 4; i++) { + if (buf[i] != -3) { + printf("Error: pre-guard overwritten buflen=%d i=%d buf[i]=%d\n", buflen, i, buf[i]); + ok = 0; + } + } + for (int i = 4 + buflen; i < 100; i++) { + if (buf[i] != -3) { + printf("Error: post-guard overwritten buflen=%d i=%d buf[i]=%d\n", buflen, i, buf[i]); + ok = 0; + } + } + char exp[100]; + strncpy(exp, str, buflen); + exp[buflen - 1] = 0; + if (strcmp(buf + 4, exp) != 0) { + printf("Error: expected %s, got %s\n", exp, buf); + ok = 0; + } + } + + printf("Test %x -> %s is %s\n", code, str, ok?"OK":"*** BAD ***"); +} + +int main() { + test_code(0x7200, "MBEDTLS_ERR_SSL_INVALID_RECORD"); + test_code(0x7780, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE"); + test_code(0x0074, "MBEDTLS_ERR_SHA256_BAD_INPUT_DATA"); + test_code(0x6600 | 0x0074, "MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH+MBEDTLS_ERR_SHA256_BAD_INPUT_DATA"); + test_code(103, "MBEDTLS_ERR_UNKNOWN (0x0067)"); +} diff --git a/lib/oofatfs/ff.c b/lib/oofatfs/ff.c index 6188aead2d..dbcfa3efc3 100644 --- a/lib/oofatfs/ff.c +++ b/lib/oofatfs/ff.c @@ -257,6 +257,11 @@ #define GET_FATTIME() get_fattime() #endif +#if FF_FS_MAKE_VOLID == 1 +#define MAKE_VOLID(x) (make_volid()) +#else +#define MAKE_VOLID(x) (GET_FATTIME()) +#endif /* File lock controls */ #if FF_FS_LOCK != 0 @@ -273,6 +278,12 @@ typedef struct { /* SBCS up-case tables (\x80-\xFF) */ +// Optimize the 437-only case with a truncated lookup table. +#if FF_CODE_PAGE == 437 +#define TBL_CT437 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ + 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5} +#else #define TBL_CT437 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ @@ -281,6 +292,7 @@ typedef struct { 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#endif #define TBL_CT720 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ @@ -2882,7 +2894,12 @@ static FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not } #elif FF_CODE_PAGE < 900 /* SBCS cfg */ wc = ff_uni2oem(wc, CODEPAGE); /* Unicode ==> ANSI/OEM code */ + // Optimize the 437-only case with a truncated lookup table. +#if FF_CODE_PAGE == 437 + if (wc & 0x80 && wc < (0xA5 - 0x80)) wc = ExCvt[wc & 0x7F]; /* Convert extended character to upper (SBCS) */ +#else if (wc & 0x80) wc = ExCvt[wc & 0x7F]; /* Convert extended character to upper (SBCS) */ +#endif #else /* DBCS cfg */ wc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE); /* Unicode ==> Upper convert ==> ANSI/OEM code */ #endif @@ -4816,6 +4833,21 @@ FRESULT f_rename ( DEF_NAMBUF + // 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; + res = f_stat(fs, path_old, &fno); + if (res != FR_OK) { + return res; + } + if ((fno.fattrib & AM_DIR) != 0 && + strlen(path_new) > strlen(path_old) && + path_new[strlen(path_old)] == '/' && + strncmp(path_old, path_new, strlen(path_old)) == 0) { + return FR_INVALID_NAME; + } + res = find_volume(fs, FA_WRITE); /* Get logical drive of the old object */ if (res == FR_OK) { djo.obj.fs = fs; @@ -5406,6 +5438,7 @@ FRESULT f_mkfs ( DWORD tbl[3]; #endif + DWORD volid = MAKE_VOLID(); /* Check mounted drive and clear work area */ fs->fs_type = 0; /* Clear mounted volume */ @@ -5607,7 +5640,7 @@ FRESULT f_mkfs ( st_dword(buf + BPB_DataOfsEx, b_data - b_vol); /* Data offset [sector] */ st_dword(buf + BPB_NumClusEx, n_clst); /* Number of clusters */ st_dword(buf + BPB_RootClusEx, 2 + tbl[0] + tbl[1]); /* Root dir cluster # */ - st_dword(buf + BPB_VolIDEx, GET_FATTIME()); /* VSN */ + st_dword(buf + BPB_VolIDEx, volid); /* VSN */ st_word(buf + BPB_FSVerEx, 0x100); /* Filesystem version (1.00) */ for (buf[BPB_BytsPerSecEx] = 0, i = ss; i >>= 1; buf[BPB_BytsPerSecEx]++) ; /* Log2 of sector size [byte] */ for (buf[BPB_SecPerClusEx] = 0, i = au; i >>= 1; buf[BPB_SecPerClusEx]++) ; /* Log2 of cluster size [sector] */ @@ -5743,7 +5776,7 @@ FRESULT f_mkfs ( st_dword(buf + BPB_HiddSec, b_vol); /* Volume offset in the physical drive [sector] */ #if FF_MKFS_FAT32 if (fmt == FS_FAT32) { - st_dword(buf + BS_VolID32, GET_FATTIME()); /* VSN */ + st_dword(buf + BS_VolID32, volid); /* VSN */ st_dword(buf + BPB_FATSz32, sz_fat); /* FAT size [sector] */ st_dword(buf + BPB_RootClus32, 2); /* Root directory cluster # (2) */ st_word(buf + BPB_FSInfo32, 1); /* Offset of FSINFO sector (VBR + 1) */ @@ -5754,7 +5787,7 @@ FRESULT f_mkfs ( } else #endif { - st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */ + st_dword(buf + BS_VolID, volid); /* VSN */ st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */ buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */ buf[BS_BootSig] = 0x29; /* Extended boot signature */ diff --git a/lib/oofatfs/ff.h b/lib/oofatfs/ff.h index a8aa00e9af..b133d770db 100644 --- a/lib/oofatfs/ff.h +++ b/lib/oofatfs/ff.h @@ -334,6 +334,10 @@ FRESULT f_setcp (WORD cp); /* Set curre DWORD get_fattime (void); #endif +#if FF_FS_MAKE_VOLID +DWORD make_volid (void); +#endif + /* LFN support functions */ #if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */ WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */ diff --git a/lib/oofatfs/ffconf.h b/lib/oofatfs/ffconf.h index 248987dda3..52ff6d0a7a 100644 --- a/lib/oofatfs/ffconf.h +++ b/lib/oofatfs/ffconf.h @@ -373,6 +373,10 @@ / SemaphoreHandle_t and etc. A header file for O/S definitions needs to be / included somewhere in the scope of ff.h. */ - +#ifndef FF_FS_MAKE_VOLID +#define FF_FS_MAKE_VOLID (0) +#endif +/* The option FF_FS_MAKE_VOLID enables the use of a function to return a 32-bit volume identifier. +/ If it is disabled, a Volume ID based on the current time is used. */ /*--- End of configuration options ---*/ diff --git a/lib/oofatfs/ffunicode.c b/lib/oofatfs/ffunicode.c index 4153f9131c..a04577616a 100644 --- a/lib/oofatfs/ffunicode.c +++ b/lib/oofatfs/ffunicode.c @@ -499,6 +499,13 @@ DWORD ff_wtoupper ( /* Returns up-converted code point */ DWORD uni /* Unicode code point to be up-converted */ ) { + #if FF_FS_CASE_INSENSITIVE_COMPARISON_ASCII_ONLY + // Only uppercase ASCII characters. Everything else will require the user to + // pass in an uppercase version. + if ('a' <= uni && uni <= 'z') { + uni -= 32; + } + #else const WORD *p; WORD uc, bc, nc, cmd; static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */ @@ -619,6 +626,7 @@ DWORD ff_wtoupper ( /* Returns up-converted code point */ } uni = uc; } + #endif return uni; } diff --git a/locale/ID.po b/locale/ID.po index 457615d505..b30c7d5d9c 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -30,15 +30,32 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" "\n" -"Harap ajukan masalah dengan konten drive CIRCUITPY Anda di\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -65,6 +82,16 @@ msgstr "output:\n" msgid "%%c requires int or char" msgstr "%%c harus int atau char" +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -72,13 +99,16 @@ msgid "" msgstr "" "%d pin alamat, %d rgb pin dan %d ubin menunjukkan ketinggian %d, bukan %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -98,23 +128,34 @@ msgstr "%q berisi pin duplikat" msgid "%q failure: %d" msgstr "%q gagal: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q sedang digunakan" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "%q indeks di luar batas" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "indeks %q harus bilangan bulat, bukan %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "" @@ -130,10 +171,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "%q panjang harus >= 1" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -154,28 +191,25 @@ msgstr "%q harus <= %d" msgid "%q must be >= %d" msgstr "%q harus >= %d" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q harus >= 0" - -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q harus >= 1" - -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q harus berupa string" - -#: py/argcheck.c -msgid "%q must be an int" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "%q harus bertipe %q" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "" + +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -195,12 +229,8 @@ msgstr "" msgid "%q out of range" msgstr "%q di luar jangkauan" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "pin %q tidak valid" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c @@ -211,11 +241,11 @@ msgstr "%q() mengambil posisi argumen %d tapi %d yang diberikan" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, dan %q semuanya harus memiliki panjang yang sama" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s kesalahan 0x%x" @@ -400,12 +430,16 @@ msgstr "ADC2 sedang digunakan oleh WiFi" msgid "Address must be %d bytes long" msgstr "Alamat harus sepanjang %d byte" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Semua perangkat I2C sedang digunakan" @@ -427,7 +461,6 @@ msgid "All SPI peripherals are in use" msgstr "Semua perangkat SPI sedang digunakan" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Semua perangkat UART sedang digunakan" @@ -480,15 +513,22 @@ msgstr "Sudah disebarkan." msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "" @@ -502,23 +542,16 @@ msgstr "Send yang lain sudah aktif" msgid "Array must contain halfwords (type 'H')" msgstr "Array harus mengandung halfwords (ketik 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Nilai array harus berupa byte tunggal." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "Paling banyak %d %q dapat ditentukan (bukan %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "" @@ -569,7 +602,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -653,7 +686,7 @@ msgstr "Blok CBC harus merupakan kelipatan 16 byte" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "" @@ -775,10 +808,6 @@ msgstr "Menulis CharacteristicBuffer tidak tersedia" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "Kode inti CircuitPython mengalami crash. Aduh!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "" - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Peregangan clock terlalu panjang" @@ -794,6 +823,14 @@ msgid "" msgstr "" "Koneksi telah terputus dan tidak dapat lagi digunakan. Buat koneksi baru." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "File .mpy rusak" @@ -818,10 +855,6 @@ msgstr "Tidak dapat memulai interupsi, RX sibuk" msgid "Couldn't allocate decoder" msgstr "Tidak dapat mengalokasikan dekoder" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Gagal ke HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Terjadi kesalahan saat menginisialisasi kanal DAC" @@ -876,10 +909,18 @@ msgstr "Tampilan harus memiliki ruang warna 16 bit." msgid "Display rotation must be in 90 degree increments" msgstr "Rotasi tampilan harus dalam kelipatan 90 derajat" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "Mode kendara tidak digunakan saat arah input." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "ECB hanya beroperasi pada 16 byte di satu waktu" @@ -905,19 +946,16 @@ msgstr "" msgid "Error in regex" msgstr "Error pada regex" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Diharapkan %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -971,10 +1009,6 @@ msgstr "Gagal terhubung: kesalahan internal" msgid "Failed to connect: timeout" msgstr "Gagal terhubung: habis waktu" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Gagal mengurai file MP3" @@ -989,13 +1023,17 @@ msgid "Failed to write internal flash." msgstr "Gagal menulis flash internal." #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "File sudah ada" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1003,7 +1041,15 @@ msgid "Filters too complex" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" #: shared-bindings/bitmaptools/__init__.c @@ -1036,13 +1082,15 @@ msgstr "Fungsinya membutuhkan kunci" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Grup sudah digunakan" @@ -1063,6 +1111,15 @@ msgstr "Perangkat keras sibuk, coba pin alternatif" msgid "Hardware in use, try alternative pins" msgstr "Perangkat keras sedang digunakan, coba pin alternatif" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "operasi I/O pada file tertutup" @@ -1072,6 +1129,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "" @@ -1079,11 +1137,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "Panjang IV harus %d byte" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1170,6 +1223,7 @@ msgid "Internal define error" msgstr "Kesalahan definisi internal" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1182,10 +1236,16 @@ msgstr "Kesalahan internal #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "%q pada tidak valid" @@ -1207,7 +1267,7 @@ msgstr "" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Argumen tidak valid" @@ -1216,6 +1276,11 @@ msgstr "Argumen tidak valid" msgid "Invalid bits per value" msgstr "Bit per nilai tidak valid" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1225,34 +1290,35 @@ msgstr "" msgid "Invalid format chunk size" msgstr "Ukuran potongan format tidak valid" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Akses memori tidak valid." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Pin-pin tidak valid" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "Panjang kunci harus 16, 24, atau 32 byte" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1269,7 +1335,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -1359,6 +1425,10 @@ msgstr "" msgid "NVS Error" msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "Nama terlalu panjang" @@ -1473,11 +1543,6 @@ msgstr "Tidak ada kunci yang ditentukan" msgid "No long integer support" msgstr "Tidak ada dukungan bilangan bulat yang panjang" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "" @@ -1513,10 +1578,6 @@ msgstr "Tidak ada file/direktori" msgid "No timer available" msgstr "Penghitung waktu tidak tersedia" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1536,10 +1597,6 @@ msgstr "Tidak terhubung" msgid "Not playing" msgstr "Tidak berfungsi" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1555,16 +1612,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "Parity ganjil tidak didukung" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Hanya 8 atau 16 bit mono dengan " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Hanya alamat IPv4 yang didukung" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "Hanysa socket IPv4 yang didukung" @@ -1598,10 +1665,15 @@ msgstr "" "didukung: %d bpp diberikan" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1624,19 +1696,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "Waktu habis" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "Kehabisan memori" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Kehabisan socket" @@ -1693,7 +1770,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "" @@ -1762,6 +1838,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull tidak digunakan saat arah output." @@ -1801,8 +1881,9 @@ msgstr "RTC tidak didukung di board ini" msgid "Random number generation error" msgstr "Kesalahan pembuatan nomor acak" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Baca-saja" @@ -1810,14 +1891,14 @@ msgstr "Baca-saja" msgid "Read-only filesystem" msgstr "sistem file (filesystem) bersifat Read-only" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "Objek Read-only" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "Segarkan terlalu cepat" @@ -1830,7 +1911,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "Mode AES yang diminta tidak didukung" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1904,7 +1985,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Potongan dan nilai panjangnya berbeda." @@ -1916,6 +1998,7 @@ msgid "Slices not supported" msgstr "Potongan tidak didukung" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1939,13 +2022,9 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Aliran tidak menemukan metode readinto() atau write()." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Berikan setidaknya satu pin UART" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -1960,15 +2039,11 @@ msgid "Temperature read timed out" msgstr "Waktu baca suhu habis" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1976,10 +2051,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1998,6 +2070,10 @@ msgstr "Tingkat sampel dari sampel tidak cocok dengan mixer" msgid "The sample's signedness does not match the mixer's" msgstr "signedness dari sampel tidak cocok dengan mixer" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2030,10 +2106,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "Untuk keluar, silahkan reset board tanpa " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2078,6 +2150,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2086,6 +2162,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2121,6 +2201,15 @@ msgstr "Nilai UUID bukan str, int atau byte buffer" msgid "Unable to allocate buffers for signed conversion" msgstr "Tidak dapat mengalokasikan buffer untuk signed conversion" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2139,14 +2228,29 @@ msgstr "Tidak dapat menemukan GCLK yang kosong" msgid "Unable to init parser" msgstr "Tidak dapat memulai parser" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "Tidak dapat membaca data palet warna" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Tidak dapat menulis ke nvm." @@ -2209,7 +2313,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "Jumlah item pada RHS tidak cocok (diharapkan %d, didapatkan %d)." @@ -2256,7 +2366,7 @@ msgstr "Panjang nilai != Panjang tetap yang dibutuhkan" msgid "Value length > max_length" msgstr "Panjang nilai > max_length" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2282,10 +2392,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -2300,6 +2406,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2309,18 +2427,57 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "Menulis tidak didukung pada Karakteristik" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "" #: py/objtype.c msgid "__init__() should return None" @@ -2338,11 +2495,7 @@ msgstr "__new__ arg harus berupa user-type" msgid "a bytes-like object is required" msgstr "sebuah objek menyerupai byte (bytes-like) dibutuhkan" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "alamat di luar batas" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "alamatnya kosong" @@ -2395,8 +2548,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "diperlukan array/byte di sisi kanan" @@ -2489,10 +2646,6 @@ msgstr "" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2534,15 +2687,10 @@ msgstr "tidak dapat menetapkan ke ekspresi" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2620,10 +2768,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "" @@ -2722,18 +2874,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "" @@ -2816,10 +2960,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "" @@ -2840,12 +2980,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "" @@ -2877,10 +3016,6 @@ msgstr "" msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2890,18 +3025,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -3000,10 +3133,6 @@ msgstr "" msgid "format requires a dict" msgstr "" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "" @@ -3116,16 +3245,16 @@ msgstr "lapisan (padding) tidak benar" msgid "index is out of bounds" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "index keluar dari jangkauan" -#: py/obj.c -msgid "indices must be integers" -msgstr "" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "" @@ -3219,10 +3348,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3241,6 +3366,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "cert tidak valid" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3267,10 +3396,18 @@ msgstr "" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "key tidak valid" + #: py/compile.c msgid "invalid micropython decorator" msgstr "micropython decorator tidak valid" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "" @@ -3292,10 +3429,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3352,19 +3485,17 @@ msgstr "" msgid "local variable referenced before assignment" msgstr "" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3493,6 +3624,10 @@ msgstr "" msgid "negative shift count" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3526,14 +3661,10 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3659,15 +3790,30 @@ msgid "offset out of bounds" msgstr "modul tidak ditemukan" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" @@ -3738,10 +3884,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "" @@ -3791,28 +3933,6 @@ msgstr "" msgid "pow() with 3 arguments requires integers" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3833,11 +3953,6 @@ msgstr "" msgid "relative import" msgstr "relative import" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3868,12 +3983,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3907,10 +4016,6 @@ msgstr "" msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3923,10 +4028,6 @@ msgstr "" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3975,14 +4076,6 @@ msgstr "" msgid "start/end indices" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "" @@ -3991,10 +4084,6 @@ msgstr "" msgid "stream operation not supported" msgstr "" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" @@ -4027,14 +4116,6 @@ msgstr "sintaksis error pada JSON" msgid "syntax error in uctypes descriptor" msgstr "sintaksis error pada pendeskripsi uctypes" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4042,10 +4123,6 @@ msgstr "" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4099,10 +4176,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4113,8 +4186,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx dan rx keduanya tidak boleh kosong" @@ -4127,14 +4198,10 @@ msgstr "" msgid "type is not an acceptable base type" msgstr "" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "" @@ -4155,7 +4222,7 @@ msgstr "" msgid "unexpected keyword argument" msgstr "argumen keyword tidak diharapkan" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "keyword argumen '%q' tidak diharapkan" @@ -4185,7 +4252,8 @@ msgid "unknown type '%q'" msgstr "" #: py/objstr.c -msgid "unmatched '{' in format" +#, c-format +msgid "unmatched '%c' in format" msgstr "" #: py/objtype.c py/runtime.c @@ -4193,7 +4261,6 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" @@ -4257,18 +4324,19 @@ msgstr "" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "wifi tidak diaktifkan" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "jendela harus <= interval" @@ -4323,18 +4391,10 @@ msgstr "nilai x di luar batas" msgid "xTaskCreate failed" msgstr "xTaskCreate gagal" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y harus menjadi int" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "Nilai y di luar batas" -#: py/objrange.c -msgid "zero step" -msgstr "nol langkah" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "zi harus ndarray" @@ -4347,6 +4407,79 @@ msgstr "zi harus berjenis float" msgid "zi must be of shape (n_section, 2)" msgstr "Zi harus berbentuk (n_section, 2)" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Berikan setidaknya satu pin UART" + +#~ msgid "%q pin invalid" +#~ msgstr "pin %q tidak valid" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Harap ajukan masalah dengan konten drive CIRCUITPY Anda di\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Gagal ke HardFault_Handler." + +#~ msgid "Invalid memory access." +#~ msgstr "Akses memori tidak valid." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q harus bertipe %q" + +#~ msgid "Expected a %q" +#~ msgstr "Diharapkan %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "Panjang IV harus %d byte" + +#~ msgid "Read-only object" +#~ msgstr "Objek Read-only" + +#~ msgid "%q length must be >= 1" +#~ msgstr "%q panjang harus >= 1" + +#~ msgid "%q must be a string" +#~ msgstr "%q harus berupa string" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Paling banyak %d %q dapat ditentukan (bukan %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Pin-pin tidak valid" + +#~ msgid "zero step" +#~ msgstr "nol langkah" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "indeks %q harus bilangan bulat, bukan %s" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "Untuk keluar, silahkan reset board tanpa " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada " + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Aliran tidak menemukan metode readinto() atau write()." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q harus >= 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q harus >= 1" + +#~ msgid "address out of bounds" +#~ msgstr "alamat di luar batas" + +#~ msgid "y should be an int" +#~ msgstr "y harus menjadi int" + #~ msgid "%q must be a tuple of length 2" #~ msgstr "%q harus berupa tuple dengan panjang 2" @@ -4742,12 +4875,6 @@ msgstr "Zi harus berbentuk (n_section, 2)" #~ msgid "Corrupt raw code" #~ msgstr "Kode raw rusak" -#~ msgid "invalid cert" -#~ msgstr "cert tidak valid" - -#~ msgid "invalid key" -#~ msgstr "key tidak valid" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Fungsi Viper saat ini tidak mendukung lebih dari 4 argumen" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 1607df3ec8..ac7b040936 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -28,11 +28,31 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" #: py/obj.c @@ -60,19 +80,32 @@ msgstr "" msgid "%%c requires int or char" msgstr "" +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -92,23 +125,34 @@ msgstr "" msgid "%q failure: %d" msgstr "" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "" @@ -124,10 +168,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -148,28 +188,25 @@ msgstr "" msgid "%q must be >= %d" msgstr "" -#: py/argcheck.c -msgid "%q must be >= 0" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be a string" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be an int" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "" - -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -189,12 +226,8 @@ msgstr "" msgid "%q out of range" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c @@ -205,11 +238,11 @@ msgstr "" msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -394,12 +427,16 @@ msgstr "" msgid "Address must be %d bytes long" msgstr "" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "" @@ -421,7 +458,6 @@ msgid "All SPI peripherals are in use" msgstr "" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "" @@ -474,15 +510,22 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "" @@ -496,23 +539,16 @@ msgstr "" msgid "Array must contain halfwords (type 'H')" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "" @@ -561,7 +597,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -645,7 +681,7 @@ msgstr "" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "" @@ -763,10 +799,6 @@ msgstr "" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "" - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "" @@ -781,6 +813,14 @@ msgid "" "connection." msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "" @@ -805,10 +845,6 @@ msgstr "" msgid "Couldn't allocate decoder" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "" - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "" @@ -863,10 +899,18 @@ msgstr "" msgid "Display rotation must be in 90 degree increments" msgstr "" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "" @@ -892,19 +936,16 @@ msgstr "" msgid "Error in regex" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -958,10 +999,6 @@ msgstr "" msgid "Failed to connect: timeout" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "" @@ -976,13 +1013,17 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -990,7 +1031,15 @@ msgid "Filters too complex" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" #: shared-bindings/bitmaptools/__init__.c @@ -1023,13 +1072,15 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -1050,6 +1101,15 @@ msgstr "" msgid "Hardware in use, try alternative pins" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "" @@ -1059,6 +1119,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "" @@ -1066,11 +1127,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1155,6 +1211,7 @@ msgid "Internal define error" msgstr "" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1167,10 +1224,16 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "" @@ -1192,7 +1255,7 @@ msgstr "" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "" @@ -1201,6 +1264,11 @@ msgstr "" msgid "Invalid bits per value" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1210,34 +1278,35 @@ msgstr "" msgid "Invalid format chunk size" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "" - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1254,7 +1323,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -1344,6 +1413,10 @@ msgstr "" msgid "NVS Error" msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "" @@ -1458,11 +1531,6 @@ msgstr "" msgid "No long integer support" msgstr "" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "" @@ -1498,10 +1566,6 @@ msgstr "" msgid "No timer available" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1521,10 +1585,6 @@ msgstr "" msgid "Not playing" msgstr "" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1539,16 +1599,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "" #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "" @@ -1578,10 +1648,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1604,19 +1679,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1671,7 +1751,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "" @@ -1735,6 +1814,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1774,8 +1857,9 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "" @@ -1783,12 +1867,12 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +msgid "Received response was invalid" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c -msgid "Received response was invalid" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" #: shared-bindings/displayio/EPaperDisplay.c @@ -1803,7 +1887,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1875,7 +1959,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1887,6 +1972,7 @@ msgid "Slices not supported" msgstr "" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1910,12 +1996,8 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "" - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c @@ -1931,15 +2013,11 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1947,10 +2025,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1969,6 +2044,10 @@ msgstr "" msgid "The sample's signedness does not match the mixer's" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2001,10 +2080,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2049,6 +2124,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2057,6 +2136,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2092,6 +2175,15 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2110,14 +2202,29 @@ msgstr "" msgid "Unable to init parser" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "" @@ -2180,7 +2287,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2225,7 +2338,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2251,10 +2364,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -2269,6 +2378,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2278,17 +2399,56 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2307,11 +2467,7 @@ msgstr "" msgid "a bytes-like object is required" msgstr "" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "" @@ -2364,8 +2520,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "" @@ -2458,10 +2618,6 @@ msgstr "" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2503,15 +2659,10 @@ msgstr "" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2589,10 +2740,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "" @@ -2691,18 +2846,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "" @@ -2785,10 +2932,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "" @@ -2809,12 +2952,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "" @@ -2846,10 +2988,6 @@ msgstr "" msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2859,18 +2997,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -2969,10 +3105,6 @@ msgstr "" msgid "format requires a dict" msgstr "" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "" @@ -3085,14 +3217,14 @@ msgstr "" msgid "index is out of bounds" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" msgstr "" #: extmod/ulab/code/ndarray.c @@ -3188,10 +3320,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3210,6 +3338,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3236,10 +3368,18 @@ msgstr "" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "" + #: py/compile.c msgid "invalid micropython decorator" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "" @@ -3261,10 +3401,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3321,19 +3457,17 @@ msgstr "" msgid "local variable referenced before assignment" msgstr "" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3462,6 +3596,10 @@ msgstr "" msgid "negative shift count" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3495,14 +3633,10 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3627,15 +3761,30 @@ msgid "offset out of bounds" msgstr "" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" @@ -3706,10 +3855,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "" @@ -3759,28 +3904,6 @@ msgstr "" msgid "pow() with 3 arguments requires integers" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3801,11 +3924,6 @@ msgstr "" msgid "relative import" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3836,12 +3954,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3875,10 +3987,6 @@ msgstr "" msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3891,10 +3999,6 @@ msgstr "" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3943,14 +4047,6 @@ msgstr "" msgid "start/end indices" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "" @@ -3959,10 +4055,6 @@ msgstr "" msgid "stream operation not supported" msgstr "" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" @@ -3995,14 +4087,6 @@ msgstr "" msgid "syntax error in uctypes descriptor" msgstr "" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4010,10 +4094,6 @@ msgstr "" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4067,10 +4147,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4081,8 +4157,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" @@ -4095,14 +4169,10 @@ msgstr "" msgid "type is not an acceptable base type" msgstr "" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "" @@ -4123,7 +4193,7 @@ msgstr "" msgid "unexpected keyword argument" msgstr "" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "" @@ -4153,7 +4223,8 @@ msgid "unknown type '%q'" msgstr "" #: py/objstr.c -msgid "unmatched '{' in format" +#, c-format +msgid "unmatched '%c' in format" msgstr "" #: py/objtype.c py/runtime.c @@ -4161,7 +4232,6 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" @@ -4225,18 +4295,19 @@ msgstr "" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" @@ -4291,18 +4362,10 @@ msgstr "" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "" -#: py/objrange.c -msgid "zero step" -msgstr "" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index 9c042c6c51..164f9c42ad 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -32,15 +32,32 @@ msgstr "" "\n" "Kód byl zastaven kvůli automatickému načtení. K načtení dojde brzy.\n" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" "\n" -"Prosím vytvořte tiket s obsahem vaší jednotky CIRCUITPY na adrese\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -67,19 +84,32 @@ msgstr " výstup:\n" msgid "%%c requires int or char" msgstr "%%c vyžaduje int nebo char" +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "%d adresní pin, %d rgb pin a %d dlaždice indikuje výšku %d, ne %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -99,23 +129,34 @@ msgstr "%q obsahuje duplicitní piny" msgid "%q failure: %d" msgstr "%q: selhání %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q se právě používá" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "Index %q je mimo rozsah" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "Indexy %q musí být celá čísla, nikoli %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "Inicializace %q selhala" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "Délka %q musí být %d" @@ -131,10 +172,6 @@ msgstr "Délka %q musí být <= %d" msgid "%q length must be >= %d" msgstr "Délka %q musí být >= %d" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "%q délka musí být >= 1" - #: py/argcheck.c msgid "%q must be %d" msgstr "%q musí být %d" @@ -155,29 +192,26 @@ msgstr "%q musí být <= %d" msgid "%q must be >= %d" msgstr "%q musí být >= %d" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q musí být >= 0" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q musí být > = 1" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "" -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q musí být string" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "" -#: py/argcheck.c -msgid "%q must be an int" -msgstr "%q musí být int" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "%q musí být typu %q" - -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q musí být typu %q nebo None" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" +msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" @@ -196,13 +230,9 @@ msgstr "%q je mimo hranice" msgid "%q out of range" msgstr "%q je mimo rozsah" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "pin %q není platný" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" -msgstr "%q s ID 0 musím být délky 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -212,11 +242,11 @@ msgstr "%q() vyžaduje %d pozičních argumentů, ale %d jich bylo zadáno" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, a %q musí mít všechny shodnou délku" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s chyba 0x%x" @@ -401,12 +431,16 @@ msgstr "WiFi používá ADC2" msgid "Address must be %d bytes long" msgstr "Adresa musí být %d bajtů dlouhá" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "Všechny CAN periferie jsou používány" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Všechny I2C periferie jsou používány" @@ -428,7 +462,6 @@ msgid "All SPI peripherals are in use" msgstr "Všechny SPI periferie jsou používány" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Všechny UART periferie jsou používány" @@ -481,15 +514,22 @@ msgstr "Již propagujeme." msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Již běží" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Již skenuje wifi sítě" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "Jiný PWMAudioOut je již aktivní" @@ -503,23 +543,16 @@ msgstr "Další odesílání je již aktivní" msgid "Array must contain halfwords (type 'H')" msgstr "Pole musí obsahovat poloviční slova (typ „H“)" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Hodnoty pole by měly být jednoduché bajty." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "Lze zadat maximálně %d %q (nikoli %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Pokus o alokování %d bloků" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "Pokus o alokaci haldy, když neběží VM." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "Konverze audia není implementována" @@ -570,8 +603,8 @@ msgid "Bitmap size and bits per value must match" msgstr "Velikost bitmapy a počet bitů na hodnotu se musí shodovat" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "Bootovací zařízení musí být první (rozhraní #0)." +msgid "Boot device must be first (interface #0)." +msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" @@ -654,7 +687,7 @@ msgstr "Bloky CBC musí být násobky 16 bajtů" msgid "CIRCUITPY drive could not be found or created." msgstr "Disk CIRCUITPY nelze nalézt nebo vytvořit." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "" @@ -773,10 +806,6 @@ msgstr "CharacteristicBuffer psaní není poskytováno" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "Jádro kódu CircuitPython tvrdě havarovalo. Jejda!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPython nedokázal alokovat haldu." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Hodiny jsou příliš dlouhé" @@ -792,6 +821,14 @@ msgid "" msgstr "" "Připojení bylo odpojeno a nelze jej dále používat. Vytvořte nové připojení." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Poškozený soubor .mpy" @@ -816,10 +853,6 @@ msgstr "Nelze začít přerušení, RX je zaneprázdněn" msgid "Couldn't allocate decoder" msgstr "Dekodér nelze přiřadit" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Pád do HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Chyba inicializace kanálu DAC" @@ -874,10 +907,18 @@ msgstr "Displej musí mít 16bitový barevný prostor." msgid "Display rotation must be in 90 degree increments" msgstr "Otočení displeje musí být po 90 stupních" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "ECB operuje najednou pouze 16 bajtů" @@ -903,19 +944,16 @@ msgstr "Chyba v MIDI přenosu na pozici %d" msgid "Error in regex" msgstr "Chyba v regulárním výrazu" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Očekává se %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -969,10 +1007,6 @@ msgstr "Připojení se nezdařilo: interní chyba" msgid "Failed to connect: timeout" msgstr "Nepodařilo se připojit: časový limit" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "Chyba inicializace WiFi" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Soubor MP3 se nepodařilo analyzovat" @@ -987,13 +1021,17 @@ msgid "Failed to write internal flash." msgstr "Nepodařilo se zapsat do interní paměti." #: supervisor/shared/safe_mode.c -msgid "Fatal error." -msgstr "Fatální chyba." +msgid "Fault detected by hardware." +msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "soubor existuje" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1001,8 +1039,16 @@ msgid "Filters too complex" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "Obraz firmwaru je nevalidní" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" @@ -1036,13 +1082,15 @@ msgstr "Funkce vyžaduje zámek" msgid "GNSS init" msgstr "Inicializace GNSS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "Základní chyba" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Skupina již byla použita" @@ -1063,6 +1111,15 @@ msgstr "Hardware je zaneprázdněn, zkuste alternativní piny" msgid "Hardware in use, try alternative pins" msgstr "Hardware je používán, zkuste alternativní piny" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "" @@ -1072,6 +1129,7 @@ msgid "I2C init error" msgstr "Chyba inicializace I2C" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "Periférie I2C je používána" @@ -1079,11 +1137,6 @@ msgstr "Periférie I2C je používána" msgid "I2SOut not available" msgstr "" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV musí být dlouhé %d bajtů" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1170,6 +1223,7 @@ msgid "Internal define error" msgstr "" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "Interní chyba" @@ -1182,10 +1236,16 @@ msgstr "Vnitřní chyba #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Neplatný pin %q" @@ -1207,7 +1267,7 @@ msgstr "Chybné BSSID" msgid "Invalid MAC address" msgstr "Chybná MAC adresa" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Neplatný argument" @@ -1216,6 +1276,11 @@ msgstr "Neplatný argument" msgid "Invalid bits per value" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1225,34 +1290,35 @@ msgstr "Chybný data_pin[%d]" msgid "Invalid format chunk size" msgstr "Neplatná velikost bloku" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Neplatný přístup k paměti." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Chybná multicastová MAC adresa" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Neplatné piny" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "Chybná velikost" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "Chybný soket pro TLS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "Chybný stav" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "Klíč musí být dlouhý 16, 24 nebo 32 bajtů" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "Mapování LED musí korespondovat s velikostí displeje" @@ -1269,7 +1335,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "MAC adresa byla chybná" @@ -1359,6 +1425,10 @@ msgstr "" msgid "NVS Error" msgstr "Chyba NVS" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "Jméno je příliš dlouhé" @@ -1473,11 +1543,6 @@ msgstr "Nebyl zadán klíč" msgid "No long integer support" msgstr "" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "Ne více než %d HID zařízení je povoleno" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "Žádná síť s takovým SSID" @@ -1513,10 +1578,6 @@ msgstr "Žádný takový soubor / adresář" msgid "No timer available" msgstr "Není k dispozici žádný časovač" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1536,10 +1597,6 @@ msgstr "Nepřipojený" msgid "Not playing" msgstr "Nehraje" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1555,16 +1612,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "" #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Pouze IPv4 adresy podporovány" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "Pouze IPv4 sokety podporovány" @@ -1594,10 +1661,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1620,19 +1692,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1687,7 +1764,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "" @@ -1753,6 +1829,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1792,8 +1872,9 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "" @@ -1801,12 +1882,12 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +msgid "Received response was invalid" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c -msgid "Received response was invalid" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" #: shared-bindings/displayio/EPaperDisplay.c @@ -1821,7 +1902,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1893,7 +1974,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1905,6 +1987,7 @@ msgid "Slices not supported" msgstr "" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1928,12 +2011,8 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "" - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c @@ -1949,15 +2028,11 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1965,10 +2040,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1987,6 +2059,10 @@ msgstr "" msgid "The sample's signedness does not match the mixer's" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2019,10 +2095,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2067,6 +2139,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2075,6 +2151,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2110,6 +2190,15 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2128,14 +2217,29 @@ msgstr "" msgid "Unable to init parser" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "" @@ -2198,7 +2302,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2243,7 +2353,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2269,10 +2379,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -2287,6 +2393,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2296,17 +2414,56 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2325,11 +2482,7 @@ msgstr "" msgid "a bytes-like object is required" msgstr "" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "" @@ -2382,8 +2535,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "" @@ -2476,10 +2633,6 @@ msgstr "" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2521,15 +2674,10 @@ msgstr "" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2607,10 +2755,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "" @@ -2709,18 +2861,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "" @@ -2803,10 +2947,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "" @@ -2827,12 +2967,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "" @@ -2864,10 +3003,6 @@ msgstr "" msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2877,18 +3012,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -2987,10 +3120,6 @@ msgstr "" msgid "format requires a dict" msgstr "" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "" @@ -3103,14 +3232,14 @@ msgstr "" msgid "index is out of bounds" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" msgstr "" #: extmod/ulab/code/ndarray.c @@ -3206,10 +3335,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3228,6 +3353,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3254,10 +3383,18 @@ msgstr "" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "" + #: py/compile.c msgid "invalid micropython decorator" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "" @@ -3279,10 +3416,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3339,19 +3472,17 @@ msgstr "" msgid "local variable referenced before assignment" msgstr "" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3480,6 +3611,10 @@ msgstr "" msgid "negative shift count" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3513,14 +3648,10 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3645,15 +3776,30 @@ msgid "offset out of bounds" msgstr "" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" @@ -3724,10 +3870,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "" @@ -3777,28 +3919,6 @@ msgstr "" msgid "pow() with 3 arguments requires integers" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3819,11 +3939,6 @@ msgstr "" msgid "relative import" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3854,12 +3969,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3893,10 +4002,6 @@ msgstr "" msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3909,10 +4014,6 @@ msgstr "" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3961,14 +4062,6 @@ msgstr "" msgid "start/end indices" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "" @@ -3977,10 +4070,6 @@ msgstr "" msgid "stream operation not supported" msgstr "" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" @@ -4013,14 +4102,6 @@ msgstr "" msgid "syntax error in uctypes descriptor" msgstr "" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4028,10 +4109,6 @@ msgstr "" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4085,10 +4162,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4099,8 +4172,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" @@ -4113,14 +4184,10 @@ msgstr "" msgid "type is not an acceptable base type" msgstr "" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "" @@ -4141,7 +4208,7 @@ msgstr "" msgid "unexpected keyword argument" msgstr "" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "" @@ -4171,7 +4238,8 @@ msgid "unknown type '%q'" msgstr "" #: py/objstr.c -msgid "unmatched '{' in format" +#, c-format +msgid "unmatched '%c' in format" msgstr "" #: py/objtype.c py/runtime.c @@ -4179,7 +4247,6 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" @@ -4243,18 +4310,19 @@ msgstr "" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" @@ -4309,18 +4377,10 @@ msgstr "" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "" -#: py/objrange.c -msgid "zero step" -msgstr "" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "" @@ -4333,6 +4393,86 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "%q pin invalid" +#~ msgstr "pin %q není platný" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Prosím vytvořte tiket s obsahem vaší jednotky CIRCUITPY na adrese\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "Pokus o alokaci haldy, když neběží VM." + +#~ msgid "Boot device must be first device (interface #0)." +#~ msgstr "Bootovací zařízení musí být první (rozhraní #0)." + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPython nedokázal alokovat haldu." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Pád do HardFault_Handler." + +#~ msgid "Fatal error." +#~ msgstr "Fatální chyba." + +#~ msgid "Invalid memory access." +#~ msgstr "Neplatný přístup k paměti." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q musí být typu %q" + +#~ msgid "%q must be of type %q or None" +#~ msgstr "%q musí být typu %q nebo None" + +#~ msgid "Expected a %q" +#~ msgstr "Očekává se %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV musí být dlouhé %d bajtů" + +#~ msgid "%q length must be >= 1" +#~ msgstr "%q délka musí být >= 1" + +#~ msgid "%q must be a string" +#~ msgstr "%q musí být string" + +#~ msgid "%q must be an int" +#~ msgstr "%q musí být int" + +#~ msgid "%q with a report ID of 0 must be of length 1" +#~ msgstr "%q s ID 0 musím být délky 1" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Lze zadat maximálně %d %q (nikoli %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Neplatné piny" + +#, c-format +#~ msgid "No more than %d HID devices allowed" +#~ msgstr "Ne více než %d HID zařízení je povoleno" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "Indexy %q musí být celá čísla, nikoli %s" + +#~ msgid "Firmware image is invalid" +#~ msgstr "Obraz firmwaru je nevalidní" + +#~ msgid "%q must be >= 0" +#~ msgstr "%q musí být >= 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q musí být > = 1" + +#~ msgid "Failed to init wifi" +#~ msgstr "Chyba inicializace WiFi" + #~ msgid "%q must be a tuple of length 2" #~ msgstr "%q musí být n-tice délky 2" diff --git a/locale/de_DE.po b/locale/de_DE.po index 8f46245988..fd309dd287 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -6,14 +6,14 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2022-05-20 19:25+0000\n" -"Last-Translator: Fabian Affolter \n" +"PO-Revision-Date: 2023-03-01 17:39+0000\n" +"Last-Translator: Ettore Atalan \n" "Language: de_DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.13-dev\n" +"X-Generator: Weblate 4.16\n" #: main.c msgid "" @@ -31,15 +31,38 @@ msgstr "" "\n" "Code wurde durch automatisches Neuladen gestoppt. Wird bald neu geladen.\n" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" +"\n" +"Ungültige CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\n" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" "\n" -"Bitte melden Sie ein Problem mit dem Inhalt Ihres CIRCUITPY-Laufwerks unter\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Sie befinden sich im abgesicherten Modus, weil:\n" #: py/obj.c msgid " File \"%q\"" @@ -66,6 +89,16 @@ msgstr " Ausgabe:\n" msgid "%%c requires int or char" msgstr "%%c erwartet Int oder Char" +#: main.c +#, c-format +msgid "%02X" +msgstr "%02X" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -74,15 +107,18 @@ msgstr "" "%d Adress-Pins, %d RGB-Pins und %d Kacheln indizieren eine Höhe von %d, " "nicht %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" -msgstr "" +msgstr "%q" #: shared-bindings/microcontroller/Pin.c msgid "%q and %q contain duplicate pins" @@ -90,7 +126,7 @@ msgstr "%q und %q enthalten doppelte Pins" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "%q and %q must be different" -msgstr "" +msgstr "%q und %q müssen unterschiedlich sein" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -100,25 +136,36 @@ msgstr "%q enthält doppelte Pins" msgid "%q failure: %d" msgstr "%q Fehler: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q in %q muss von Typ %q sein, nicht %q" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q in Benutzung" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "Der Index %q befindet sich außerhalb des Bereiches" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q Indizes müssen Integer sein, nicht %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" -msgstr "" +msgstr "%q Initialisierung ist gescheitert" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q ist %q" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q ist für diese Platine schreibgeschützt" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" -msgstr "" +msgstr "%q länge muss %d betragen" #: py/argcheck.c msgid "%q length must be %d-%d" @@ -126,19 +173,15 @@ msgstr "%q Länge muss %d-%d sein" #: py/argcheck.c msgid "%q length must be <= %d" -msgstr "" +msgstr "%q länge muss kleiner oder gleich %d sein" #: py/argcheck.c msgid "%q length must be >= %d" -msgstr "" - -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "%q Länge muss >= 1 sein" +msgstr "%q länge muss größer oder gleich %d sein" #: py/argcheck.c msgid "%q must be %d" -msgstr "" +msgstr "%q muss %d entsprechen" #: py/argcheck.c msgid "%q must be %d-%d" @@ -156,29 +199,27 @@ msgstr "%q muss <= %d sein" msgid "%q must be >= %d" msgstr "%q muss >= %d sein" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q muss >= 0 sein" - -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q muss >= 1 sein" - -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q muss ein String sein" - -#: py/argcheck.c -msgid "%q must be an int" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "%q muss vom Type %q sein" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q muss vom Type %q oder None sein" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "" +"%q muss ein Byte-Array oder ein array vom Typ 'h', 'H', 'b', oder 'B' sein" + +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q muss von Typ %q oder %q sein, nicht %q" + +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" +msgstr "%q muss von Typ %q sein, nicht %q" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" @@ -197,13 +238,9 @@ msgstr "%q außerhalb der Grenzen" msgid "%q out of range" msgstr "%q außerhalb des Bereichs" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "%q Pin ungültig" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" -msgstr "%q mit Berichts-ID von 0 muss von Länge 1 sein" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "Schritt %q kann nicht Null sein" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -214,11 +251,11 @@ msgstr "" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q und %q müssen alle die gleiche Länge haben" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s Fehler 0x%x" @@ -403,12 +440,16 @@ msgstr "ADC2 wird vom WiFi benutzt" msgid "Address must be %d bytes long" msgstr "Die Adresse muss %d Bytes lang sein" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "Adressbereich nicht erlaubt" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "Alle CAN-Schnittstellen sind in Benutzung" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Alle I2C-Peripheriegeräte sind in Benutzung" @@ -430,7 +471,6 @@ msgid "All SPI peripherals are in use" msgstr "Alle SPI-Peripheriegeräte sind in Benutzung" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Alle UART-Peripheriegeräte sind in Benutzung" @@ -483,15 +523,22 @@ msgstr "Bereits am Anbieten (advertising)." msgid "Already have all-matches listener" msgstr "All-Matchers-Listener bereits vorhanden" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Läuft bereits" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Sucht bereits nach Wifi-Netzwerken" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "Ein anderer PWMAudioOut ist bereits aktiv" @@ -505,23 +552,16 @@ msgstr "Ein anderer Sendevorgang ist schon aktiv" msgid "Array must contain halfwords (type 'H')" msgstr "Array muss Halbwörter enthalten (type 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Array-Werte sollten aus Einzelbytes bestehen." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "Es darf höchstens %d %q spezifiziert werden (nicht %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Versuche %d Blöcke zu allokieren" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "Versuchte Heap-Zuordnung wenn VM nicht läuft." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "Audio-Konvertierung nicht implementiert" @@ -543,8 +583,8 @@ msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -"Automatisches Neuladen ist aktiv. Speichere Dateien über USB um sie " -"auszuführen oder verbinde dich mit der REPL zum Deaktivieren.\n" +"Automatisches Neuladen ist aktiviert. Speichere Dateien einfach über USB, um " +"sie auszuführen, oder gib REPL ein, um sie zu deaktivieren.\n" #: ports/espressif/common-hal/canio/CAN.c msgid "Baudrate not supported by peripheral" @@ -572,8 +612,8 @@ msgid "Bitmap size and bits per value must match" msgstr "Bitmap-Grösse und Bits pro Wert müssen übereinstimmen" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "Boot-Gerät muss erstes Gerät sein (interface #0)." +msgid "Boot device must be first (interface #0)." +msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" @@ -656,7 +696,7 @@ msgstr "CBC-Blöcke müssen ein Vielfaches von 16 Bytes sein" msgid "CIRCUITPY drive could not be found or created." msgstr "CIRCUITPY-Laufwerk konnte nicht gefunden oder erzeugt werden." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "CRC oder Checksumme ungültig" @@ -666,7 +706,7 @@ msgstr "Rufe super().__init__() vor dem Zugriff auf ein natives Objekt auf." #: ports/cxd56/common-hal/camera/Camera.c msgid "Camera init" -msgstr "" +msgstr "Kamera Initialiserung" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on RTC IO from deep sleep." @@ -734,7 +774,7 @@ msgstr "'/' kann nicht wiedereingehängt werden, wenn per USB sichtbar." #: ports/cxd56/common-hal/microcontroller/__init__.c #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c msgid "Cannot reset into bootloader because no bootloader is present" -msgstr "" +msgstr "Kann nicht in den Bootloader resetten, weil keiner vorhanden ist" #: ports/espressif/common-hal/socketpool/Socket.c msgid "Cannot set socket options" @@ -755,7 +795,7 @@ msgstr "Slice kann keine sub-klasse sein" #: shared-module/bitbangio/SPI.c msgid "Cannot transfer without MOSI and MISO pins" -msgstr "" +msgstr "Kann nicht ohne MISO und MOSI Pins transferieren" #: shared-bindings/pwmio/PWMOut.c msgid "Cannot vary frequency on a timer that is already in use" @@ -763,8 +803,9 @@ msgstr "" "Die Frequenz eines bereits verwendeten Timers kann nicht variiert werden" #: ports/nrf/common-hal/alarm/pin/PinAlarm.c +#, fuzzy msgid "Cannot wake on pin edge, only level" -msgstr "" +msgstr "Kann nicht durch \"Pin edge\" geweckt werden nur durch \"level\"" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." @@ -778,10 +819,6 @@ msgstr "Schreiben von CharacteristicBuffer ist nicht vorgesehen" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "Der CircuitPython-Kerncode ist hart abgestürzt. Hoppla!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPython war es nicht möglich heap-Speicher zu allozieren." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Clock stretch zu lang" @@ -795,8 +832,16 @@ msgid "" "Connection has been disconnected and can no longer be used. Create a new " "connection." msgstr "" -"Die Verbindung wurde getrennt und kann nicht mehr verwendet werden. " -"Erstellen Sie eine neue Verbindung." +"Die Verbindung wurde getrennt und kann nicht mehr verwendet werden. Erstelle " +"eine neue Verbindung." + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" #: py/persistentcode.c msgid "Corrupt .mpy file" @@ -822,17 +867,13 @@ msgstr "Interrupt konnte nicht gestartet werden, RX beschäftigt" msgid "Couldn't allocate decoder" msgstr "Decoder konnte nicht zugeordnet werden" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Absturz in den HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "DAC-Kanal-Initialisierungsfehler" #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Device Init Error" -msgstr "DAC Device Initialisierungs-Fehler" +msgstr "DAC-Gerät-Initialisierungsfehler" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "DAC already in use" @@ -880,10 +921,20 @@ msgstr "Display muss einen 16 Bit Farbraum haben." msgid "Display rotation must be in 90 degree increments" msgstr "Die Rotation der Anzeige muss in 90-Grad-Schritten erfolgen" +#: main.c +msgid "Done" +msgstr "Fertig" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "Drive mode wird nicht verwendet, wenn die Richtung input ist." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" +"Während der Behandlung der oben genannten Ausnahme trat eine weitere " +"Ausnahme auf:" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "Die EZB arbeitet jeweils nur mit 16 Bytes" @@ -909,20 +960,17 @@ msgstr "Fehler in MIDI Datenstrom um Position %d" msgid "Error in regex" msgstr "Fehler in regex" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "Error: Bind Fehler" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Erwartet ein(e) %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" -msgstr "Alarm erwartet" +msgid "Expected a kind of %q" +msgstr "Erwartete eine Art von %q" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -953,7 +1001,7 @@ msgstr "Mutex konnte nicht akquiriert werden. Status: 0x%04x" #: shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" -msgstr "" +msgstr "Allokieren des %q Buffers ist fehlgeschlagen" #: ports/espressif/common-hal/wifi/__init__.c msgid "Failed to allocate Wifi memory" @@ -976,10 +1024,6 @@ msgstr "Verbindung fehlgeschlagen: interner Fehler" msgid "Failed to connect: timeout" msgstr "Verbindung nicht erfolgreich: timeout" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "Wifi Initialisierung ist fehlgeschlagen" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "MP3-Datei konnte nicht analysiert werden" @@ -994,13 +1038,17 @@ msgid "Failed to write internal flash." msgstr "Interner Flash konnte nicht geschrieben werden." #: supervisor/shared/safe_mode.c -msgid "Fatal error." -msgstr "Fataler Fehler." +msgid "Fault detected by hardware." +msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "Datei existiert" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "Datei nicht gefunden" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1008,8 +1056,16 @@ msgid "Filters too complex" msgstr "Filter zu komplex" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "Firmware Image ist ungültig" +msgid "Firmware is duplicate" +msgstr "Die Firmware ist doppelt vorhanden" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "Die Firmware ist ungültig" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "Die Firmware ist zu groß" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" @@ -1043,15 +1099,17 @@ msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde" #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" -msgstr "" +msgstr "GNSS-Initialisierung" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "Generischer Fehler" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Gruppe schon benutzt" @@ -1066,21 +1124,31 @@ msgstr "Hald-Duplex SPI is tnicht implementiert" #: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/canio/CAN.c #: ports/stm/common-hal/sdioio/SDCard.c msgid "Hardware busy, try alternative pins" -msgstr "Hardware beschäftigt, versuchen Sie alternative Pins" +msgstr "Hardware beschäftigt, versuche alternative Pins" #: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "Hardware in use, try alternative pins" msgstr "Hardware in Benutzung, probiere alternative Pins" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "Lese/Schreibe-operation an geschlossener Datei" #: ports/stm/common-hal/busio/I2C.c msgid "I2C init error" -msgstr "" +msgstr "I2C-Initialisierungsfehler" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "I2C Peripherie in Verwendung" @@ -1088,11 +1156,6 @@ msgstr "I2C Peripherie in Verwendung" msgid "I2SOut not available" msgstr "I2SOut nicht verfügbar" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV muss %d Bytes lang sein" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "In-Puffer-Elemente müssen <= 4 Bytes lang sein" @@ -1102,8 +1165,8 @@ msgid "" "Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" "mpy-update for more info." msgstr "" -"Inkompatible mpy-Datei. Bitte aktualisieren Sie alle mpy-Dateien. Siehe " -"http://adafru.it/mpy-update für weitere Informationen." +"Inkompatible .mpy-Datei. Bitte aktualisiere alle .mpy-Dateien. Siehe http://" +"adafru.it/mpy-update für weitere Informationen." #: shared-bindings/_pew/PewPew.c msgid "Incorrect buffer size" @@ -1183,6 +1246,7 @@ msgid "Internal define error" msgstr "Interner Definitionsfehler" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "Interner Fehler" @@ -1193,12 +1257,18 @@ msgstr "Interner Fehler #%d" #: supervisor/shared/safe_mode.c msgid "Internal watchdog timer expired." +msgstr "Der Interne WatchDog Timer ist abgelaufen." + +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." msgstr "" -#: py/argcheck.c +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "Ungültiger %q" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Ungültiger %q Pin" @@ -1220,7 +1290,7 @@ msgstr "Ungültige BSSID" msgid "Invalid MAC address" msgstr "Ungültige MAC-Adresse" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Ungültiges Argument" @@ -1229,6 +1299,11 @@ msgstr "Ungültiges Argument" msgid "Invalid bits per value" msgstr "Ungültige Bits pro Wert" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "Ungültiges Byte %.*s" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1238,34 +1313,35 @@ msgstr "Ungültige data_pins[%d]" msgid "Invalid format chunk size" msgstr "Ungültige format chunk size" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Ungültiger Speicherzugriff." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Ungültige Multicast-MAC-Adresse" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Ungültige Pins" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "Ungültige Größe" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "Ungültiges Socket für TLS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "Ungültiger Zustand" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "Der Schlüssel muss 16, 24 oder 32 Byte lang sein" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "Schlüssel nicht gefunden" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "LED-Zuordnungen müssen der Display-Größe entsprechen" @@ -1276,13 +1352,13 @@ msgstr "LHS des Schlüsselwortarguments muss eine id sein" #: shared-module/displayio/Group.c msgid "Layer already in a group" -msgstr "" +msgstr "Ebene ist bereits in der Gruppe" #: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass" -msgstr "" +msgstr "Ebene muss eine Gruppe oder eine TileGrid Subklasse sein" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "MAC Adresse war ungültig" @@ -1315,7 +1391,7 @@ msgstr "Fehlender MISO- oder MOSI-Pin" #: ports/stm/common-hal/busio/SPI.c msgid "Missing MISO or MOSI pin" -msgstr "" +msgstr "MISO oder MOSI Pin fehlt" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format @@ -1373,6 +1449,10 @@ msgstr "NLR-Sprung fehlgeschlagen. Mögliche Speicher-Beschädigung." msgid "NVS Error" msgstr "NVS-Fehler" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "Name oder Dienst nicht bekannt" + #: py/qstr.c msgid "Name too long" msgstr "Name zu lang" @@ -1413,7 +1493,7 @@ msgstr "Kein I2C-Gerät an Adresse: 0x%x" #: supervisor/shared/web_workflow/web_workflow.c msgid "No IP" -msgstr "" +msgstr "Keine IP" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c @@ -1422,7 +1502,7 @@ msgstr "Kein MISO-Pin" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MISO pin" -msgstr "" +msgstr "Miso Pin fehlt" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c @@ -1431,7 +1511,7 @@ msgstr "Kein MOSI-Pin" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MOSI pin" -msgstr "" +msgstr "MOSI Pin fehlt" #: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c @@ -1487,11 +1567,6 @@ msgstr "Es wurde kein Schlüssel angegeben" msgid "No long integer support" msgstr "Keine langen Integer (long) unterstützt" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "Keine weiteren %d HID-Geräte zulässig" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "Kein Netzwerk mit dieser SSID" @@ -1527,10 +1602,6 @@ msgstr "Keine solche Datei/Verzeichnis" msgid "No timer available" msgstr "Kein Timer verfügbar" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "Nordic System-Firmware Fehler Assertion." - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "Nordic System-Firmware kein Speicher verfügbar" @@ -1550,10 +1621,6 @@ msgstr "Nicht verbunden" msgid "Not playing" msgstr "Spielt nicht ab" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "Kann nicht gesetzt werden" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1570,16 +1637,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "Eine ungerade Parität wird nicht unterstützt" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "Aus" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "Ok" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Nur 8 oder 16 bit mono mit " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Nur IPv4-Adressen werden unterstützt" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "Nur IPv4-Sockets werden unterstützt" @@ -1613,10 +1690,15 @@ msgstr "" "unterstützt: %d bpp wurden gegeben" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." -msgstr "Nur ein TouchAlarm kann in Deep Sleep gesetzt werden." +msgid "Only one %q can be set in deep sleep." +msgstr "Nur ein %q kann im Deep-Sleep gesetzt werden." -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "Es kann nur ein %q festgelegt werden." + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "Nur eine Adresse ist erlaubt" @@ -1624,7 +1706,7 @@ msgstr "Nur eine Adresse ist erlaubt" #: ports/nrf/common-hal/alarm/time/TimeAlarm.c #: ports/stm/common-hal/alarm/time/TimeAlarm.c msgid "Only one alarm.time alarm can be set" -msgstr "" +msgstr "Nur ein alarm.time Alarm kann gesetzt werden" #: ports/espressif/common-hal/alarm/time/TimeAlarm.c #: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c @@ -1639,19 +1721,24 @@ msgstr "Nur eine Farbe kann transparent sein zu einer Zeit" msgid "Operation not permitted" msgstr "Operation nicht erlaubt" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "Vorgang oder Funktion wird nicht unterstützt" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "Zeit für Vorgang abgelaufen" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "Kein Speicher mehr verfügbar" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Keine Sockets mehr verfügbar" @@ -1674,7 +1761,7 @@ msgstr "Die PWM-Frequenz ist nicht schreibbar, wenn variable_Frequenz = False." #: ports/stm/common-hal/pwmio/PWMOut.c msgid "PWM restart" -msgstr "" +msgstr "PWM Neustart" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "PWM slice already in use" @@ -1706,7 +1793,6 @@ msgid "Pin interrupt already in use" msgstr "Pin-Interrupt wird bereits verwendet" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "Pin kann nur als Eingang verwendet werden" @@ -1726,8 +1812,8 @@ msgid "" "constructor" msgstr "" "Pinbelegung verwendet %d Bytes pro Element, was mehr als die idealen %d " -"Bytes verbraucht. Wenn dies nicht vermieden werden kann, übergeben Sie " -"allow_inefficient = True an den Konstruktor" +"Bytes verbraucht. Wenn dies nicht vermieden werden kann, übergib " +"allow_inefficient=True an den Konstruktor" #: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c msgid "Pins must be sequential" @@ -1776,6 +1862,10 @@ msgstr "Programm macht OUT ohne Laden von OSR" msgid "Program size invalid" msgstr "Programm-Größe ist ungültig" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "Programm zu lang" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull wird nicht verwendet, wenn die Richtung output ist." @@ -1800,7 +1890,7 @@ msgstr "RNG Init-Fehler" #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nrf/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" -msgstr "" +msgstr "RS485" #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1815,8 +1905,9 @@ msgstr "Eine RTC wird auf diesem Board nicht unterstützt" msgid "Random number generation error" msgstr "Fehler bei der Erzeugung von Zufallszahlen" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Nur lesen möglich, da Schreibgeschützt" @@ -1824,14 +1915,14 @@ msgstr "Nur lesen möglich, da Schreibgeschützt" msgid "Read-only filesystem" msgstr "Schreibgeschützte Dateisystem" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "Schreibgeschützte Objekt" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "Erhaltene Antwort ist ungültig" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "Wiederherstellung der Verbindungen" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "Zu früh neu geladen" @@ -1844,7 +1935,7 @@ msgstr "RemoteTransmissionRequests limitiert auf 8 Bytes" msgid "Requested AES mode is unsupported" msgstr "Der angeforderte AES-Modus wird nicht unterstützt" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "Angefragte Ressource nicht gefunden" @@ -1862,7 +1953,7 @@ msgstr "SD-Card CSD-Format nicht unterstützt" #: ports/cxd56/common-hal/sdioio/SDCard.c msgid "SDCard init" -msgstr "" +msgstr "SDCard-Initialisierung" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format @@ -1880,7 +1971,7 @@ msgstr "SPI-Konfiguration fehlgeschlagen" #: ports/stm/common-hal/busio/SPI.c msgid "SPI init error" -msgstr "" +msgstr "SPI-Initialisierungsfehler" #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" @@ -1888,7 +1979,7 @@ msgstr "SPI-Peripheriegeräte wird bereits verwendet" #: ports/stm/common-hal/busio/SPI.c msgid "SPI re-init" -msgstr "" +msgstr "SPI wird erneut initialisiert" #: shared-bindings/is31fl3741/FrameBuffer.c msgid "Scale dimensions must divide by 3" @@ -1897,7 +1988,7 @@ msgstr "Maßstabs-Abmeßungen müssen durch 3 teilbar sein" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c msgid "Scan already in progess. Stop with stop_scan." -msgstr "Scannen Sie bereits in Bearbeitung. Stoppen Sie mit stop_scan." +msgstr "Scannen bereits in Bearbeitung. Stoppe mit stop_scan." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -1916,7 +2007,8 @@ msgstr "Größe nicht unterstützt" msgid "Sleep Memory not available" msgstr "Sleep-Speicher nicht verfügbar" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice und Wert (value) haben unterschiedliche Längen." @@ -1928,6 +2020,7 @@ msgid "Slices not supported" msgstr "Slices werden nicht unterstützt" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool kann nur mit wifi.radio verwendet werden" @@ -1937,7 +2030,7 @@ msgstr "Quell- und Zielbuffer müssen gleich lang sein" #: shared-bindings/paralleldisplay/ParallelBus.c msgid "Specify exactly one of data0 or data_pins" -msgstr "Geben Sie genau einen von data0 oder data_pins an" +msgstr "Gib genau einen von data0 oder data_pins an" #: extmod/modure.c msgid "Splitting with sub-captures" @@ -1951,17 +2044,13 @@ msgstr "Stereo links muss sich auf PWM-Kanal A befinden" msgid "Stereo right must be on PWM channel B" msgstr "Stereo rechts muss sich auf PWM-Kanal B befinden" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Stream fehlt readinto() oder write() Methode." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Geben Sie mindestens einen UART-Pin an" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" -msgstr "Geben Sie entweder monotonic_time oder epoch_time an" +msgstr "Gib entweder monotonic_time oder epoch_time an" #: shared-bindings/gnss/GNSS.c msgid "System entry must be gnss.SatelliteSystem" @@ -1972,35 +2061,21 @@ msgid "Temperature read timed out" msgstr "Zeitüberschreitung beim Auslesen der Temperatur" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -"Der Heap von CircuitPython wurde beschädigt, weil der Stack zu klein war.\n" -"Vergrößern Sie den Stack, wenn Sie wissen, wie. Wenn nicht:" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" -"Das Modul `microcontroller` wurde zum Booten in den abgesicherten Modus " -"verwendet. Drücken Sie Reset, um den abgesicherten Modus zu verlassen." +"Die oben genannte Ausnahme war die direkte Ursache für die folgende Ausnahme:" #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "Die Länge von rgb_pins muss 6, 12, 18, 24 oder 30 betragen" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" -"Der Mikrocontroller hatte einen Stromausfall. Vergewissern Sie sich, dass " -"die\n" -"Stromversorgung genügend Strom für die gesamte Schaltung liefert und drücken " -"Sie Reset (nach dem Auswerfen von CIRCUITPY)." #: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" @@ -2020,6 +2095,10 @@ msgid "The sample's signedness does not match the mixer's" msgstr "" "Die Art des Vorzeichens des Samples stimmt nicht mit dem des Mixers überein" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "Dieser Mikrocontroller unterstützt keine kontinuierliche Erfassung." @@ -2055,13 +2134,9 @@ msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" "Zeitbeschränkung ist zu groß: Maximale Zeitbeschränkung ist %d Sekunden" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "Zum beenden, resette bitte das board ohne " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" -msgstr "" +msgstr "Zu viele Kanäle im Beispiel" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." @@ -2096,20 +2171,28 @@ msgstr "Tuple- oder struct_time-Argument erforderlich" #: ports/stm/common-hal/busio/UART.c msgid "UART de-init" -msgstr "" +msgstr "UART wird de-initialisiert" #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "UART init" +msgstr "UART-Initialisierung" + +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" msgstr "" #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" -msgstr "" +msgstr "UART wird erneut Initialisiert" #: ports/stm/common-hal/busio/UART.c msgid "UART write" -msgstr "" +msgstr "UART wird geschrieben" + +#: main.c +msgid "UID:" +msgstr "UID:" #: shared-module/usb_hid/Device.c msgid "USB busy" @@ -2146,6 +2229,15 @@ msgstr "Der UUID-Wert ist kein str-, int- oder Byte-Puffer" msgid "Unable to allocate buffers for signed conversion" msgstr "Konnte keine Buffer für Vorzeichenumwandlung allozieren" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "Lock kann nicht erzeugt werden" @@ -2164,14 +2256,29 @@ msgstr "Konnte keinen freien GCLK finden" msgid "Unable to init parser" msgstr "Parser konnte nicht gestartet werden" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "Konnte Farbpalettendaten nicht lesen" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "mDNS-Abfrage kann nicht gestartet werden" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "An die Adresse kann nicht geschrieben werden." + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Schreiben in nvm nicht möglich." @@ -2234,7 +2341,13 @@ msgstr "Unbekannter Systemfirmware Fehler: %04x" msgid "Unknown system firmware error: %d" msgstr "Unbekannter System-Firmware-Fehler: %d" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "Unbekannter Fehlercode %d" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2263,7 +2376,7 @@ msgstr "Nicht unterstütztes Format" #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" -msgstr "" +msgstr "Hash Algorithmus wird nicht unterstützt" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Update Failed" @@ -2283,7 +2396,7 @@ msgstr "Wert Länge != Erforderliche feste Länge" msgid "Value length > max_length" msgstr "Länge des Wertes > max_length" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "Version ist ungültig" @@ -2314,10 +2427,6 @@ msgstr "" "WatchDogTimer.mode kann nicht geändert werden, nachdem er auf WatchDogMode." "RESET gesetzt wurde" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "WatchDogTimer.timeout muss größer als 0 sein" - #: py/builtinhelp.c #, c-format msgid "" @@ -2335,8 +2444,20 @@ msgstr "" #: supervisor/shared/web_workflow/web_workflow.c msgid "Wi-Fi: " +msgstr "Wi-Fi: " + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "WLAN ist nicht aktiviert" + #: main.c msgid "Woken up by alarm.\n" msgstr "Aufgeweckt durch Alarm.\n" @@ -2346,20 +2467,57 @@ msgstr "Aufgeweckt durch Alarm.\n" msgid "Writes not supported on Characteristic" msgstr "Schreiben nicht unterstüzt für diese Charakteristik" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" -msgstr "Du bist im abgesicherten Modus weil:\n" - -#: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" -"Du hast beim Booten die Reset-Taste gedrückt. Drücke sie erneut, um den " -"abgesicherten Modus zu beenden." #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "Du hast das Starten im abgesicherten Modus ausgelöst durch " +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "" #: py/objtype.c msgid "__init__() should return None" @@ -2377,11 +2535,7 @@ msgstr "__new__ arg muss user-type sein" msgid "a bytes-like object is required" msgstr "ein Byte-ähnliches Objekt ist erforderlich" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "Adresse außerhalb der Grenzen" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "addresses ist leer" @@ -2432,10 +2586,14 @@ msgstr "Array- und Indexlänge müssen gleich sein" #: extmod/ulab/code/numpy/io/io.c msgid "array has too many dimensions" +msgstr "Das Array hat zu viele Dimensionen" + +#: extmod/ulab/code/ndarray.c +msgid "array is too big" msgstr "" #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "Array/Bytes auf der rechten Seite erforderlich" @@ -2445,7 +2603,7 @@ msgstr "Versuch (arg)min/(arg)max einer leeren Sequenz zu holen" #: extmod/ulab/code/numpy/numerical.c msgid "attempt to get argmin/argmax of an empty sequence" -msgstr "Sie haben versucht argmin/argmax einer leeren Sequenz zu erhalten" +msgstr "Versuch, argmin/argmax einer leeren Sequenz zu ermitteln" #: py/objstr.c msgid "attributes not supported yet" @@ -2528,10 +2686,6 @@ msgstr "Der Puffer ist zu klein" msgid "buffer too small for requested bytes" msgstr "Der Puffer ist zu klein für die angefragten Bytes" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "Byteorder ist kein String" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "Byte-Länge ist kein vielfaches der Item-Größe" @@ -2551,7 +2705,7 @@ msgstr "Kalibrierung ist Schreibgeschützt" #: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c #: shared-module/vectorio/Rectangle.c msgid "can only have one parent" -msgstr "" +msgstr "kann nur ein Elternteil haben" #: py/emitinlinethumb.c msgid "can only have up to 4 parameters to Thumb assembly" @@ -2575,15 +2729,10 @@ msgstr "kann keinem Ausdruck zuweisen" msgid "can't cancel self" msgstr "kann self nicht abbrechen" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "kann %q nicht zu %q konvertieren" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "kann %q nicht nach int konvertieren" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2663,10 +2812,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "Kann Blockgröße von 512 nicht setzen" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "kann Attribut nicht setzen" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "Speichern von '%q' nicht möglich" @@ -2731,7 +2884,7 @@ msgstr "Umwandlung (cast)" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "channel re-init" -msgstr "" +msgstr "Kanal wird erneut initialisiert" #: shared-bindings/_stage/Text.c msgid "chars buffer too small" @@ -2771,18 +2924,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "Farbe muss zwischen 0x000000 und 0xffffff liegen" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "Farbe sollte ein int sein" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "Vergleich von int und uint" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "Komplexe Division durch null" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "Komplexe Zahlen nicht unterstützt" @@ -2813,7 +2958,7 @@ msgstr "Convolve Argumente dürfen nicht leer sein" #: extmod/ulab/code/numpy/io/io.c msgid "corrupted file" -msgstr "" +msgstr "Korrupte Datei" #: extmod/ulab/code/numpy/poly.c msgid "could not invert Vandermonde matrix" @@ -2867,10 +3012,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "Der Zielpuffer muss ein Array vom Typ 'H' für bit_depth = 16 sein" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "destination_length muss ein int >= 0 sein" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "Die Wörterbuch-Aktualisierungssequenz hat eine falsche Länge" @@ -2891,12 +3032,11 @@ msgstr "Abmessungen stimmen nicht überein" msgid "div/mod not implemented for uint" msgstr "div/mod für uint nicht implementiert" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "durch Null dividieren" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "Division durch Null" @@ -2910,7 +3050,7 @@ msgstr "leer" #: extmod/ulab/code/numpy/io/io.c msgid "empty file" -msgstr "" +msgstr "Leere Datei" #: extmod/moduasyncio.c extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" @@ -2928,10 +3068,6 @@ msgstr "leere Sequenz" msgid "end of format while looking for conversion specifier" msgstr "Ende des Formats wärend der Suche nach einem conversion specifier" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "end_x sollte ein int sein" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "epoch_time wird auf diesem Board nicht unterstützt" @@ -2941,18 +3077,16 @@ msgstr "epoch_time wird auf diesem Board nicht unterstützt" msgid "error = 0x%08lX" msgstr "Fehler = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "Exceptions müssen von BaseException abgeleitet sein" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "erwartet '%q' aber bekommen '%q'" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "erwartete '%q' oder '%q', aber bekam '%q'" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "erwarte ':' nach format specifier" @@ -3051,10 +3185,6 @@ msgstr "Die Schriftart (font) muss 2048 Byte lang sein" msgid "format requires a dict" msgstr "Format erfordert ein Wörterbuch (dict)" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "Frequenz ist für dieses Board schreibgeschützt" - #: py/objdeque.c msgid "full" msgstr "voll" @@ -3169,23 +3299,23 @@ msgstr "padding ist inkorrekt" msgid "index is out of bounds" msgstr "Index ist außerhalb der Grenzen" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "index außerhalb der Reichweite" -#: py/obj.c -msgid "indices must be integers" -msgstr "Indizes müssen Integer sein" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "Indizes müssen Integer, Slices oder Boolesche Listen sein" #: ports/espressif/common-hal/busio/I2C.c msgid "init I2C" -msgstr "" +msgstr "initialisiere I2C" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" @@ -3234,7 +3364,7 @@ msgstr "Eingabematrix ist singulär" #: extmod/ulab/code/numpy/create.c msgid "input must be 1- or 2-d" -msgstr "" +msgstr "Eingabe muss 1- oder 2-d sein" #: extmod/ulab/code/numpy/carray/carray.c msgid "input must be a 1D ndarray" @@ -3272,10 +3402,6 @@ msgstr "Eingabevektoren müssen gleich lang sein" msgid "inputs are not iterable" msgstr "Eingaben sind nicht iterierbar" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "int() arg 2 muss >= 2 und <= 36 sein" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "interp ist für 1D-Iterables gleicher Länge definiert" @@ -3294,6 +3420,10 @@ msgstr "ungültige Architektur" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "ungültige Bits_pro_Pixel %d, muss 1, 2, 4, 8, 16, 24 oder 32 sein" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "ungültiges cert" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3320,10 +3450,18 @@ msgstr "ungültiger Formatbezeichner" msgid "invalid hostname" msgstr "ungültiger Hostname" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "ungültiger Schlüssel" + #: py/compile.c msgid "invalid micropython decorator" msgstr "ungültiger micropython decorator" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "Invalide Einstellung" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "ungültiger Schritt (step)" @@ -3345,10 +3483,6 @@ msgstr "ungültige Syntax für integer mit Basis %d" msgid "invalid syntax for number" msgstr "ungültige Syntax für number" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "ungültiger Traceback" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 muss eine Klasse sein" @@ -3370,8 +3504,8 @@ msgstr "" #: py/argcheck.c msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" -"Schlüsselwort-Argument(e) noch nicht implementiert - verwenden Sie " -"stattdessen normale Argumente" +"Schlüsselwort-Argument(e) noch nicht implementiert - verwende stattdessen " +"normale Argumente" #: py/bc.c msgid "keywords must be strings" @@ -3411,19 +3545,17 @@ msgstr "" "Es wurde versucht auf eine Variable zuzugreifen, die es (noch) nicht gibt. " "Variablen immer zuerst Zuweisen" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "long int wird in diesem Build nicht unterstützt" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "Loopback + Silent Mode wird vom Peripheriegerät nicht unterstützt" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "mDNS bereits initialisiert" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "mDNS funktioniert nur mit integriertem WiFi" @@ -3452,7 +3584,7 @@ msgstr "max_length muss 0-%d sein, wenn fixed_length %s ist" #: extmod/ulab/code/ndarray.c msgid "maximum number of dimensions is " -msgstr "" +msgstr "Maximale Anzahl an Dimensionen ist " #: py/runtime.c msgid "maximum recursion depth exceeded" @@ -3552,6 +3684,10 @@ msgstr "negative Potenz ohne Gleitkomma (float) Unterstützung" msgid "negative shift count" msgstr "Negative shift Anzahl" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "keine SD-Karte" @@ -3585,14 +3721,10 @@ msgstr "kein Reset Pin verfügbar" msgid "no response from SD card" msgstr "keine Antwort von der SD-Karte" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "kein solches Attribut" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "Nicht-Gerät in %q" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3699,7 +3831,7 @@ msgstr "String mit ungerader Länge" #: supervisor/shared/web_workflow/web_workflow.c msgid "off" -msgstr "" +msgstr "aus" #: extmod/ulab/code/utils/utils.c msgid "offset is too large" @@ -3719,15 +3851,30 @@ msgid "offset out of bounds" msgstr "offset außerhalb der Grenzen" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "nur eine bit_depth=16 wird unterstützt" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "nur Mono wird unterstützt" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "nur eine sample_rate=16000 wird unterstützt" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" "Es werden nur Slices mit Schritt = 1 (auch bekannt als None) unterstützt" @@ -3801,10 +3948,6 @@ msgstr "pack erwartete %d Artikel zum Packen (erhalten %d)" msgid "palette must be 32 bytes long" msgstr "Die Palette muss 32 Byte lang sein" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_index sollte ein int sein" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "Die Parameter müssen Register der Reihenfolge a2 bis a5 sein" @@ -3854,28 +3997,6 @@ msgstr "pow() drittes Argument darf nicht 0 sein" msgid "pow() with 3 arguments requires integers" msgstr "pow() mit 3 Argumenten erfordert Integer" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "Drücken der Boot-Taste beim Start.\n" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "Drücken Sie beim Start beide Tasten.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "Drücken der linken Taste beim Einschalten\n" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "Pull-Masken kollidieren mit Richtungsmasken" @@ -3896,11 +4017,6 @@ msgstr "Real- und Imaginärteile müssen gleich lang sein" msgid "relative import" msgstr "relativer Import" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "die ersuchte Länge ist %d, aber das Objekt hat eine Länge von %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "Ergebnisse können nicht in den angegebenen Typ umgewandelt werden" @@ -3931,14 +4047,6 @@ msgstr "Roll-Argument muss ein ndarray sein" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"sample_source buffer muss ein Bytearray oder ein Array vom Typ 'h', 'H', 'b' " -"oder 'B' sein" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3972,10 +4080,6 @@ msgstr "Vorzeichen nicht erlaubt in einem String formatierungs specifier" msgid "sign not allowed with integer format specifier 'c'" msgstr "Vorzeichen mit ganzzahligem Formatbezeichner 'c' nicht erlaubt" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "einzelne '}' in Formatierungs-String gefunden" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "Größe ist nur für ndarrays definiert" @@ -3988,10 +4092,6 @@ msgstr "Die Schlafdauer darf nicht negativ sein" msgid "slice step can't be zero" msgstr "Slice-Schritt darf nicht Null sein" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "Der Slice-Schritt kann nicht Null sein" - #: py/nativeglue.c msgid "slice unsupported" msgstr "Slice nicht unterstützt" @@ -4040,14 +4140,6 @@ msgstr "source_bitmap muss value_count von 8 haben" msgid "start/end indices" msgstr "start/end Indizes" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "start_x sollte ein int sein" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "Schritt (step) darf nicht Null sein" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "stop ist von start aus nicht erreichbar" @@ -4056,14 +4148,9 @@ msgstr "stop ist von start aus nicht erreichbar" msgid "stream operation not supported" msgstr "stream operation ist nicht unterstützt" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "String Indizes müssen Integer sein, nicht %q" - #: py/stream.c msgid "string not supported; use bytes or bytearray" -msgstr "" -"Zeichenfolgen werden nicht unterstützt; Verwenden Sie bytes oder bytearray" +msgstr "Zeichenfolgen werden nicht unterstützt; verwende bytes oder bytearray" #: extmod/moductypes.c msgid "struct: can't index" @@ -4093,14 +4180,6 @@ msgstr "Syntaxfehler in JSON" msgid "syntax error in uctypes descriptor" msgstr "Syntaxfehler in uctypes Deskriptor" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "threshold muss im Intervall 0-65536 liegen" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time() nimmt eine 9-Sequenz an" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4108,10 +4187,6 @@ msgstr "time.struct_time() nimmt eine 9-Sequenz an" msgid "timeout duration exceeded the maximum supported value" msgstr "Das Zeitlimit hat den maximal zulässigen Wert überschritten" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "Das Zeitlimit muss 0,0-100,0 Sekunden betragen" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "timeout muss kleiner als 655.35 Sekunden sein" @@ -4126,7 +4201,7 @@ msgstr "Zeitlimit beim warten auf v2 Karte" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "timer re-init" -msgstr "" +msgstr "Timer wird erneut initialisiert" #: shared-bindings/time/__init__.c msgid "timestamp out of range for platform time_t" @@ -4165,10 +4240,6 @@ msgstr "trapz ist für 1D-Arrays gleicher Länge definiert" msgid "trapz is defined for 1D iterables" msgstr "trapz ist für 1D-Iterables definiert" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "tupel/list hat falsche Länge" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4179,8 +4250,6 @@ msgstr "twai_driver_install gab esp-idf-Fehler zurück #%d" msgid "twai_start returned esp-idf error #%d" msgstr "twai_start gab esp-idf-Fehler zurück #%d" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx und rx können nicht beide None sein" @@ -4193,14 +4262,10 @@ msgstr "Typ '%q' ist kein akzeptierter Basis-Typ" msgid "type is not an acceptable base type" msgstr "Typ ist kein akzeptierter Basis-Typ" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "Typ vom Objekt '%q' hat kein Attribut '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "Das Typ-Objekt 'generator' hat kein Attribut '__await__'" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "Typ akzeptiert 1 oder 3 Argumente" @@ -4223,7 +4288,7 @@ msgstr "" msgid "unexpected keyword argument" msgstr "unerwartetes Schlüsselwort-Argument" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "unerwartetes Schlüsselwort-Argument '%q'" @@ -4253,15 +4318,15 @@ msgid "unknown type '%q'" msgstr "unbekannter Typ '%q'" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "'{' ohne passende Zuordnung im Format" +#, c-format +msgid "unmatched '%c' in format" +msgstr "" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "nicht lesbares Attribut" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "Nicht unterstützter %q-Typ" @@ -4302,11 +4367,11 @@ msgstr "nicht unterstützte Typen für %q: '%q', '%q'" #: extmod/ulab/code/numpy/io/io.c msgid "usecols is too high" -msgstr "" +msgstr "usecols ist zu hoch/groß" #: extmod/ulab/code/numpy/io/io.c msgid "usecols keyword must be specified" -msgstr "" +msgstr "usecols muss definiert sein" #: py/objint.c #, c-format @@ -4325,18 +4390,19 @@ msgstr "value_count muss größer als 0 sein" msgid "watchdog not initialized" msgstr "watchdog nicht initialisiert" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "watchdog Zeitlimit muss größer als 0 sein" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "Breite muss größer als 0 sein" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "wifi ist nicht aktiviert" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "wifi.Monitor nicht verfügbar" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "Fenster muss <= Intervall sein" @@ -4351,7 +4417,7 @@ msgstr "falsche Achse gewählt" #: extmod/ulab/code/numpy/io/io.c msgid "wrong dtype" -msgstr "" +msgstr "Falsches dtype" #: extmod/ulab/code/numpy/transform.c msgid "wrong index type" @@ -4369,7 +4435,7 @@ msgstr "falsche Länge des Array von Bedingungen" #: extmod/ulab/code/numpy/transform.c msgid "wrong length of index array" -msgstr "" +msgstr "Falsche Länge des Index Arrays" #: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c msgid "wrong number of arguments" @@ -4391,18 +4457,10 @@ msgstr "x Wert außerhalb der Grenzen" msgid "xTaskCreate failed" msgstr "xTaskCreate fehlgeschlagen" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y sollte ein int sein" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "y Wert außerhalb der Grenzen" -#: py/objrange.c -msgid "zero step" -msgstr "Nullschritt" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "zi muss ein ndarray sein" @@ -4415,6 +4473,313 @@ msgstr "zi muss eine Gleitkommazahl sein" msgid "zi must be of shape (n_section, 2)" msgstr "zi muss die Form (n_section, 2) haben" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Gib mindestens einen UART-Pin an" + +#~ msgid "%q pin invalid" +#~ msgstr "%q Pin ungültig" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Bitte melde ein Problem mit dem Inhalt Ihres CIRCUITPY-Laufwerks unter\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "Versuchte Heap-Zuordnung wenn VM nicht läuft." + +#~ msgid "Boot device must be first device (interface #0)." +#~ msgstr "Boot-Gerät muss erstes Gerät sein (interface #0)." + +#~ msgid "Both buttons were pressed at start up.\n" +#~ msgstr "Beim Starten wurden beide Tasten gedrückt.\n" + +#~ msgid "Button A was pressed at start up.\n" +#~ msgstr "Beim Starten wurde Taste A gedrückt.\n" + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPython war es nicht möglich heap-Speicher zu allozieren." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Absturz in den HardFault_Handler." + +#~ msgid "Fatal error." +#~ msgstr "Fataler Fehler." + +#~ msgid "Invalid memory access." +#~ msgstr "Ungültiger Speicherzugriff." + +#~ msgid "Nordic system firmware failure assertion." +#~ msgstr "Nordic System-Firmware Fehler Assertion." + +#~ msgid "The BOOT button was pressed at start up.\n" +#~ msgstr "Beim Starten wurde die Taste BOOT gedrückt.\n" + +#~ msgid "" +#~ "The CircuitPython heap was corrupted because the stack was too small.\n" +#~ "Increase the stack size if you know how. If not:" +#~ msgstr "" +#~ "Der Heap von CircuitPython wurde beschädigt, weil der Stack zu klein " +#~ "war.\n" +#~ "Vergrößere den Stack, wenn du weißt, wie. Wenn nicht:" + +#~ msgid "The SW38 button was pressed at start up.\n" +#~ msgstr "Beim Starten wurde die Taste SW38 gedrückt.\n" + +#~ msgid "The VOLUME button was pressed at start up.\n" +#~ msgstr "Beim Starten wurde die Taste VOLUME gedrückt.\n" + +#~ msgid "" +#~ "The `microcontroller` module was used to boot into safe mode. Press reset " +#~ "to exit safe mode." +#~ msgstr "" +#~ "Das Modul `microcontroller` wurde zum Booten in den abgesicherten Modus " +#~ "verwendet. Drücke Reset, um den abgesicherten Modus zu verlassen." + +#~ msgid "The central button was pressed at start up.\n" +#~ msgstr "Beim Starten wurde die zentrale Taste gedrückt.\n" + +#~ msgid "The left button was pressed at start up.\n" +#~ msgstr "Beim Starten wurde die linke Taste gedrückt.\n" + +#~ msgid "" +#~ "The microcontroller's power dipped. Make sure your power supply provides\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY)." +#~ msgstr "" +#~ "Der Mikrocontroller hatte einen Stromausfall. Vergewisser dich, dass die\n" +#~ "Stromversorgung genügend Strom für die gesamte Schaltung liefert und\n" +#~ "drücke Reset (nach dem Auswerfen von CIRCUITPY)." + +#~ msgid "To exit, please reset the board without requesting safe mode." +#~ msgstr "" +#~ "Zum Beenden setze bitte das Board zurück, ohne den abgesicherten Modus " +#~ "aufzurufen." + +#~ msgid "You are in safe mode because:\n" +#~ msgstr "Du befindest dich im abgesicherten Modus, weil:\n" + +#~ msgid "" +#~ "You pressed the reset button during boot. Press again to exit safe mode." +#~ msgstr "" +#~ "Du hast beim Booten die Reset-Taste gedrückt. Drücke sie erneut, um den " +#~ "abgesicherten Modus zu beenden." + +#~ msgid "" +#~ "esp32_camera.Camera requires reserved PSRAM to be configured. See the " +#~ "documentation for instructions." +#~ msgstr "" +#~ "esp32_camera.Camera benötigt reservierten PSRAM um konfiguriert werden zu " +#~ "können. Sieh in der Dokumentation für eine Anleitung nach." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q muss vom Type %q sein" + +#~ msgid "%q must be of type %q or None" +#~ msgstr "%q muss vom Type %q oder None sein" + +#~ msgid "Expected a %q" +#~ msgstr "Erwartet ein(e) %q" + +#~ msgid "Expected a %q or %q" +#~ msgstr "Erwartete ein %q oder %q" + +#~ msgid "Expected an %q" +#~ msgstr "Erwartet ein %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV muss %d Bytes lang sein" + +#~ msgid "Not settable" +#~ msgstr "Kann nicht gesetzt werden" + +#~ msgid "expected '%q' but got '%q'" +#~ msgstr "erwartet '%q' aber bekommen '%q'" + +#~ msgid "expected '%q' or '%q' but got '%q'" +#~ msgstr "erwartete '%q' oder '%q', aber bekam '%q'" + +#~ msgid "Read-only object" +#~ msgstr "Schreibgeschützte Objekt" + +#~ msgid "frequency is read-only for this board" +#~ msgstr "Frequenz ist für dieses Board schreibgeschützt" + +#~ msgid "Unable to write" +#~ msgstr "Schreiben nicht möglich" + +#~ msgid "%q length must be >= 1" +#~ msgstr "%q Länge muss >= 1 sein" + +#~ msgid "%q must be a string" +#~ msgstr "%q muss ein String sein" + +#~ msgid "%q must be an int" +#~ msgstr "%q muss vom Typ Integer sein" + +#~ msgid "%q with a report ID of 0 must be of length 1" +#~ msgstr "%q mit Berichts-ID von 0 muss von Länge 1 sein" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Es darf höchstens %d %q spezifiziert werden (nicht %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Ungültige Pins" + +#, c-format +#~ msgid "No more than %d HID devices allowed" +#~ msgstr "Keine weiteren %d HID-Geräte zulässig" + +#~ msgid "byteorder is not a string" +#~ msgstr "Byteorder ist kein String" + +#~ msgid "can't convert %q to int" +#~ msgstr "kann %q nicht nach int konvertieren" + +#~ msgid "complex division by zero" +#~ msgstr "Komplexe Division durch null" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "int() arg 2 muss >= 2 und <= 36 sein" + +#~ msgid "long int not supported in this build" +#~ msgstr "long int wird in diesem Build nicht unterstützt" + +#~ msgid "slice step cannot be zero" +#~ msgstr "Der Slice-Schritt kann nicht Null sein" + +#~ msgid "step must be non-zero" +#~ msgstr "Schritt (step) darf nicht Null sein" + +#~ msgid "string indices must be integers, not %q" +#~ msgstr "String Indizes müssen Integer sein, nicht %q" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time() nimmt eine 9-Sequenz an" + +#~ msgid "zero step" +#~ msgstr "Nullschritt" + +#~ msgid "invalid traceback" +#~ msgstr "ungültiger Traceback" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "%q Indizes müssen Integer sein, nicht %s" + +#~ msgid "WatchDogTimer.timeout must be greater than 0" +#~ msgstr "WatchDogTimer.timeout muss größer als 0 sein" + +#~ msgid "indices must be integers" +#~ msgstr "Indizes müssen Integer sein" + +#~ msgid "non-Device in %q" +#~ msgstr "Nicht-Gerät in %q" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "die ersuchte Länge ist %d, aber das Objekt hat eine Länge von %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "einzelne '}' in Formatierungs-String gefunden" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "threshold muss im Intervall 0-65536 liegen" + +#~ msgid "timeout must be 0.0-100.0 seconds" +#~ msgstr "Das Zeitlimit muss 0,0-100,0 Sekunden betragen" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "tupel/list hat falsche Länge" + +#~ msgid "unmatched '{' in format" +#~ msgstr "'{' ohne passende Zuordnung im Format" + +#~ msgid "watchdog timeout must be greater than 0" +#~ msgstr "watchdog Zeitlimit muss größer als 0 sein" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "Zum beenden, resette bitte das board ohne " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "Du hast das Starten im abgesicherten Modus ausgelöst durch " + +#~ msgid "pressing BOOT button at start up.\n" +#~ msgstr "BOOT Taste wird beim Starten gedrückt.\n" + +#~ msgid "pressing SW38 button at start up.\n" +#~ msgstr "SW38 Taste wird beim Starten gedrückt.\n" + +#~ msgid "pressing VOLUME button at start up.\n" +#~ msgstr "VOLUME Taste wird beim Starten gedrückt.\n" + +#~ msgid "pressing boot button at start up.\n" +#~ msgstr "Drücken der Boot-Taste beim Start.\n" + +#~ msgid "pressing both buttons at start up.\n" +#~ msgstr "Drücken Sie beim Start beide Tasten.\n" + +#~ msgid "pressing the left button at start up\n" +#~ msgstr "Drücken der linken Taste beim Einschalten\n" + +#~ msgid "Only one TouchAlarm can be set in deep sleep." +#~ msgstr "Nur ein TouchAlarm kann in Deep Sleep gesetzt werden." + +#~ msgid "Firmware image is invalid" +#~ msgstr "Firmware Image ist ungültig" + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Stream fehlt readinto() oder write() Methode." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q muss >= 0 sein" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q muss >= 1 sein" + +#~ msgid "address out of bounds" +#~ msgstr "Adresse außerhalb der Grenzen" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "destination_length muss ein int >= 0 sein" + +#~ msgid "type object 'generator' has no attribute '__await__'" +#~ msgstr "Das Typ-Objekt 'generator' hat kein Attribut '__await__'" + +#~ msgid "color should be an int" +#~ msgstr "Farbe sollte ein int sein" + +#~ msgid "end_x should be an int" +#~ msgstr "end_x sollte ein int sein" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_index sollte ein int sein" + +#~ msgid "start_x should be an int" +#~ msgstr "start_x sollte ein int sein" + +#~ msgid "y should be an int" +#~ msgstr "y sollte ein int sein" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "sample_source buffer muss ein Byte-Array oder ein Array vom Typ 'h', 'H', " +#~ "'b' oder 'B' sein" + +#~ msgid "Expected an alarm" +#~ msgstr "Alarm erwartet" + +#~ msgid "All I2C targets are in use" +#~ msgstr "Alle I2C-Ziele sind in Verwendung" + +#~ msgid "Failed to init wifi" +#~ msgstr "Wifi Initialisierung ist fehlgeschlagen" + #~ msgid "input must be a tensor of rank 2" #~ msgstr "Eingabe muss ein Tensor von Rang 2 sein" @@ -5024,12 +5389,6 @@ msgstr "zi muss die Form (n_section, 2) haben" #~ msgid "can only save bytecode" #~ msgstr "kann nur Bytecode speichern" -#~ msgid "invalid cert" -#~ msgstr "ungültiges cert" - -#~ msgid "invalid key" -#~ msgstr "ungültiger Schlüssel" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Viper-Funktionen unterstützen derzeit nicht mehr als 4 Argumente" diff --git a/locale/el.po b/locale/el.po index e7abd4d7ff..b36d0a39b6 100644 --- a/locale/el.po +++ b/locale/el.po @@ -8,56 +8,93 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2022-10-05 12:23+0000\n" +"Last-Translator: Bill Sideris \n" "Language-Team: none\n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.14.1\n" #: main.c msgid "" "\n" "Code done running.\n" msgstr "" +"\n" +"Η εκτέλεση του κώδικα ολοκληρώθηκε.\n" #: main.c msgid "" "\n" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +"\n" +"Ο κώδικας σταμάτησε λόγω της αυτόματης επαναφόρτωσης. Η επαναφόρτωση θα " +"γίνει σύντομα.\n" + +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" #: py/obj.c msgid " File \"%q\"" -msgstr "" +msgstr " Αρχείο \"%q\"" #: py/obj.c msgid " File \"%q\", line %d" -msgstr "" +msgstr " Αρχείο \"%q\", γραμμή %d" #: py/builtinhelp.c msgid " is of type %q\n" -msgstr "" +msgstr " είναι τύπου %q\n" #: main.c msgid " not found.\n" -msgstr "" +msgstr " δεν βρέθηκε.\n" #: main.c msgid " output:\n" -msgstr "" +msgstr " έξοδος:\n" #: py/objstr.c #, c-format msgid "%%c requires int or char" +msgstr "%%c απαιτεί int ή char" + +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -65,120 +102,128 @@ msgstr "" msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +"%d pin διεύθυνσης, %d rgb ping και %d πλακίδια αναδεικνύουν ύψος %d, όχι %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" -msgstr "" +msgstr "%q" #: shared-bindings/microcontroller/Pin.c msgid "%q and %q contain duplicate pins" -msgstr "" +msgstr "%q και %q περιέχουν διπλότυπα pins" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "%q and %q must be different" -msgstr "" +msgstr "%q και %q πρεπει να είναι διαφορετικά" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" -msgstr "" +msgstr "%q περιέχει διπλότυπα pins" #: ports/atmel-samd/common-hal/sdioio/SDCard.c msgid "%q failure: %d" +msgstr "%q αποτυχία: %d" + +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" -msgstr "" +msgstr "%q είναι σε χρήση" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" -msgstr "" - -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "" +msgstr "%q δείκτης εκτός εμβέλειας" #: shared-module/bitbangio/SPI.c msgid "%q init failed" +msgstr "%q εκκίνηση απέτυχε" + +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" msgstr "" -#: py/argcheck.c -msgid "%q length must be %d" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" msgstr "" +#: py/argcheck.c shared-bindings/usb_hid/Device.c +msgid "%q length must be %d" +msgstr "%q μήκος πρέπει να είναι %d" + #: py/argcheck.c msgid "%q length must be %d-%d" -msgstr "" +msgstr "%q μήκος πρέπει να είναι %d-%d" #: py/argcheck.c msgid "%q length must be <= %d" -msgstr "" +msgstr "%q μήκος πρέπει να είναι <= %d" #: py/argcheck.c msgid "%q length must be >= %d" -msgstr "" - -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "" +msgstr "%q μήκος πρέπει να είναι >= %d" #: py/argcheck.c msgid "%q must be %d" -msgstr "" +msgstr "%q πρέπει να είναι %d" #: py/argcheck.c msgid "%q must be %d-%d" -msgstr "" +msgstr "%q πρέπει να είναι %d-%d" #: shared-bindings/displayio/Display.c msgid "%q must be 1 when %q is True" -msgstr "" +msgstr "%q πρέπει να είναι 1 όταν %q είναι True" #: py/argcheck.c shared-bindings/gifio/GifWriter.c msgid "%q must be <= %d" -msgstr "" +msgstr "%q πρέπει να είναι <= %d" #: py/argcheck.c msgid "%q must be >= %d" +msgstr "%q πρέπει να είναι >= %d" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/argcheck.c -msgid "%q must be >= 0" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q πρέπει να είναι bytearray ή array τύπου 'h', 'H', 'b', ή 'B'" + +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" msgstr "" -#: py/argcheck.c -msgid "%q must be a string" -msgstr "" - -#: py/argcheck.c -msgid "%q must be an int" -msgstr "" - -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "" - -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" -msgstr "" +msgstr "%q πρέπει να είναι δύναμη του 2" #: shared-bindings/wifi/Monitor.c msgid "%q out of bounds" -msgstr "" +msgstr "%q εκτός ορίων" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c @@ -187,266 +232,266 @@ msgstr "" #: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c #: shared-bindings/canio/Match.c msgid "%q out of range" -msgstr "" +msgstr "%q εκτός εμβέλειας" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" -msgstr "" +msgstr "%q() παίρνει %d ορίσματα θέσεως αλλά %d δόθηκαν" #: shared-bindings/usb_hid/Device.c msgid "%q, %q, and %q must all be the same length" -msgstr "" +msgstr "%q, %q, και %q πρέπει να είναι όλα του ιδίου μήκους" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" -msgstr "" +msgstr "%s σφάλμα 0x%x" #: py/argcheck.c msgid "'%q' argument required" -msgstr "" +msgstr "'%q' όρισμα απαιτείται" #: py/proto.c msgid "'%q' object does not support '%q'" -msgstr "" +msgstr "'%q' αντικείμενο δεν υποστηρίζει '%q'" #: py/runtime.c msgid "'%q' object is not an iterator" -msgstr "" +msgstr "'%q' αντικείμενο δεν είναι επαναλήπτης" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c msgid "'%q' object is not callable" -msgstr "" +msgstr "'%q' αντικείμενο δεν καλείται" #: py/runtime.c msgid "'%q' object is not iterable" -msgstr "" +msgstr "'%q' αντικείμενο δεν είναι επαναληπτικό" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format msgid "'%s' expects a label" -msgstr "" +msgstr "'%s' περιμένει μια ετικέτα" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format msgid "'%s' expects a register" -msgstr "" +msgstr "'%s' περιμένει έναν καταχωρητή" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects a special register" -msgstr "" +msgstr "'%s' περιμένει έναν ειδικό καταχωρητή" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects an FPU register" -msgstr "" +msgstr "'%s' περιμένει έναν FPU καταχωρητή" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects an address of the form [a, b]" -msgstr "" +msgstr "'%s' περιμένει μια διεύθυνση της μορφής [a, b]" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format msgid "'%s' expects an integer" -msgstr "" +msgstr "'%s' περιμένει έναν ακέραιο" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects at most r%d" -msgstr "" +msgstr "'%s' περιμένει το πολύ r%d" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects {r0, r1, ...}" -msgstr "" +msgstr "'%s' περιμένει {r0, r1, ...}" #: py/emitinlinextensa.c #, c-format msgid "'%s' integer %d isn't within range %d..%d" -msgstr "" +msgstr "'%s' ακέραιος %d δεν είναι μέσα στο επιτρεπτό εύρος %d..%d" #: py/emitinlinethumb.c #, c-format msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" -msgstr "" +msgstr "'%s' ακέραιος 0x%x δεν χωράει στην μάσκα 0x%x" #: py/obj.c #, c-format msgid "'%s' object doesn't support item assignment" -msgstr "" +msgstr "'%s' αντικείμενο δεν υποστηρίζει ορισμό πράγματος" #: py/obj.c #, c-format msgid "'%s' object doesn't support item deletion" -msgstr "" +msgstr "'%s' αντικείμενο δεν υποστηρίζει διαγραφή πράγματος" #: py/runtime.c msgid "'%s' object has no attribute '%q'" -msgstr "" +msgstr "'%s' αντικείμενο δεν έχει γνώρισμα '%q'" #: py/obj.c #, c-format msgid "'%s' object isn't subscriptable" -msgstr "" +msgstr "'%s' αντικείμενο δεν είναι subscriptable" #: py/objstr.c msgid "'=' alignment not allowed in string format specifier" -msgstr "" +msgstr "Ευθυγράμμιση του '=' δεν επιτρέπεται εντός προσδιοριστή string format" #: shared-module/struct/__init__.c msgid "'S' and 'O' are not supported format types" -msgstr "" +msgstr "'S' και 'O' δεν είναι υποστηριζόμενοι τύποι format" #: py/compile.c msgid "'align' requires 1 argument" -msgstr "" +msgstr "'align' απαιτεί τουλάχιστον ένα όρισμα" #: py/compile.c msgid "'await' outside function" -msgstr "" +msgstr "'await' εκτός συνάρτησης" #: py/compile.c msgid "'await', 'async for' or 'async with' outside async function" -msgstr "" +msgstr "'await', 'async for' ή 'async with' εκτός ασύνχρονης συνάρτησης" #: py/compile.c msgid "'break' outside loop" -msgstr "" +msgstr "'break' εκτός επανάληψης" #: py/compile.c msgid "'continue' outside loop" -msgstr "" +msgstr "'continue' εκτός επανάληψης" #: py/objgenerator.c msgid "'coroutine' object is not an iterator" -msgstr "" +msgstr "'coroutine' αντικείμενο δεν μπορεί να χρησιμοποιηθεί σαν επαναλήπτης" #: py/compile.c msgid "'data' requires at least 2 arguments" -msgstr "" +msgstr "'data' απαιτεί τουλάχιστον 2 παραμέτρους" #: py/compile.c msgid "'data' requires integer arguments" -msgstr "" +msgstr "'data' απαιτεί ακέραιες παραμέτρους" #: py/compile.c msgid "'label' requires 1 argument" -msgstr "" +msgstr "'label' απαιτεί ένα όρισμα" #: py/compile.c msgid "'return' outside function" -msgstr "" +msgstr "'return' εκτός συνάρτησης" #: py/compile.c msgid "'yield from' inside async function" -msgstr "" +msgstr "'yield from' εκτός ασύνχρονης συνάρτησης" #: py/compile.c msgid "'yield' outside function" -msgstr "" +msgstr "'yield' εκτός συνάρτησης" #: py/compile.c msgid "*x must be assignment target" -msgstr "" +msgstr "*x πρέπει να είναι στόχος ανάθεσης" #: py/obj.c msgid ", in %q\n" -msgstr "" +msgstr ", στο %q\n" #: py/objcomplex.c msgid "0.0 to a complex power" -msgstr "" +msgstr "0.0 σε μία σύνθετη δύναμη" #: py/modbuiltins.c msgid "3-arg pow() not supported" -msgstr "" +msgstr "pow() με 3 παραμέτρους δεν υποστηρίζεται" #: shared-module/msgpack/__init__.c +#, fuzzy msgid "64 bit types" -msgstr "" +msgstr "64 bit τύποι" #: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c #: ports/atmel-samd/common-hal/countio/Counter.c #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "A hardware interrupt channel is already in use" -msgstr "" +msgstr "Ένα κανάλι interrupt υλικού είναι ήδη σε χρήση" #: ports/espressif/common-hal/analogio/AnalogIn.c msgid "ADC2 is being used by WiFi" -msgstr "" +msgstr "Το ADC2 χρησιμοποιείται απο το WIFI" #: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" +msgstr "Η διεύθυνση πρέπει να είναι %d bytes μεγάλη" + +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" msgstr "" #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" -msgstr "" +msgstr "Όλα τα περιφεριακά CAN είναι σε χρήση" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" -msgstr "" +msgstr "Όλα τα I2C περιφεριακά ειναι σε χρήση" #: ports/espressif/common-hal/countio/Counter.c #: ports/espressif/common-hal/frequencyio/FrequencyIn.c #: ports/espressif/common-hal/rotaryio/IncrementalEncoder.c msgid "All PCNT units in use" -msgstr "" +msgstr "Όλες οι μονάδες PCNT είναι σε χρήση" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "All RX FIFOs in use" -msgstr "" +msgstr "Όλα τα RX FIFOs είναι σε χρήση" #: ports/espressif/common-hal/busio/SPI.c ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" -msgstr "" +msgstr "Όλα τα SPI περιφεριακά είναι σε χρήση" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" -msgstr "" +msgstr "Όλα τα UART περιφεριακά ειναι σε χρήση" #: ports/nrf/common-hal/countio/Counter.c #: ports/nrf/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/rotaryio/IncrementalEncoder.c #: shared-bindings/pwmio/PWMOut.c msgid "All channels in use" -msgstr "" +msgstr "Όλα τα κανάλια είναι σε χρήση" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "All event channels in use" -msgstr "" +msgstr "Όλα τα κανάλια συμβάντων είναι σε χρήση" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "All state machines in use" -msgstr "" +msgstr "Όλες οι μηχανές κατάστασης είναι σε χρήση" #: ports/atmel-samd/audio_dma.c msgid "All sync event channels in use" -msgstr "" +msgstr "Όλα τα κανάλια συμβάντων συγχρονισμού είναι σε χρήση" #: shared-bindings/pwmio/PWMOut.c msgid "All timers for this pin are in use" -msgstr "" +msgstr "Όλοι οι χρονιστές για αυτό το pin χρησιμοποιούνται ήδη" #: ports/atmel-samd/common-hal/_pew/PewPew.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -463,167 +508,169 @@ msgstr "" #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" -msgstr "" +msgstr "Όλοι οι χρονιστές βρίσκονται σε χρήση" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c msgid "Already advertising." -msgstr "" +msgstr "Ήδη διαφημίζουμε." #: ports/atmel-samd/common-hal/canio/Listener.c msgid "Already have all-matches listener" -msgstr "" +msgstr "Ύπάρχει ήδη all-matches ακροατής" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" -msgstr "" +msgstr "Τρέχει ήδη" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" +msgstr "Ήδη γίνεται σάρωση για δίκτυα wifi" + +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" msgstr "" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" -msgstr "" +msgstr "Και άλλο PWMAudioOut είναι σε χρήση" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c msgid "Another send is already active" -msgstr "" +msgstr "Άλλη αποστολή είναι ήδη ενεργή" #: shared-bindings/pulseio/PulseOut.c msgid "Array must contain halfwords (type 'H')" -msgstr "" +msgstr "H παράταξη πρέπει να περιέχει halfwords (τύπου 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." -msgstr "" - -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "" +msgstr "Η τιμές της παράταξη πρέπει να είναι μονά bytes." #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" +msgstr "Προσπάθεια να δεσμευτούν %d blocks" #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" -msgstr "" +msgstr "Η μετατροπή ήχου δεν υποστηρίζεται" #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" -msgstr "" +msgstr "AuthMode.OPEN δεν μπορεί να χρησιμοποιηθεί με κωδικό" #: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c msgid "Authentication failure" -msgstr "" +msgstr "Αποτυχία αυθεντικοποίησης" #: main.c msgid "Auto-reload is off.\n" -msgstr "" +msgstr "Η αυτόματη επαναφόρτωση είναι απενεργοποιημένη.\n" #: main.c msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" +"Η αυτόματη επαναφόρτωση είναι ενεργή. Αποθηκεύστε αρχεία μέσω USB για να " +"τρέξετε ή ανοίξτε το REPL για απενεργοποίηση.\n" #: ports/espressif/common-hal/canio/CAN.c msgid "Baudrate not supported by peripheral" -msgstr "" +msgstr "Baudrate δεν υποστηρίζεται από την περιφεριακή συσκευή" #: shared-module/displayio/Display.c #: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" -msgstr "" +msgstr "Χαμηλότερο από το ελάχιστο frame rate" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Bit clock and word select must be sequential pins" -msgstr "" +msgstr "Ρολόι bit και word select πρέπει να είναι διαδοχικά pins" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Bit clock and word select must share a clock unit" -msgstr "" +msgstr "Ρολόι bit και word select πρέπει να μοιράζονται μια μονάδα ρολογιού" #: shared-bindings/audiobusio/PDMIn.c msgid "Bit depth must be multiple of 8." -msgstr "" +msgstr "Βάθος bit πρέπει να είναι πολλαπλάσιο του 8." #: shared-bindings/bitmaptools/__init__.c msgid "Bitmap size and bits per value must match" -msgstr "" +msgstr "Το μέγεθος του bitmap και τα bits ανα τιμή πρέπει να ταιριάζουν" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" -msgstr "" +msgstr "Και RX και TX απαιτούνται για έλεγχο flow" #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" -msgstr "" +msgstr "Και τα δύο pin πρέπει να υποστηρίζουν interrupts υλικού" #: shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c #: shared-bindings/is31fl3741/FrameBuffer.c #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "Brightness must be 0-1.0" -msgstr "" +msgstr "Η φωτινότητα πρέπει να είναι μεταξύ 0-1.0" #: shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" -msgstr "" +msgstr "H φωτεινότητα δεν μπορεί να προσαρμοστεί" #: shared-bindings/_bleio/UUID.c #, c-format msgid "Buffer + offset too small %d %d %d" -msgstr "" +msgstr "Buffer + offset είναι πολύ μικρά %d %d %d" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Buffer elements must be 4 bytes long or less" -msgstr "" +msgstr "Στοιχεία του buffer πρέπει να είναι το πολύ 4 bytes" #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." -msgstr "" +msgstr "Το buffer δεν είναι ένα bytearray." #: ports/cxd56/common-hal/camera/Camera.c shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" -msgstr "" +msgstr "Πολύ μικρό buffer" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c #, c-format msgid "Buffer length %d too big. It must be less than %d" -msgstr "" +msgstr "Το μήκος buffer %d είναι πολύ μεγάλο. Πρέπει ν α είναι λιγότερο απο %d" #: ports/atmel-samd/common-hal/sdioio/SDCard.c #: ports/cxd56/common-hal/sdioio/SDCard.c shared-module/sdcardio/SDCard.c msgid "Buffer length must be a multiple of 512" -msgstr "" +msgstr "Το μήκος buffer πρέπει να είναι πολλαπλάσιο του 512" #: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c msgid "Buffer must be a multiple of 512 bytes" -msgstr "" +msgstr "Buffer πρέπει να είναι πολλαπλάσιο των 512 bytes" #: shared-bindings/_bleio/PacketBuffer.c #, c-format msgid "Buffer too short by %d bytes" -msgstr "" +msgstr "Buffer πολύ μικρό κατα %d bytes" #: ports/espressif/common-hal/imagecapture/ParallelImageCapture.c msgid "Buffers must be same size" -msgstr "" +msgstr "Τα Buffers πρέπει να είναι του ιδίου μεγέθους" #: ports/atmel-samd/common-hal/paralleldisplay/ParallelBus.c #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c @@ -631,218 +678,228 @@ msgstr "" #: ports/raspberrypi/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Bus pin %d is already in use" -msgstr "" +msgstr "Bus pin %d είναι ήδη σε χρήση" #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." -msgstr "" +msgstr "Byte buffer πρέπει να είναι 16 bytes." #: shared-bindings/aesio/aes.c msgid "CBC blocks must be multiples of 16 bytes" -msgstr "" +msgstr "CBC blocks πρέπει να είναι πολλαπλάσια του 16 bytes" #: supervisor/shared/safe_mode.c msgid "CIRCUITPY drive could not be found or created." -msgstr "" +msgstr "Ο CIRCUITPY δίσκος δεν μπόρεσε να βρεθεί ή να δημιουργηθεί." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" -msgstr "" +msgstr "CRC ή checksum ήταν άκυρο" #: py/objtype.c msgid "Call super().__init__() before accessing native object." -msgstr "" +msgstr "Κλήση super().__init__() πρίν την πρόσβαση του τοπικού αντικειμένου." #: ports/cxd56/common-hal/camera/Camera.c msgid "Camera init" -msgstr "" +msgstr "Εκκίνηση κάμερας" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on RTC IO from deep sleep." -msgstr "" +msgstr "Μόνο IO alarm ή RTC επιτρέπονται από βαθύ ύπνο." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" +"Μόνο ένα alarm από low pin ενώ τα άλλα alarm θα είναι απο high σε βαθύ ύπνο." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on two low pins from deep sleep." -msgstr "" +msgstr "Μπορεί να γίνει alarm μόνο σε δύο low pins σε βαθύ ύπνο." #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nrf/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" -msgstr "" +msgstr "Δεν μπορεί να οριστεί CCCD σε τοπικό Characteristic" #: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c #: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c msgid "Cannot change USB devices now" -msgstr "" +msgstr "Δεν μπορούν να αλλάξουν οι USB συσκευές τώρα" #: shared-bindings/_bleio/Adapter.c msgid "Cannot create a new Adapter; use _bleio.adapter;" msgstr "" +"Δεν μπορεί να δημιουργηθεί νέο Adapter; χρησιμοποιείστε _bleio.adapter;" #: shared-bindings/displayio/Bitmap.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c msgid "Cannot delete values" -msgstr "" +msgstr "Δεν μπορούν να διαγραφούν οι τιμές" #: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c #: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c #: ports/nrf/common-hal/digitalio/DigitalInOut.c #: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c msgid "Cannot get pull while in output mode" -msgstr "" +msgstr "Δεν γίνεται να διαβαστεί το pull όσο είναι σε output mode" #: ports/nrf/common-hal/microcontroller/Processor.c msgid "Cannot get temperature" -msgstr "" +msgstr "Δεν μπορεί να διαβαστεί η θερμοκρασία" #: shared-bindings/_bleio/Adapter.c msgid "Cannot have scan responses for extended, connectable advertisements." msgstr "" +"Δεν μπορούμε να έχουμε απαντήσεις scan για εκτεταμένες, συνδεόμενες " +"διαφημήσεις." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot pull on input-only pin." -msgstr "" +msgstr "Δεν γίνεται pull σε pin μόνο για εισόδο." #: shared-bindings/audiobusio/PDMIn.c msgid "Cannot record to a file" -msgstr "" +msgstr "Δεν μπορεί να γίνει καταγραφή σε αρχείο" #: shared-module/storage/__init__.c msgid "Cannot remount '/' when visible via USB." -msgstr "" +msgstr "Δεν μπορεί να γίνει remount του '/' όταν είναι ορατό μέσω USB." #: ports/atmel-samd/common-hal/microcontroller/__init__.c #: ports/cxd56/common-hal/microcontroller/__init__.c #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c msgid "Cannot reset into bootloader because no bootloader is present" msgstr "" +"Δεν μπορεί να γίνει επανεκκίνηση στον bootloader διότι δεν υπάρχει " +"bootloader παρόν" #: ports/espressif/common-hal/socketpool/Socket.c msgid "Cannot set socket options" -msgstr "" +msgstr "Δεν μπορεί να γίνει ρύθμιση των επιλογών του socket" #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." -msgstr "" +msgstr "Δεν μπορεί να οριστεί τιμή οταν η κατεύθυνση είναι input." #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Cannot specify RTS or CTS in RS485 mode" -msgstr "" +msgstr "Δεν μπορεί να οριστεί RTS ή CTS σε RS485 mode" #: py/objslice.c msgid "Cannot subclass slice" -msgstr "" +msgstr "Δεν γίνεται υποκατηγορία ενός slice" #: shared-module/bitbangio/SPI.c msgid "Cannot transfer without MOSI and MISO pins" -msgstr "" +msgstr "Δεν μπορεί να γίνει μεταφορά χωρίς MOSI και MISO pins" #: shared-bindings/pwmio/PWMOut.c msgid "Cannot vary frequency on a timer that is already in use" msgstr "" +"Δεν μπορεί να γίνει δυναμική μεταβολή της συχνότητας σε έναν χρονιστή που " +"είναι ήδη σε χρήση" #: ports/nrf/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" -msgstr "" +msgstr "Δεν γίνεται αφύπνηση σε pin edge, αλλά μόνο σε level" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." -msgstr "" +msgstr "Δεν μπορεί να γίνει αφύπνηση σε pin edge. Μόνο level." #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" -msgstr "" +msgstr "Δεν υποστηρίζονται εγγραφές στο CharacteristicBuffer" #: supervisor/shared/safe_mode.c msgid "CircuitPython core code crashed hard. Whoops!\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "" +msgstr "Ο πυρήνας της CircuitPython κατέρευσε. Οουπς!\n" #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" -msgstr "" +msgstr "Stretch ρολογιού πολύ μεγάλο" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Clock unit in use" -msgstr "" +msgstr "Μονάδα ρολογιού ήδη σε χρήση" #: shared-bindings/_bleio/Connection.c msgid "" "Connection has been disconnected and can no longer be used. Create a new " "connection." msgstr "" +"Έχει γίνει αποσύνδεση και αυτή η συνδεση δεν μπορεί να χρησιμοποιηθεί. " +"Δημιουργήστε μια νέα σύνδεση." + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" #: py/persistentcode.c msgid "Corrupt .mpy file" -msgstr "" +msgstr "Κατεστραμένο .mpy αρχείο" #: ports/espressif/common-hal/neopixel_write/__init__.c msgid "Could not retrieve clock" -msgstr "" +msgstr "Δεν μπόρεσε να ανακληθεί το ρολόι" #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" -msgstr "" +msgstr "Δεν μπόρεσε να ρυθμιστεί η διεύθυνση" #: shared-bindings/pwmio/PWMOut.c msgid "Could not start PWM" -msgstr "" +msgstr "Δεν μπόρεσε να ξεκινήσει το PWM" #: ports/stm/common-hal/busio/UART.c msgid "Could not start interrupt, RX busy" -msgstr "" +msgstr "Δεν μπόρεσε να εκκινηθεί το interrupt, RX κατειλημμένο" #: shared-module/audiomp3/MP3Decoder.c msgid "Couldn't allocate decoder" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "" +msgstr "Δεν μπόρεσε να δεσμευτεί decoder" #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" -msgstr "" +msgstr "Σφάλμα εκκίνησης καναλιού DAC" #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Device Init Error" -msgstr "" +msgstr "Σφάλμα εκκίνησης συσκευής DAC" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "DAC already in use" -msgstr "" +msgstr "DAC είναι ήδη σε χρήση" #: ports/atmel-samd/common-hal/paralleldisplay/ParallelBus.c #: ports/nrf/common-hal/paralleldisplay/ParallelBus.c msgid "Data 0 pin must be byte aligned" -msgstr "" +msgstr "Το Data 0 pin πρέπει να είναι byte aligned" #: shared-module/audiocore/WaveFile.c msgid "Data chunk must follow fmt chunk" -msgstr "" +msgstr "Το data chunk πρέπει να ακολουθεί το fmt chunk" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c msgid "Data not supported with directed advertising" -msgstr "" +msgstr "Δεν υποστηρίζονται δεδομένα με κατευθυνόμενη διαφήμιση" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c msgid "Data too large for advertisement packet" -msgstr "" +msgstr "Τα δεδομένα είναι πολύ μεγάλα για πακέτο διαφημίσεων" #: ports/stm/common-hal/alarm/pin/PinAlarm.c msgid "Deep sleep pins must use a rising edge with pulldown" -msgstr "" +msgstr "Τα pins βαθύ ύπνου πρέπει να χρησιμοποιούν rising edge με pulldown" #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." @@ -863,10 +920,18 @@ msgstr "" msgid "Display rotation must be in 90 degree increments" msgstr "" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "" @@ -892,19 +957,16 @@ msgstr "" msgid "Error in regex" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -958,10 +1020,6 @@ msgstr "" msgid "Failed to connect: timeout" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "" @@ -976,13 +1034,17 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -990,7 +1052,15 @@ msgid "Filters too complex" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" #: shared-bindings/bitmaptools/__init__.c @@ -1023,13 +1093,15 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -1050,6 +1122,15 @@ msgstr "" msgid "Hardware in use, try alternative pins" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "" @@ -1059,6 +1140,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "" @@ -1066,11 +1148,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1155,6 +1232,7 @@ msgid "Internal define error" msgstr "" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1167,10 +1245,16 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "" @@ -1192,7 +1276,7 @@ msgstr "" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "" @@ -1201,6 +1285,11 @@ msgstr "" msgid "Invalid bits per value" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1210,34 +1299,35 @@ msgstr "" msgid "Invalid format chunk size" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "" - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1254,7 +1344,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -1344,6 +1434,10 @@ msgstr "" msgid "NVS Error" msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "" @@ -1458,11 +1552,6 @@ msgstr "" msgid "No long integer support" msgstr "" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "" @@ -1498,10 +1587,6 @@ msgstr "" msgid "No timer available" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1521,10 +1606,6 @@ msgstr "" msgid "Not playing" msgstr "" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1539,16 +1620,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "" #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "" @@ -1578,10 +1669,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1604,19 +1700,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1671,7 +1772,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "" @@ -1718,10 +1818,12 @@ msgstr "" #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" +"Πατήστε οποιοδήποτε πλήκτρο για να μπείτε στο REPL. Πατήστε CTRL-D για " +"επαναφόρτωση.\n" #: main.c msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" -msgstr "" +msgstr "Προσποίηση βαθύ ύπνου μεχρι γεγονότος, CTRL-C ή εγγραφή αρχείου.\n" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Program does IN without loading ISR" @@ -1735,6 +1837,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1774,8 +1880,9 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "" @@ -1783,12 +1890,12 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +msgid "Received response was invalid" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c -msgid "Received response was invalid" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" #: shared-bindings/displayio/EPaperDisplay.c @@ -1803,7 +1910,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1875,7 +1982,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1887,6 +1995,7 @@ msgid "Slices not supported" msgstr "" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1910,12 +2019,8 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "" - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c @@ -1931,15 +2036,11 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1947,10 +2048,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1969,6 +2067,10 @@ msgstr "" msgid "The sample's signedness does not match the mixer's" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2001,10 +2103,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2049,6 +2147,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2057,6 +2159,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2092,6 +2198,15 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2110,14 +2225,29 @@ msgstr "" msgid "Unable to init parser" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "" @@ -2180,7 +2310,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2225,7 +2361,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2251,10 +2387,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -2269,6 +2401,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2278,17 +2422,56 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2307,11 +2490,7 @@ msgstr "" msgid "a bytes-like object is required" msgstr "" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "" @@ -2364,8 +2543,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "" @@ -2458,10 +2641,6 @@ msgstr "" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2503,15 +2682,10 @@ msgstr "" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2589,10 +2763,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "" @@ -2691,18 +2869,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "" @@ -2785,10 +2955,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "" @@ -2809,12 +2975,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "" @@ -2846,10 +3011,6 @@ msgstr "" msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2859,18 +3020,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -2969,10 +3128,6 @@ msgstr "" msgid "format requires a dict" msgstr "" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "" @@ -3085,14 +3240,14 @@ msgstr "" msgid "index is out of bounds" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" msgstr "" #: extmod/ulab/code/ndarray.c @@ -3188,10 +3343,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3210,6 +3361,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3236,10 +3391,18 @@ msgstr "" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "" + #: py/compile.c msgid "invalid micropython decorator" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "" @@ -3261,10 +3424,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3321,19 +3480,17 @@ msgstr "" msgid "local variable referenced before assignment" msgstr "" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3462,6 +3619,10 @@ msgstr "" msgid "negative shift count" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3495,14 +3656,10 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3627,15 +3784,30 @@ msgid "offset out of bounds" msgstr "" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" @@ -3706,10 +3878,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "" @@ -3759,28 +3927,6 @@ msgstr "" msgid "pow() with 3 arguments requires integers" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3801,11 +3947,6 @@ msgstr "" msgid "relative import" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3836,12 +3977,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3875,10 +4010,6 @@ msgstr "" msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3891,10 +4022,6 @@ msgstr "" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3943,14 +4070,6 @@ msgstr "" msgid "start/end indices" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "" @@ -3959,10 +4078,6 @@ msgstr "" msgid "stream operation not supported" msgstr "" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" @@ -3995,14 +4110,6 @@ msgstr "" msgid "syntax error in uctypes descriptor" msgstr "" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4010,10 +4117,6 @@ msgstr "" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4067,10 +4170,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4081,8 +4180,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" @@ -4095,14 +4192,10 @@ msgstr "" msgid "type is not an acceptable base type" msgstr "" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "" @@ -4123,7 +4216,7 @@ msgstr "" msgid "unexpected keyword argument" msgstr "" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "" @@ -4153,7 +4246,8 @@ msgid "unknown type '%q'" msgstr "" #: py/objstr.c -msgid "unmatched '{' in format" +#, c-format +msgid "unmatched '%c' in format" msgstr "" #: py/objtype.c py/runtime.c @@ -4161,7 +4255,6 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" @@ -4225,18 +4318,19 @@ msgstr "" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" @@ -4291,18 +4385,10 @@ msgstr "" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "" -#: py/objrange.c -msgid "zero step" -msgstr "" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "" @@ -4314,3 +4400,58 @@ msgstr "" #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be of shape (n_section, 2)" msgstr "" + +#~ msgid "%q pin invalid" +#~ msgstr "%q άκυρο pin" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Παρακαλώ δημιουγήστε ενα πρόβλημα με τα περιεχόμενα του CIRCUITPY δίσκου " +#~ "στο\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "Προσπάθεια δέσμευσης heap όταν το VM δεν τρέχει." + +#~ msgid "Boot device must be first device (interface #0)." +#~ msgstr "Η συσκευή boot πρέπει να είναι η πρώτη συσκευή (interface #0)." + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "Η CircuitPython δεν μπορέσε να δεσμεύσει το heap." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Κατέρευσε μέσα στο HardFault_Handler." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q πρέπει να είναι τύπου %q" + +#~ msgid "%q must be of type %q or None" +#~ msgstr "%q πρέπει να είναι τύπου %q ή None" + +#~ msgid "%q length must be >= 1" +#~ msgstr "%q μήκος πρέπει να είναι >= 1" + +#~ msgid "%q must be a string" +#~ msgstr "%q πρέπει να είναι string" + +#~ msgid "%q must be an int" +#~ msgstr "%q πρέπει να είναι int" + +#~ msgid "%q with a report ID of 0 must be of length 1" +#~ msgstr "%q με ID αναφοράς 0 πρέπει να έχει μήκος 1" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Το πολύ %d %q μπορεί να είναι καθορισμένα (όχι %d)" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "%q δείκτες πρέπει να είναι ακέραιοι, όχι %s" + +#~ msgid "%q must be >= 0" +#~ msgstr "%q πρέπει να είναι >= 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q πρέπει να είναι >= 1" diff --git a/locale/en_GB.po b/locale/en_GB.po index f3b8bedb75..b1c1c46b50 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -34,15 +34,32 @@ msgstr "" "\n" "Code stopped by auto-reload. Reloading soon.\n" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -69,6 +86,16 @@ msgstr " output:\n" msgid "%%c requires int or char" msgstr "%%c requires int or char" +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -76,13 +103,16 @@ msgid "" msgstr "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -102,23 +132,34 @@ msgstr "%q contains duplicate pins" msgid "%q failure: %d" msgstr "%q failure: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q in use" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "%q index out of range" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q indices must be integers, not %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "" @@ -134,10 +175,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "%q length must be >= 1" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -158,28 +195,25 @@ msgstr "" msgid "%q must be >= %d" msgstr "%q must be >= %d" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q must be >= 0" - -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q must be >= 1" - -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q must be a string" - -#: py/argcheck.c -msgid "%q must be an int" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "" + +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -199,12 +233,8 @@ msgstr "" msgid "%q out of range" msgstr "%q out of range" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "%q pin invalid" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c @@ -215,11 +245,11 @@ msgstr "%q() takes %d positional arguments but %d were given" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, and %q must all be the same length" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s error 0x%x" @@ -404,12 +434,16 @@ msgstr "ADC2 is being used by WiFi" msgid "Address must be %d bytes long" msgstr "Address must be %d bytes long" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "All CAN peripherals are in use" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "All I2C peripherals are in use" @@ -431,7 +465,6 @@ msgid "All SPI peripherals are in use" msgstr "All SPI peripherals are in use" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "All UART peripherals are in use" @@ -484,15 +517,22 @@ msgstr "Already advertising." msgid "Already have all-matches listener" msgstr "Already have all-matches listener" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Already running" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Already scanning for WiFi networks" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "Another PWMAudioOut is already active" @@ -506,23 +546,16 @@ msgstr "Another send is already active" msgid "Array must contain halfwords (type 'H')" msgstr "Array must contain halfwords (type 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Array values should be single bytes." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "At most %d %q may be specified (not %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Attempt to allocate %d blocks" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "Attempted heap allocation when VM not running." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "Audio conversion not implemented" @@ -573,7 +606,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -657,7 +690,7 @@ msgstr "CBC blocks must be multiples of 16 bytes" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "CRC or checksum was invalid" @@ -775,10 +808,6 @@ msgstr "CharacteristicBuffer writing not provided" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "CircuitPython core code crashed hard. Crikey!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPython was unable to allocate the heap." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Clock stretch too long" @@ -795,6 +824,14 @@ msgstr "" "Connection has been disconnected and can no longer be used. Create a new " "connection." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Corrupt .mpy file" @@ -819,10 +856,6 @@ msgstr "Could not start interrupt, RX busy" msgid "Couldn't allocate decoder" msgstr "Couldn't allocate decoder" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Crash into the HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "DAC channel init error" @@ -877,10 +910,18 @@ msgstr "Display must have a 16 bit colourspace." msgid "Display rotation must be in 90 degree increments" msgstr "Display rotation must be in 90 degree increments" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "Drive mode not used when direction is input." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "ECB only operates on 16 bytes at a time" @@ -906,20 +947,17 @@ msgstr "Error in MIDI stream at position %d" msgid "Error in regex" msgstr "Error in regex" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "Error: Failure to bind" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Expected a %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" -msgstr "Expected an alarm" +msgid "Expected a kind of %q" +msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -972,10 +1010,6 @@ msgstr "Failed to connect: internal error" msgid "Failed to connect: timeout" msgstr "Failed to connect: timeout" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "Failed to init WiFi" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Failed to parse MP3 file" @@ -990,13 +1024,17 @@ msgid "Failed to write internal flash." msgstr "Failed to write internal flash." #: supervisor/shared/safe_mode.c -msgid "Fatal error." -msgstr "Fatal error." +msgid "Fault detected by hardware." +msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "File exists" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1004,8 +1042,16 @@ msgid "Filters too complex" msgstr "Filters too complex" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "Firmware image is invalid" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" @@ -1037,13 +1083,15 @@ msgstr "Function requires lock" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "Generic Failure" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Group already used" @@ -1064,6 +1112,15 @@ msgstr "Hardware busy, try alternative pins" msgid "Hardware in use, try alternative pins" msgstr "Hardware in use, try alternative pins" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "I/O operation on closed file" @@ -1073,6 +1130,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "I2C peripheral in use" @@ -1080,11 +1138,6 @@ msgstr "I2C peripheral in use" msgid "I2SOut not available" msgstr "I2SOut not available" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV must be %d bytes long" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "In-buffer elements must be <= 4 bytes long" @@ -1171,6 +1224,7 @@ msgid "Internal define error" msgstr "Internal define error" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1183,10 +1237,16 @@ msgstr "Internal error #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "Invalid %q" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Invalid %q pin" @@ -1208,7 +1268,7 @@ msgstr "Invalid BSSID" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Invalid argument" @@ -1217,6 +1277,11 @@ msgstr "Invalid argument" msgid "Invalid bits per value" msgstr "Invalid bits per value" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1226,34 +1291,35 @@ msgstr "Invalid data_pins[%d]" msgid "Invalid format chunk size" msgstr "Invalid format chunk size" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Invalid memory access." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Invalid pins" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "Invalid size" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "Invalid socket for TLS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "Invalid state" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "Key must be 16, 24, or 32 bytes long" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1270,7 +1336,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "MAC address was invalid" @@ -1360,6 +1426,10 @@ msgstr "NLR jump failed. Likely memory corruption." msgid "NVS Error" msgstr "NVS Error" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "Name too long" @@ -1474,11 +1544,6 @@ msgstr "No key was specified" msgid "No long integer support" msgstr "No long integer support" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "No more than %d HID devices allowed" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "No network with that ssid" @@ -1514,10 +1579,6 @@ msgstr "No such file/directory" msgid "No timer available" msgstr "No timer available" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "Nordic system firmware failure assertion." - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "Nordic system firmware out of memory" @@ -1537,10 +1598,6 @@ msgstr "Not connected" msgid "Not playing" msgstr "Not playing" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "Not settable" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1556,16 +1613,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "Odd parity is not supported" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Only 8 or 16 bit mono with " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Only IPv4 addresses supported" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "Only IPv4 sockets supported" @@ -1598,10 +1665,15 @@ msgstr "" "%d bpp given" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." -msgstr "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." +msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1624,19 +1696,24 @@ msgstr "Only one colour can be transparent at a time" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "Operation or feature not supported" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "Operation timed out" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "Out of memory" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Out of sockets" @@ -1692,7 +1769,6 @@ msgid "Pin interrupt already in use" msgstr "Pin interrupt already in use" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "Pin is input only" @@ -1759,6 +1835,10 @@ msgstr "Program does OUT without loading OSR" msgid "Program size invalid" msgstr "Program size invalid" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull not used when direction is output." @@ -1798,8 +1878,9 @@ msgstr "RTC is not supported on this board" msgid "Random number generation error" msgstr "Random number generation error" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Read-only" @@ -1807,14 +1888,14 @@ msgstr "Read-only" msgid "Read-only filesystem" msgstr "Read-only filesystem" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "Read-only object" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "Received response was invalid" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "Refresh too soon" @@ -1827,7 +1908,7 @@ msgstr "RemoteTransmissionRequests limited to 8 bytes" msgid "Requested AES mode is unsupported" msgstr "Requested AES mode is unsupported" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "Requested resource not found" @@ -1899,7 +1980,8 @@ msgstr "Size not supported" msgid "Sleep Memory not available" msgstr "Sleep Memory not available" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice and value different lengths." @@ -1911,6 +1993,7 @@ msgid "Slices not supported" msgstr "Slices not supported" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool can only be used with wifi.radio" @@ -1934,13 +2017,9 @@ msgstr "Stereo left must be on PWM channel A" msgid "Stereo right must be on PWM channel B" msgstr "Stereo right must be on PWM channel B" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Stream missing readinto() or write() method." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Supply at least one UART pin" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -1955,34 +2034,20 @@ msgid "Temperature read timed out" msgstr "Temperature read timed out" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "The length of rgb_pins must be 6, 12, 18, 24, or 30" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." #: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" @@ -2000,6 +2065,10 @@ msgstr "The sample's sample rate does not match the mixer's" msgid "The sample's signedness does not match the mixer's" msgstr "The sample's signedness does not match the mixer's" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2032,10 +2101,6 @@ msgstr "Time is in the past." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Timeout is too long: Maximum timeout length is %d seconds" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "To exit, please reset the board without " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2080,6 +2145,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2088,6 +2157,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "USB busy" @@ -2123,6 +2196,15 @@ msgstr "UUID value is not str, int or byte buffer" msgid "Unable to allocate buffers for signed conversion" msgstr "Unable to allocate buffers for signed conversion" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "Unable to create lock" @@ -2141,14 +2223,29 @@ msgstr "Unable to find free GCLK" msgid "Unable to init parser" msgstr "Unable to init parser" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "Unable to read colour palette data" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Unable to write to nvm." @@ -2211,7 +2308,13 @@ msgstr "Unknown system firmware error: %04x" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "Unmatched number of items on RHS (expected %d, got %d)." @@ -2258,7 +2361,7 @@ msgstr "Value length != required fixed length" msgid "Value length > max_length" msgstr "Value length > max_length" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "Version was invalid" @@ -2284,10 +2387,6 @@ msgstr "WatchDogTimer is not currently running" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "WatchDogTimer.timeout must be greater than 0" - #: py/builtinhelp.c #, c-format msgid "" @@ -2302,6 +2401,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "Woken up by alarm.\n" @@ -2311,19 +2422,57 @@ msgstr "Woken up by alarm.\n" msgid "Writes not supported on Characteristic" msgstr "Writes not supported on Characteristic" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" -msgstr "You are in safe mode because:\n" - -#: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" -"You pressed the reset button during boot. Press again to exit safe mode." #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "You requested starting safe mode by " +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "" #: py/objtype.c msgid "__init__() should return None" @@ -2341,11 +2490,7 @@ msgstr "__new__ arg must be a user-type" msgid "a bytes-like object is required" msgstr "a bytes-like object is required" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "address out of bounds" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "addresses is empty" @@ -2398,8 +2543,12 @@ msgstr "array and index length must be equal" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "array/bytes required on right side" @@ -2492,10 +2641,6 @@ msgstr "Buffer too small" msgid "buffer too small for requested bytes" msgstr "Buffer too small for requested bytes" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "Byteorder is not a string" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "Bytes length not a multiple of item size" @@ -2537,15 +2682,10 @@ msgstr "Can't assign to expression" msgid "can't cancel self" msgstr "can't cancel self" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "Can't convert %q to %q" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "can't convert %q to int" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2623,10 +2763,14 @@ msgstr "can't send non-None value to a just-started generator" msgid "can't set 512 block size" msgstr "can't set 512 block size" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "can't set attribute" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "can't store '%q'" @@ -2727,18 +2871,10 @@ msgstr "colour buffer must be a bytearray or array of type 'b' or 'B'" msgid "color must be between 0x000000 and 0xffffff" msgstr "colour must be between 0x000000 and 0xffffff" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "colour should be an int" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "comparison of int and uint" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "complex division by zero" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "complex values not supported" @@ -2822,10 +2958,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "destination buffer must be an array of type 'H' for bit_depth = 16" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "destination_length must be an int >= 0" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "dict update sequence has wrong length" @@ -2846,12 +2978,11 @@ msgstr "dimensions do not match" msgid "div/mod not implemented for uint" msgstr "div/mod not implemented for uint" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "divide by zero" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "division by zero" @@ -2883,10 +3014,6 @@ msgstr "empty sequence" msgid "end of format while looking for conversion specifier" msgstr "end of format while looking for conversion specifier" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "end_x should be an int" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "epoch_time not supported on this board" @@ -2896,18 +3023,16 @@ msgstr "epoch_time not supported on this board" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "exceptions must derive from BaseException" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "expected '%q' but got '%q'" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "expected '%q' or '%q' but got '%q'" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "expected ':' after format specifier" @@ -3006,10 +3131,6 @@ msgstr "font must be 2048 bytes long" msgid "format requires a dict" msgstr "format requires a dict" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "full" @@ -3122,16 +3243,16 @@ msgstr "incorrect padding" msgid "index is out of bounds" msgstr "index is out of bounds" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "index out of range" -#: py/obj.c -msgid "indices must be integers" -msgstr "indices must be integers" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "indices must be integers, slices, or Boolean lists" @@ -3225,10 +3346,6 @@ msgstr "input vectors must be of equal length" msgid "inputs are not iterable" msgstr "inputs are not iterable" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "int() arg 2 must be >= 2 and <= 36" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "interp is defined for 1D iterables of equal length" @@ -3247,6 +3364,10 @@ msgstr "invalid architecture" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "invalid cert" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3273,10 +3394,18 @@ msgstr "invalid format specifier" msgid "invalid hostname" msgstr "invalid hostname" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "invalid key" + #: py/compile.c msgid "invalid micropython decorator" msgstr "invalid micropython decorator" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "invalid step" @@ -3298,10 +3427,6 @@ msgstr "invalid syntax for integer with base %d" msgid "invalid syntax for number" msgstr "invalid syntax for number" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "invalid traceback" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 must be a class" @@ -3358,19 +3483,17 @@ msgstr "local '%q' used before type known" msgid "local variable referenced before assignment" msgstr "local variable referenced before assignment" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "long int not supported in this build" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "loopback + silent mode not supported by peripheral" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3499,6 +3622,10 @@ msgstr "negative power with no float support" msgid "negative shift count" msgstr "negative shift count" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "no SD card" @@ -3532,14 +3659,10 @@ msgstr "no reset pin available" msgid "no response from SD card" msgstr "no response from SD card" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "no such attribute" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "non-Device in %q" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3664,15 +3787,30 @@ msgid "offset out of bounds" msgstr "offset out of bounds" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "only bit_depth=16 is supported" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "only sample_rate=16000 is supported" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "only slices with step=1 (aka None) are supported" @@ -3743,10 +3881,6 @@ msgstr "pack expected %d items for packing (got %d)" msgid "palette must be 32 bytes long" msgstr "palette must be 32 bytes long" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_index should be an int" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "parameters must be registers in sequence a2 to a5" @@ -3796,28 +3930,6 @@ msgstr "pow() 3rd argument cannot be 0" msgid "pow() with 3 arguments requires integers" msgstr "pow() with 3 arguments requires integers" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "pressing boot button at start up.\n" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "pressing both buttons at start up.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "pressing the left button at start up\n" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "pull masks conflict with direction masks" @@ -3838,11 +3950,6 @@ msgstr "real and imaginary parts must be of equal length" msgid "relative import" msgstr "relative import" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "requested length %d but object has length %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "results cannot be cast to specified type" @@ -3873,14 +3980,6 @@ msgstr "roll argument must be an ndarray" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3914,10 +4013,6 @@ msgstr "sign not allowed in string format specifier" msgid "sign not allowed with integer format specifier 'c'" msgstr "sign not allowed with integer format specifier 'c'" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "single '}' encountered in format string" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "size is defined for ndarrays only" @@ -3930,10 +4025,6 @@ msgstr "sleep length must be non-negative" msgid "slice step can't be zero" msgstr "slice step can't be zero" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "slice step cannot be zero" - #: py/nativeglue.c msgid "slice unsupported" msgstr "slice unsupported" @@ -3982,14 +4073,6 @@ msgstr "" msgid "start/end indices" msgstr "start/end indices" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "start_x should be an int" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "step must be non-zero" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "stop not reachable from start" @@ -3998,10 +4081,6 @@ msgstr "stop not reachable from start" msgid "stream operation not supported" msgstr "stream operation not supported" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "string indices must be integers, not %q" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "string not supported; use bytes or bytearray" @@ -4034,14 +4113,6 @@ msgstr "syntax error in JSON" msgid "syntax error in uctypes descriptor" msgstr "syntax error in uctypes descriptor" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "threshold must be in the range 0-65536" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time() takes a 9-sequence" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4049,10 +4120,6 @@ msgstr "time.struct_time() takes a 9-sequence" msgid "timeout duration exceeded the maximum supported value" msgstr "timeout duration exceeded the maximum supported value" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "timeout must be 0.0-100.0 seconds" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "timeout must be < 655.35 secs" @@ -4106,10 +4173,6 @@ msgstr "trapz is defined for 1D arrays of equal length" msgid "trapz is defined for 1D iterables" msgstr "trapz is defined for 1D iterables" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "tuple/list has wrong length" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4120,8 +4183,6 @@ msgstr "twai_driver_install returned esp-idf error #%d" msgid "twai_start returned esp-idf error #%d" msgstr "twai_start returned esp-idf error #%d" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx and rx cannot both be None" @@ -4134,14 +4195,10 @@ msgstr "type '%q' is not an acceptable base type" msgid "type is not an acceptable base type" msgstr "type is not an acceptable base type" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "type object '%q' has no attribute '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "type object 'generator' has no attribute '__await__'" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "type takes 1 or 3 arguments" @@ -4162,7 +4219,7 @@ msgstr "unexpected indent" msgid "unexpected keyword argument" msgstr "unexpected keyword argument" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "unexpected keyword argument '%q'" @@ -4192,15 +4249,15 @@ msgid "unknown type '%q'" msgstr "unknown type '%q'" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "unmatched '{' in format" +#, c-format +msgid "unmatched '%c' in format" +msgstr "" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "unreadable attribute" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "unsupported %q type" @@ -4264,18 +4321,19 @@ msgstr "value_count must be > 0" msgid "watchdog not initialized" msgstr "WatchDog not initialised" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "WatchDog timeout must be greater than 0" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "width must be greater than zero" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "WiFi is not enabled" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "window must be <= interval" @@ -4330,18 +4388,10 @@ msgstr "x value out of bounds" msgid "xTaskCreate failed" msgstr "xTaskCreate failed" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y should be an int" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "y value out of bounds" -#: py/objrange.c -msgid "zero step" -msgstr "zero step" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "zi must be an ndarray" @@ -4354,6 +4404,239 @@ msgstr "zi must be of float type" msgid "zi must be of shape (n_section, 2)" msgstr "zi must be of shape (n_section, 2)" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Supply at least one UART pin" + +#~ msgid "%q pin invalid" +#~ msgstr "%q pin invalid" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "Attempted heap allocation when VM not running." + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPython was unable to allocate the heap." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Crash into the HardFault_Handler." + +#~ msgid "Fatal error." +#~ msgstr "Fatal error." + +#~ msgid "Invalid memory access." +#~ msgstr "Invalid memory access." + +#~ msgid "Nordic system firmware failure assertion." +#~ msgstr "Nordic system firmware failure assertion." + +#~ msgid "" +#~ "The CircuitPython heap was corrupted because the stack was too small.\n" +#~ "Increase the stack size if you know how. If not:" +#~ msgstr "" +#~ "The CircuitPython heap was corrupted because the stack was too small.\n" +#~ "Increase the stack size if you know how. If not:" + +#~ msgid "" +#~ "The `microcontroller` module was used to boot into safe mode. Press reset " +#~ "to exit safe mode." +#~ msgstr "" +#~ "The `microcontroller` module was used to boot into safe mode. Press reset " +#~ "to exit safe mode." + +#~ msgid "" +#~ "The microcontroller's power dipped. Make sure your power supply provides\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY)." +#~ msgstr "" +#~ "The microcontroller's power dipped. Make sure your power supply provides\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY)." + +#~ msgid "You are in safe mode because:\n" +#~ msgstr "You are in safe mode because:\n" + +#~ msgid "" +#~ "You pressed the reset button during boot. Press again to exit safe mode." +#~ msgstr "" +#~ "You pressed the reset button during boot. Press again to exit safe mode." + +#~ msgid "Expected a %q" +#~ msgstr "Expected a %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV must be %d bytes long" + +#~ msgid "Not settable" +#~ msgstr "Not settable" + +#~ msgid "expected '%q' but got '%q'" +#~ msgstr "expected '%q' but got '%q'" + +#~ msgid "expected '%q' or '%q' but got '%q'" +#~ msgstr "expected '%q' or '%q' but got '%q'" + +#~ msgid "Read-only object" +#~ msgstr "Read-only object" + +#~ msgid "%q length must be >= 1" +#~ msgstr "%q length must be >= 1" + +#~ msgid "%q must be a string" +#~ msgstr "%q must be a string" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "At most %d %q may be specified (not %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Invalid pins" + +#, c-format +#~ msgid "No more than %d HID devices allowed" +#~ msgstr "No more than %d HID devices allowed" + +#~ msgid "byteorder is not a string" +#~ msgstr "Byteorder is not a string" + +#~ msgid "can't convert %q to int" +#~ msgstr "can't convert %q to int" + +#~ msgid "complex division by zero" +#~ msgstr "complex division by zero" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "int() arg 2 must be >= 2 and <= 36" + +#~ msgid "long int not supported in this build" +#~ msgstr "long int not supported in this build" + +#~ msgid "slice step cannot be zero" +#~ msgstr "slice step cannot be zero" + +#~ msgid "step must be non-zero" +#~ msgstr "step must be non-zero" + +#~ msgid "string indices must be integers, not %q" +#~ msgstr "string indices must be integers, not %q" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time() takes a 9-sequence" + +#~ msgid "zero step" +#~ msgstr "zero step" + +#~ msgid "invalid traceback" +#~ msgstr "invalid traceback" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "%q indices must be integers, not %s" + +#~ msgid "WatchDogTimer.timeout must be greater than 0" +#~ msgstr "WatchDogTimer.timeout must be greater than 0" + +#~ msgid "indices must be integers" +#~ msgstr "indices must be integers" + +#~ msgid "non-Device in %q" +#~ msgstr "non-Device in %q" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "requested length %d but object has length %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "single '}' encountered in format string" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "threshold must be in the range 0-65536" + +#~ msgid "timeout must be 0.0-100.0 seconds" +#~ msgstr "timeout must be 0.0-100.0 seconds" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "tuple/list has wrong length" + +#~ msgid "unmatched '{' in format" +#~ msgstr "unmatched '{' in format" + +#~ msgid "watchdog timeout must be greater than 0" +#~ msgstr "WatchDog timeout must be greater than 0" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "To exit, please reset the board without " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "You requested starting safe mode by " + +#~ msgid "pressing boot button at start up.\n" +#~ msgstr "pressing boot button at start up.\n" + +#~ msgid "pressing both buttons at start up.\n" +#~ msgstr "pressing both buttons at start up.\n" + +#~ msgid "pressing the left button at start up\n" +#~ msgstr "pressing the left button at start up\n" + +#~ msgid "Only one TouchAlarm can be set in deep sleep." +#~ msgstr "Only one TouchAlarm can be set in deep sleep." + +#~ msgid "Firmware image is invalid" +#~ msgstr "Firmware image is invalid" + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Stream missing readinto() or write() method." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q must be >= 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q must be >= 1" + +#~ msgid "address out of bounds" +#~ msgstr "address out of bounds" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "destination_length must be an int >= 0" + +#~ msgid "type object 'generator' has no attribute '__await__'" +#~ msgstr "type object 'generator' has no attribute '__await__'" + +#~ msgid "color should be an int" +#~ msgstr "colour should be an int" + +#~ msgid "end_x should be an int" +#~ msgstr "end_x should be an int" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_index should be an int" + +#~ msgid "start_x should be an int" +#~ msgstr "start_x should be an int" + +#~ msgid "y should be an int" +#~ msgstr "y should be an int" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" + +#~ msgid "Expected an alarm" +#~ msgstr "Expected an alarm" + +#~ msgid "Failed to init wifi" +#~ msgstr "Failed to init WiFi" + #~ msgid "input must be a tensor of rank 2" #~ msgstr "input must be a tensor of rank 2" @@ -4988,12 +5271,6 @@ msgstr "zi must be of shape (n_section, 2)" #~ msgid "can only save bytecode" #~ msgstr "Can only save bytecode" -#~ msgid "invalid cert" -#~ msgstr "invalid cert" - -#~ msgid "invalid key" -#~ msgstr "invalid key" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Viper functions don't currently support more than 4 arguments" diff --git a/locale/es.po b/locale/es.po index 3652d1847e..ee2c98a23b 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,15 +8,15 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-08-23 14:19+0000\n" -"Last-Translator: Jeff Epler \n" +"PO-Revision-Date: 2023-03-09 10:38+0000\n" +"Last-Translator: Jose David M \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.8.1-dev\n" +"X-Generator: Weblate 4.16.2-dev\n" #: main.c msgid "" @@ -31,16 +31,46 @@ msgid "" "\n" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +"\n" +"Código detenido por la auto-recarga. Recargando pronto.\n" + +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" +"\n" +"CIRCUITPY_PYSTACK_SIZE inválido\n" +"\n" +"\n" #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" "\n" -"Presente un problema con el contenido de su unidad CIRCUITPY en\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Por favor describa su problema en https://github.com/adafruit/circuitpython/" +"issues." + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" +"\n" +"Presione reset para salir del modo seguro.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" +"\n" +"Estas en modo seguro porque:\n" #: py/obj.c msgid " File \"%q\"" @@ -67,6 +97,16 @@ msgstr " salida:\n" msgid "%%c requires int or char" msgstr "%%c requiere int o char" +#: main.c +#, c-format +msgid "%02X" +msgstr "%02X" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -75,71 +115,81 @@ msgstr "" "%d pines de dirección, %d pines rgb y %d tiles indican una altura de %d, y " "no de %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" -msgstr "" +msgstr "%q" #: shared-bindings/microcontroller/Pin.c msgid "%q and %q contain duplicate pins" -msgstr "" +msgstr "%q y %q contienen pines duplicados" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "%q and %q must be different" -msgstr "" +msgstr "%q y %q deben ser diferentes" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" -msgstr "" +msgstr "%q contiene pines duplicados" #: ports/atmel-samd/common-hal/sdioio/SDCard.c msgid "%q failure: %d" msgstr "%q fallo: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q en %q debe ser del tipo %q, no %q" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q está siendo utilizado" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" -msgstr "%q indice fuera de rango" - -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q indices deben ser enteros, no %s" +msgstr "%q índice fuera de rango" #: shared-module/bitbangio/SPI.c msgid "%q init failed" -msgstr "" +msgstr "%q inicializado fallido" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q es %q" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q es solamente de lectura en esta tarjeta" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" -msgstr "" +msgstr "%q longitud debe ser %d" #: py/argcheck.c msgid "%q length must be %d-%d" -msgstr "" +msgstr "%q longitud debe ser %d-%d" #: py/argcheck.c msgid "%q length must be <= %d" -msgstr "" +msgstr "%q longitud debe ser <= %d" #: py/argcheck.c msgid "%q length must be >= %d" -msgstr "" - -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "" +msgstr "%q longitud debe ser >= %d" #: py/argcheck.c msgid "%q must be %d" -msgstr "" +msgstr "%q debe ser %d" #: py/argcheck.c msgid "%q must be %d-%d" @@ -147,47 +197,44 @@ msgstr "%q debe ser %d-%d" #: shared-bindings/displayio/Display.c msgid "%q must be 1 when %q is True" -msgstr "" +msgstr "%q debe ser 1 cuando %q es True" #: py/argcheck.c shared-bindings/gifio/GifWriter.c msgid "%q must be <= %d" -msgstr "" +msgstr "%q debe ser <= %d" #: py/argcheck.c msgid "%q must be >= %d" msgstr "%q debe ser >= %d" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q debe ser >= 0" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "%q debe ser un arreglo de tipo 'H'" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q debe ser >= 1" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q debe ser un bytearray o array de tipo 'H' o 'B'" -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q debe ser una cadena" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q debe ser un byte-matriz o matriz de tipo 'h', 'H', 'b', o 'B'" -#: py/argcheck.c -msgid "%q must be an int" -msgstr "" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q debe ser del tipo %q o %q, y no %q" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "" - -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" +msgstr "%q debe ser del tipo %q, y no %q" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" -msgstr "" +msgstr "%q debe ser potencia de 2" #: shared-bindings/wifi/Monitor.c msgid "%q out of bounds" -msgstr "" +msgstr "%q fuera de limites" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c @@ -198,13 +245,9 @@ msgstr "" msgid "%q out of range" msgstr "%q fuera de rango" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "pin inválido %q" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" -msgstr "" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "%q paso no puede ser cero" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -212,13 +255,13 @@ msgstr "%q() toma %d argumentos posicionales pero %d fueron dados" #: shared-bindings/usb_hid/Device.c msgid "%q, %q, and %q must all be the same length" -msgstr "" +msgstr "%q, %q, y %q deben tener la misma longitud" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s error 0x%x" @@ -318,7 +361,7 @@ msgstr "'=' alineación no permitida en el especificador string format" #: shared-module/struct/__init__.c msgid "'S' and 'O' are not supported format types" -msgstr "'S' y 'O' no son compatibles con los tipos de formato" +msgstr "'S' y 'O' no son tipos de formato soportados" #: py/compile.c msgid "'align' requires 1 argument" @@ -392,7 +435,7 @@ msgstr "tipos de 64 bit" #: ports/atmel-samd/common-hal/countio/Counter.c #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "A hardware interrupt channel is already in use" -msgstr "El canal EXTINT ya está siendo utilizado" +msgstr "Un canal de interrupción por hardware ya está en uso" #: ports/espressif/common-hal/analogio/AnalogIn.c msgid "ADC2 is being used by WiFi" @@ -401,17 +444,21 @@ msgstr "ADC2 está siendo usado por WiFi" #: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format msgid "Address must be %d bytes long" -msgstr "La dirección debe tener %d bytes de largo" +msgstr "La dirección debe tener %d bytes de longitud" + +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "Rango de dirección no permitido" #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "Todos los periféricos CAN están en uso" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" -msgstr "Todos los periféricos I2C están siendo usados" +msgstr "Todos los periféricos I2C están en uso" #: ports/espressif/common-hal/countio/Counter.c #: ports/espressif/common-hal/frequencyio/FrequencyIn.c @@ -427,37 +474,36 @@ msgstr "Todos los FIFOs de RX en uso" #: ports/espressif/common-hal/busio/SPI.c ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" -msgstr "Todos los periféricos SPI están siendo usados" +msgstr "Todos los periféricos SPI están en uso" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" -msgstr "Todos los periféricos UART están siendo usados" +msgstr "Todos los periféricos UART están en uso" #: ports/nrf/common-hal/countio/Counter.c #: ports/nrf/common-hal/pulseio/PulseIn.c #: ports/nrf/common-hal/rotaryio/IncrementalEncoder.c #: shared-bindings/pwmio/PWMOut.c msgid "All channels in use" -msgstr "Todos los canales esta en uso" +msgstr "Todos los canales están en uso" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "All event channels in use" -msgstr "Todos los canales de eventos estan siendo usados" +msgstr "Todos los canales de eventos están en uso" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "All state machines in use" -msgstr "Todas las máquinas de estado en uso" +msgstr "Todas las máquinas de estado están en uso" #: ports/atmel-samd/audio_dma.c msgid "All sync event channels in use" msgstr "" "Todos los canales de eventos de sincronización (sync event channels) están " -"siendo utilizados" +"en uso" #: shared-bindings/pwmio/PWMOut.c msgid "All timers for this pin are in use" -msgstr "Todos los timers para este pin están siendo utilizados" +msgstr "Todos los timers para este pin están en uso" #: ports/atmel-samd/common-hal/_pew/PewPew.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -485,15 +531,22 @@ msgstr "Ya se encuentra publicando." msgid "Already have all-matches listener" msgstr "Ya se tiene un escucha de todas las coincidencias" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Ya está en ejecución" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Ya se están buscando redes wifi" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "Un error ocurrió mientras recuperaba '%s':\n" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "Otra salida PWMAudioOut esta ya activada" @@ -507,26 +560,19 @@ msgstr "Otro envío ya está activo" msgid "Array must contain halfwords (type 'H')" msgstr "El array debe contener medias palabras (escriba 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Valores del array deben ser bytes individuales." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "Como máximo %d %q se puede especificar (no %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Tratando de localizar %d bloques" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "Asignación del montículo mientras la VM no esta ejecutándose." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" -msgstr "" +msgstr "Conversión de audio no está implementada" #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" @@ -545,12 +591,12 @@ msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -"Auto-reload habilitado. Simplemente guarda los archivos via USB para " -"ejecutarlos o entra al REPL para desabilitarlos.\n" +"Auto-reload habilitado. Simplemente guarda los archivos vía USB para " +"ejecutarlos o entra al REPL para deshabilitarlo.\n" #: ports/espressif/common-hal/canio/CAN.c msgid "Baudrate not supported by peripheral" -msgstr "El periférico no maneja el Baudrate" +msgstr "Baudrate no soportado por el periférico" #: shared-module/displayio/Display.c #: shared-module/framebufferio/FramebufferDisplay.c @@ -559,7 +605,8 @@ msgstr "Por debajo de la tasa mínima de refrescamiento" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Bit clock and word select must be sequential pins" -msgstr "Le reloj de bit y de selector de palabra deben ser pines secuenciales" +msgstr "" +"Los pines de reloj de bit y de selector de palabra deben ser secuenciales" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Bit clock and word select must share a clock unit" @@ -571,11 +618,11 @@ msgstr "Bits depth debe ser múltiplo de 8." #: shared-bindings/bitmaptools/__init__.c msgid "Bitmap size and bits per value must match" -msgstr "" +msgstr "El tamaño del mapa de bits y los bits por valor deben coincidir" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "" +msgid "Boot device must be first (interface #0)." +msgstr "El dispositivo de inicialización debe estar primero (interface #0)." #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" @@ -600,12 +647,11 @@ msgstr "El brillo no se puede ajustar" #: shared-bindings/_bleio/UUID.c #, c-format msgid "Buffer + offset too small %d %d %d" -msgstr "Búfer + compensado muy pequeños %d %d %d" +msgstr "Buffer + offset muy pequeños %d %d %d" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Buffer elements must be 4 bytes long or less" -msgstr "" -"Los elementos del búfer deben de ser de una longitud de 4 bytes o menos" +msgstr "Los elementos del buffer deben tener una longitud de 4 bytes o menos" #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." @@ -614,30 +660,31 @@ msgstr "Buffer no es un bytearray." #: ports/cxd56/common-hal/camera/Camera.c shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" -msgstr "El buffer es muy pequeño" +msgstr "Buffer es muy pequeño" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c #, c-format msgid "Buffer length %d too big. It must be less than %d" -msgstr "Longitud del buffer %d es demasiado grande. Tiene que ser menor a %d" +msgstr "" +"La longitud del buffer %d es demasiado grande. Tiene que ser menor a %d" #: ports/atmel-samd/common-hal/sdioio/SDCard.c #: ports/cxd56/common-hal/sdioio/SDCard.c shared-module/sdcardio/SDCard.c msgid "Buffer length must be a multiple of 512" -msgstr "El tamaño del búfer debe ser múltiplo de 512" +msgstr "El tamaño del buffer debe ser múltiplo de 512" #: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c msgid "Buffer must be a multiple of 512 bytes" -msgstr "Búfer deber ser un múltiplo de 512 bytes" +msgstr "El buffer deber ser un múltiplo de 512 bytes" #: shared-bindings/_bleio/PacketBuffer.c #, c-format msgid "Buffer too short by %d bytes" -msgstr "Búffer muy corto por %d bytes" +msgstr "Buffer muy corto por %d bytes" #: ports/espressif/common-hal/imagecapture/ParallelImageCapture.c msgid "Buffers must be same size" -msgstr "" +msgstr "Los buffers deben ser del mismo tamaño" #: ports/atmel-samd/common-hal/paralleldisplay/ParallelBus.c #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c @@ -657,9 +704,9 @@ msgstr "Los bloques CBC deben ser múltiplos de 16 bytes" #: supervisor/shared/safe_mode.c msgid "CIRCUITPY drive could not be found or created." -msgstr "" +msgstr "El dispositivo CIRCUITPY no pudo ser encontrado o creado." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "CRC o suma de comprobación inválida" @@ -669,7 +716,7 @@ msgstr "Llame a super().__init__() antes de acceder al objeto nativo." #: ports/cxd56/common-hal/camera/Camera.c msgid "Camera init" -msgstr "" +msgstr "Inicialización de cámara" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on RTC IO from deep sleep." @@ -724,7 +771,7 @@ msgstr "" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot pull on input-only pin." -msgstr "No puede hacer pull en un pin de entrada sola." +msgstr "No puede hacer pull en un pin de solo entrada." #: shared-bindings/audiobusio/PDMIn.c msgid "Cannot record to a file" @@ -739,6 +786,8 @@ msgstr "No se puede remountar '/' cuanto se es visible vía USB." #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c msgid "Cannot reset into bootloader because no bootloader is present" msgstr "" +"No puede se reinicilizado al bootloader porque el bootloader no se encuentra " +"presente" #: ports/espressif/common-hal/socketpool/Socket.c msgid "Cannot set socket options" @@ -759,7 +808,7 @@ msgstr "No se puede manejar la partición en una subclase" #: shared-module/bitbangio/SPI.c msgid "Cannot transfer without MOSI and MISO pins" -msgstr "" +msgstr "No puede ser transferido si los pines MOSI y MISO" #: shared-bindings/pwmio/PWMOut.c msgid "Cannot vary frequency on a timer that is already in use" @@ -767,7 +816,7 @@ msgstr "No puede variar la frecuencia en un temporizador que ya está en uso" #: ports/nrf/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" -msgstr "" +msgstr "No puede ser despertado en transición de pin, only nivel" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." @@ -781,10 +830,6 @@ msgstr "CharateristicBuffer escritura no proporcionada" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "El código central de CircuitPython se estrelló con fuerza. ¡Whoops!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPython no puedo encontrar el montículo." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Estirado de reloj demasiado largo" @@ -801,6 +846,14 @@ msgstr "" "La conexión se ha desconectado y ya no se puede usar. Crea una nueva " "conexión." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "Las matrices de coordenadas tienen diferentes longitudes" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "Las matrices de coordenadas tienen diferentes tamaños" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Archivo .mpy corrupto" @@ -825,10 +878,6 @@ msgstr "No se pudo iniciar la interrupción, RX ocupado" msgid "Couldn't allocate decoder" msgstr "No se pudo encontrar el decodificador" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Choque contra el HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Error de inicio del canal DAC" @@ -884,10 +933,18 @@ msgstr "La pantalla debe tener un espacio de color de 16 bits." msgid "Display rotation must be in 90 degree increments" msgstr "Rotación de display debe ser en incrementos de 90 grados" +#: main.c +msgid "Done" +msgstr "Hecho" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "Modo Drive no se usa cuando la dirección es input." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "Durante el procesamiento de esta excepción, otra excepción ocurrió:" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "ECB solo opera sobre 16 bytes a la vez" @@ -913,20 +970,17 @@ msgstr "Error en el flujo MIDI en la posición %d" msgid "Error in regex" msgstr "Error en regex" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "Error en safemode.py." + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "Error: fallo al vincular" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Se espera un %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" -msgstr "Un objecto alarm era esperado" +msgid "Expected a kind of %q" +msgstr "Esperando un tipo %q" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -956,7 +1010,7 @@ msgstr "No se puede adquirir el mutex, error 0x%04x" #: shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" -msgstr "" +msgstr "Fallo para asignar el %q búfer" #: ports/espressif/common-hal/wifi/__init__.c msgid "Failed to allocate Wifi memory" @@ -979,10 +1033,6 @@ msgstr "Error al conectar: error interno" msgid "Failed to connect: timeout" msgstr "Error al conectar: tiempo de espera agotado" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "Fallo al inicializar wifi" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Error al analizar el archivo MP3" @@ -997,13 +1047,17 @@ msgid "Failed to write internal flash." msgstr "Error al escribir el flash interno." #: supervisor/shared/safe_mode.c -msgid "Fatal error." -msgstr "Error grave." +msgid "Fault detected by hardware." +msgstr "Falló detectado por el hardware." #: py/moduerrno.c msgid "File exists" msgstr "El archivo ya existe" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "Archivo no encontrado" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1011,16 +1065,27 @@ msgid "Filters too complex" msgstr "Filtros muy complejos" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "La imagen de firmware es inválida" +msgid "Firmware is duplicate" +msgstr "El Firmware es duplicado" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "El Firmware es inválido" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "El Firmaware es muy grande" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" msgstr "" +"Para el espacio de color L8, el bitmap de entrada debe tener 8 bits por pixel" #: shared-bindings/bitmaptools/__init__.c msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" +"Para espacios de colores RGB, el bitmap de entrada debe tener 16 bits por " +"pixel" #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" @@ -1030,6 +1095,8 @@ msgstr "Sin capacidades para el formato" msgid "" "Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" msgstr "" +"La frecuencia debe ser 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 o " +"1008 Mhz" #: shared-bindings/pwmio/PWMOut.c msgid "Frequency must match existing PWMOut using this timer" @@ -1043,15 +1110,17 @@ msgstr "La función requiere lock" #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" -msgstr "" +msgstr "Inicialización GNSS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "Fallo Genérico" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Grupo ya está siendo utilizado" @@ -1060,7 +1129,7 @@ msgstr "Grupo ya está siendo utilizado" #: ports/mimxrt10xx/common-hal/busio/SPI.c ports/nrf/common-hal/busio/SPI.c #: ports/raspberrypi/common-hal/busio/SPI.c msgid "Half duplex SPI is not implemented" -msgstr "" +msgstr "SPI Half Duplex no está implementado" #: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c #: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/canio/CAN.c @@ -1072,15 +1141,26 @@ msgstr "Hardware ocupado, pruebe pines alternativos" msgid "Hardware in use, try alternative pins" msgstr "Hardware en uso, pruebe pines alternativos" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "Alocación del Heap cuando la VM no esta corriendo." + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" +"El Heap está corrupto, ya que la pila era muy pequeña. Incremente el tamaño." + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "Operación I/O en archivo cerrado" #: ports/stm/common-hal/busio/I2C.c msgid "I2C init error" -msgstr "" +msgstr "Error en la inicialización I2C" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "Dispositivo I2C en uso" @@ -1088,11 +1168,6 @@ msgstr "Dispositivo I2C en uso" msgid "I2SOut not available" msgstr "I2SOut no disponible" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV debe tener %d bytes de longitud" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1175,19 +1250,20 @@ msgstr "Cifrado insuficiente" #: ports/espressif/common-hal/wifi/Radio.c msgid "Interface must be started" -msgstr "" +msgstr "La interfaz debe ser iniciada" #: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c msgid "Internal audio buffer too small" -msgstr "" +msgstr "El búfer de audio interno es muy pequeño" #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Error interno de definición" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" -msgstr "" +msgstr "Error interno" #: shared-module/rgbmatrix/RGBMatrix.c #, c-format @@ -1196,12 +1272,18 @@ msgstr "Error interno #%d" #: supervisor/shared/safe_mode.c msgid "Internal watchdog timer expired." -msgstr "" +msgstr "El temporizador interno watchdog terminó." -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Error de interrupción." + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "%q inválido" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Pin %q inválido" @@ -1221,9 +1303,9 @@ msgstr "BSSID inválido" #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" -msgstr "" +msgstr "Dirección MAC inválida" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Argumento inválido" @@ -1232,6 +1314,11 @@ msgstr "Argumento inválido" msgid "Invalid bits per value" msgstr "Inválido bits por valor" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "byte %.*s Inválido" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1241,37 +1328,38 @@ msgstr "Inválidos los data_pins[%d]" msgid "Invalid format chunk size" msgstr "Formato de fragmento de formato no válido" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Acceso a memoria no válido." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" -msgstr "" +msgstr "Dirección MAC de multidifusión inválida" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "pines inválidos" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "Tamaño incorrecto" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "socket invalido para TLS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "Estado invalido" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "Unicode del caracter \"escape\" inválido" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "La llave debe tener 16, 24 o 32 bytes de longitud" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "Key no fue encontrada" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" -msgstr "" +msgstr "Los mappings LED deben coincidir con el tamaño del display" #: py/compile.c msgid "LHS of keyword arg must be an id" @@ -1279,19 +1367,19 @@ msgstr "LHS del agumento por palabra clave deberia ser un identificador" #: shared-module/displayio/Group.c msgid "Layer already in a group" -msgstr "" +msgstr "El Layer ya esta en un grupo" #: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass" -msgstr "" +msgstr "El Layer debe ser un grupo o una subclase de TileGrid" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "La dirección MAC es incorrecta" #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" -msgstr "" +msgstr "El mapping debe ser una dupla" #: shared-module/displayio/Shape.c #, c-format @@ -1305,11 +1393,11 @@ msgstr "Micrófono demora de inicio debe estar en el rango 0.0 a 1.0" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" -msgstr "" +msgstr "Inconsistencia en el tamaño de los datos" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched swap flag" -msgstr "" +msgstr "Inconsistencia en el flag de recambio" #: ports/mimxrt10xx/common-hal/busio/SPI.c msgid "Missing MISO or MOSI Pin" @@ -1317,7 +1405,7 @@ msgstr "Falta el pin MISO o MOSI" #: ports/stm/common-hal/busio/SPI.c msgid "Missing MISO or MOSI pin" -msgstr "" +msgstr "Falta el pin MISO o MOSI" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format @@ -1356,7 +1444,7 @@ msgstr "" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" +msgstr "Falta el jmp_pin. La instrucción %d se dispara en el pin" #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." @@ -1379,17 +1467,21 @@ msgstr "Salto NLR falló. Probablemente corrupción de memoria." msgid "NVS Error" msgstr "Error NVS" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "Nombre o servicio desconocido" + #: py/qstr.c msgid "Name too long" msgstr "Nombre muy largo" #: shared-bindings/displayio/TileGrid.c msgid "New bitmap must be same size as old bitmap" -msgstr "" +msgstr "El nuevo bitmap debe ser del mismo tamaño que el bitmap anterior" #: ports/espressif/common-hal/_bleio/__init__.c msgid "Nimble out of memory" -msgstr "" +msgstr "Nimble sin memoria" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nrf/common-hal/_bleio/Characteristic.c @@ -1415,11 +1507,11 @@ msgstr "timer por establecedor de paso DMA no encontrado" #: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c #, c-format msgid "No I2C device at address: 0x%x" -msgstr "" +msgstr "No hay dispositivo en la dirección: 0x%x" #: supervisor/shared/web_workflow/web_workflow.c msgid "No IP" -msgstr "" +msgstr "No IP" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c @@ -1428,7 +1520,7 @@ msgstr "Sin pin MISO" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MISO pin" -msgstr "" +msgstr "No pin MISO" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c @@ -1437,7 +1529,7 @@ msgstr "Sin pin MOSI" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MOSI pin" -msgstr "" +msgstr "No pin MOSI" #: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c @@ -1459,7 +1551,7 @@ msgstr "Relojes no disponibles" #: ports/espressif/common-hal/imagecapture/ParallelImageCapture.c msgid "No capture in progress" -msgstr "" +msgstr "No hay captura en marcha" #: shared-bindings/_bleio/PacketBuffer.c msgid "No connection: length cannot be determined" @@ -1493,11 +1585,6 @@ msgstr "No se especificó ninguna llave" msgid "No long integer support" msgstr "No hay soporte de entero largo" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "No se permiten más de %d dispositivos HID permitidos" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "No hay una red con ese ssid" @@ -1523,7 +1610,7 @@ msgstr "No queda espacio en el dispositivo" #: py/moduerrno.c msgid "No such device" -msgstr "" +msgstr "No hay tal dispositivo" #: py/moduerrno.c msgid "No such file/directory" @@ -1533,10 +1620,6 @@ msgstr "No existe el archivo/directorio" msgid "No timer available" msgstr "No hay temporizador disponible" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "Falla en la aserción del firmware del dispositivo Nordic." - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "El firmware del sistema Nordic no tiene memoria" @@ -1556,14 +1639,10 @@ msgstr "No conectado" msgid "Not playing" msgstr "No reproduciendo" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "No configurable" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" -msgstr "" +msgstr "El numero de pines de datos debe ser 8 o 16, no %d" #: shared-bindings/util.c msgid "" @@ -1576,16 +1655,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "Paridad impar no soportada" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "Apagado" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "Ok" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Solo mono de 8 ó 16 bit con " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Solo hay capacidad para direcciones IPv4" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "Solo se admiten sockets IPv4" @@ -1619,18 +1708,23 @@ msgstr "" "más: %d bpp proporcionados" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." -msgstr "Solamente una TouchAlarm puede ser configurada durante deep sleep." +msgid "Only one %q can be set in deep sleep." +msgstr "Solamente un %q puede ser establecido en deep sleep." -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "Solamente un %q puede ser establecido." + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" -msgstr "" +msgstr "Solamente una dirección es permitida" #: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c #: ports/nrf/common-hal/alarm/time/TimeAlarm.c #: ports/stm/common-hal/alarm/time/TimeAlarm.c msgid "Only one alarm.time alarm can be set" -msgstr "" +msgstr "Solamente una alarma alarm.time puede ser establecida" #: ports/espressif/common-hal/alarm/time/TimeAlarm.c #: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c @@ -1643,21 +1737,26 @@ msgstr "Solo un color puede ser transparente a la vez" #: py/moduerrno.c msgid "Operation not permitted" -msgstr "" +msgstr "La operación no es permitida" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "Operación no característica no soportada" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "Tiempo de espera agotado" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "No hay slots MDNS de servicio" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "Memoria agotada" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Se acabaron los enchufes" @@ -1682,7 +1781,7 @@ msgstr "" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "PWM restart" -msgstr "" +msgstr "Reinicio de PWM" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "PWM slice already in use" @@ -1714,7 +1813,6 @@ msgid "Pin interrupt already in use" msgstr "Interrupción de Pin ya está en uso" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "El pin es solo de entrada" @@ -1743,7 +1841,7 @@ msgstr "Los pines deben estar en orden secuencial" #: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c msgid "Pins must be sequential GPIO pins" -msgstr "" +msgstr "Los pines deben ser pines GPIO secuenciales" #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Pins must share PWM slice" @@ -1769,7 +1867,7 @@ msgstr "" #: main.c msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" msgstr "" -"Pretendiendo ir a deep sleep hasta la alarma, CTRL-C or una escritura de " +"Pretendiendo ir a deep sleep hasta la alarma, CTRL-C o una escritura de " "archivo\n" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -1784,6 +1882,10 @@ msgstr "El programa hace OUT sin cargar OSR" msgid "Program size invalid" msgstr "El tamaño del programa no es correcto" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "El programa es demasiado grande" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull no se usa cuando la dirección es output." @@ -1795,7 +1897,7 @@ msgstr "El modo RAISE no esta implementado" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "RISE_AND_FALL not available on this chip" -msgstr "" +msgstr "RISE_AND_FALL no esta disponible para este chip" #: ports/stm/common-hal/os/__init__.c msgid "RNG DeInit Error" @@ -1808,7 +1910,7 @@ msgstr "Error de inicialización de RNG" #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nrf/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" -msgstr "" +msgstr "RS485" #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1823,8 +1925,9 @@ msgstr "RTC no soportado en esta placa" msgid "Random number generation error" msgstr "Error de generación de números aleatorios" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Solo-lectura" @@ -1832,14 +1935,14 @@ msgstr "Solo-lectura" msgid "Read-only filesystem" msgstr "Sistema de archivos de solo-Lectura" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "Objeto de solo-lectura" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "La respuesta recibida es invalida" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "Reconectando" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "Refresco demasiado pronto" @@ -1852,7 +1955,7 @@ msgstr "RemoteTransmissionRequests limitado a 8 bytes" msgid "Requested AES mode is unsupported" msgstr "El modo AES solicitado no es compatible" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "Recurso solicitado no encontrado" @@ -1871,7 +1974,7 @@ msgstr "Sin capacidad para formato CSD para tarjeta SD" #: ports/cxd56/common-hal/sdioio/SDCard.c msgid "SDCard init" -msgstr "" +msgstr "Inicialización SDCard" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format @@ -1889,7 +1992,7 @@ msgstr "Configuración de SPI fallida" #: ports/stm/common-hal/busio/SPI.c msgid "SPI init error" -msgstr "" +msgstr "Error de inicialización SPI" #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" @@ -1897,11 +2000,11 @@ msgstr "Periférico SPI en uso" #: ports/stm/common-hal/busio/SPI.c msgid "SPI re-init" -msgstr "" +msgstr "Re-inicialización SPI" #: shared-bindings/is31fl3741/FrameBuffer.c msgid "Scale dimensions must divide by 3" -msgstr "" +msgstr "Las dimensiones de escala debe ser divisibles por 3" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -1925,7 +2028,8 @@ msgstr "Sin capacidades para el tamaño" msgid "Sleep Memory not available" msgstr "Memoria de sueño no disponible" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice y value tienen tamaños diferentes." @@ -1937,6 +2041,7 @@ msgid "Slices not supported" msgstr "Rebanadas no soportadas" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool solo se puede usar con wifi.radio" @@ -1946,7 +2051,7 @@ msgstr "Los buffers de fuente y destino deben ser del mismo tamaño" #: shared-bindings/paralleldisplay/ParallelBus.c msgid "Specify exactly one of data0 or data_pins" -msgstr "" +msgstr "Especifique exactamente uno de data0 or data_pins" #: extmod/modure.c msgid "Splitting with sub-captures" @@ -1960,13 +2065,9 @@ msgstr "Estéreo izquierdo debe estar en el canal PWM A" msgid "Stereo right must be on PWM channel B" msgstr "Estéreo derecho debe estar en el canal PWM B" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "A Stream le falta el método readinto() o write()." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Suministre al menos un pin UART" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "Parar el AP no esta soportado." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -1981,35 +2082,22 @@ msgid "Temperature read timed out" msgstr "Lectura de temperatura expirada" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -"El montículo de CircuitPython está corrupto porque la pila era muy pequeña.\n" -"Aumente el tamaño de pila si sabe como. De lo contrario:" +"El modulo `microcontrolador` fue usado para inicializar en modo seguro." -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." -msgstr "" -"El módulo de `microcontroller` se usó para un arranque en modo seguro. " -"Presione reset para salir del modo seguro." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" +msgstr "La excepción fue la causa directa de la excepción siguiente:" #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "La longitud de rgb_pins debe ser 6, 12, 18, 24, o 30" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" -"La corriente eléctrica de la microcontroladora bajó. Asegúrate que tu fuente " -"de poder provee\n" -"suficiente corriente para todo el circuito y presiones reset (luego de " -"expulsar CIRCUITPY)." +"La potencia calló. Asegúrese que está suministrando suficiente energía." #: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" @@ -2027,15 +2115,21 @@ msgstr "El sample rate del sample no iguala al del mixer" msgid "The sample's signedness does not match the mixer's" msgstr "El signo del sample no iguala al del mixer" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "Error gráve del firmware de un tercero." + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." -msgstr "" +msgstr "Este microcontrolador no soporta captura continua." #: shared-module/paralleldisplay/ParallelBus.c msgid "" "This microcontroller only supports data0=, not data_pins=, because it " "requires contiguous pins." msgstr "" +"Este microcontrolador solamente soporta data0=, not data_pins=, porque " +"requiere pines adyacentes." #: shared-bindings/displayio/TileGrid.c msgid "Tile height must exactly divide bitmap height" @@ -2061,13 +2155,9 @@ msgstr "" "Tiempo de espera demasiado largo: El tiempo máximo de espera es de %d " "segundos" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "Para salir, por favor reinicia la tarjeta sin " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" -msgstr "" +msgstr "Demasiados canales en la muestra" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." @@ -2102,20 +2192,28 @@ msgstr "Argumento tuple o struct_time requerido" #: ports/stm/common-hal/busio/UART.c msgid "UART de-init" -msgstr "" +msgstr "Desinicialización de UART" #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "UART init" -msgstr "" +msgstr "Inicialización de UART" + +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "Periférico UART en uso" #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" -msgstr "" +msgstr "Re-inicialización de UART" #: ports/stm/common-hal/busio/UART.c msgid "UART write" -msgstr "" +msgstr "Escribiendo UART" + +#: main.c +msgid "UID:" +msgstr "UID:" #: shared-module/usb_hid/Device.c msgid "USB busy" @@ -2152,6 +2250,15 @@ msgstr "UUID valor no es un str, int o byte buffer" msgid "Unable to allocate buffers for signed conversion" msgstr "No se pudieron asignar buffers para la conversión con signo" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "Imposible de asignar el heap." + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "Imposible de configurar el controlador ADC DMA , código de error:%d" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "No se puede crear bloqueo" @@ -2170,13 +2277,29 @@ msgstr "No se pudo encontrar un GCLK libre" msgid "Unable to init parser" msgstr "Incapaz de inicializar el parser" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" +"No es posible de inicializar el controlador ADC DMA, código de error:%d" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "No se pudo leer los datos de la paleta de colores" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "Imposible de iniciar el controlador ADC DMA, código de error:%d" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" -msgstr "" +msgstr "Imposible de incializar una consulta mDNS" + +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "Imposible de escribir en esa dirección." #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." @@ -2198,12 +2321,12 @@ msgstr "Error no manejado de ESP TLS %d %d %x %d" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown BLE error at %s:%d: %d" -msgstr "" +msgstr "Error BLE desconocido en %s:%d: %d" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown BLE error: %d" -msgstr "" +msgstr "Error BLE desconocido: %d" #: shared-bindings/wifi/Radio.c #, c-format @@ -2228,7 +2351,7 @@ msgstr "Error de seguridad desconocido: 0x%04x" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error at %s:%d: %d" -msgstr "" +msgstr "Error del sistema firmware desconocido en %s:%d: %d" #: ports/nrf/common-hal/_bleio/__init__.c #, c-format @@ -2238,9 +2361,15 @@ msgstr "Error desconocido en el firmware sistema: %04x" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error: %d" -msgstr "" +msgstr "Error del sistema de firmware desconocido: %d" + +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "Codigo de error desconocido: %d" #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "Número incomparable de elementos en RHS (%d esperado,%d obtenido)." @@ -2255,7 +2384,7 @@ msgstr "" #: shared-bindings/bitmaptools/__init__.c msgid "Unsupported colorspace" -msgstr "" +msgstr "Espacio de color no sportado" #: shared-module/displayio/display_core.c msgid "Unsupported display bus type" @@ -2267,7 +2396,7 @@ msgstr "Formato no soportado" #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" -msgstr "" +msgstr "Algoritmo hash no soportado" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Update Failed" @@ -2287,7 +2416,7 @@ msgstr "Tamaño del valor != del tamaño fijo requerido" msgid "Value length > max_length" msgstr "Tamaño de valor > max_length" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "La versión era invalida" @@ -2316,10 +2445,6 @@ msgstr "" "WatchDogTimer.mode no se puede modificar luego de configurar WatchDogMode." "RESET" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "WatchDogTimer.timeout debe ser mayor a 0" - #: py/builtinhelp.c #, c-format msgid "" @@ -2329,10 +2454,27 @@ msgid "" "\n" "To list built-in modules type `help(\"modules\")`.\n" msgstr "" +"Bienvenido a Adafruit CircuitPython %s!\n" +"\n" +"Visite circuitpython.org para mayor informacion.\n" +"\n" +"Para conocer la lista de modules built-in escriba `help(\"modules\")`.\n" #: supervisor/shared/web_workflow/web_workflow.c msgid "Wi-Fi: " -msgstr "" +msgstr "Wi-Fi: " + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "Wifi est en modo de access point." + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "Wifi esta en modo station." + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "Wifi no esta activado" #: main.c msgid "Woken up by alarm.\n" @@ -2343,20 +2485,57 @@ msgstr "Despertado por la alarma.\n" msgid "Writes not supported on Characteristic" msgstr "Escrituras no admitidas en Characteristic" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" -msgstr "Estás en modo seguro por la razón:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "Usted presionó ambos botones al iniciar." + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." +msgstr "Usted presionó el botón A al iniciar." #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." -msgstr "" -"Has presionado el botón de reset durante el arranque. Presiones de nuevo " -"para salir del modo seguro." +msgid "You pressed the BOOT button at start up" +msgstr "Usted presionó el botón BOOT al iniciar" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "Presionaste el botón GPIO0 al inicio." + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "Presionó el botón Rec al inicio." + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "Presionó el botón SW38 al iniciar." + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "Usted presionó el botón de volumen al iniciar." + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "Usted presionó el botón central al iniciar." + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "Usted presionó el botón izquierdo al iniciar." #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "Solicitaste iniciar en modo seguro por " +msgid "You pressed the reset button during boot." +msgstr "Presionó el botón de reinicio durante el arranque." + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "[truncado debido a la longitud]" #: py/objtype.c msgid "__init__() should return None" @@ -2374,11 +2553,7 @@ msgstr "__new__ arg debe ser un user-type" msgid "a bytes-like object is required" msgstr "se requiere un objeto bytes-like" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "address fuera de límites" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "addresses esta vacío" @@ -2429,10 +2604,14 @@ msgstr "Longitud del array e índice tienen que ser iguales" #: extmod/ulab/code/numpy/io/io.c msgid "array has too many dimensions" -msgstr "" +msgstr "La matriz tiene demasiadas dimensiones" + +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "el arreglo es muy grande" #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "array/bytes requeridos en el lado derecho" @@ -2462,7 +2641,7 @@ msgstr "Eje demasiado largo" #: shared-bindings/bitmaptools/__init__.c msgid "background value out of range of target" -msgstr "" +msgstr "El valor del fondo esta fuera del rango del objectivo" #: py/builtinevex.c msgid "bad compile mode" @@ -2486,7 +2665,7 @@ msgstr "operacion binaria %q no implementada" #: shared-bindings/bitmaptools/__init__.c msgid "bitmap sizes must match" -msgstr "" +msgstr "Los tamaños de los bitmap deben coincidir" #: extmod/modurandom.c msgid "bits must be 32 or less" @@ -2525,10 +2704,6 @@ msgstr "buffer demasiado pequeño" msgid "buffer too small for requested bytes" msgstr "búfer muy pequeño para los bytes solicitados" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "byteorder no es una cadena" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "el tamaño en bytes no es un múltiplo del tamaño del item" @@ -2548,7 +2723,7 @@ msgstr "calibration es de solo lectura" #: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c #: shared-module/vectorio/Rectangle.c msgid "can only have one parent" -msgstr "" +msgstr "solamente puede tener un parent" #: py/emitinlinethumb.c msgid "can only have up to 4 parameters to Thumb assembly" @@ -2570,15 +2745,10 @@ msgstr "no se puede asignar a la expresión" msgid "can't cancel self" msgstr "no se puede cancelar a si mismo" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "no puede convertir %q a %q" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "no se puede convertir %q a int" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2590,7 +2760,7 @@ msgstr "no se puede convertir el objeto '%q' a %q implícitamente" #: extmod/ulab/code/numpy/vector.c msgid "can't convert complex to float" -msgstr "" +msgstr "no se puede convertir complejo a float" #: py/obj.c msgid "can't convert to %q" @@ -2646,7 +2816,7 @@ msgstr "no se puede cargar con el índice '%q'" #: py/builtinimport.c msgid "can't perform relative import" -msgstr "" +msgstr "no se puede realizar una importacion relativa" #: py/objgenerator.c msgid "can't send non-None value to a just-started generator" @@ -2657,10 +2827,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "no se puede definir un tamaño de bloque de 512" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "no se puede asignar el atributo" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "no se puede configurar el attributo '%q'" + #: py/emitnative.c msgid "can't store '%q'" msgstr "no se puede almacenar '%q'" @@ -2689,7 +2863,7 @@ msgstr "" #: extmod/ulab/code/ndarray.c msgid "cannot assign new shape" -msgstr "" +msgstr "no se puede asignar una nueva forma" #: extmod/ulab/code/ndarray_operators.c msgid "cannot cast output with casting rule" @@ -2697,11 +2871,11 @@ msgstr "No se puede realizar cast de la salida sin una regla de cast" #: extmod/ulab/code/ndarray.c msgid "cannot convert complex to dtype" -msgstr "" +msgstr "no se puede convertir complex a dtype" #: extmod/ulab/code/ndarray.c msgid "cannot convert complex type" -msgstr "" +msgstr "no se puede convertir tipo complejo" #: py/objtype.c msgid "cannot create '%q' instances" @@ -2725,7 +2899,7 @@ msgstr "convirtiendo tipo" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "channel re-init" -msgstr "" +msgstr "re-nicialización del canal" #: shared-bindings/_stage/Text.c msgid "chars buffer too small" @@ -2763,18 +2937,10 @@ msgstr "color buffer deberia ser un bytearray o array de tipo 'b' o 'B'" msgid "color must be between 0x000000 and 0xffffff" msgstr "color debe estar entre 0x000000 y 0xffffff" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "color deberia ser un int" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "comparación entre int y uint" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "división compleja por cero" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "valores complejos no soportados" @@ -2805,7 +2971,7 @@ msgstr "los argumentos para convolve no deben estar vacíos" #: extmod/ulab/code/numpy/io/io.c msgid "corrupted file" -msgstr "" +msgstr "Archivo corrompido" #: extmod/ulab/code/numpy/poly.c msgid "could not invert Vandermonde matrix" @@ -2859,10 +3025,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "el buffer de destino debe ser un array de tipo 'H' para bit_depth = 16" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "destination_length debe ser un int >= 0" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "la secuencia de actualizacion del dict tiene una longitud incorrecta" @@ -2883,18 +3045,17 @@ msgstr "las dimensiones no concuerdan" msgid "div/mod not implemented for uint" msgstr "div/mod no implementado para uint" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "divide por cero" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "división por cero" #: extmod/ulab/code/numpy/vector.c msgid "dtype must be float, or complex" -msgstr "" +msgstr "dtype debe ser float, o complex" #: py/objdeque.c msgid "empty" @@ -2902,7 +3063,7 @@ msgstr "vacío" #: extmod/ulab/code/numpy/io/io.c msgid "empty file" -msgstr "" +msgstr "archivo vacio" #: extmod/moduasyncio.c extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" @@ -2920,10 +3081,6 @@ msgstr "secuencia vacía" msgid "end of format while looking for conversion specifier" msgstr "el final del formato mientras se busca el especificador de conversión" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "end_x debe ser un int" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "epoch_time no esta soportado en esta tarjeta" @@ -2933,18 +3090,18 @@ msgstr "epoch_time no esta soportado en esta tarjeta" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" +"espcamera. La cámara requiere una configuración de PSRAM reservada. " +"Refiérase a la documentación para más instrucciones." + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "las excepciones deben derivar de BaseException" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "se espera '%q' pero se recibe '%q'" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "se espera '%q' o '%q' pero se recibe '%q'" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "se esperaba ':' después de un especificador de tipo format" @@ -2989,7 +3146,7 @@ msgstr "el archivo deberia ser una archivo abierto en modo byte" #: shared-bindings/traceback/__init__.c msgid "file write is not available" -msgstr "" +msgstr "la escritura del archivo no esta disponible" #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" @@ -3043,10 +3200,6 @@ msgstr "font debe ser 2048 bytes de largo" msgid "format requires a dict" msgstr "format requiere un dict" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "lleno" @@ -3074,7 +3227,7 @@ msgstr "Función solo definida para ndarrays" #: extmod/ulab/code/numpy/carray/carray.c msgid "function is implemented for ndarrays only" -msgstr "" +msgstr "la funcion esta implementada solamente para ndarrays" #: py/argcheck.c #, c-format @@ -3159,23 +3312,23 @@ msgstr "relleno (padding) incorrecto" msgid "index is out of bounds" msgstr "el índice está fuera de límites" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "el indice debe ser tuple o int" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "index fuera de rango" -#: py/obj.c -msgid "indices must be integers" -msgstr "indices deben ser enteros" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "los índices deben ser enteros, particiones o listas de booleanos" #: ports/espressif/common-hal/busio/I2C.c msgid "init I2C" -msgstr "" +msgstr "inicializacion I2C" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" @@ -3211,7 +3364,7 @@ msgstr "los datos de entrada deben ser iterables" #: extmod/ulab/code/numpy/vector.c msgid "input dtype must be float or complex" -msgstr "" +msgstr "dtype de entrada debe ser float o complex" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "input matrix is asymmetric" @@ -3224,11 +3377,11 @@ msgstr "la matriz de entrada es singular" #: extmod/ulab/code/numpy/create.c msgid "input must be 1- or 2-d" -msgstr "" +msgstr "entrada debe ser 1-d o 2-d" #: extmod/ulab/code/numpy/carray/carray.c msgid "input must be a 1D ndarray" -msgstr "" +msgstr "entrada debe ser un ndarray de 1D" #: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c msgid "input must be a dense ndarray" @@ -3240,7 +3393,7 @@ msgstr "Entrada tiene que ser un ndarray" #: extmod/ulab/code/numpy/carray/carray.c msgid "input must be an ndarray, or a scalar" -msgstr "" +msgstr "entrada debe ser una ndarray o un escalar" #: extmod/ulab/code/scipy/signal/signal.c msgid "input must be one-dimensional" @@ -3262,10 +3415,6 @@ msgstr "los vectores de entrada deben ser de igual tamaño" msgid "inputs are not iterable" msgstr "Entradas no son iterables" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "int() arg 2 debe ser >= 2 y <= 36" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "interp está definido para iterables 1D de igual tamaño" @@ -3282,7 +3431,11 @@ msgstr "arquitectura inválida" #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" -msgstr "" +msgstr "bits_per_pixel %d invalidos, deben ser, 1, 2, 4, 8, 16, 24, o 32" + +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "certificado inválido" #: shared-bindings/bitmaptools/__init__.c #, c-format @@ -3296,7 +3449,7 @@ msgstr "el element_size %d,no es valido, debe ser 1,2 ó 4" #: shared-bindings/traceback/__init__.c msgid "invalid exception" -msgstr "" +msgstr "excepcion invalida" #: extmod/modframebuf.c msgid "invalid format" @@ -3310,10 +3463,18 @@ msgstr "especificador de formato inválido" msgid "invalid hostname" msgstr "hostname inválido" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "llave inválida" + #: py/compile.c msgid "invalid micropython decorator" msgstr "decorador de micropython inválido" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "configuracion invalida" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "paso inválido" @@ -3335,10 +3496,6 @@ msgstr "sintaxis inválida para entero con base %d" msgid "invalid syntax for number" msgstr "sintaxis inválida para número" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 debe ser una clase" @@ -3398,21 +3555,19 @@ msgstr "variable local '%q' usada antes del tipo conocido" msgid "local variable referenced before assignment" msgstr "variable local referenciada antes de la asignación" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "long int no soportado en esta compilación" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "Loopback + modo silencioso no están soportados por periférico" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" -msgstr "" +msgstr "mDNS ya esta inicializado" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" -msgstr "" +msgstr "mDNS solo funciona con WIFI incorporado" #: py/parse.c msgid "malformed f-string" @@ -3439,7 +3594,7 @@ msgstr "max_length debe ser 0-%d cuando fixed_length es %s" #: extmod/ulab/code/ndarray.c msgid "maximum number of dimensions is " -msgstr "" +msgstr "el numero maximo de dimensiones es " #: py/runtime.c msgid "maximum recursion depth exceeded" @@ -3473,7 +3628,7 @@ msgstr "" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "mode must be complete, or reduced" -msgstr "" +msgstr "el modo debe ser completo o reducido" #: py/builtinimport.c msgid "module not found" @@ -3481,7 +3636,7 @@ msgstr "módulo no encontrado" #: ports/espressif/common-hal/wifi/Monitor.c msgid "monitor init failed" -msgstr "" +msgstr "fallo en el monitor de inicializacion" #: extmod/ulab/code/numpy/poly.c msgid "more degrees of freedom than data points" @@ -3540,6 +3695,10 @@ msgstr "potencia negativa sin float support" msgid "negative shift count" msgstr "cuenta de corrimientos negativo" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "indice anidado debe ser int" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "no hay tarjeta SD" @@ -3573,14 +3732,10 @@ msgstr "no hay pin de reinicio disponible" msgid "no response from SD card" msgstr "no hay respuesta de la tarjeta SD" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "no hay tal atributo" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "hay un no-Device en %q" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3627,7 +3782,7 @@ msgstr "no suficientes argumentos para format string" #: extmod/ulab/code/numpy/carray/carray_tools.c msgid "not implemented for complex dtype" -msgstr "" +msgstr "no esta implementado para complex dtype" #: extmod/ulab/code/numpy/create.c msgid "number of points must be at least 2" @@ -3689,7 +3844,7 @@ msgstr "string de longitud impar" #: supervisor/shared/web_workflow/web_workflow.c msgid "off" -msgstr "" +msgstr "apagado" #: extmod/ulab/code/utils/utils.c msgid "offset is too large" @@ -3708,15 +3863,30 @@ msgid "offset out of bounds" msgstr "offset fuera de límites" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "solo se admite bit_depth=16" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "solamente mono esta suportado" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "solamente ndarrays pueden ser concatenadas" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "solamente oversample=64 esta soportado" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "solo se admite sample_rate=16000" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "solo se admiten segmentos con step=1 (alias None)" @@ -3731,11 +3901,11 @@ msgstr "los operandos no se pueden transmitir juntos" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "operation is defined for 2D arrays only" -msgstr "" +msgstr "la operacion esta definida para matrices 2D solamente" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "operation is defined for ndarrays only" -msgstr "" +msgstr "la operacion esta definida para ndarrays solamente" #: extmod/ulab/code/ndarray.c msgid "operation is implemented for 1D Boolean arrays only" @@ -3787,10 +3957,6 @@ msgstr "pack espera %d items para empaquetado (se recibió %d)" msgid "palette must be 32 bytes long" msgstr "palette debe ser 32 bytes de largo" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_index deberia ser un int" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "los parámetros deben ser registros en secuencia de a2 a a5" @@ -3813,7 +3979,7 @@ msgstr "pixel_shader debe ser displayio.Palette o displayio.ColorConverter" #: extmod/vfs_posix_file.c msgid "poll on file not available on win32" -msgstr "" +msgstr "el sondeo del archivo no esta disponible en win32" #: ports/espressif/common-hal/pulseio/PulseIn.c msgid "pop from an empty PulseIn" @@ -3840,28 +4006,6 @@ msgstr "el 3er argumento de pow() no puede ser 0" msgid "pow() with 3 arguments requires integers" msgstr "pow() con 3 argumentos requiere enteros" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "presionando botón de arranque al inicio.\n" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "presionando ambos botones al inicio.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "presione el botón izquierdo al arranque\n" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "máscara de pull en conflicto con máscara de dirección" @@ -3872,7 +4016,7 @@ msgstr "desbordamiento de cola(queue)" #: py/parse.c msgid "raw f-strings are not supported" -msgstr "" +msgstr "raw f-strings no esta soportadas" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "real and imaginary parts must be of equal length" @@ -3882,11 +4026,6 @@ msgstr "las partes reales e imaginarias deben ser de igual longitud" msgid "relative import" msgstr "import relativo" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "longitud solicitada %d pero el objeto tiene longitud %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "resultados no pueden aplicar cast a un tipo específico" @@ -3917,14 +4056,6 @@ msgstr "Argumento enrolado tiene que ser un ndarray" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"sample_source buffer debe ser un bytearray o un array de tipo 'h', 'H', 'b' " -"o'B'" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3958,10 +4089,6 @@ msgstr "signo no permitido en el espeficador de string format" msgid "sign not allowed with integer format specifier 'c'" msgstr "signo no permitido con el especificador integer format 'c'" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "un solo '}' encontrado en format string" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "el tamaño se define solo para ndarrays" @@ -3974,10 +4101,6 @@ msgstr "la longitud de sleep no puede ser negativa" msgid "slice step can't be zero" msgstr "el tamaño de la división no puede ser cero" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "slice step no puede ser cero" - #: py/nativeglue.c msgid "slice unsupported" msgstr "sin capacidades para rebanado" @@ -4012,28 +4135,20 @@ msgstr "paleta fuente muy larga" #: shared-bindings/bitmaptools/__init__.c msgid "source_bitmap must have value_count of 2 or 65536" -msgstr "" +msgstr "source_bitmap debe tener value_count de 2 o 65536" #: shared-bindings/bitmaptools/__init__.c msgid "source_bitmap must have value_count of 65536" -msgstr "" +msgstr "source_bitmap debe tener value_count de 65536" #: shared-bindings/bitmaptools/__init__.c msgid "source_bitmap must have value_count of 8" -msgstr "" +msgstr "source_bitmap debe tener value_count de 8" #: py/objstr.c msgid "start/end indices" msgstr "índices inicio/final" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "start_x deberia ser un int" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "paso debe ser numero no cero" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "stop no se puede alcanzar del principio" @@ -4042,10 +4157,6 @@ msgstr "stop no se puede alcanzar del principio" msgid "stream operation not supported" msgstr "operación stream no soportada" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "índices de cadena deben ser enteros, no %q" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "string no soportado; usa bytes o bytearray" @@ -4078,14 +4189,6 @@ msgstr "error de sintaxis en JSON" msgid "syntax error in uctypes descriptor" msgstr "error de sintaxis en el descriptor uctypes" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "limite debe ser en el rango 0-65536" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time() toma un sequencio 9" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4094,10 +4197,6 @@ msgid "timeout duration exceeded the maximum supported value" msgstr "" "la duración de tiempo de espera ha excedido la capacidad máxima del valor" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "el tiempo de espera debe ser 0.0-100.0 segundos" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "timeout debe ser < 655.35 segundos" @@ -4112,7 +4211,7 @@ msgstr "tiempo de espera agotado esperando a tarjeta v2" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "timer re-init" -msgstr "" +msgstr "temporizador re-inicializado" #: shared-bindings/time/__init__.c msgid "timestamp out of range for platform time_t" @@ -4151,10 +4250,6 @@ msgstr "trapz está definido para arreglos 1D de igual tamaño" msgid "trapz is defined for 1D iterables" msgstr "trapz está definido para iterables 1D" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "tupla/lista tiene una longitud incorrecta" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4165,8 +4260,6 @@ msgstr "twai_driver_install devolvió esp-idf error #%d" msgid "twai_start returned esp-idf error #%d" msgstr "twai_start devolvió esp-idf error #%d" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "Ambos tx y rx no pueden ser None" @@ -4179,14 +4272,10 @@ msgstr "type '%q' no es un tipo de base aceptable" msgid "type is not an acceptable base type" msgstr "type no es un tipo de base aceptable" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "objeto de tipo '%q' no tiene atributo '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "objeto tipo 'generator' no tiene un atributo '__await__'" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "type acepta 1 ó 3 argumentos" @@ -4207,7 +4296,7 @@ msgstr "sangría inesperada" msgid "unexpected keyword argument" msgstr "argumento por palabra clave inesperado" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "argumento por palabra clave inesperado '%q'" @@ -4217,7 +4306,7 @@ msgstr "nombre en unicode escapa" #: py/parse.c msgid "unindent doesn't match any outer indent level" -msgstr "" +msgstr "unindent no coteja ningún nivel de espacio exterior" #: py/objstr.c #, c-format @@ -4237,15 +4326,15 @@ msgid "unknown type '%q'" msgstr "tipo desconocido '%q'" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "No coinciden '{' en format" +#, c-format +msgid "unmatched '%c' in format" +msgstr "no coteja '%c' en formato" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "atributo no legible" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo de %q no soportado" @@ -4261,11 +4350,11 @@ msgstr "instrucción Xtensa '%s' con %d argumentos no soportada" #: shared-module/gifio/GifWriter.c msgid "unsupported colorspace for GifWriter" -msgstr "" +msgstr "espacio de color no soportado para GifWriter" #: shared-bindings/bitmaptools/__init__.c msgid "unsupported colorspace for dither" -msgstr "" +msgstr "espacio de color no soportado para tramado" #: py/objstr.c #, c-format @@ -4286,11 +4375,11 @@ msgstr "tipos no soportados para %q: '%q', '%q'" #: extmod/ulab/code/numpy/io/io.c msgid "usecols is too high" -msgstr "" +msgstr "usecols es muy alto" #: extmod/ulab/code/numpy/io/io.c msgid "usecols keyword must be specified" -msgstr "" +msgstr "usecols palabra clave debe de ser especificada" #: py/objint.c #, c-format @@ -4299,7 +4388,7 @@ msgstr "el valor debe caber en %d byte(s)" #: shared-bindings/bitmaptools/__init__.c msgid "value out of range of target" -msgstr "" +msgstr "valor fuera de alcance al blanco" #: shared-bindings/displayio/Bitmap.c msgid "value_count must be > 0" @@ -4309,18 +4398,19 @@ msgstr "value_count debe ser > 0" msgid "watchdog not initialized" msgstr "watchdog no inicializado" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "el tiempo de espera del perro guardián debe ser mayor a 0" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "el ancho debe ser mayor que cero" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "wifi no esta habilitado" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "wifi.Monitor no esta disponible" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "la ventana debe ser <= intervalo" @@ -4335,7 +4425,7 @@ msgstr "eje especificado erróneo" #: extmod/ulab/code/numpy/io/io.c msgid "wrong dtype" -msgstr "" +msgstr "erroneo dtype" #: extmod/ulab/code/numpy/transform.c msgid "wrong index type" @@ -4349,11 +4439,11 @@ msgstr "tipo de entrada incorrecta" #: extmod/ulab/code/numpy/transform.c msgid "wrong length of condition array" -msgstr "" +msgstr "largo erroneo en el arreglo de condiciones" #: extmod/ulab/code/numpy/transform.c msgid "wrong length of index array" -msgstr "" +msgstr "largo erroneo en el arreglo de índices" #: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c msgid "wrong number of arguments" @@ -4375,18 +4465,10 @@ msgstr "valor x fuera de límites" msgid "xTaskCreate failed" msgstr "fallo en xTaskCreate" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y deberia ser un int" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "valor y fuera de límites" -#: py/objrange.c -msgid "zero step" -msgstr "paso cero" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "zi debe ser un ndarray" @@ -4399,6 +4481,281 @@ msgstr "zi debe ser de tipo flotante" msgid "zi must be of shape (n_section, 2)" msgstr "zi debe ser una forma (n_section,2)" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Suministre al menos un pin UART" + +#~ msgid "%q pin invalid" +#~ msgstr "pin inválido %q" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Presente un problema con el contenido de su unidad CIRCUITPY en\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "Asignación del montículo mientras la VM no esta ejecutándose." + +#~ msgid "Boot device must be first device (interface #0)." +#~ msgstr "" +#~ "El dispositivo de arranque debe de ser el primer dispositivo (interfase " +#~ "#0)." + +#~ msgid "Both buttons were pressed at start up.\n" +#~ msgstr "Ambos botones fueron prensados al inicio\n" + +#~ msgid "Button A was pressed at start up.\n" +#~ msgstr "Botón A fue presionado al inicio.\n" + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPython no puedo encontrar el montículo." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Choque contra el HardFault_Handler." + +#~ msgid "Fatal error." +#~ msgstr "Error grave." + +#~ msgid "Invalid memory access." +#~ msgstr "Acceso a memoria no válido." + +#~ msgid "Nordic system firmware failure assertion." +#~ msgstr "Falla en la aserción del firmware del dispositivo Nordic." + +#~ msgid "The BOOT button was pressed at start up.\n" +#~ msgstr "El boton BOOT fur presionado durante el arranque.\n" + +#~ msgid "" +#~ "The CircuitPython heap was corrupted because the stack was too small.\n" +#~ "Increase the stack size if you know how. If not:" +#~ msgstr "" +#~ "El montículo de CircuitPython está corrupto porque la pila era muy " +#~ "pequeña.\n" +#~ "Aumente el tamaño de pila si sabe como. De lo contrario:" + +#~ msgid "The SW38 button was pressed at start up.\n" +#~ msgstr "El boton SW38 fue presionado durante el arranque.\n" + +#~ msgid "The VOLUME button was pressed at start up.\n" +#~ msgstr "El boton de Volumen fue presionado durante el arranque.\n" + +#~ msgid "" +#~ "The `microcontroller` module was used to boot into safe mode. Press reset " +#~ "to exit safe mode." +#~ msgstr "" +#~ "El módulo de `microcontroller` se usó para un arranque en modo seguro. " +#~ "Presione reset para salir del modo seguro." + +#~ msgid "The central button was pressed at start up.\n" +#~ msgstr "El boton central fue presionado durante el arranque.\n" + +#~ msgid "The left button was pressed at start up.\n" +#~ msgstr "El boton izquierdo fue presionado durante el arranque.\n" + +#~ msgid "" +#~ "The microcontroller's power dipped. Make sure your power supply provides\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY)." +#~ msgstr "" +#~ "La corriente eléctrica de la microcontroladora bajó. Asegúrate que tu " +#~ "fuente de poder provee\n" +#~ "suficiente corriente para todo el circuito y presiones reset (luego de " +#~ "expulsar CIRCUITPY)." + +#~ msgid "To exit, please reset the board without requesting safe mode." +#~ msgstr "Para salir, por favor reinicialice la tarjeta sin pedir safe mode." + +#~ msgid "You are in safe mode because:\n" +#~ msgstr "Estás en modo seguro por la razón:\n" + +#~ msgid "" +#~ "You pressed the reset button during boot. Press again to exit safe mode." +#~ msgstr "" +#~ "Has presionado el botón de reset durante el arranque. Presiones de nuevo " +#~ "para salir del modo seguro." + +#~ msgid "" +#~ "esp32_camera.Camera requires reserved PSRAM to be configured. See the " +#~ "documentation for instructions." +#~ msgstr "" +#~ "esp32_camera. la camara necesita PSRAM reservada para ser configurada. " +#~ "Vea la documentacion para mas instrucciones." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q debe ser de typo %q" + +#~ msgid "%q must be of type %q or None" +#~ msgstr "%q debe ser de tipo %q o None" + +#~ msgid "Expected a %q" +#~ msgstr "Se espera un %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV debe tener %d bytes de longitud" + +#~ msgid "Not settable" +#~ msgstr "No configurable" + +#~ msgid "expected '%q' but got '%q'" +#~ msgstr "se espera '%q' pero se recibe '%q'" + +#~ msgid "expected '%q' or '%q' but got '%q'" +#~ msgstr "se espera '%q' o '%q' pero se recibe '%q'" + +#~ msgid "Read-only object" +#~ msgstr "Objeto de solo-lectura" + +#~ msgid "%q length must be >= 1" +#~ msgstr "%q tamaño debe ser >= 1" + +#~ msgid "%q must be a string" +#~ msgstr "%q debe ser una cadena" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Como máximo %d %q se puede especificar (no %d)" + +#~ msgid "Invalid pins" +#~ msgstr "pines inválidos" + +#, c-format +#~ msgid "No more than %d HID devices allowed" +#~ msgstr "No se permiten más de %d dispositivos HID permitidos" + +#~ msgid "byteorder is not a string" +#~ msgstr "byteorder no es una cadena" + +#~ msgid "can't convert %q to int" +#~ msgstr "no se puede convertir %q a int" + +#~ msgid "complex division by zero" +#~ msgstr "división compleja por cero" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "int() arg 2 debe ser >= 2 y <= 36" + +#~ msgid "long int not supported in this build" +#~ msgstr "long int no soportado en esta compilación" + +#~ msgid "slice step cannot be zero" +#~ msgstr "slice step no puede ser cero" + +#~ msgid "step must be non-zero" +#~ msgstr "paso debe ser numero no cero" + +#~ msgid "string indices must be integers, not %q" +#~ msgstr "índices de cadena deben ser enteros, no %q" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time() toma un sequencio 9" + +#~ msgid "zero step" +#~ msgstr "paso cero" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "%q indices deben ser enteros, no %s" + +#~ msgid "WatchDogTimer.timeout must be greater than 0" +#~ msgstr "WatchDogTimer.timeout debe ser mayor a 0" + +#~ msgid "indices must be integers" +#~ msgstr "indices deben ser enteros" + +#~ msgid "non-Device in %q" +#~ msgstr "hay un no-Device en %q" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "longitud solicitada %d pero el objeto tiene longitud %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "un solo '}' encontrado en format string" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "limite debe ser en el rango 0-65536" + +#~ msgid "timeout must be 0.0-100.0 seconds" +#~ msgstr "el tiempo de espera debe ser 0.0-100.0 segundos" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "tupla/lista tiene una longitud incorrecta" + +#~ msgid "unmatched '{' in format" +#~ msgstr "No coinciden '{' en format" + +#~ msgid "watchdog timeout must be greater than 0" +#~ msgstr "el tiempo de espera del perro guardián debe ser mayor a 0" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "Para salir, por favor reinicia la tarjeta sin " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "Solicitaste iniciar en modo seguro por " + +#~ msgid "pressing boot button at start up.\n" +#~ msgstr "presionando botón de arranque al inicio.\n" + +#~ msgid "pressing both buttons at start up.\n" +#~ msgstr "presionando ambos botones al inicio.\n" + +#~ msgid "pressing the left button at start up\n" +#~ msgstr "presione el botón izquierdo al arranque\n" + +#~ msgid "Only one TouchAlarm can be set in deep sleep." +#~ msgstr "Solamente una TouchAlarm puede ser configurada durante deep sleep." + +#~ msgid "Firmware image is invalid" +#~ msgstr "La imagen de firmware es inválida" + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "A Stream le falta el método readinto() o write()." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q debe ser >= 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q debe ser >= 1" + +#~ msgid "address out of bounds" +#~ msgstr "address fuera de límites" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "destination_length debe ser un int >= 0" + +#~ msgid "type object 'generator' has no attribute '__await__'" +#~ msgstr "objeto tipo 'generator' no tiene un atributo '__await__'" + +#~ msgid "color should be an int" +#~ msgstr "color deberia ser un int" + +#~ msgid "end_x should be an int" +#~ msgstr "end_x debe ser un int" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_index deberia ser un int" + +#~ msgid "start_x should be an int" +#~ msgstr "start_x deberia ser un int" + +#~ msgid "y should be an int" +#~ msgstr "y deberia ser un int" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "sample_source buffer debe ser un bytearray o un array de tipo 'h', 'H', " +#~ "'b' o'B'" + +#~ msgid "Expected an alarm" +#~ msgstr "Un objecto alarm era esperado" + +#~ msgid "Failed to init wifi" +#~ msgstr "Fallo al inicializar wifi" + #~ msgid "input must be a tensor of rank 2" #~ msgstr "Entrada tiene que ser un tensor de rango 2" @@ -5048,12 +5405,6 @@ msgstr "zi debe ser una forma (n_section,2)" #~ msgid "can only save bytecode" #~ msgstr "solo puede almacenar bytecode" -#~ msgid "invalid cert" -#~ msgstr "certificado inválido" - -#~ msgid "invalid key" -#~ msgstr "llave inválida" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "funciones Viper no soportan por el momento, más de 4 argumentos" diff --git a/locale/fil.po b/locale/fil.po index 4cf9806fa3..02b8fda384 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -6,8 +6,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-08-23 14:19+0000\n" -"Last-Translator: Jeff Epler \n" +"PO-Revision-Date: 2022-12-27 18:02+0000\n" +"Last-Translator: Blinka CircuitPython \n" "Language-Team: fil\n" "Language: fil\n" "MIME-Version: 1.0\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1 && n != 2 && n != 3 && (n % 10 == 4 " "|| n % 10 == 6 || n % 10 == 9);\n" -"X-Generator: Weblate 4.8.1-dev\n" +"X-Generator: Weblate 4.15.1-dev\n" #: main.c msgid "" @@ -29,11 +29,31 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" #: py/obj.c @@ -61,19 +81,32 @@ msgstr " output:\n" msgid "%%c requires int or char" msgstr "%%c nangangailangan ng int o char" +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "%S" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -93,23 +126,34 @@ msgstr "" msgid "%q failure: %d" msgstr "" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q ay ginagamit" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "%q indeks wala sa sakop" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q indeks ay dapat integers, hindi %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "" @@ -125,10 +169,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -149,29 +189,25 @@ msgstr "" msgid "%q must be >= %d" msgstr "" -#: py/argcheck.c -msgid "%q must be >= 0" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -#, fuzzy -msgid "%q must be >= 1" -msgstr "aarehas na haba dapat ang buffer slices" - -#: py/argcheck.c -msgid "%q must be a string" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be an int" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" msgstr "" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -191,12 +227,8 @@ msgstr "" msgid "%q out of range" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c @@ -208,11 +240,11 @@ msgstr "" msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -275,7 +307,7 @@ msgstr "Inaasahan ng '%s' ang hangang r%d" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects {r0, r1, ...}" -msgstr "Inaasahan ng '%s' ay {r0, r1, …}" +msgstr "Inaasahan ng '%s' ay {r0, r1, ...}" #: py/emitinlinextensa.c #, c-format @@ -397,12 +429,16 @@ msgstr "" msgid "Address must be %d bytes long" msgstr "ang palette ay dapat 32 bytes ang haba" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Lahat ng I2C peripherals ginagamit" @@ -424,7 +460,6 @@ msgid "All SPI peripherals are in use" msgstr "Lahat ng SPI peripherals ay ginagamit" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c #, fuzzy msgid "All UART peripherals are in use" msgstr "Lahat ng I2C peripherals ginagamit" @@ -478,15 +513,22 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "" @@ -500,23 +542,16 @@ msgstr "Isa pang send ay aktibo na" msgid "Array must contain halfwords (type 'H')" msgstr "May halfwords (type 'H') dapat ang array" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Array values ay dapat single bytes." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "" @@ -567,7 +602,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -652,7 +687,7 @@ msgstr "" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "" @@ -771,10 +806,6 @@ msgstr "" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "" - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Masyadong mahaba ang Clock stretch" @@ -789,6 +820,14 @@ msgid "" "connection." msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "" @@ -813,10 +852,6 @@ msgstr "" msgid "Couldn't allocate decoder" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "" - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "" @@ -874,10 +909,18 @@ msgstr "" msgid "Display rotation must be in 90 degree increments" msgstr "" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "Drive mode ay hindi ginagamit kapag ang direksyon ay input." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "" @@ -903,19 +946,16 @@ msgstr "" msgid "Error in regex" msgstr "May pagkakamali sa REGEX" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Umasa ng %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -969,10 +1009,6 @@ msgstr "" msgid "Failed to connect: timeout" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "" @@ -987,13 +1023,17 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "Mayroong file" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1001,7 +1041,15 @@ msgid "Filters too complex" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" #: shared-bindings/bitmaptools/__init__.c @@ -1034,13 +1082,15 @@ msgstr "Function nangangailangan ng lock" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -1061,6 +1111,15 @@ msgstr "" msgid "Hardware in use, try alternative pins" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "I/O operasyon sa saradong file" @@ -1070,6 +1129,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "" @@ -1077,11 +1137,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1168,6 +1223,7 @@ msgid "Internal define error" msgstr "" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1180,10 +1236,16 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Mali ang %q pin" @@ -1205,7 +1267,7 @@ msgstr "" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Maling argumento" @@ -1214,6 +1276,11 @@ msgstr "Maling argumento" msgid "Invalid bits per value" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1223,34 +1290,35 @@ msgstr "" msgid "Invalid format chunk size" msgstr "Mali ang format ng chunk size" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "" - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Mali ang pins" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1267,7 +1335,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -1357,6 +1425,10 @@ msgstr "" msgid "NVS Error" msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "" @@ -1471,11 +1543,6 @@ msgstr "" msgid "No long integer support" msgstr "" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "" @@ -1511,10 +1578,6 @@ msgstr "Walang file/directory" msgid "No timer available" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1535,10 +1598,6 @@ msgstr "Hindi maka connect sa AP" msgid "Not playing" msgstr "Hindi playing" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1555,16 +1614,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "Odd na parity ay hindi supportado" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Tanging 8 o 16 na bit mono na may " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "" @@ -1594,10 +1663,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1620,19 +1694,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1688,7 +1767,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "" @@ -1752,6 +1830,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull hindi ginagamit kapag ang direksyon ay output." @@ -1791,8 +1873,9 @@ msgstr "Hindi supportado ang RTC sa board na ito" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Basahin-lamang" @@ -1800,15 +1883,14 @@ msgstr "Basahin-lamang" msgid "Read-only filesystem" msgstr "Basahin-lamang mode" -#: shared-module/displayio/Bitmap.c -#, fuzzy -msgid "Read-only object" -msgstr "Basahin-lamang" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "" @@ -1821,7 +1903,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1893,7 +1975,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice at value iba't ibang haba." @@ -1905,6 +1988,7 @@ msgid "Slices not supported" msgstr "Hindi suportado ang Slices" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1928,12 +2012,8 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Stream kulang ng readinto() o write() method." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c @@ -1949,15 +2029,11 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1965,10 +2041,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1987,6 +2060,10 @@ msgstr "Ang sample rate ng sample ay hindi tugma sa mixer" msgid "The sample's signedness does not match the mixer's" msgstr "Ang signedness ng sample hindi tugma sa mixer" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2019,10 +2096,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "Para lumabas, paki-reset ang board na wala ang " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2067,6 +2140,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2075,6 +2152,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2110,6 +2191,15 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "Hindi ma-allocate ang buffers para sa naka-sign na conversion" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2128,14 +2218,29 @@ msgstr "Hindi mahanap ang libreng GCLK" msgid "Unable to init parser" msgstr "Hindi ma-init ang parser" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Hindi ma i-sulat sa NVM." @@ -2199,7 +2304,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2245,7 +2356,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2271,10 +2382,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -2289,6 +2396,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2298,18 +2417,57 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "Ikaw ang humiling sa safe mode sa pamamagitan ng " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "" #: py/objtype.c msgid "__init__() should return None" @@ -2327,11 +2485,7 @@ msgstr "__new__ arg ay dapat na user-type" msgid "a bytes-like object is required" msgstr "a bytes-like object ay kailangan" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "wala sa sakop ang address" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "walang laman ang address" @@ -2384,8 +2538,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "array/bytes kinakailangan sa kanang bahagi" @@ -2479,10 +2637,6 @@ msgstr "masyadong maliit ang buffer" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2525,15 +2679,10 @@ msgstr "hindi ma i-assign sa expression" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2612,10 +2761,14 @@ msgstr "hindi mapadala ang non-None value sa isang kaka umpisang generator" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "hindi ma i-set ang attribute" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "hindi ma i-store ang '%q'" @@ -2712,24 +2865,16 @@ msgstr "" #: shared-bindings/displayio/Palette.c msgid "color buffer must be a bytearray or array of type 'b' or 'B'" -msgstr "ang color buffer ay dapat bytearray o array na type ‘b’ or ‘B’" +msgstr "ang color buffer ay dapat bytearray o array na type 'b' or 'B'" #: shared-bindings/displayio/Palette.c msgid "color must be between 0x000000 and 0xffffff" msgstr "color ay dapat mula sa 0x000000 hangang 0xffffff" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "color ay dapat na int" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "kumplikadong dibisyon sa pamamagitan ng zero" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "kumplikadong values hindi sinusuportahan" @@ -2816,10 +2961,6 @@ msgstr "" "ang destination buffer ay dapat na isang array ng uri 'H' para sa bit_depth " "= 16" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "ang destination_length ay dapat na isang int >= 0" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "may mali sa haba ng dict update sequence" @@ -2840,12 +2981,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "dibisyon ng zero" @@ -2877,11 +3017,6 @@ msgstr "walang laman ang sequence" msgid "end of format while looking for conversion specifier" msgstr "sa huli ng format habang naghahanap sa conversion specifier" -#: shared-bindings/displayio/Shape.c -#, fuzzy -msgid "end_x should be an int" -msgstr "y ay dapat int" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2891,18 +3026,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "ang mga exceptions ay dapat makuha mula sa BaseException" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "umaasa ng ':' pagkatapos ng format specifier" @@ -3001,10 +3134,6 @@ msgstr "font ay dapat 2048 bytes ang haba" msgid "format requires a dict" msgstr "kailangan ng format ng dict" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "puno" @@ -3118,16 +3247,16 @@ msgstr "mali ang padding" msgid "index is out of bounds" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "index wala sa sakop" -#: py/obj.c -msgid "indices must be integers" -msgstr "ang mga indeks ay dapat na integer" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "" @@ -3221,10 +3350,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "int() arg 2 ay dapat >=2 at <= 36" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3243,6 +3368,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "mali ang cert" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3269,10 +3398,18 @@ msgstr "mali ang format specifier" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "mali ang key" + #: py/compile.c msgid "invalid micropython decorator" msgstr "mali ang micropython decorator" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "mali ang step" @@ -3294,10 +3431,6 @@ msgstr "maling sintaks sa integer na may base %d" msgid "invalid syntax for number" msgstr "maling sintaks sa number" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 ay dapat na class" @@ -3358,19 +3491,17 @@ msgstr "local '%q' ginamit bago alam ang type" msgid "local variable referenced before assignment" msgstr "local variable na reference bago na i-assign" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "long int hindi sinusuportahan sa build na ito" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3499,6 +3630,10 @@ msgstr "negatibong power na walang float support" msgid "negative shift count" msgstr "negative shift count" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3532,14 +3667,10 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "walang ganoon na attribute" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3665,15 +3796,30 @@ msgid "offset out of bounds" msgstr "wala sa sakop ang address" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "ang mga slices lamang na may hakbang = 1 (aka None) ang sinusuportahan" @@ -3744,10 +3890,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "ang palette ay dapat 32 bytes ang haba" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_index ay dapat na int" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "ang mga parameter ay dapat na nagrerehistro sa sequence a2 hanggang a5" @@ -3798,28 +3940,6 @@ msgstr "pow() 3rd argument ay hindi maaring 0" msgid "pow() with 3 arguments requires integers" msgstr "pow() na may 3 argumento kailangan ng integers" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3840,11 +3960,6 @@ msgstr "" msgid "relative import" msgstr "relative import" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "hiniling ang haba %d ngunit may haba ang object na %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3855,7 +3970,7 @@ msgstr "return annotation ay dapat na identifier" #: py/emitnative.c msgid "return expected '%q' but got '%q'" -msgstr "return umasa ng '%q' pero ang nakuha ay ‘%q’" +msgstr "return umasa ng '%q' pero ang nakuha ay '%q'" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format @@ -3875,14 +3990,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"ang sample_source buffer ay dapat na isang bytearray o array ng uri na 'h', " -"'H', 'b' o'B'" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3916,10 +4023,6 @@ msgstr "sign hindi maaring string format specifier" msgid "sign not allowed with integer format specifier 'c'" msgstr "sign hindi maari sa integer format specifier 'c'" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "isang '}' nasalubong sa format string" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3932,10 +4035,6 @@ msgstr "sleep length ay dapat hindi negatibo" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "slice step ay hindi puedeng 0" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3984,15 +4083,6 @@ msgstr "" msgid "start/end indices" msgstr "start/end indeks" -#: shared-bindings/displayio/Shape.c -#, fuzzy -msgid "start_x should be an int" -msgstr "y ay dapat int" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "step ay dapat hindi zero" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "stop hindi maabot sa simula" @@ -4001,10 +4091,6 @@ msgstr "stop hindi maabot sa simula" msgid "stream operation not supported" msgstr "stream operation hindi sinusuportahan" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "string hindi supportado; gumamit ng bytes o kaya bytearray" @@ -4037,14 +4123,6 @@ msgstr "sintaks error sa JSON" msgid "syntax error in uctypes descriptor" msgstr "may pagkakamali sa sintaks sa uctypes descriptor" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "ang threshold ay dapat sa range 0-65536" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time() kumukuha ng 9-sequence" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4052,10 +4130,6 @@ msgstr "time.struct_time() kumukuha ng 9-sequence" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4109,10 +4183,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "mali ang haba ng tuple/list" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4123,8 +4193,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx at rx hindi pwedeng parehas na None" @@ -4137,14 +4205,10 @@ msgstr "hindi maari ang type na '%q' para sa base type" msgid "type is not an acceptable base type" msgstr "hindi puede ang type para sa base type" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "type object '%q' ay walang attribute '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "type kumuhuha ng 1 o 3 arguments" @@ -4165,7 +4229,7 @@ msgstr "hindi inaasahang indent" msgid "unexpected keyword argument" msgstr "hindi inaasahang argumento ng keyword" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "hindi inaasahang argumento ng keyword na '%q'" @@ -4195,15 +4259,15 @@ msgid "unknown type '%q'" msgstr "hindi malaman ang type '%q'" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "hindi tugma ang '{' sa format" +#, c-format +msgid "unmatched '%c' in format" +msgstr "" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "hindi mabasa ang attribute" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "Hindi supportadong tipo ng %q" @@ -4267,18 +4331,19 @@ msgstr "" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" @@ -4334,19 +4399,11 @@ msgstr "wala sa sakop ang address" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y ay dapat int" - #: shared-module/displayio/Shape.c #, fuzzy msgid "y value out of bounds" msgstr "wala sa sakop ang address" -#: py/objrange.c -msgid "zero step" -msgstr "zero step" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "" @@ -4359,6 +4416,102 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Expected a %q" +#~ msgstr "Umasa ng %q" + +#, fuzzy +#~ msgid "Read-only object" +#~ msgstr "Basahin-lamang" + +#~ msgid "Invalid pins" +#~ msgstr "Mali ang pins" + +#~ msgid "complex division by zero" +#~ msgstr "kumplikadong dibisyon sa pamamagitan ng zero" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "int() arg 2 ay dapat >=2 at <= 36" + +#~ msgid "long int not supported in this build" +#~ msgstr "long int hindi sinusuportahan sa build na ito" + +#~ msgid "slice step cannot be zero" +#~ msgstr "slice step ay hindi puedeng 0" + +#~ msgid "step must be non-zero" +#~ msgstr "step ay dapat hindi zero" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time() kumukuha ng 9-sequence" + +#~ msgid "zero step" +#~ msgstr "zero step" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "%q indeks ay dapat integers, hindi %s" + +#~ msgid "indices must be integers" +#~ msgstr "ang mga indeks ay dapat na integer" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "hiniling ang haba %d ngunit may haba ang object na %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "isang '}' nasalubong sa format string" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "ang threshold ay dapat sa range 0-65536" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "mali ang haba ng tuple/list" + +#~ msgid "unmatched '{' in format" +#~ msgstr "hindi tugma ang '{' sa format" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "Para lumabas, paki-reset ang board na wala ang " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "Ikaw ang humiling sa safe mode sa pamamagitan ng " + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Stream kulang ng readinto() o write() method." + +#, fuzzy +#~ msgid "%q must be >= 1" +#~ msgstr "aarehas na haba dapat ang buffer slices" + +#~ msgid "address out of bounds" +#~ msgstr "wala sa sakop ang address" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "ang destination_length ay dapat na isang int >= 0" + +#~ msgid "color should be an int" +#~ msgstr "color ay dapat na int" + +#, fuzzy +#~ msgid "end_x should be an int" +#~ msgstr "y ay dapat int" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_index ay dapat na int" + +#, fuzzy +#~ msgid "start_x should be an int" +#~ msgstr "y ay dapat int" + +#~ msgid "y should be an int" +#~ msgstr "y ay dapat int" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "ang sample_source buffer ay dapat na isang bytearray o array ng uri na " +#~ "'h', 'H', 'b' o'B'" + #, fuzzy #~ msgid "%q should be an int" #~ msgstr "y ay dapat int" @@ -4536,7 +4689,7 @@ msgstr "" #~ "Mangyaring bisitahin ang learn.adafruit.com/category/circuitpython para " #~ "sa project guides.\n" #~ "\n" -#~ "Para makita ang listahan ng modules, `help(“modules”)`.\n" +#~ "Para makita ang listahan ng modules, `help(\"modules\")`.\n" #~ msgid "integer required" #~ msgstr "kailangan ng int" @@ -4615,12 +4768,6 @@ msgstr "" #~ msgid "can only save bytecode" #~ msgstr "maaring i-save lamang ang bytecode" -#~ msgid "invalid cert" -#~ msgstr "mali ang cert" - -#~ msgid "invalid key" -#~ msgstr "mali ang key" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "" #~ "Ang mga function ng Viper ay kasalukuyang hindi sumusuporta sa higit sa 4 " diff --git a/locale/fr.po b/locale/fr.po index 8cf8e5cb77..322314b018 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2022-07-19 23:15+0000\n" -"Last-Translator: Maxime Leroy \n" +"PO-Revision-Date: 2023-02-26 06:37+0000\n" +"Last-Translator: Neradoc \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.14-dev\n" +"X-Generator: Weblate 4.16-dev\n" #: main.c msgid "" @@ -34,16 +34,40 @@ msgstr "" "Le code a été arrêté par l'actualisation automatique. Rechargement " "prochain.\n" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" +"\n" +"CIRCUITPY_PYSTACK_SIZE invalide\n" +"\n" +"\n" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" msgstr "" "\n" -"Veuillez signaler un problème avec le contenu de votre lecteur CIRCUITPY à " -"l'adresse\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Appuyer sur reset pour sortir du mode sûr.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" +"\n" +"Le mode sûr est actif:\n" #: py/obj.c msgid " File \"%q\"" @@ -70,6 +94,16 @@ msgstr " sortie :\n" msgid "%%c requires int or char" msgstr "%%c nécessite un chiffre entier 'int' ou un caractère 'char'" +#: main.c +#, c-format +msgid "%02X" +msgstr "%02X" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "%S" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -78,13 +112,16 @@ msgstr "" "%d broches d'adresse, %d broches RGB et %d pour tile indique une hauteur de " "%d, et non %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -104,23 +141,34 @@ msgstr "%q contient des broches en double" msgid "%q failure: %d" msgstr "Échec de %q : %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q dans %q doit être de type %q, pas %q" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q en cours d'utilisation" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "index %q hors de portée" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "les indices %q doivent être des entiers, pas %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "échec de l'initialisation %q" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q est en lecture seule sur cette carte" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "La longeur de %q doit être %d" @@ -136,10 +184,6 @@ msgstr "La longeur de %q doit être <= %d" msgid "%q length must be >= %d" msgstr "La longeur de %q doit être >= %d" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "La longueur de %q doit être >= 1" - #: py/argcheck.c msgid "%q must be %d" msgstr "%q doit être %d" @@ -160,29 +204,26 @@ msgstr "%q doit être <= %d" msgid "%q must be >= %d" msgstr "%q doit être >= %d" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q doit être >= 0" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q doit être >= 1" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q doit être un bytearray ou matrice de type 'H' ou 'B'" -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q doit être une chaîne de caractères" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q doit être a bytearray ou array de type 'h', 'H', 'b', ou 'B'" -#: py/argcheck.c -msgid "%q must be an int" -msgstr "%q doit être un entier" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q doit être de type %q ou %q, pas %q" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "%q doit être du type %q" - -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q doit être du type %q ou None" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" +msgstr "%q doit être de type %q, pas %q" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" @@ -201,13 +242,9 @@ msgstr "%q est hors limites" msgid "%q out of range" msgstr "%q est hors de porté" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "broche %q invalide" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" -msgstr "%q avec un identifiant de rapport à 0 doit être de longueur 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "le pas ne peut être zéro dans %q" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -217,11 +254,11 @@ msgstr "%q() prend %d paramètres positionnels mais %d ont été donnés" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, et %q doivent tous être de la même longueur" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s erreur 0x%x" @@ -406,12 +443,16 @@ msgstr "ADC2 est utilisé pars le Wifi" msgid "Address must be %d bytes long" msgstr "L'adresse doit être longue de %d octets" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "Plage d'adresses non autorisée" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "Tous les périphériques CAN sont utilisés" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Tous les périphériques I2C sont utilisés" @@ -433,7 +474,6 @@ msgid "All SPI peripherals are in use" msgstr "Tous les périphériques SPI sont utilisés" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Tous les périphériques UART sont utilisés" @@ -486,15 +526,22 @@ msgstr "S'annonce déjà." msgid "Already have all-matches listener" msgstr "Il y a déjà un auditeur all-matches" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Déjà en cours d'exécution" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Déjà à la recherche des réseaux wifi" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "Erreur survenue en récupérant '%s':\n" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "Un autre PWMAudioOut est déjà actif" @@ -508,25 +555,16 @@ msgstr "Un autre envoi est déjà actif" msgid "Array must contain halfwords (type 'H')" msgstr "La matrice doit contenir des demi-mots (type 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Les valeurs de la matrice doivent être des octets singuliers." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "Au plus %d %q peut être spécifié (pas %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Tentative d'allocation de %d blocs" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" -"Tentative d'allocation à la pile quand la Machine Virtuelle n'est pas en " -"exécution." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "La conversion audio n'est pas implémentée" @@ -579,8 +617,8 @@ msgid "Bitmap size and bits per value must match" msgstr "La dimension et la taille en bits de l'image doivent correspondre" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "L'appareil de démarrage doit être le premier (interface #0)." +msgid "Boot device must be first (interface #0)." +msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" @@ -661,9 +699,9 @@ msgstr "Les blocs CBC doivent être des multiples de 16 octets" #: supervisor/shared/safe_mode.c msgid "CIRCUITPY drive could not be found or created." -msgstr "L’appareil CIRCUITPY ne peut pas être trouvé ou créé." +msgstr "L'appareil CIRCUITPY ne peut pas être trouvé ou créé." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "CRC ou somme de contrôle invalide" @@ -793,10 +831,6 @@ msgstr "Ecriture sur 'CharacteristicBuffer' non fournie" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "Le code principal de CircuitPython s'est complètement planté. Oups !\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPython n'as pu faire l'allocation de la pile." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Période de l'horloge trop longue" @@ -813,17 +847,25 @@ msgstr "" "La connexion a été déconnectée et ne peut plus être utilisée. Créez une " "nouvelle connexion." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Fichier .mpy corrompu" #: ports/espressif/common-hal/neopixel_write/__init__.c msgid "Could not retrieve clock" -msgstr "Impossible d’obtenir l’horloge" +msgstr "Impossible d'obtenir l'horloge" #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" -msgstr "Impossible de définir l’adresse" +msgstr "Impossible de définir l'adresse" #: shared-bindings/pwmio/PWMOut.c msgid "Could not start PWM" @@ -837,10 +879,6 @@ msgstr "Impossible de démarrer l'interruption, RX occupé" msgid "Couldn't allocate decoder" msgstr "Impossible d'allouer le décodeur" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Échec vers le HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Erreur d'initialisation du canal DAC" @@ -896,11 +934,19 @@ msgstr "L'affichage doit avoir un espace colorimétrique de 16 bits." msgid "Display rotation must be in 90 degree increments" msgstr "La rotation d'affichage doit se faire par incréments de 90 degrés" +#: main.c +msgid "Done" +msgstr "OK" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "" "Le mode Drive n'est pas utilisé quand la direction est entrante ('input')." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "Pendant la gestion de cette exception, un autre s'est produite:" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "La BCE ne fonctionne que sur 16 octets à la fois" @@ -926,20 +972,17 @@ msgstr "Erreur dans le flot MIDI à la position %d" msgid "Error in regex" msgstr "Erreur dans l'expression régulière" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "Erreur dans safemode.py." + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "Erreur : Impossible de lier" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Attendu un %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" -msgstr "Une alarme était prévue" +msgid "Expected a kind of %q" +msgstr "Argument de type %q attendu" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -974,7 +1017,7 @@ msgstr "Échec d'allocation du tampon %q" #: ports/espressif/common-hal/wifi/__init__.c msgid "Failed to allocate Wifi memory" -msgstr "Impossible d’allouer la mémoire pour Wifi" +msgstr "Impossible d'allouer la mémoire pour Wifi" #: ports/espressif/common-hal/wifi/ScannedNetworks.c msgid "Failed to allocate wifi scan memory" @@ -993,10 +1036,6 @@ msgstr "Impossible de se connecter : erreur interne" msgid "Failed to connect: timeout" msgstr "Impossible de se connecter: délai dépassé" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "Echec de l'initialisation du Wifi" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Impossible d'analyser le fichier MP3" @@ -1011,13 +1050,17 @@ msgid "Failed to write internal flash." msgstr "Échec de l'écriture vers flash interne." #: supervisor/shared/safe_mode.c -msgid "Fatal error." -msgstr "Erreurre fatale." +msgid "Fault detected by hardware." +msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "Le fichier existe" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "Fichier non trouvé" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1025,8 +1068,16 @@ msgid "Filters too complex" msgstr "Filtres trop complexe" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "Image du microprogramme est invalide" +msgid "Firmware is duplicate" +msgstr "Le logiciel est identique" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "Logiciel invalide" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "Logiciel trop volumineux" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" @@ -1064,13 +1115,15 @@ msgstr "La fonction nécessite un verrou ('lock')" msgid "GNSS init" msgstr "Initialisation GNSS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "Échec génerique" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Groupe déjà utilisé" @@ -1092,6 +1145,15 @@ msgstr "Matériel occupé, essayez d'autres broches" msgid "Hardware in use, try alternative pins" msgstr "Matériel utilisé, essayez d'autres broches" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "Allocation du tas en dehors de la MV." + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "Tas corrompu parce que la pile était trop petite. Augmenter la pile." + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "Opération d'E/S sur un fichier fermé" @@ -1101,18 +1163,14 @@ msgid "I2C init error" msgstr "Erreur d'initialisation I2C" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" -msgstr "périphérique I2C utilisé" +msgstr "Périphérique I2C utilisé" #: shared-bindings/audiobusio/I2SOut.c msgid "I2SOut not available" msgstr "I2SOut n'est pas disponible" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV doit être de longueur de %d octets" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "Éléments dans le tampon doivent être <= à 4 octets" @@ -1208,6 +1266,7 @@ msgid "Internal define error" msgstr "Erreur de définition interne" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "Erreur interne" @@ -1221,10 +1280,16 @@ msgstr "Erreur interne #%d" msgid "Internal watchdog timer expired." msgstr "Le minuteur du watchdog interne a expiré." -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Erreur d'interruption." + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "%q invalide" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Broche invalide pour '%q'" @@ -1246,7 +1311,7 @@ msgstr "BSSID invalide" msgid "Invalid MAC address" msgstr "Adresse MAC invalide" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Paramètre invalide" @@ -1255,6 +1320,11 @@ msgstr "Paramètre invalide" msgid "Invalid bits per value" msgstr "Bits par valeur invalides" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "Octet invalide %.*s" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1264,34 +1334,35 @@ msgstr "data_pins[%d] invalide" msgid "Invalid format chunk size" msgstr "Taille de bloc de formatage invalide" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Accès à la mémoire invalide." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Adresse MAC multicast invalide" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Broches invalides" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "Taille invalide" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "Socket non valide pour TLS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "État invalide" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "Séquence unicode invalide" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "La clé doit comporter 16, 24 ou 32 octets" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "Clé non trouvée" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "La disposition des LED doit correspondre à la taille de l'écran" @@ -1308,7 +1379,7 @@ msgstr "Ce calque est déjà dans un groupe" msgid "Layer must be a Group or TileGrid subclass" msgstr "Le calque doit être une sous-classe de Group ou TileGrid" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "Adresse physique (MAC) invalide" @@ -1401,6 +1472,10 @@ msgstr "Saut NLR échoué. Corruption de mémoire probable." msgid "NVS Error" msgstr "Erreur NVS" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "Nom ou service inconnu" + #: py/qstr.c msgid "Name too long" msgstr "Nom trop long" @@ -1516,11 +1591,6 @@ msgstr "Aucune clé n'a été spécifiée" msgid "No long integer support" msgstr "Pas de support pour chiffre entier long" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "Pas plus de %d appareils HID autorisés" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "Aucun réseau avec ce ssid" @@ -1556,13 +1626,9 @@ msgstr "Fichier/répertoire introuvable" msgid "No timer available" msgstr "Aucun minuteur disponible" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "Assertion échouée du logiciel systême Nordic." - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" -msgstr "Logiciel systême Nordic hors de mémoire" +msgstr "Logiciel système Nordic n'a plus de mémoire" #: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c msgid "Not a valid IP string" @@ -1579,10 +1645,6 @@ msgstr "Non connecté" msgid "Not playing" msgstr "Ne joue pas" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "Non réglable" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1599,16 +1661,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "Parité impaire non supportée" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "Inactif" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "OK" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Uniquement 8 ou 16 bit mono avec " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Seulement les adresses IPv4 sont supportées" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "Seulement les sockets IPv4 sont supportés" @@ -1642,10 +1714,15 @@ msgstr "" "supportés: %d bpp fournis" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." -msgstr "Seulement une TouchAlarm peu être réglée en sommeil profond." +msgid "Only one %q can be set in deep sleep." +msgstr "Une seul %q autorisée en sommeil profond." -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "Un seul %q peut être défini." + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "Seulement une adresse est autorisée" @@ -1668,19 +1745,24 @@ msgstr "Une seule couleur peut être transparente à la fois" msgid "Operation not permitted" msgstr "Cette opération n'est pas permise" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "Opération ou fonction non supportée" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "Timeout de l'opération" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c -msgid "Out of memory" -msgstr "Hors de mémoire" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "À cours de services MDNS" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +msgid "Out of memory" +msgstr "Mémoire insuffisante" + +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Plus de sockets" @@ -1737,7 +1819,6 @@ msgid "Pin interrupt already in use" msgstr "L'interruption de cette broche est déjà utilisée" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "La broche est entrée uniquement" @@ -1778,7 +1859,7 @@ msgstr "Ainsi que tout autres modules présents sur le système de fichiers\n" #: shared-module/vectorio/Polygon.c msgid "Polygon needs at least 3 points" -msgstr "Polygon a besoin d’au moins 3 points" +msgstr "Polygon a besoin d'au moins 3 points" #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" @@ -1808,6 +1889,10 @@ msgstr "Le programme fait des sorties sans charger d'OSR" msgid "Program size invalid" msgstr "Taille du programme invalide" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "Programme trop long" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'." @@ -1847,8 +1932,9 @@ msgstr "RTC non supporté sur cette carte" msgid "Random number generation error" msgstr "Erreur de génération de chiffres aléatoires" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Lecture seule" @@ -1856,14 +1942,14 @@ msgstr "Lecture seule" msgid "Read-only filesystem" msgstr "Système de fichier en lecture seule" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "Objet en lecture seule" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "Réponse reçue invalide" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "Reconnexion" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "Rafraîchissement trop tôt" @@ -1876,7 +1962,7 @@ msgstr "RemoteTransmissionRequests limité à 8 octets" msgid "Requested AES mode is unsupported" msgstr "Le mode AES demandé n'est pas supporté" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "Resource demandée non trouvée" @@ -1948,7 +2034,8 @@ msgstr "Taille n'est pas supportée" msgid "Sleep Memory not available" msgstr "La mémoire de sommeil n'est pas disponible" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Tranche et valeur de tailles différentes." @@ -1960,6 +2047,7 @@ msgid "Slices not supported" msgstr "Tranches non supportées" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool ne s'utilise qu'avec wifi.radio" @@ -1983,13 +2071,9 @@ msgstr "Canal stéréo gauche doit être sur le canal PWM A" msgid "Stereo right must be on PWM channel B" msgstr "Canal stéréo droit doit être sur le canal PWM B" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Il manque une méthode readinto() ou write() au flux." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Fournissez au moins une broche UART" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "Stopper n'est pas supporté." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -2004,35 +2088,20 @@ msgid "Temperature read timed out" msgstr "Délais de lecture de température dépassée" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" -msgstr "" -"La pile de CircuitPython est corrompue parce que la pile était trop petite.\n" -"Augmentez la taille de la pile si vous savez comment. Sinon :" +msgid "The `microcontroller` module was used to boot into safe mode." +msgstr "Le module microcontroller a été utilisé pour démarrer en mode sûr." -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." -msgstr "" -"Le module `microcontroller` a été utilisé pour démarrer en mode sûr. Pressez " -"reset pour quitter le mode sûr." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" +msgstr "L'exception précédente est la cause directe de l'exception suivante:" #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "La taille de rgb_pins doit être 6, 12, 18, 24 ou 30" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." -msgstr "" -"L'alimentation du microcontrôleur a diminué. Veillez à ce que votre " -"alimentation fournisse\n" -"assez de puissance pour tout le circuit, puis appuyez sur 'reset' (après " -"avoir éjecté CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." +msgstr "La puissance a chu. Assurez vous de fournir assez de puissance." #: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" @@ -2051,6 +2120,10 @@ msgstr "L'échantillonage de l'échantillon ne correspond pas à celui du mixer" msgid "The sample's signedness does not match the mixer's" msgstr "Le signe de l'échantillon ne correspond pas à celui du mixer" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "Erreur fatale de logiciel système tierce partie." + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "Ce microcontrôleur ne support pas la capture continue." @@ -2085,10 +2158,6 @@ msgstr "L'heure est dans le passé." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Le délai est trop long : le délai maximal est de %d secondes" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "Pour quitter, SVP redémarrez la carte sans " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "Trop de canaux dans l'échantillon" @@ -2133,6 +2202,10 @@ msgstr "Dé-initialisation du UART" msgid "UART init" msgstr "Initialisation UART" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "Périphérique UART utilisé" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "Ré-initialisation du UART" @@ -2141,6 +2214,11 @@ msgstr "Ré-initialisation du UART" msgid "UART write" msgstr "Écriture UART" +#: main.c +#, fuzzy +msgid "UID:" +msgstr "UID:" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "L'USB est occupé" @@ -2179,6 +2257,15 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "Impossible d'allouer des tampons pour une conversion signée" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "Impossible d'allouer le tas." + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "Impossible de créer un verrou ('lock')" @@ -2197,14 +2284,29 @@ msgstr "Impossible de trouver un GCLK libre" msgid "Unable to init parser" msgstr "Impossible d'initialiser le parser" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "Impossible de lire les données de la palette de couleurs" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "Impossible de lancer la requête mDNS" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "L'écriture a échoué." + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Écriture impossible vers nvm." @@ -2255,19 +2357,25 @@ msgstr "Erreur de sécurité inconnue : 0x%04x" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error at %s:%d: %d" -msgstr "Erreur du firmware système inconnue à %s:%d : %d" +msgstr "Erreur du logiciel système inconnue à %s:%d : %d" #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error: %04x" -msgstr "Faute inconnue du logiciel systême : %04x" +msgstr "Faute inconnue du logiciel système : %04x" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error: %d" -msgstr "Erreur du firmware système inconnue : %d" +msgstr "Erreur du logiciel système inconnue : %d" + +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "Erreur inconnue %d" #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2315,7 +2423,7 @@ msgstr "Longueur de valeur != Longueur fixe requise" msgid "Value length > max_length" msgstr "Longueur de la valeur > max_length" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "Version est invalide" @@ -2345,10 +2453,6 @@ msgstr "" "WatchDogTimer.mode ne peut pas être changé une fois réglé à WatchDogMode." "RESET" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "WatchDogTimer.timeout doit être supérieur à 0" - #: py/builtinhelp.c #, c-format msgid "" @@ -2368,6 +2472,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "Wi-Fi : " +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "Wifi en mode point d'accès." + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "Wifi en mode station." + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "Le wifi n'est pas activé" + #: main.c msgid "Woken up by alarm.\n" msgstr "Réveil par alarme.\n" @@ -2377,20 +2493,57 @@ msgstr "Réveil par alarme.\n" msgid "Writes not supported on Characteristic" msgstr "Écritures non supporté vers les Characteristic" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" -msgstr "Vous êtres en mode sûr parce que :\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "Vous avez appuyé les deux boutons au démarrage." + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." +msgstr "Vous avez appuyé le bouton A au démarrage." #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "Vous avez appuyé le bouton BOOT au démarrage" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "Vous avez appuyé le bouton GPIO0 au démarrage." + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." msgstr "" -"Vous avez pressé le bouton reset pendant le démarrage. Pressez-le à nouveau " -"pour sortir du mode sûr." + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "Vous avez appuyé le bouton SW38 au démarrage." + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "Vous avez appuyé le bouton VOLUME au démarrage." + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "Vous avez appuyé le bouton central au démarrage." + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "Vous avez appuyé le bouton gauche au démarrage." #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "Vous avez demandé à démarrer en mode sans-échec par " +msgid "You pressed the reset button during boot." +msgstr "Vous avez appuyé le bouton reset au démarrage." + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "[taille limite atteinte]" #: py/objtype.c msgid "__init__() should return None" @@ -2408,11 +2561,7 @@ msgstr "l'argument __new__ doit être d'un type défini par l'utilisateur" msgid "a bytes-like object is required" msgstr "un objet 'bytes-like' est requis" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "adresse hors limites" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "adresses vides" @@ -2434,7 +2583,7 @@ msgstr "Le paramêtre argsort doit être un ndarray" #: extmod/ulab/code/numpy/numerical.c msgid "argsort is not implemented for flattened arrays" -msgstr "argsort n'est pas mis en œuvre pour les matrices aplatis" +msgstr "argsort n'est pas implémenté pour les matrices aplaties" #: py/runtime.c shared-bindings/supervisor/__init__.c msgid "argument has wrong type" @@ -2465,14 +2614,18 @@ msgstr "la taille de la matrice et de l'index doivent être égaux" msgid "array has too many dimensions" msgstr "la tableau à trop de dimensions" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "matrice trop grande" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "matrice/octets requis à la droite" #: extmod/ulab/code/numpy/numerical.c msgid "attempt to get (arg)min/(arg)max of empty sequence" -msgstr "tentative d’obtenir (arg)min/(arg)max d'une séquence vide" +msgstr "tentative d'obtenir (arg)min/(arg)max d'une séquence vide" #: extmod/ulab/code/numpy/numerical.c msgid "attempt to get argmin/argmax of an empty sequence" @@ -2540,7 +2693,7 @@ msgstr "tampon est plus petit que la taille demandée" #: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" -msgstr "taille du tampon doit être un multiple de la taille de l’élément" +msgstr "taille du tampon doit être un multiple de la taille de l'élément" #: shared-module/struct/__init__.c msgid "buffer size must match format" @@ -2559,10 +2712,6 @@ msgstr "tampon trop petit" msgid "buffer too small for requested bytes" msgstr "tampon trop petit pour le nombre d'octets demandé" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "byteorder n'est pas une chaîne" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "bytes length n'est pas un multiple de la taille d'un élément" @@ -2605,15 +2754,10 @@ msgstr "ne peut pas assigner à une expression" msgid "can't cancel self" msgstr "ne peut pas s'annuler soi-même" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "impossible de convertir %q en %q" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "ne peut convertir %q à int" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2693,10 +2837,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "impossible de définir une taille de bloc de 512" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "attribut non modifiable" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "attribut '%q' non modifiable" + #: py/emitnative.c msgid "can't store '%q'" msgstr "impossible de stocker '%q'" @@ -2802,18 +2950,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "la couleur doit être entre 0x000000 et 0xffffff" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "la couleur doit être un entier 'int'" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "comparaison entre int et uint" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "division complexe par zéro" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "valeurs complexes non supportées" @@ -2899,10 +3039,6 @@ msgstr "" "le tampon de destination doit être une matrice de type 'H' pour bit_depth = " "16" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "destination_length doit être un entier >= 0" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "la séquence de mise à jour de dict a une mauvaise longueur" @@ -2923,12 +3059,11 @@ msgstr "les dimensions ne correspondent pas" msgid "div/mod not implemented for uint" msgstr "div/mod ne sont pas implémentés pour uint" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "division par zéro" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "division par zéro" @@ -2960,10 +3095,6 @@ msgstr "séquence vide" msgid "end of format while looking for conversion specifier" msgstr "fin de format en cherchant une spécification de conversion" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "end_x doit être un entier 'int'" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "epoch_time n'est pas supporté sur ce panneau" @@ -2973,18 +3104,18 @@ msgstr "epoch_time n'est pas supporté sur ce panneau" msgid "error = 0x%08lX" msgstr "erreur = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" +"espcamera.Camera a besoin de PSRAM réservée. Voir la documentation pour les " +"instructions." + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "les exceptions doivent dériver de 'BaseException'" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "'%q' était attendu, mais reçu '%q'" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "'%q' ou '%q' était attendu, mais reçu '%q'" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "':' attendu après la spécification de format" @@ -3083,10 +3214,6 @@ msgstr "la police doit être longue de 2048 octets" msgid "format requires a dict" msgstr "le format nécessite un dict" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "la fréquence est en lecture seule pour cette carte" - #: py/objdeque.c msgid "full" msgstr "plein" @@ -3106,7 +3233,7 @@ msgstr "la fonction a reçu plusieurs valeurs pour l'argument '%q'" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "function has the same sign at the ends of interval" -msgstr "la fonction a le même signe aux extrémités de l’intervalle" +msgstr "la fonction a le même signe aux extrémités de l'intervalle" #: extmod/ulab/code/ndarray.c msgid "function is defined for ndarrays only" @@ -3199,16 +3326,16 @@ msgstr "espacement incorrect" msgid "index is out of bounds" msgstr "l'index est hors limites" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "l'index doit être un tuple ou entier" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "index est hors bornes" -#: py/obj.c -msgid "indices must be integers" -msgstr "les indices doivent être des entiers" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "" @@ -3303,10 +3430,6 @@ msgstr "les vecteurs d'entrée doivent être de longueur égale" msgid "inputs are not iterable" msgstr "les entrées ne sont pas itérables" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "Le deuxième argument de int() doit être compris entre 2 et 36 inclus" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "interp n'est défini que pour les 1D itérables de taille identique" @@ -3326,6 +3449,10 @@ msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" "%d est invalide pour bits_per_pixel, doit être 1, 2, 4, 8, 16, 24, ou 32" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "certificat invalide" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3352,10 +3479,18 @@ msgstr "spécification de format invalide" msgid "invalid hostname" msgstr "hostname incorrect" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "clé invalide" + #: py/compile.c msgid "invalid micropython decorator" msgstr "décorateur micropython invalide" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "réglage invalide" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "pas invalide" @@ -3377,10 +3512,6 @@ msgstr "syntaxe invalide pour un entier de base %d" msgid "invalid syntax for number" msgstr "syntaxe invalide pour un nombre" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "traceback invalide" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "l'argument 1 de issubclass() doit être une classe" @@ -3442,19 +3573,17 @@ msgstr "variable locale '%q' utilisée avant d'en connaitre le type" msgid "local variable referenced before assignment" msgstr "variable locale référencée avant d'être assignée" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "entiers longs non supportés dans cette build" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "loopback + silent mode non pris en charge par le périphérique" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "mDNS a déjà été initialisé" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "mDNS ne fonctionne que avec le WiFi intégré" @@ -3583,6 +3712,10 @@ msgstr "puissance négative sans support des nombres à virgule flottante" msgid "negative shift count" msgstr "compte de décalage négatif" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "sous index doit être entier" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "pas de carte SD" @@ -3616,14 +3749,10 @@ msgstr "pas de broche de réinitialisation disponible" msgid "no response from SD card" msgstr "pas de réponse de la carte SD" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "pas de tel attribut" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "aucun appareil dans %q" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3751,15 +3880,30 @@ msgid "offset out of bounds" msgstr "décalage hors limites" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "seul bit_depth = 16 est pris en charge" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "seul mono est supporté" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "seul oversample=64 supporté" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "seul sample_rate = 16000 est pris en charge" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "seules les tranches avec 'step=1' (cad None) sont supportées" @@ -3831,10 +3975,6 @@ msgstr "pack attend %d element(s) (%d reçu)" msgid "palette must be 32 bytes long" msgstr "la palette doit être longue de 32 octets" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_index devrait être un entier 'int'" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "les paramètres doivent être des registres dans la séquence a2 à a5" @@ -3885,28 +4025,6 @@ msgstr "le 3e argument de pow() ne peut être 0" msgid "pow() with 3 arguments requires integers" msgstr "pow() avec 3 arguments nécessite des entiers" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "presser le bouton SW38 au démarrage.\n" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "bouton boot appuyé lors du démarrage.\n" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "les deux boutons appuyés lors du démarrage.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "appuyer le bouton de gauche au démarage\n" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "masque pull est en conflit avec les masques de direction" @@ -3927,11 +4045,6 @@ msgstr "les parties réelles et imaginaires doivent être de longueur égale" msgid "relative import" msgstr "import relatif" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "la longueur requise est %d mais l'objet est long de %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "résultats ne peuvent être transformé au type spécifié" @@ -3962,14 +4075,6 @@ msgstr "paramêtre roll doit être un ndarray" msgid "rsplit(None,n)" msgstr "rsplit(None, n)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"tampon sample_source doit être un bytearray ou une matrice de type 'h', 'H', " -"'b' ou 'B'" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4003,10 +4108,6 @@ msgstr "signe non autorisé dans les spéc. de formats de chaînes de caractère msgid "sign not allowed with integer format specifier 'c'" msgstr "signe non autorisé avec la spéc. de format d'entier 'c'" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "'}' seule rencontrée dans une chaîne de format" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "la taille n'est définie que pour les ndarrays" @@ -4019,10 +4120,6 @@ msgstr "la longueur de sleep ne doit pas être négative" msgid "slice step can't be zero" msgstr "le pas 'step' de la tranche ne peut être zéro" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "le pas 'step' de la tranche ne peut être zéro" - #: py/nativeglue.c msgid "slice unsupported" msgstr "slice non-supporté" @@ -4071,14 +4168,6 @@ msgstr "source_bitmap doit avoir une value_count de 8" msgid "start/end indices" msgstr "indices de début/fin" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "'start_x' doit être un entier 'int'" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "le pas 'step' doit être non nul" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "stop n'est pas accessible au démarrage" @@ -4087,10 +4176,6 @@ msgstr "stop n'est pas accessible au démarrage" msgid "stream operation not supported" msgstr "opération de flux non supportée" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "les indices d'une chaîne doivent être des entiers, pas %q" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" @@ -4124,14 +4209,6 @@ msgstr "erreur de syntaxe JSON" msgid "syntax error in uctypes descriptor" msgstr "erreur de syntaxe dans le descripteur d'uctypes" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "le seuil doit être dans la portée 0-65536" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time() prend une séquence de longueur 9" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4139,21 +4216,17 @@ msgstr "time.struct_time() prend une séquence de longueur 9" msgid "timeout duration exceeded the maximum supported value" msgstr "le délai d'expiration a dépassé la valeur maximale prise en charge" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "le délai doit être compris entre 0.0 et 100.0 secondes" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "le délai (timeout) doit être < 655.35 secondes" #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v1 card" -msgstr "Délai d’expiration dépassé en attendant une carte v1" +msgstr "Délai d'expiration dépassé en attendant une carte v1" #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v2 card" -msgstr "Délai d’expiration dépassé en attendant une carte v2" +msgstr "Délai d'expiration dépassé en attendant une carte v2" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "timer re-init" @@ -4196,10 +4269,6 @@ msgstr "trapz n'est défini que pour des matrices 1D de longueur égales" msgid "trapz is defined for 1D iterables" msgstr "trapz est défini pour les 1D itérables" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "tuple/liste a une mauvaise longueur" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4210,8 +4279,6 @@ msgstr "twai_driver_install a renvoyé l'erreur esp-idf #%d" msgid "twai_start returned esp-idf error #%d" msgstr "twai_start a renvoyé l'erreur esp-idf #%d" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx et rx ne peuvent être 'None' tous les deux" @@ -4224,14 +4291,10 @@ msgstr "le type '%q' n'est pas un type de base accepté" msgid "type is not an acceptable base type" msgstr "le type n'est pas un type de base accepté" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "l'objet de type '%q' n'a pas d'attribut '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "le type 'generator' n'a pas d'attribut '__await__'" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "le type prend 1 ou 3 arguments" @@ -4252,7 +4315,7 @@ msgstr "indentation inattendue" msgid "unexpected keyword argument" msgstr "paramètre nommé inattendu" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "paramètre nommé '%q' inattendu" @@ -4282,15 +4345,15 @@ msgid "unknown type '%q'" msgstr "type '%q' inconnu" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "'{' sans correspondance dans le format" +#, c-format +msgid "unmatched '%c' in format" +msgstr "'%c' sans correspondance dans le format" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "attribut illisible" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "type %q non pris on charge" @@ -4354,17 +4417,18 @@ msgstr "'value_count' doit être > 0" msgid "watchdog not initialized" msgstr "chien de garde (watchdog) non initialisé" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "watchdog timeout doit être supérieur à 0" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "width doit être plus que zero" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" -msgstr "wifi n’est pas activé" +msgstr "wifi n'est pas activé" + +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "wifi.Monitor non disponible" #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" @@ -4420,18 +4484,10 @@ msgstr "valeur x hors limites" msgid "xTaskCreate failed" msgstr "Échec de xTaskCreate" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "'y' doit être un entier 'int'" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "valeur y hors limites" -#: py/objrange.c -msgid "zero step" -msgstr "'step' nul" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "zi doit être un ndarray" @@ -4444,6 +4500,313 @@ msgstr "zi doit être de type float" msgid "zi must be of shape (n_section, 2)" msgstr "zi doit être de forme (n_section, 2)" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Fournissez au moins une broche UART" + +#~ msgid "%q pin invalid" +#~ msgstr "broche %q invalide" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Veuillez signaler un problème avec le contenu de votre lecteur CIRCUITPY " +#~ "à l'adresse\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "" +#~ "Tentative d'allocation à la pile quand la Machine Virtuelle n'est pas en " +#~ "exécution." + +#~ msgid "Boot device must be first device (interface #0)." +#~ msgstr "L'appareil de démarrage doit être le premier (interface #0)." + +#~ msgid "Both buttons were pressed at start up.\n" +#~ msgstr "Les deux boutons étaient pressés au démarrage.\n" + +#~ msgid "Button A was pressed at start up.\n" +#~ msgstr "Le bouton A était pressé au démarrage.\n" + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPython n'as pu faire l'allocation de la pile." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Échec vers le HardFault_Handler." + +#~ msgid "Fatal error." +#~ msgstr "Erreurre fatale." + +#~ msgid "Invalid memory access." +#~ msgstr "Accès à la mémoire invalide." + +#~ msgid "Nordic system firmware failure assertion." +#~ msgstr "Assertion échouée du logiciel système Nordic." + +#~ msgid "The BOOT button was pressed at start up.\n" +#~ msgstr "Le bouton BOOT était pressé au démarrage.\n" + +#~ msgid "" +#~ "The CircuitPython heap was corrupted because the stack was too small.\n" +#~ "Increase the stack size if you know how. If not:" +#~ msgstr "" +#~ "La pile de CircuitPython est corrompue parce que la pile était trop " +#~ "petite.\n" +#~ "Augmentez la taille de la pile si vous savez comment. Sinon :" + +#~ msgid "The SW38 button was pressed at start up.\n" +#~ msgstr "Le bouton SW38 était pressé au démarrage.\n" + +#~ msgid "The VOLUME button was pressed at start up.\n" +#~ msgstr "Le bouton VOLUME était pressé au démarrage.\n" + +#~ msgid "" +#~ "The `microcontroller` module was used to boot into safe mode. Press reset " +#~ "to exit safe mode." +#~ msgstr "" +#~ "Le module `microcontroller` a été utilisé pour démarrer en mode sûr. " +#~ "Pressez reset pour quitter le mode sûr." + +#~ msgid "The central button was pressed at start up.\n" +#~ msgstr "Le bouton central était pressé au démarrage.\n" + +#~ msgid "The left button was pressed at start up.\n" +#~ msgstr "Le bouton gauche était pressé au démarrage.\n" + +#~ msgid "" +#~ "The microcontroller's power dipped. Make sure your power supply provides\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY)." +#~ msgstr "" +#~ "L'alimentation du microcontrôleur a diminué. Veillez à ce que votre " +#~ "alimentation fournisse\n" +#~ "assez de puissance pour tout le circuit, puis appuyez sur 'reset' (après " +#~ "avoir éjecté CIRCUITPY)." + +#~ msgid "To exit, please reset the board without requesting safe mode." +#~ msgstr "Pour le quitter, redémarrez sans demander le mode sans-échec." + +#~ msgid "You are in safe mode because:\n" +#~ msgstr "Vous êtres en mode sûr parce que :\n" + +#~ msgid "" +#~ "You pressed the reset button during boot. Press again to exit safe mode." +#~ msgstr "" +#~ "Vous avez pressé le bouton reset pendant le démarrage. Pressez-le à " +#~ "nouveau pour sortir du mode sûr." + +#~ msgid "" +#~ "esp32_camera.Camera requires reserved PSRAM to be configured. See the " +#~ "documentation for instructions." +#~ msgstr "" +#~ "esp32_camera.Camera nécessite la configuration de PSRAM réservée. Se " +#~ "référer à la documentation." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q doit être du type %q" + +#~ msgid "%q must be of type %q or None" +#~ msgstr "%q doit être du type %q ou None" + +#~ msgid "Expected a %q" +#~ msgstr "Attendu un %q" + +#~ msgid "Expected a %q or %q" +#~ msgstr "Attendu un %q ou %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV doit être de longueur de %d octets" + +#~ msgid "Not settable" +#~ msgstr "Non réglable" + +#~ msgid "expected '%q' but got '%q'" +#~ msgstr "'%q' était attendu, mais reçu '%q'" + +#~ msgid "expected '%q' or '%q' but got '%q'" +#~ msgstr "'%q' ou '%q' était attendu, mais reçu '%q'" + +#~ msgid "Read-only object" +#~ msgstr "Objet en lecture seule" + +#~ msgid "frequency is read-only for this board" +#~ msgstr "la fréquence est en lecture seule pour cette carte" + +#~ msgid "Unable to write" +#~ msgstr "Écriture impossible" + +#~ msgid "%q length must be >= 1" +#~ msgstr "La longueur de %q doit être >= 1" + +#~ msgid "%q must be a string" +#~ msgstr "%q doit être une chaîne de caractères" + +#~ msgid "%q must be an int" +#~ msgstr "%q doit être un entier" + +#~ msgid "%q with a report ID of 0 must be of length 1" +#~ msgstr "%q avec un identifiant de rapport à 0 doit être de longueur 1" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Au plus %d %q peut être spécifié (pas %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Broches invalides" + +#, c-format +#~ msgid "No more than %d HID devices allowed" +#~ msgstr "Pas plus de %d appareils HID autorisés" + +#~ msgid "byteorder is not a string" +#~ msgstr "byteorder n'est pas une chaîne" + +#~ msgid "can't convert %q to int" +#~ msgstr "ne peut convertir %q à int" + +#~ msgid "complex division by zero" +#~ msgstr "division complexe par zéro" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "" +#~ "Le deuxième argument de int() doit être compris entre 2 et 36 inclus" + +#~ msgid "long int not supported in this build" +#~ msgstr "entiers longs non supportés dans cette build" + +#~ msgid "slice step cannot be zero" +#~ msgstr "le pas 'step' de la tranche ne peut être zéro" + +#~ msgid "step must be non-zero" +#~ msgstr "le pas 'step' doit être non nul" + +#~ msgid "string indices must be integers, not %q" +#~ msgstr "les indices d'une chaîne doivent être des entiers, pas %q" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time() prend une séquence de longueur 9" + +#~ msgid "zero step" +#~ msgstr "'step' nul" + +#~ msgid "invalid traceback" +#~ msgstr "traceback invalide" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "les indices %q doivent être des entiers, pas %s" + +#~ msgid "WatchDogTimer.timeout must be greater than 0" +#~ msgstr "WatchDogTimer.timeout doit être supérieur à 0" + +#~ msgid "indices must be integers" +#~ msgstr "les indices doivent être des entiers" + +#~ msgid "non-Device in %q" +#~ msgstr "aucun appareil dans %q" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "la longueur requise est %d mais l'objet est long de %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "'}' seule rencontrée dans une chaîne de format" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "le seuil doit être dans la portée 0-65536" + +#~ msgid "timeout must be 0.0-100.0 seconds" +#~ msgstr "le délai doit être compris entre 0.0 et 100.0 secondes" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "tuple/liste a une mauvaise longueur" + +#~ msgid "unmatched '{' in format" +#~ msgstr "'{' sans correspondance dans le format" + +#~ msgid "watchdog timeout must be greater than 0" +#~ msgstr "watchdog timeout doit être supérieur à 0" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "Pour quitter, SVP redémarrez la carte sans " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "Vous avez demandé à démarrer en mode sans-échec par " + +#~ msgid "pressing BOOT button at start up.\n" +#~ msgstr "presser le bouton BOOT au démarrage.\n" + +#~ msgid "pressing SW38 button at start up.\n" +#~ msgstr "presser le bouton SW38 au démarrage.\n" + +#~ msgid "pressing VOLUME button at start up.\n" +#~ msgstr "presser le bouton VOLUME au démarrage.\n" + +#~ msgid "pressing boot button at start up.\n" +#~ msgstr "bouton boot appuyé lors du démarrage.\n" + +#~ msgid "pressing both buttons at start up.\n" +#~ msgstr "les deux boutons appuyés lors du démarrage.\n" + +#~ msgid "pressing the left button at start up\n" +#~ msgstr "appuyer le bouton de gauche au démarage\n" + +#~ msgid "Only one TouchAlarm can be set in deep sleep." +#~ msgstr "Seulement une TouchAlarm peu être réglée en sommeil profond." + +#~ msgid "Firmware image is invalid" +#~ msgstr "Image du microprogramme est invalide" + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Il manque une méthode readinto() ou write() au flux." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q doit être >= 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q doit être >= 1" + +#~ msgid "address out of bounds" +#~ msgstr "adresse hors limites" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "destination_length doit être un entier >= 0" + +#~ msgid "type object 'generator' has no attribute '__await__'" +#~ msgstr "le type 'generator' n'a pas d'attribut '__await__'" + +#~ msgid "color should be an int" +#~ msgstr "la couleur doit être un entier 'int'" + +#~ msgid "end_x should be an int" +#~ msgstr "end_x doit être un entier 'int'" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_index devrait être un entier 'int'" + +#~ msgid "start_x should be an int" +#~ msgstr "'start_x' doit être un entier 'int'" + +#~ msgid "y should be an int" +#~ msgstr "'y' doit être un entier 'int'" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "tampon sample_source doit être un bytearray ou une matrice de type 'h', " +#~ "'H', 'b' ou 'B'" + +#~ msgid "Expected an alarm" +#~ msgstr "Une alarme était prévue" + +#~ msgid "All I2C targets are in use" +#~ msgstr "Toutes les cibles I2C sont utilisées" + +#~ msgid "Failed to init wifi" +#~ msgstr "Echec de l'initialisation du Wifi" + #~ msgid "input must be a tensor of rank 2" #~ msgstr "l'entrée doit être un tenseur de rang 2" @@ -5101,12 +5464,6 @@ msgstr "zi doit être de forme (n_section, 2)" #~ msgid "can only save bytecode" #~ msgstr "ne peut sauvegarder que du bytecode" -#~ msgid "invalid cert" -#~ msgstr "certificat invalide" - -#~ msgid "invalid key" -#~ msgstr "clé invalide" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "" #~ "les fonctions de Viper ne supportent pas plus de 4 arguments actuellement" diff --git a/locale/hi.po b/locale/hi.po index aea67d4580..649b98c521 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -28,11 +28,31 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" #: py/obj.c @@ -60,19 +80,32 @@ msgstr "" msgid "%%c requires int or char" msgstr "" +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -92,23 +125,34 @@ msgstr "" msgid "%q failure: %d" msgstr "" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "" @@ -124,10 +168,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -148,28 +188,25 @@ msgstr "" msgid "%q must be >= %d" msgstr "" -#: py/argcheck.c -msgid "%q must be >= 0" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be a string" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be an int" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "" - -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -189,12 +226,8 @@ msgstr "" msgid "%q out of range" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c @@ -205,11 +238,11 @@ msgstr "" msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -394,12 +427,16 @@ msgstr "" msgid "Address must be %d bytes long" msgstr "" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "" @@ -421,7 +458,6 @@ msgid "All SPI peripherals are in use" msgstr "" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "" @@ -474,15 +510,22 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "" @@ -496,23 +539,16 @@ msgstr "" msgid "Array must contain halfwords (type 'H')" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "" @@ -561,7 +597,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -645,7 +681,7 @@ msgstr "" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "" @@ -763,10 +799,6 @@ msgstr "" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "" - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "" @@ -781,6 +813,14 @@ msgid "" "connection." msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "" @@ -805,10 +845,6 @@ msgstr "" msgid "Couldn't allocate decoder" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "" - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "" @@ -863,10 +899,18 @@ msgstr "" msgid "Display rotation must be in 90 degree increments" msgstr "" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "" @@ -892,19 +936,16 @@ msgstr "" msgid "Error in regex" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -958,10 +999,6 @@ msgstr "" msgid "Failed to connect: timeout" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "" @@ -976,13 +1013,17 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -990,7 +1031,15 @@ msgid "Filters too complex" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" #: shared-bindings/bitmaptools/__init__.c @@ -1023,13 +1072,15 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -1050,6 +1101,15 @@ msgstr "" msgid "Hardware in use, try alternative pins" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "" @@ -1059,6 +1119,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "" @@ -1066,11 +1127,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1155,6 +1211,7 @@ msgid "Internal define error" msgstr "" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1167,10 +1224,16 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "" @@ -1192,7 +1255,7 @@ msgstr "" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "" @@ -1201,6 +1264,11 @@ msgstr "" msgid "Invalid bits per value" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1210,34 +1278,35 @@ msgstr "" msgid "Invalid format chunk size" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "" - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1254,7 +1323,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -1344,6 +1413,10 @@ msgstr "" msgid "NVS Error" msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "" @@ -1458,11 +1531,6 @@ msgstr "" msgid "No long integer support" msgstr "" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "" @@ -1498,10 +1566,6 @@ msgstr "" msgid "No timer available" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1521,10 +1585,6 @@ msgstr "" msgid "Not playing" msgstr "" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1539,16 +1599,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "" #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "" @@ -1578,10 +1648,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1604,19 +1679,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1671,7 +1751,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "" @@ -1735,6 +1814,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1774,8 +1857,9 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "" @@ -1783,12 +1867,12 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +msgid "Received response was invalid" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c -msgid "Received response was invalid" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" #: shared-bindings/displayio/EPaperDisplay.c @@ -1803,7 +1887,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1875,7 +1959,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1887,6 +1972,7 @@ msgid "Slices not supported" msgstr "" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1910,12 +1996,8 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "" - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c @@ -1931,15 +2013,11 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1947,10 +2025,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1969,6 +2044,10 @@ msgstr "" msgid "The sample's signedness does not match the mixer's" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2001,10 +2080,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2049,6 +2124,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2057,6 +2136,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2092,6 +2175,15 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2110,14 +2202,29 @@ msgstr "" msgid "Unable to init parser" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "" @@ -2180,7 +2287,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2225,7 +2338,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2251,10 +2364,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -2269,6 +2378,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2278,17 +2399,56 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2307,11 +2467,7 @@ msgstr "" msgid "a bytes-like object is required" msgstr "" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "" @@ -2364,8 +2520,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "" @@ -2458,10 +2618,6 @@ msgstr "" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2503,15 +2659,10 @@ msgstr "" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2589,10 +2740,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "" @@ -2691,18 +2846,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "" @@ -2785,10 +2932,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "" @@ -2809,12 +2952,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "" @@ -2846,10 +2988,6 @@ msgstr "" msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2859,18 +2997,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -2969,10 +3105,6 @@ msgstr "" msgid "format requires a dict" msgstr "" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "" @@ -3085,14 +3217,14 @@ msgstr "" msgid "index is out of bounds" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" msgstr "" #: extmod/ulab/code/ndarray.c @@ -3188,10 +3320,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3210,6 +3338,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3236,10 +3368,18 @@ msgstr "" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "" + #: py/compile.c msgid "invalid micropython decorator" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "" @@ -3261,10 +3401,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3321,19 +3457,17 @@ msgstr "" msgid "local variable referenced before assignment" msgstr "" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3462,6 +3596,10 @@ msgstr "" msgid "negative shift count" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3495,14 +3633,10 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3627,15 +3761,30 @@ msgid "offset out of bounds" msgstr "" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" @@ -3706,10 +3855,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "" @@ -3759,28 +3904,6 @@ msgstr "" msgid "pow() with 3 arguments requires integers" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3801,11 +3924,6 @@ msgstr "" msgid "relative import" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3836,12 +3954,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3875,10 +3987,6 @@ msgstr "" msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3891,10 +3999,6 @@ msgstr "" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3943,14 +4047,6 @@ msgstr "" msgid "start/end indices" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "" @@ -3959,10 +4055,6 @@ msgstr "" msgid "stream operation not supported" msgstr "" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" @@ -3995,14 +4087,6 @@ msgstr "" msgid "syntax error in uctypes descriptor" msgstr "" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4010,10 +4094,6 @@ msgstr "" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4067,10 +4147,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4081,8 +4157,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" @@ -4095,14 +4169,10 @@ msgstr "" msgid "type is not an acceptable base type" msgstr "" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "" @@ -4123,7 +4193,7 @@ msgstr "" msgid "unexpected keyword argument" msgstr "" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "" @@ -4153,7 +4223,8 @@ msgid "unknown type '%q'" msgstr "" #: py/objstr.c -msgid "unmatched '{' in format" +#, c-format +msgid "unmatched '%c' in format" msgstr "" #: py/objtype.c py/runtime.c @@ -4161,7 +4232,6 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" @@ -4225,18 +4295,19 @@ msgstr "" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" @@ -4291,18 +4362,10 @@ msgstr "" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "" -#: py/objrange.c -msgid "zero step" -msgstr "" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index e418f789f9..a6ab324c58 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -31,15 +31,32 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" "\n" -"Per favore, segnala il problema con il contenuto del tuo CIRCUITPY a\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -66,6 +83,16 @@ msgstr " output:\n" msgid "%%c requires int or char" msgstr "%%c necessita di int o char" +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -73,13 +100,16 @@ msgid "" msgstr "" "%d pin indirizzo, %d pin rgb e %d tessere indicano l'altezza di %d, non %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -99,23 +129,34 @@ msgstr "" msgid "%q failure: %d" msgstr "%q fallito: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q in uso" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "indice %q fuori intervallo" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "gli indici %q devono essere interi, non %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "" @@ -131,10 +172,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -155,29 +192,25 @@ msgstr "" msgid "%q must be >= %d" msgstr "" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q deve essere >= 0" - -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -#, fuzzy -msgid "%q must be >= 1" -msgstr "slice del buffer devono essere della stessa lunghezza" - -#: py/argcheck.c -msgid "%q must be a string" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/argcheck.c -msgid "%q must be an int" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -197,12 +230,8 @@ msgstr "" msgid "%q out of range" msgstr "%q oltre il limite" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "%q pin non valido" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c @@ -213,11 +242,11 @@ msgstr "%q() prende %d argomenti posizionali ma ne sono stati forniti %d" msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s errore 0x%x" @@ -403,12 +432,16 @@ msgstr "ADC2 sta usando il WiFi" msgid "Address must be %d bytes long" msgstr "L'indirizzo deve essere lungo %d byte" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "Tutte le periferiche CAN sono in uso" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Tutte le periferiche I2C sono in uso" @@ -430,7 +463,6 @@ msgid "All SPI peripherals are in use" msgstr "Tutte le periferiche SPI sono in uso" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c #, fuzzy msgid "All UART peripherals are in use" msgstr "Tutte le periferiche I2C sono in uso" @@ -484,15 +516,22 @@ msgstr "" msgid "Already have all-matches listener" msgstr "Già in possesso di tutti i listener abbinati" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Già in funzione" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Già in ricerca di collegamenti WiFi" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "" @@ -506,23 +545,16 @@ msgstr "Another send è gia activato" msgid "Array must contain halfwords (type 'H')" msgstr "Array deve avere mezzoparole (typo 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "I valori dell'Array dovrebbero essere bytes singoli." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "Almeno %d %q devono essere specificati (non %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Provo ad allocare %d blocchi" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "" @@ -574,7 +606,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -658,7 +690,7 @@ msgstr "I blocchi CBC devono essere multipli di 16 bytes" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "CRC o controllo totale è risultato non valido" @@ -777,10 +809,6 @@ msgstr "CharacteristicBuffer scritura non dato" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "" - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Orologio e troppo allungato" @@ -795,6 +823,14 @@ msgid "" "connection." msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "" @@ -819,10 +855,6 @@ msgstr "" msgid "Couldn't allocate decoder" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "" - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "" @@ -879,10 +911,18 @@ msgstr "" msgid "Display rotation must be in 90 degree increments" msgstr "" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "" @@ -908,19 +948,16 @@ msgstr "" msgid "Error in regex" msgstr "Errore nella regex" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Atteso un %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -974,10 +1011,6 @@ msgstr "" msgid "Failed to connect: timeout" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "" @@ -992,13 +1025,17 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "File esistente" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1006,7 +1043,15 @@ msgid "Filters too complex" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" #: shared-bindings/bitmaptools/__init__.c @@ -1039,13 +1084,15 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -1066,6 +1113,15 @@ msgstr "" msgid "Hardware in use, try alternative pins" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "operazione I/O su file chiuso" @@ -1075,6 +1131,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "" @@ -1082,11 +1139,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1173,6 +1225,7 @@ msgid "Internal define error" msgstr "" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1185,10 +1238,16 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Pin %q non valido" @@ -1210,7 +1269,7 @@ msgstr "" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Argomento non valido" @@ -1219,6 +1278,11 @@ msgstr "Argomento non valido" msgid "Invalid bits per value" msgstr "bits per valore invalido" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1228,34 +1292,35 @@ msgstr "" msgid "Invalid format chunk size" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "" - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Pin non validi" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1272,7 +1337,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -1363,6 +1428,10 @@ msgstr "" msgid "NVS Error" msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "" @@ -1477,11 +1546,6 @@ msgstr "" msgid "No long integer support" msgstr "" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "" @@ -1517,10 +1581,6 @@ msgstr "Nessun file/directory esistente" msgid "No timer available" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1541,10 +1601,6 @@ msgstr "Impossible connettersi all'AP" msgid "Not playing" msgstr "In pausa" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1562,16 +1618,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "operazione I2C non supportata" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "" #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "" @@ -1601,10 +1667,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1627,19 +1698,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1697,7 +1773,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "" @@ -1762,6 +1837,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1801,8 +1880,9 @@ msgstr "RTC non supportato su questa scheda" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Sola lettura" @@ -1810,15 +1890,14 @@ msgstr "Sola lettura" msgid "Read-only filesystem" msgstr "Filesystem in sola lettura" -#: shared-module/displayio/Bitmap.c -#, fuzzy -msgid "Read-only object" -msgstr "Sola lettura" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "" @@ -1831,7 +1910,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1903,7 +1982,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1915,6 +1995,7 @@ msgid "Slices not supported" msgstr "Slice non supportate" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1938,12 +2019,8 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Metodi mancanti readinto() o write() allo stream." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c @@ -1959,15 +2036,11 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1975,10 +2048,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1997,6 +2067,10 @@ msgstr "" msgid "The sample's signedness does not match the mixer's" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2029,10 +2103,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "Per uscire resettare la scheda senza " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2077,6 +2147,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2085,6 +2159,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2120,6 +2198,15 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "Ipossibilitato ad allocare buffer per la conversione con segno" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2138,14 +2225,29 @@ msgstr "Impossibile trovare un GCLK libero" msgid "Unable to init parser" msgstr "Inizilizzazione del parser non possibile" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Imposibile scrivere su nvm." @@ -2209,7 +2311,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2255,7 +2363,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2281,10 +2389,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -2299,6 +2403,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2308,18 +2424,57 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "È stato richiesto l'avvio in modalità sicura da " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "" #: py/objtype.c msgid "__init__() should return None" @@ -2337,11 +2492,7 @@ msgstr "" msgid "a bytes-like object is required" msgstr "un oggetto byte-like è richiesto" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "indirizzo fuori limite" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "gli indirizzi sono vuoti" @@ -2394,8 +2545,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "" @@ -2491,10 +2646,6 @@ msgstr "buffer troppo piccolo" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2537,15 +2688,10 @@ msgstr "impossibile assegnare all'espressione" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, fuzzy, c-format msgid "can't convert %s to complex" @@ -2623,10 +2769,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "impossibile impostare attributo" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "impossibile memorizzare '%q'" @@ -2727,18 +2877,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "il colore deve essere compreso tra 0x000000 e 0xffffff" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "il colore deve essere un int" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "complex divisione per zero" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "valori complessi non supportai" @@ -2824,10 +2966,6 @@ msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" "il buffer di destinazione deve essere un array di tipo 'H' con bit_depth = 16" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "destination_length deve essere un int >= 0" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "sequanza di aggiornamento del dizionario ha la lunghezza errata" @@ -2848,12 +2986,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "divisione per zero" @@ -2885,11 +3022,6 @@ msgstr "sequenza vuota" msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/displayio/Shape.c -#, fuzzy -msgid "end_x should be an int" -msgstr "y dovrebbe essere un int" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2899,18 +3031,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "errore = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "le eccezioni devono derivare da BaseException" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "':' atteso dopo lo specificatore di formato" @@ -3009,10 +3139,6 @@ msgstr "il font deve essere lungo 2048 byte" msgid "format requires a dict" msgstr "la formattazione richiede un dict" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "pieno" @@ -3126,16 +3252,16 @@ msgstr "padding incorretto" msgid "index is out of bounds" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "indice fuori intervallo" -#: py/obj.c -msgid "indices must be integers" -msgstr "gli indici devono essere interi" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "" @@ -3229,10 +3355,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "il secondo argomanto di int() deve essere >= 2 e <= 36" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3251,6 +3373,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "certificato non valido" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3277,10 +3403,18 @@ msgstr "specificatore di formato non valido" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "chiave non valida" + #: py/compile.c msgid "invalid micropython decorator" msgstr "decoratore non valido in micropython" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "step non valida" @@ -3302,10 +3436,6 @@ msgstr "sintassi invalida per l'intero con base %d" msgid "invalid syntax for number" msgstr "sintassi invalida per il numero" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "il primo argomento di issubclass() deve essere una classe" @@ -3367,19 +3497,17 @@ msgstr "locla '%q' utilizzato prima che il tipo fosse noto" msgid "local variable referenced before assignment" msgstr "variabile locale richiamata prima di un assegnamento" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "long int non supportata in questa build" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3508,6 +3636,10 @@ msgstr "potenza negativa senza supporto per float" msgid "negative shift count" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3541,14 +3673,10 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "attributo inesistente" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3676,15 +3804,30 @@ msgid "offset out of bounds" msgstr "indirizzo fuori limite" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "solo slice con step=1 (aka None) sono supportate" @@ -3756,10 +3899,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "la palette deve essere lunga 32 byte" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_index deve essere un int" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "parametri devono essere i registri in sequenza da a2 a a5" @@ -3811,28 +3950,6 @@ msgstr "il terzo argomento di pow() non può essere 0" msgid "pow() with 3 arguments requires integers" msgstr "pow() con 3 argomenti richiede interi" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3853,11 +3970,6 @@ msgstr "" msgid "relative import" msgstr "importazione relativa" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "lunghezza %d richiesta ma l'oggetto ha lunghezza %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3888,14 +4000,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"il buffer sample_source deve essere un bytearray o un array di tipo 'h', " -"'H', 'b' o 'B'" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3929,10 +4033,6 @@ msgstr "segno non permesso nello spcificatore di formato della stringa" msgid "sign not allowed with integer format specifier 'c'" msgstr "segno non permesso nello spcificatore di formato 'c' della stringa" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "'}' singolo presente nella stringa di formattazione" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3945,10 +4045,6 @@ msgstr "la lunghezza di sleed deve essere non negativa" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "la step della slice non può essere zero" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3997,15 +4093,6 @@ msgstr "" msgid "start/end indices" msgstr "" -#: shared-bindings/displayio/Shape.c -#, fuzzy -msgid "start_x should be an int" -msgstr "y dovrebbe essere un int" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "step deve essere non zero" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "stop non raggiungibile dall'inizio" @@ -4014,10 +4101,6 @@ msgstr "stop non raggiungibile dall'inizio" msgid "stream operation not supported" msgstr "operazione di stream non supportata" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" @@ -4050,14 +4133,6 @@ msgstr "errore di sintassi nel JSON" msgid "syntax error in uctypes descriptor" msgstr "errore di sintassi nel descrittore uctypes" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "la soglia deve essere nell'intervallo 0-65536" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4065,10 +4140,6 @@ msgstr "" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4122,10 +4193,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "tupla/lista ha la lunghezza sbagliata" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4136,8 +4203,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx e rx non possono essere entrambi None" @@ -4150,14 +4215,10 @@ msgstr "il tipo '%q' non è un tipo di base accettabile" msgid "type is not an acceptable base type" msgstr "il tipo non è un tipo di base accettabile" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "l'oggetto di tipo '%q' non ha l'attributo '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "tipo prende 1 o 3 argomenti" @@ -4178,7 +4239,7 @@ msgstr "indentazione inaspettata" msgid "unexpected keyword argument" msgstr "argomento nominato inaspettato" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "argomento nominato '%q' inaspettato" @@ -4208,15 +4269,15 @@ msgid "unknown type '%q'" msgstr "tipo '%q' sconosciuto" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "'{' spaiato nella stringa di formattazione" +#, c-format +msgid "unmatched '%c' in format" +msgstr "" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "attributo non leggibile" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo di %q non supportato" @@ -4280,18 +4341,19 @@ msgstr "" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" @@ -4347,19 +4409,11 @@ msgstr "indirizzo fuori limite" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y dovrebbe essere un int" - #: shared-module/displayio/Shape.c #, fuzzy msgid "y value out of bounds" msgstr "indirizzo fuori limite" -#: py/objrange.c -msgid "zero step" -msgstr "zero step" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "" @@ -4372,6 +4426,117 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "%q pin invalid" +#~ msgstr "%q pin non valido" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Per favore, segnala il problema con il contenuto del tuo CIRCUITPY a\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Expected a %q" +#~ msgstr "Atteso un %q" + +#, fuzzy +#~ msgid "Read-only object" +#~ msgstr "Sola lettura" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Almeno %d %q devono essere specificati (non %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Pin non validi" + +#~ msgid "complex division by zero" +#~ msgstr "complex divisione per zero" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "il secondo argomanto di int() deve essere >= 2 e <= 36" + +#~ msgid "long int not supported in this build" +#~ msgstr "long int non supportata in questa build" + +#~ msgid "slice step cannot be zero" +#~ msgstr "la step della slice non può essere zero" + +#~ msgid "step must be non-zero" +#~ msgstr "step deve essere non zero" + +#~ msgid "zero step" +#~ msgstr "zero step" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "gli indici %q devono essere interi, non %s" + +#~ msgid "indices must be integers" +#~ msgstr "gli indici devono essere interi" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "lunghezza %d richiesta ma l'oggetto ha lunghezza %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "'}' singolo presente nella stringa di formattazione" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "la soglia deve essere nell'intervallo 0-65536" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "tupla/lista ha la lunghezza sbagliata" + +#~ msgid "unmatched '{' in format" +#~ msgstr "'{' spaiato nella stringa di formattazione" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "Per uscire resettare la scheda senza " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "È stato richiesto l'avvio in modalità sicura da " + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Metodi mancanti readinto() o write() allo stream." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q deve essere >= 0" + +#, fuzzy +#~ msgid "%q must be >= 1" +#~ msgstr "slice del buffer devono essere della stessa lunghezza" + +#~ msgid "address out of bounds" +#~ msgstr "indirizzo fuori limite" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "destination_length deve essere un int >= 0" + +#~ msgid "color should be an int" +#~ msgstr "il colore deve essere un int" + +#, fuzzy +#~ msgid "end_x should be an int" +#~ msgstr "y dovrebbe essere un int" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_index deve essere un int" + +#, fuzzy +#~ msgid "start_x should be an int" +#~ msgstr "y dovrebbe essere un int" + +#~ msgid "y should be an int" +#~ msgstr "y dovrebbe essere un int" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "il buffer sample_source deve essere un bytearray o un array di tipo 'h', " +#~ "'H', 'b' o 'B'" + #~ msgid "%q must be a tuple of length 2" #~ msgstr "%q deve essere una tupla di lunghezza 2" @@ -4648,12 +4813,6 @@ msgstr "" #~ msgid "can only save bytecode" #~ msgstr "È possibile salvare solo bytecode" -#~ msgid "invalid cert" -#~ msgstr "certificato non valido" - -#~ msgid "invalid key" -#~ msgstr "chiave non valida" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Le funzioni Viper non supportano più di 4 argomenti al momento" diff --git a/locale/ja.po b/locale/ja.po index 7fb9268a9d..e8a70816c8 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -8,37 +8,58 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-08-24 06:48+0000\n" -"Last-Translator: Jeff Epler \n" +"PO-Revision-Date: 2023-01-05 02:52+0000\n" +"Last-Translator: Matt Watson \n" "Language-Team: none\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.8.1-dev\n" +"X-Generator: Weblate 4.15.1-dev\n" #: main.c msgid "" "\n" "Code done running.\n" msgstr "" +"\n" +"コード実行完了\n" #: main.c msgid "" "\n" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +"\n" +"オートリロードでコード実行は中止された。まもなくリロードする。\n" + +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" "\n" -"CIRCUITPYドライブの内容を添えて問題を以下で報告してください:\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -54,7 +75,7 @@ msgstr "" #: main.c msgid " not found.\n" -msgstr "" +msgstr " 見るからない\n" #: main.c msgid " output:\n" @@ -65,21 +86,35 @@ msgstr " 出力:\n" msgid "%%c requires int or char" msgstr "%%c にはintまたはcharが必要" +#: main.c +#, fuzzy, c-format +msgid "%02X" +msgstr "%02X" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" -msgstr "" +msgstr "%dアドレスピン、%dRGBピン、%dタイルは%dの高さを指示する。%dではない。" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c +#, fuzzy msgid "%q" -msgstr "" +msgstr "%q" #: shared-bindings/microcontroller/Pin.c msgid "%q and %q contain duplicate pins" @@ -87,7 +122,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "%q and %q must be different" -msgstr "" +msgstr "%qと%qが必ず異なるのは必要" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -97,23 +132,34 @@ msgstr "" msgid "%q failure: %d" msgstr "%q 失敗: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%qは使用中" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "%q インデックスは範囲外" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" -msgstr "" +msgstr "%qは初期化には失敗" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%qは%q" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "このボードでは%qが読み取り専用" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "" @@ -129,10 +175,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -153,28 +195,25 @@ msgstr "" msgid "%q must be >= %d" msgstr "" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%qは0以上でなければなりません" - -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%qは1以上でなければなりません" - -#: py/argcheck.c -msgid "%q must be a string" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/argcheck.c -msgid "%q must be an int" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -194,12 +233,8 @@ msgstr "" msgid "%q out of range" msgstr "%q が範囲外" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "%q ピンは無効" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c @@ -210,11 +245,11 @@ msgstr "%q() は %d 個の位置引数を取りますが、%d 個与えられま msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -399,12 +434,16 @@ msgstr "" msgid "Address must be %d bytes long" msgstr "アドレスは、%dバイト長でなければなりません" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "全てのCAN周辺機器が使用中" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "全てのI2C周辺機器が使用中" @@ -426,7 +465,6 @@ msgid "All SPI peripherals are in use" msgstr "全てのSPI周辺機器が使用中" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "全てのUART周辺機器が使用中" @@ -479,15 +517,22 @@ msgstr "すでにアドバータイズ中" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "すでに実行中" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "" @@ -501,23 +546,16 @@ msgstr "他のsendがすでにアクティブ" msgid "Array must contain halfwords (type 'H')" msgstr "array のタイプは16ビット ('H') でなければなりません" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Arrayの各値は1バイトでなければなりません" -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "最大で %d個の %q が指定できます(%d個でなく)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "%d個のブロックの確保を試みました" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "" @@ -568,7 +606,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -652,7 +690,7 @@ msgstr "CBCブロックは16バイトの整数倍でなければなりません" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "" @@ -772,10 +810,6 @@ msgstr "" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "CircuitPythonのコアコードが激しくクラッシュしました。おっと!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPythonはヒープを確保できませんでした" - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "クロックのストレッチが長すぎ" @@ -790,6 +824,14 @@ msgid "" "connection." msgstr "接続は切断済みでもう使えません。新しい接続を作成してください" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "破損した .mpy ファイル" @@ -814,10 +856,6 @@ msgstr "割り込みをスタートできません。RXビジー" msgid "Couldn't allocate decoder" msgstr "デコーダを確保できません" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "クラッシュしてHardFault_Handlerに入りました" - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "DACチャネル初期化エラー" @@ -872,10 +910,18 @@ msgstr "ディスプレイは16ビット色空間を持たなければなりま msgid "Display rotation must be in 90 degree increments" msgstr "ディスプレイの回転は90度の倍数でなければなりません" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "方向がinputのときドライブモードは使われません" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "ECBは一度に16バイトの演算のみを行います" @@ -901,19 +947,16 @@ msgstr "" msgid "Error in regex" msgstr "正規表現にエラーがあります" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "%qが必要" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -967,10 +1010,6 @@ msgstr "接続失敗: 内部エラー" msgid "Failed to connect: timeout" msgstr "接続失敗: タイムアウト" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "MP3ファイルのパーズに失敗" @@ -985,13 +1024,17 @@ msgid "Failed to write internal flash." msgstr "内部フラッシュ書き込みに失敗" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "ファイルが存在します" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -999,7 +1042,15 @@ msgid "Filters too complex" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" #: shared-bindings/bitmaptools/__init__.c @@ -1032,13 +1083,15 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "グループはすでに使われています" @@ -1059,6 +1112,15 @@ msgstr "ハードウェアビジー。代替のピンを試してください" msgid "Hardware in use, try alternative pins" msgstr "ハードウェア使用中。代わりのピンを試してください" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "閉じられたファイルへのI/O操作" @@ -1068,6 +1130,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "" @@ -1075,11 +1138,6 @@ msgstr "" msgid "I2SOut not available" msgstr "I2SOutが利用できません" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IVは%dバイト長でなければなりません" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1166,6 +1224,7 @@ msgid "Internal define error" msgstr "内部定義エラー" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1178,10 +1237,16 @@ msgstr "内部エラー #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "不正な %q" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "不正な%qピン" @@ -1203,7 +1268,7 @@ msgstr "不正なBSSID" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "不正な引数" @@ -1212,6 +1277,11 @@ msgstr "不正な引数" msgid "Invalid bits per value" msgstr "不正なbits per value" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1221,34 +1291,35 @@ msgstr "" msgid "Invalid format chunk size" msgstr "フォーマットチャンクのサイズが不正" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "不正なメモリアクセス" - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "ピンが不正" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "Keyの長さは、16, 24, 32バイトのいずれかでなければなりません" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1265,7 +1336,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -1355,6 +1426,10 @@ msgstr "" msgid "NVS Error" msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "名前が長すぎます" @@ -1469,11 +1544,6 @@ msgstr "キーが指定されていません" msgid "No long integer support" msgstr "long integerに対応していません" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "" @@ -1509,10 +1579,6 @@ msgstr "指定されたファイル/ディレクトリはありません" msgid "No timer available" msgstr "利用できるタイマーなし" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1532,10 +1598,6 @@ msgstr "接続されていません" msgid "Not playing" msgstr "再生していません" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1552,16 +1614,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "奇数パリティには対応していません" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "8または16ビットの " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "" @@ -1591,10 +1663,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1617,19 +1694,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1684,7 +1766,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "ピンは入力専用" @@ -1731,6 +1812,7 @@ msgstr "Prefixバッファはヒープ上になければなりません" #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" +"REPLに入るため、エンターキーを押す。リーロードするため、Ctl-Dを入力する。\n" #: main.c msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" @@ -1748,6 +1830,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "方向がoutputのときpullは使われません" @@ -1787,8 +1873,9 @@ msgstr "このボードはRTCに対応していません" msgid "Random number generation error" msgstr "乱数生成エラー" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "読み込み専用" @@ -1796,14 +1883,14 @@ msgstr "読み込み専用" msgid "Read-only filesystem" msgstr "読み込み専用のファイルシステム" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "読み込み専用のオブジェクト" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "リフレッシュが早すぎます" @@ -1816,7 +1903,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "要求のAESモードは非対応" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1888,7 +1975,8 @@ msgstr "サイズは対応していません" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "スライスと値の長さが一致しません" @@ -1900,6 +1988,7 @@ msgid "Slices not supported" msgstr "スライスは対応していません" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1923,13 +2012,9 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "ストリームにreadinto()またはwrite()メソッドがありません" - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "少なくとも1つのUARTピンが必要" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -1944,15 +2029,11 @@ msgid "Temperature read timed out" msgstr "温度読み取りがタイムアウトしました" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1960,10 +2041,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1982,6 +2060,10 @@ msgstr "サンプルレートがサンプルとミキサーで一致しません msgid "The sample's signedness does not match the mixer's" msgstr "符号の有無がサンプルとミキサーで一致しません" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2014,10 +2096,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "タイムアウトが長すぎです。最大のタイムアウト長は%d秒" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2062,6 +2140,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2070,6 +2152,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2106,6 +2192,15 @@ msgstr "UUIDの値がstr, int, bufferのいずれでもありません" msgid "Unable to allocate buffers for signed conversion" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2124,14 +2219,29 @@ msgstr "" msgid "Unable to init parser" msgstr "パーザを初期化できません" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "カラーパレットデータを読み込めません" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "nvmに書き込みできません" @@ -2194,7 +2304,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "右辺の要素数が一致しません (expected %d, got %d)" @@ -2239,7 +2355,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2265,10 +2381,6 @@ msgstr "WatchDogTimerは現在動作していません" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "WatchDogTimer.modeはいったんWatchDogMode.RESETに設定すると変更不可" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "WatchDogTimer.timeoutは0以上でなければなりません" - #: py/builtinhelp.c #, c-format msgid "" @@ -2283,6 +2395,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2292,17 +2416,56 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2321,11 +2484,7 @@ msgstr "__new__の引数はユーザ型でなければなりません" msgid "a bytes-like object is required" msgstr "bytes-likeオブジェクトが必要" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "アドレスが範囲外" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "" @@ -2378,8 +2537,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "右辺にはarray/bytesが必要" @@ -2472,10 +2635,6 @@ msgstr "" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "byteorderが文字列ではありません" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2517,15 +2676,10 @@ msgstr "式には代入できません" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "%qを%qに変換できません" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2603,10 +2757,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "" @@ -2707,18 +2865,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "色は0x000000から0xffffffでなければなりません" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "複素数ゼロ除算" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "" @@ -2803,10 +2953,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "bit_depath = 16用のバッファはタイプ'H'のarrayでなければなりません" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "desitination_lengthは正の整数でなければなりません" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "" @@ -2827,12 +2973,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "ゼロ除算 (division by zero)" @@ -2864,10 +3009,6 @@ msgstr "" msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "end_xは整数でなければなりません" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2877,18 +3018,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "error = 0x1%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "例外はBaseExceptionから派生していなければなりません" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "書式化指定子の後に':'が必要" @@ -2987,10 +3126,6 @@ msgstr "fontは2048バイト長でなければなりません" msgid "format requires a dict" msgstr "formatにはdictが必要" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "" @@ -3103,16 +3238,16 @@ msgstr "" msgid "index is out of bounds" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "インデクスが範囲外" -#: py/obj.c -msgid "indices must be integers" -msgstr "インデクスは整数でなければなりません" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "" @@ -3207,10 +3342,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "int()の第2引数は2以上36以下でなければなりません" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3229,6 +3360,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "不正な証明書" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3255,10 +3390,18 @@ msgstr "" msgid "invalid hostname" msgstr "不正なホスト名" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "不正な鍵" + #: py/compile.c msgid "invalid micropython decorator" msgstr "不正なmicropythonデコレータ" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "不正なステップ" @@ -3280,10 +3423,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "数字として不正な構文" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass()の第1引数はクラスでなければなりません" @@ -3340,19 +3479,17 @@ msgstr "" msgid "local variable referenced before assignment" msgstr "" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "このビルドはlong intに非対応" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3481,6 +3618,10 @@ msgstr "" msgid "negative shift count" msgstr "シフトカウントが負数" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "SDカードがありません" @@ -3514,14 +3655,10 @@ msgstr "利用可能なリセットピンがありません" msgid "no response from SD card" msgstr "SDカードからの応答がありません" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "指定の属性はありません" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3646,15 +3783,30 @@ msgid "offset out of bounds" msgstr "" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "bit_depth=16のみ対応しています" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" @@ -3725,10 +3877,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "パレットの長さは32バイトでなければなりません" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_indexには整数が必要" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "" @@ -3780,28 +3928,6 @@ msgstr "pow()の3つ目の引数は0にできません" msgid "pow() with 3 arguments requires integers" msgstr "pow()の第3引数には整数が必要" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3822,11 +3948,6 @@ msgstr "実数部と虚数部は同じ長さでなければなりません" msgid "relative import" msgstr "相対インポート" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "必要な長さは%dですがオブジェクトの長さは%d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3857,13 +3978,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"sample_source バッファには bytearray または 'h','H','b','B'型のarrayが必要" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3897,10 +4011,6 @@ msgstr "文字列フォーマット指定子で符号は使えません" msgid "sign not allowed with integer format specifier 'c'" msgstr "整数フォーマット指定子'c'で符号は使えません" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "文字列フォーマット中に孤立した '}' があります" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3913,10 +4023,6 @@ msgstr "sleepの長さは非負数でなければなりません" msgid "slice step can't be zero" msgstr "スライスのステップは0にできません" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3965,14 +4071,6 @@ msgstr "" msgid "start/end indices" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "stepは非ゼロ値でなければなりません" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "" @@ -3981,10 +4079,6 @@ msgstr "" msgid "stream operation not supported" msgstr "ストリーム操作は非対応" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "文字列のインデクスは整数でなければなりません (%qでなく)" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "文字列ではなくbytesまたはbytesarrayが必要" @@ -4017,14 +4111,6 @@ msgstr "JSONに構文エラーがあります" msgid "syntax error in uctypes descriptor" msgstr "uctypedディスクリプタの構文エラー" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "threshouldは0から65536まで" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time()は9要素のシーケンスを受け取ります" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4032,10 +4118,6 @@ msgstr "time.struct_time()は9要素のシーケンスを受け取ります" msgid "timeout duration exceeded the maximum supported value" msgstr "タイムアウト長は対応する最大値を超えています" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "timeoutは0.0〜100.0秒でなければなりません" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4089,10 +4171,6 @@ msgstr "trapzは同じ長さの1次元arrayに対して定義されています" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "タプル/リストの長さが正しくありません" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4103,8 +4181,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "txとrxを両方ともNoneにできません" @@ -4117,14 +4193,10 @@ msgstr "型'%q'はベース型として使えません" msgid "type is not an acceptable base type" msgstr "この型はベース型にできません" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "typeは1つか3つの引数をとります" @@ -4145,7 +4217,7 @@ msgstr "" msgid "unexpected keyword argument" msgstr "" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "キーワード引数'%q'は使えません" @@ -4175,15 +4247,15 @@ msgid "unknown type '%q'" msgstr "不明な型 '%q'" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "書式中にマッチしない '{' があります" +#, c-format +msgid "unmatched '%c' in format" +msgstr "" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "読み込み不可能な属性" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "非対応の型 %q" @@ -4247,18 +4319,19 @@ msgstr "value_countは0より大きくなければなりません" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "watchdogのtimeoutは0以上でなければなりません" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "windowはinterval以下でなければなりません" @@ -4313,18 +4386,10 @@ msgstr "xが範囲外" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "yは整数でなければなりません" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "yが範囲外" -#: py/objrange.c -msgid "zero step" -msgstr "ステップが0" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "ziはndarrayでなければなりません" @@ -4337,6 +4402,128 @@ msgstr "ziはfloat値でなければなりません" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Supply at least one UART pin" +#~ msgstr "少なくとも1つのUARTピンが必要" + +#~ msgid "%q pin invalid" +#~ msgstr "%q ピンは無効" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "CIRCUITPYドライブの内容を添えて問題を以下で報告してください:\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPythonはヒープを確保できませんでした" + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "クラッシュしてHardFault_Handlerに入りました" + +#~ msgid "Invalid memory access." +#~ msgstr "不正なメモリアクセス" + +#~ msgid "Expected a %q" +#~ msgstr "%qが必要" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IVは%dバイト長でなければなりません" + +#~ msgid "Read-only object" +#~ msgstr "読み込み専用のオブジェクト" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "最大で %d個の %q が指定できます(%d個でなく)" + +#~ msgid "Invalid pins" +#~ msgstr "ピンが不正" + +#~ msgid "byteorder is not a string" +#~ msgstr "byteorderが文字列ではありません" + +#~ msgid "complex division by zero" +#~ msgstr "複素数ゼロ除算" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "int()の第2引数は2以上36以下でなければなりません" + +#~ msgid "long int not supported in this build" +#~ msgstr "このビルドはlong intに非対応" + +#~ msgid "step must be non-zero" +#~ msgstr "stepは非ゼロ値でなければなりません" + +#~ msgid "string indices must be integers, not %q" +#~ msgstr "文字列のインデクスは整数でなければなりません (%qでなく)" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time()は9要素のシーケンスを受け取ります" + +#~ msgid "zero step" +#~ msgstr "ステップが0" + +#~ msgid "WatchDogTimer.timeout must be greater than 0" +#~ msgstr "WatchDogTimer.timeoutは0以上でなければなりません" + +#~ msgid "indices must be integers" +#~ msgstr "インデクスは整数でなければなりません" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "必要な長さは%dですがオブジェクトの長さは%d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "文字列フォーマット中に孤立した '}' があります" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "threshouldは0から65536まで" + +#~ msgid "timeout must be 0.0-100.0 seconds" +#~ msgstr "timeoutは0.0〜100.0秒でなければなりません" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "タプル/リストの長さが正しくありません" + +#~ msgid "unmatched '{' in format" +#~ msgstr "書式中にマッチしない '{' があります" + +#~ msgid "watchdog timeout must be greater than 0" +#~ msgstr "watchdogのtimeoutは0以上でなければなりません" + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "ストリームにreadinto()またはwrite()メソッドがありません" + +#~ msgid "%q must be >= 0" +#~ msgstr "%qは0以上でなければなりません" + +#~ msgid "%q must be >= 1" +#~ msgstr "%qは1以上でなければなりません" + +#~ msgid "address out of bounds" +#~ msgstr "アドレスが範囲外" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "desitination_lengthは正の整数でなければなりません" + +#~ msgid "end_x should be an int" +#~ msgstr "end_xは整数でなければなりません" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_indexには整数が必要" + +#~ msgid "y should be an int" +#~ msgstr "yは整数でなければなりません" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "sample_source バッファには bytearray または 'h','H','b','B'型のarrayが必要" + #~ msgid "%q must be a tuple of length 2" #~ msgstr "%qは長さ2のタプルでなければなりません" @@ -4761,12 +4948,6 @@ msgstr "" #~ msgid "Corrupt raw code" #~ msgstr "破損したraw code" -#~ msgid "invalid cert" -#~ msgstr "不正な証明書" - -#~ msgid "invalid key" -#~ msgstr "不正な鍵" - #~ msgid "parameter annotation must be an identifier" #~ msgstr "引数アノテーションは識別子でなければなりません" diff --git a/locale/ko.po b/locale/ko.po index fce40622bd..6b09cf6e94 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -29,11 +29,31 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" #: py/obj.c @@ -61,19 +81,32 @@ msgstr " 산출:\n" msgid "%%c requires int or char" msgstr "%%c 전수(int)또는 캐릭터(char)필요합니다" +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -93,23 +126,34 @@ msgstr "" msgid "%q failure: %d" msgstr "" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q 사용 중입니다" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "%q 인덱스 범위를 벗어났습니다" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q 인덱스는 %s 가 아닌 정수 여야합니다" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "" @@ -125,10 +169,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -149,28 +189,25 @@ msgstr "" msgid "%q must be >= %d" msgstr "" -#: py/argcheck.c -msgid "%q must be >= 0" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q 는 >=1이어야합니다" - -#: py/argcheck.c -msgid "%q must be a string" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be an int" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" msgstr "" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -190,12 +227,8 @@ msgstr "" msgid "%q out of range" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c @@ -206,11 +239,11 @@ msgstr "" msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -395,12 +428,16 @@ msgstr "" msgid "Address must be %d bytes long" msgstr "" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "사용중인 모든 I2C주변 기기" @@ -422,7 +459,6 @@ msgid "All SPI peripherals are in use" msgstr "사용중인 모든 SPI주변 기기" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "사용중인 모든 UART주변 기기" @@ -475,15 +511,22 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "" @@ -497,23 +540,16 @@ msgstr "" msgid "Array must contain halfwords (type 'H')" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "" @@ -564,7 +600,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -648,7 +684,7 @@ msgstr "" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "" @@ -766,10 +802,6 @@ msgstr "" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "" - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "" @@ -784,6 +816,14 @@ msgid "" "connection." msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "" @@ -808,10 +848,6 @@ msgstr "" msgid "Couldn't allocate decoder" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "" - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "" @@ -866,10 +902,18 @@ msgstr "" msgid "Display rotation must be in 90 degree increments" msgstr "" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "" @@ -895,19 +939,16 @@ msgstr "" msgid "Error in regex" msgstr "Regex에 오류가 있습니다." +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "%q 이 예상되었습니다." - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -961,10 +1002,6 @@ msgstr "" msgid "Failed to connect: timeout" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "" @@ -979,13 +1016,17 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -993,7 +1034,15 @@ msgid "Filters too complex" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" #: shared-bindings/bitmaptools/__init__.c @@ -1026,13 +1075,15 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -1053,6 +1104,15 @@ msgstr "" msgid "Hardware in use, try alternative pins" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "" @@ -1062,6 +1122,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "" @@ -1069,11 +1130,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1158,6 +1214,7 @@ msgid "Internal define error" msgstr "" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1170,10 +1227,16 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "" @@ -1195,7 +1258,7 @@ msgstr "" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "" @@ -1204,6 +1267,11 @@ msgstr "" msgid "Invalid bits per value" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1213,34 +1281,35 @@ msgstr "" msgid "Invalid format chunk size" msgstr "형식 청크 크기가 잘못되었습니다" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "" - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "핀이 유효하지 않습니다" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1257,7 +1326,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -1347,6 +1416,10 @@ msgstr "" msgid "NVS Error" msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "" @@ -1461,11 +1534,6 @@ msgstr "" msgid "No long integer support" msgstr "" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "" @@ -1501,10 +1569,6 @@ msgstr "" msgid "No timer available" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1524,10 +1588,6 @@ msgstr "" msgid "Not playing" msgstr "" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1542,16 +1602,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "" #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "" @@ -1581,10 +1651,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1607,19 +1682,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1674,7 +1754,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "" @@ -1738,6 +1817,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1777,8 +1860,9 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "" @@ -1786,12 +1870,12 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +msgid "Received response was invalid" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c -msgid "Received response was invalid" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" #: shared-bindings/displayio/EPaperDisplay.c @@ -1806,7 +1890,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1878,7 +1962,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1890,6 +1975,7 @@ msgid "Slices not supported" msgstr "" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1913,12 +1999,8 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "" - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c @@ -1934,15 +2016,11 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1950,10 +2028,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1972,6 +2047,10 @@ msgstr "" msgid "The sample's signedness does not match the mixer's" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2004,10 +2083,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2052,6 +2127,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2060,6 +2139,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2096,6 +2179,15 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2114,14 +2206,29 @@ msgstr "" msgid "Unable to init parser" msgstr "파서를 초기화(init) 할 수 없습니다" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "" @@ -2184,7 +2291,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2229,7 +2342,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2255,10 +2368,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -2273,6 +2382,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2282,17 +2403,56 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2311,11 +2471,7 @@ msgstr "" msgid "a bytes-like object is required" msgstr "" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "" @@ -2368,8 +2524,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "" @@ -2462,10 +2622,6 @@ msgstr "" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2507,15 +2663,10 @@ msgstr "" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2593,10 +2744,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "" @@ -2695,18 +2850,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "" @@ -2789,10 +2936,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "" @@ -2813,12 +2956,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "" @@ -2850,10 +2992,6 @@ msgstr "" msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2863,18 +3001,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "':'이 예상되었습니다" @@ -2973,10 +3109,6 @@ msgstr "" msgid "format requires a dict" msgstr "" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "완전한(full)" @@ -3089,14 +3221,14 @@ msgstr "" msgid "index is out of bounds" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" msgstr "" #: extmod/ulab/code/ndarray.c @@ -3192,10 +3324,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3214,6 +3342,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "cert가 유효하지 않습니다" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3240,10 +3372,18 @@ msgstr "형식 지정자(format specifier)가 유효하지 않습니다" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "키가 유효하지 않습니다" + #: py/compile.c msgid "invalid micropython decorator" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "단계(step)가 유효하지 않습니다" @@ -3265,10 +3405,6 @@ msgstr "구문(syntax)가 정수가 유효하지 않습니다" msgid "invalid syntax for number" msgstr "숫자에 대한 구문(syntax)가 유효하지 않습니다" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3325,19 +3461,17 @@ msgstr "" msgid "local variable referenced before assignment" msgstr "" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3466,6 +3600,10 @@ msgstr "" msgid "negative shift count" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3499,14 +3637,10 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3631,15 +3765,30 @@ msgid "offset out of bounds" msgstr "" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" @@ -3710,10 +3859,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "" @@ -3763,28 +3908,6 @@ msgstr "" msgid "pow() with 3 arguments requires integers" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3805,11 +3928,6 @@ msgstr "" msgid "relative import" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3840,12 +3958,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3879,10 +3991,6 @@ msgstr "" msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3895,10 +4003,6 @@ msgstr "" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3947,14 +4051,6 @@ msgstr "" msgid "start/end indices" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "" @@ -3963,10 +4059,6 @@ msgstr "" msgid "stream operation not supported" msgstr "" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" @@ -3999,14 +4091,6 @@ msgstr "" msgid "syntax error in uctypes descriptor" msgstr "" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4014,10 +4098,6 @@ msgstr "" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4071,10 +4151,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4085,8 +4161,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" @@ -4099,14 +4173,10 @@ msgstr "" msgid "type is not an acceptable base type" msgstr "" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "" @@ -4127,7 +4197,7 @@ msgstr "" msgid "unexpected keyword argument" msgstr "" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "" @@ -4157,7 +4227,8 @@ msgid "unknown type '%q'" msgstr "" #: py/objstr.c -msgid "unmatched '{' in format" +#, c-format +msgid "unmatched '%c' in format" msgstr "" #: py/objtype.c py/runtime.c @@ -4165,7 +4236,6 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" @@ -4229,18 +4299,19 @@ msgstr "" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" @@ -4295,18 +4366,10 @@ msgstr "" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "" -#: py/objrange.c -msgid "zero step" -msgstr "" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "" @@ -4319,6 +4382,18 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Expected a %q" +#~ msgstr "%q 이 예상되었습니다." + +#~ msgid "Invalid pins" +#~ msgstr "핀이 유효하지 않습니다" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "%q 인덱스는 %s 가 아닌 정수 여야합니다" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q 는 >=1이어야합니다" + #~ msgid "%q should be an int" #~ msgstr "%q 는 정수(int) 여야합니다" @@ -4374,12 +4449,6 @@ msgstr "" #~ msgid "invalid dupterm index" #~ msgstr "Dupterm index가 유효하지 않습니다" -#~ msgid "invalid cert" -#~ msgstr "cert가 유효하지 않습니다" - -#~ msgid "invalid key" -#~ msgstr "키가 유효하지 않습니다" - #~ msgid "bits must be 7, 8 or 9" #~ msgstr "비트(bits)는 7, 8 또는 9 여야합니다" diff --git a/locale/nl.po b/locale/nl.po index 55b10b872a..90c3e8130e 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -28,15 +28,32 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" "\n" -"Meld een probleem met de inhoud van de CIRCUITPY drive op:\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -63,19 +80,32 @@ msgstr " uitvoer:\n" msgid "%%c requires int or char" msgstr "%%c vereist een int of char" +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -95,23 +125,34 @@ msgstr "" msgid "%q failure: %d" msgstr "%q fout: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q in gebruik" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "%q index buiten bereik" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q indexen moeten integers zijn, niet %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "" @@ -127,10 +168,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -151,28 +188,25 @@ msgstr "" msgid "%q must be >= %d" msgstr "" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q moet >= 0 zijn" - -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q moet >= 1 zijn" - -#: py/argcheck.c -msgid "%q must be a string" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/argcheck.c -msgid "%q must be an int" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -192,12 +226,8 @@ msgstr "" msgid "%q out of range" msgstr "%q buiten bereik" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "%q pin onjuist" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c @@ -208,11 +238,11 @@ msgstr "%q() verwacht %d positionele argumenten maar kreeg %d" msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -275,7 +305,7 @@ msgstr "'%s' verwacht op zijn meest r%d" #: py/emitinlinethumb.c #, c-format msgid "'%s' expects {r0, r1, ...}" -msgstr "'%s' verwacht {r0, r1, …}" +msgstr "'%s' verwacht {r0, r1, ...}" #: py/emitinlinextensa.c #, c-format @@ -397,12 +427,16 @@ msgstr "ADC2 wordt gebruikt door WiFi" msgid "Address must be %d bytes long" msgstr "Adres moet %d bytes lang zijn" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "Alle CAN-peripherals zijn in gebruik" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Alle I2C peripherals zijn in gebruik" @@ -424,7 +458,6 @@ msgid "All SPI peripherals are in use" msgstr "Alle SPI peripherals zijn in gebruik" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Alle UART peripherals zijn in gebruik" @@ -477,15 +510,22 @@ msgstr "Advertising is al bezig." msgid "Already have all-matches listener" msgstr "Heeft al een luisteraar voor 'all-matches'" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Wordt al uitgevoerd" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Zoekt al naar WiFi netwerken" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "" @@ -499,23 +539,16 @@ msgstr "Een andere send is al actief" msgid "Array must contain halfwords (type 'H')" msgstr "Array moet halfwords (type 'H') bevatten" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Array waardes moet enkele bytes zijn." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "Op zijn meest %d %q mogen worden gespecificeerd (niet %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Poging om %d blokken toe te wijzen" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "" @@ -566,7 +599,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -650,7 +683,7 @@ msgstr "CBC blocks moeten meervouden van 16 bytes zijn" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "" @@ -769,10 +802,6 @@ msgstr "CharacteristicBuffer schrijven is niet beschikbaar" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "CircuitPython core code is hard gecrashed. Ojee!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPython kon het heap geheugen niet toewijzen." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Clock stretch is te lang" @@ -789,6 +818,14 @@ msgstr "" "Verbinding is verbroken en kan niet langer gebruikt worden. Creëer een " "nieuwe verbinding." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Corrupt .mpy bestand" @@ -813,10 +850,6 @@ msgstr "Kan interrupt niet starten, RX is bezig" msgid "Couldn't allocate decoder" msgstr "Kan decoder niet alloceren" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Crash naar de HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "DAC kanaal Init Fout" @@ -871,10 +904,18 @@ msgstr "Beeldscherm moet een 16bit kleurruimte hebben." msgid "Display rotation must be in 90 degree increments" msgstr "Beeldscherm rotatie moet in stappen van 90 graden" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "Drive modus niet gebruikt als de richting input is." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "ECB werkt alleen met 16 bytes tegelijkertijd" @@ -900,20 +941,17 @@ msgstr "" msgid "Error in regex" msgstr "Fout in regex" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Verwacht een %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" -msgstr "Verwachtte een alarm" +msgid "Expected a kind of %q" +msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -966,10 +1004,6 @@ msgstr "Verbinding mislukt: interne fout" msgid "Failed to connect: timeout" msgstr "Verbinding mislukt: timeout" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "Kon WiFi niet initialiseren" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Mislukt om MP3 bestand te ontleden" @@ -984,13 +1018,17 @@ msgid "Failed to write internal flash." msgstr "Schrijven naar interne flash mislukt." #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "Bestand bestaat" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -998,8 +1036,16 @@ msgid "Filters too complex" msgstr "Filters zijn te complex" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "Firmware image is ongeldig" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" @@ -1032,13 +1078,15 @@ msgstr "Functie vereist lock" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Groep al gebruikt" @@ -1059,6 +1107,15 @@ msgstr "Hardware bezig, probeer alternatieve pinnen" msgid "Hardware in use, try alternative pins" msgstr "Hardware in gebruik, probeer alternatieve pinnen" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "I/O actie op gesloten bestand" @@ -1068,6 +1125,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "" @@ -1075,11 +1133,6 @@ msgstr "" msgid "I2SOut not available" msgstr "I2SOut is niet beschikbaar" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV %d bytes lang zijn" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1166,6 +1219,7 @@ msgid "Internal define error" msgstr "Interne define fout" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1178,10 +1232,16 @@ msgstr "Interne fout #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "Ongeldige %q" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Ongeldige %q pin" @@ -1203,7 +1263,7 @@ msgstr "Ongeldig BSSID" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Ongeldig argument" @@ -1212,6 +1272,11 @@ msgstr "Ongeldig argument" msgid "Invalid bits per value" msgstr "Ongeldige bits per waarde" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1221,34 +1286,35 @@ msgstr "" msgid "Invalid format chunk size" msgstr "Ongeldig formaat stuk grootte" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Ongeldig geheugen adres." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Ongeldige pinnen" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "Sleutel moet 16, 24, of 32 bytes lang zijn" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1265,7 +1331,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -1355,6 +1421,10 @@ msgstr "" msgid "NVS Error" msgstr "NVS-fout" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "Naam te lang" @@ -1469,11 +1539,6 @@ msgstr "Een sleutel was niet gespecificeerd" msgid "No long integer support" msgstr "Geen lange integer ondersteuning" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "Geen netwerk met dat SSID gevonden" @@ -1509,10 +1574,6 @@ msgstr "Bestand/map bestaat niet" msgid "No timer available" msgstr "Geen timer beschikbaar" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1532,10 +1593,6 @@ msgstr "Niet verbonden" msgid "Not playing" msgstr "Wordt niet afgespeeld" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "Niet instelbaar" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1552,16 +1609,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "Oneven pariteit is niet ondersteund" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Alleen 8 of 16 bit mono met " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Alleen IPv4 adressen worden ondersteund" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "Alleen IPv4-sockets ondersteund" @@ -1595,10 +1662,15 @@ msgstr "" "zijn ondersteund: %d bpp is gegeven" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1621,19 +1693,24 @@ msgstr "Er kan maar één kleur per keer transparant zijn" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Geen sockets meer beschikbaar" @@ -1690,7 +1767,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "Pin kan alleen voor invoer gebruikt worden" @@ -1759,6 +1835,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull niet gebruikt wanneer de richting output is." @@ -1798,8 +1878,9 @@ msgstr "RTC is niet ondersteund door dit board" msgid "Random number generation error" msgstr "Random number generatie fout" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Alleen-lezen" @@ -1807,14 +1888,14 @@ msgstr "Alleen-lezen" msgid "Read-only filesystem" msgstr "Alleen-lezen bestandssysteem" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "Alleen-lezen object" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "Verversing te snel" @@ -1827,7 +1908,7 @@ msgstr "RemoteTransmissionRequests is beperkt tot 8 bytes" msgid "Requested AES mode is unsupported" msgstr "Gevraagde AES modus is niet ondersteund" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1899,7 +1980,8 @@ msgstr "Afmeting niet ondersteund" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice en waarde hebben verschillende lengtes." @@ -1911,6 +1993,7 @@ msgid "Slices not supported" msgstr "Slices niet ondersteund" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool kan alleen met wifi.radio gebruikt worden" @@ -1934,13 +2017,9 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Stream mist readinto() of write() methode." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Geef op zijn minst 1 UART pin op" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -1955,15 +2034,11 @@ msgid "Temperature read timed out" msgstr "Temperatuur lees time-out" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1971,10 +2046,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "De lengte van rgb_pins moet 6, 12, 18, 24 of 30 zijn" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1993,6 +2065,10 @@ msgstr "De sample's sample rate komt niet overeen met die van de mixer" msgid "The sample's signedness does not match the mixer's" msgstr "De sample's signature komt niet overeen met die van de mixer" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2025,10 +2101,6 @@ msgstr "Tijdstip ligt in het verleden." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Time-out is te lang. Maximale time-out lengte is %d seconden" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "Om te beëindigen, reset het bord zonder " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2073,6 +2145,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2081,6 +2157,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2116,6 +2196,15 @@ msgstr "UUID waarde is geen str, int, of byte buffer" msgid "Unable to allocate buffers for signed conversion" msgstr "Niet in staat buffers voor gesigneerde conversie te alloceren" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "Kan vergrendeling niet maken" @@ -2134,14 +2223,29 @@ msgstr "Niet in staat een vrije GCLK te vinden" msgid "Unable to init parser" msgstr "Niet in staat om de parser te initialiseren" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "Niet in staat kleurenpalet data te lezen" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Niet in staat om naar nvm te schrijven." @@ -2204,7 +2308,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "Niet overeenkomend aantal RHS items (verwachtte %d, kreeg %d)." @@ -2251,7 +2361,7 @@ msgstr "Waarde lengte != vereist vaste lengte" msgid "Value length > max_length" msgstr "Waarde length > max_length" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2281,10 +2391,6 @@ msgstr "" "WatchDogTimer.mode kan niet worden gewijzigd zodra de modus is ingesteld op " "WatchDogMode.RESET" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "WatchDogTimer.timeout moet groter dan 0 zijn" - #: py/builtinhelp.c #, c-format msgid "" @@ -2299,6 +2405,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "Gewekt door alarm.\n" @@ -2308,18 +2426,57 @@ msgstr "Gewekt door alarm.\n" msgid "Writes not supported on Characteristic" msgstr "Schrijven niet ondersteund op Characteristic" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "Je hebt aangeven de veilige modus te starten door " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "" #: py/objtype.c msgid "__init__() should return None" @@ -2337,11 +2494,7 @@ msgstr "__new__ arg moet een user-type zijn" msgid "a bytes-like object is required" msgstr "een bytes-achtig object is vereist" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "adres buiten bereik" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "adressen zijn leeg" @@ -2394,8 +2547,12 @@ msgstr "array en indexlengte moeten gelijk zijn" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "array/bytes vereist aan de rechterkant" @@ -2488,10 +2645,6 @@ msgstr "buffer te klein" msgid "buffer too small for requested bytes" msgstr "buffer te klein voor gevraagde bytes" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "byteorder is geen string" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "bytes lengte is geen veelvoud van itemgrootte" @@ -2534,15 +2687,10 @@ msgstr "kan niet toewijzen aan expressie" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "kan %q niet naar %q converteren" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2620,10 +2768,14 @@ msgstr "kan geen niet-'None' waarde naar een net gestartte generator sturen" msgid "can't set 512 block size" msgstr "kan geen 512 blokgrootte instellen" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "kan attribute niet instellen" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "kan '%q' niet opslaan" @@ -2722,18 +2874,10 @@ msgstr "kleurbuffer moet een bytearray of array van type 'b' of 'B' zijn" msgid "color must be between 0x000000 and 0xffffff" msgstr "kleur moet tussen 0x000000 en 0xffffff liggen" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "kleur moet een int zijn" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "complexe deling door 0" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "complexe waardes niet ondersteund" @@ -2818,10 +2962,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "bestemming buffer moet een array van het type 'H' voor bit_depth = 16" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "destination_lengte moest een int groter dan of gelijk zijn aan 0 zijn" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "dict update sequence heeft de verkeerde lengte" @@ -2842,12 +2982,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "deling door nul" @@ -2879,10 +3018,6 @@ msgstr "lege sequentie" msgid "end of format while looking for conversion specifier" msgstr "einde van format terwijl zoekend naar conversie-specifier" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "end_x moet een int zijn" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "epoch_time niet ondersteund op dit bord" @@ -2892,18 +3027,16 @@ msgstr "epoch_time niet ondersteund op dit bord" msgid "error = 0x%08lX" msgstr "fout = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "uitzonderingen moeten afleiden van BaseException" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "verwachtte '%q' maar ontving '%q'" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "verwachtte '%q' of '%q' maar ontving '%q'" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "verwachtte ':' na format specifier" @@ -3002,10 +3135,6 @@ msgstr "lettertype moet 2048 bytes lang zijn" msgid "format requires a dict" msgstr "format vereist een dict" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "vol" @@ -3119,16 +3248,16 @@ msgstr "vulling (padding) is onjuist" msgid "index is out of bounds" msgstr "index is buiten bereik" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "index is buiten bereik" -#: py/obj.c -msgid "indices must be integers" -msgstr "indices moeten integers zijn" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "indices moeten integers, segmenten (slices) of Boolean lijsten zijn" @@ -3222,10 +3351,6 @@ msgstr "invoervectors moeten van gelijke lengte zijn" msgid "inputs are not iterable" msgstr "invoer is niet itereerbaar" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "int() argument 2 moet >=2 en <= 36 zijn" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3244,6 +3369,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "ongeldig certificaat" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3270,10 +3399,18 @@ msgstr "ongeldige formaatspecificatie" msgid "invalid hostname" msgstr "onjuiste hostnaam" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "ongeldige sleutel" + #: py/compile.c msgid "invalid micropython decorator" msgstr "ongeldige micropython decorator" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "ongeldige stap" @@ -3295,10 +3432,6 @@ msgstr "ongeldige syntax voor integer met grondtal %d" msgid "invalid syntax for number" msgstr "ongeldige syntax voor nummer" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() argument 1 moet een klasse zijn" @@ -3358,19 +3491,17 @@ msgstr "lokale '%q' gebruikt voordat type bekend is" msgid "local variable referenced before assignment" msgstr "verwijzing naar een (nog) niet toegewezen lokale variabele" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "long int wordt niet ondersteund in deze build" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "loopback + silent mode wordt niet ondersteund door randapparaat" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3499,6 +3630,10 @@ msgstr "negatieve macht terwijl er geen ondersteuning is voor float" msgid "negative shift count" msgstr "negatieve verschuivingstelling (shift count)" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "geen SD kaart" @@ -3532,14 +3667,10 @@ msgstr "geen reset pin beschikbaar" msgid "no response from SD card" msgstr "geen antwoord van SD kaart" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "niet zo'n attribuut" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3664,15 +3795,30 @@ msgid "offset out of bounds" msgstr "offset buiten bereik" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "alleen bit_depth=16 wordt ondersteund" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "alleen sample_rate=16000 wordt ondersteund" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "alleen segmenten met step=1 (ook wel None) worden ondersteund" @@ -3743,10 +3889,6 @@ msgstr "pack verwachtte %d elementen (ontving %d)" msgid "palette must be 32 bytes long" msgstr "palette moet 32 bytes lang zijn" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_index moet een int zijn" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "parameters moeten registers zijn in de volgorde a2 tot a5" @@ -3796,28 +3938,6 @@ msgstr "derde argument van pow() mag geen 0 zijn" msgid "pow() with 3 arguments requires integers" msgstr "pow() met 3 argumenten vereist integers" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "druk bootknop in bij opstarten.\n" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "druk beide knoppen in bij opstarten.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3838,11 +3958,6 @@ msgstr "reëel en imaginair deel moeten gelijke lengte hebben" msgid "relative import" msgstr "relatieve import" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "gevraagde lengte is %d maar object heeft lengte %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "resultaat kan niet naar gespecificeerd type geconverteerd worden" @@ -3873,14 +3988,6 @@ msgstr "roll argument moet een ndarray zijn" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"sample_source buffer moet een bytearray of array van type 'h', 'H', 'b' of " -"'B' zijn" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3914,10 +4021,6 @@ msgstr "teken niet toegestaan in string formaatspecificatie" msgid "sign not allowed with integer format specifier 'c'" msgstr "teken niet toegestaan bij integer formaatspecificatie 'c'" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "enkele '}' aangetroffen in formaat tekenreeks (string)" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "omvang is alleen voor ndarrays gedefinieerd" @@ -3930,10 +4033,6 @@ msgstr "de slaapduur mag niet negatief zijn" msgid "slice step can't be zero" msgstr "segmentstap mag niet nul zijn" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "segmentstap mag niet nul zijn" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3982,14 +4081,6 @@ msgstr "" msgid "start/end indices" msgstr "start/stop indices" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "start_x moet een int zijn" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "step mag geen nul zijn" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "stop is niet bereikbaar vanaf start" @@ -3998,10 +4089,6 @@ msgstr "stop is niet bereikbaar vanaf start" msgid "stream operation not supported" msgstr "stream operatie niet ondersteund" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "string indices moeten integers zijn, geen %q" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "string niet ondersteund; gebruik bytes of bytearray" @@ -4034,14 +4121,6 @@ msgstr "syntaxisfout in JSON" msgid "syntax error in uctypes descriptor" msgstr "syntaxisfout in uctypes aanduiding" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "drempelwaarde moet in het bereik 0-65536 liggen" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time() accepteert een 9-rij" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4049,10 +4128,6 @@ msgstr "time.struct_time() accepteert een 9-rij" msgid "timeout duration exceeded the maximum supported value" msgstr "time-outduur is groter dan de ondersteunde maximale waarde" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "timeout moet tussen 0.0 en 100.0 seconden zijn" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4106,10 +4181,6 @@ msgstr "trapz is gedefinieerd voor eendimensionale arrays van gelijke lengte" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "tuple of lijst heeft onjuiste lengte" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4120,8 +4191,6 @@ msgstr "twai_driver_install geeft esp-idf fout #%d" msgid "twai_start returned esp-idf error #%d" msgstr "twai_start geeft esp-idf error #%d" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx en rx kunnen niet beiden None zijn" @@ -4134,14 +4203,10 @@ msgstr "type '%q' is geen aanvaardbaar basistype" msgid "type is not an acceptable base type" msgstr "type is geen aanvaardbaar basistype" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "objecttype '%q' heeft geen attribuut '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "het type object 'generator' heeft geen attribuut '__await__'" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "type accepteert 1 of 3 argumenten" @@ -4162,7 +4227,7 @@ msgstr "onverwachte inspringing" msgid "unexpected keyword argument" msgstr "onverwacht trefwoordargument" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "onverwacht trefwoordargument '%q'" @@ -4192,15 +4257,15 @@ msgid "unknown type '%q'" msgstr "onbekend type '%q'" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "'{' zonder overeenkomst in formaat" +#, c-format +msgid "unmatched '%c' in format" +msgstr "" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "onleesbaar attribuut" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "niet ondersteund %q type" @@ -4264,18 +4329,19 @@ msgstr "value_count moet groter dan 0 zijn" msgid "watchdog not initialized" msgstr "watchdog niet geïnitialiseerd" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "watchdog time-out moet groter zijn dan 0" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "breedte moet groter dan nul zijn" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "window moet <= interval zijn" @@ -4330,18 +4396,10 @@ msgstr "x-waarde buiten bereik" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y moet een int zijn" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "y-waarde buiten bereik" -#: py/objrange.c -msgid "zero step" -msgstr "nul-stap" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "zi moet een ndarray zijn" @@ -4354,6 +4412,175 @@ msgstr "zi moet van type float zijn" msgid "zi must be of shape (n_section, 2)" msgstr "zi moet vorm (n_section, 2) hebben" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Geef op zijn minst 1 UART pin op" + +#~ msgid "%q pin invalid" +#~ msgstr "%q pin onjuist" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Meld een probleem met de inhoud van de CIRCUITPY drive op:\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPython kon het heap geheugen niet toewijzen." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Crash naar de HardFault_Handler." + +#~ msgid "Invalid memory access." +#~ msgstr "Ongeldig geheugen adres." + +#~ msgid "Expected a %q" +#~ msgstr "Verwacht een %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV %d bytes lang zijn" + +#~ msgid "Not settable" +#~ msgstr "Niet instelbaar" + +#~ msgid "expected '%q' but got '%q'" +#~ msgstr "verwachtte '%q' maar ontving '%q'" + +#~ msgid "expected '%q' or '%q' but got '%q'" +#~ msgstr "verwachtte '%q' of '%q' maar ontving '%q'" + +#~ msgid "Read-only object" +#~ msgstr "Alleen-lezen object" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Op zijn meest %d %q mogen worden gespecificeerd (niet %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Ongeldige pinnen" + +#~ msgid "byteorder is not a string" +#~ msgstr "byteorder is geen string" + +#~ msgid "complex division by zero" +#~ msgstr "complexe deling door 0" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "int() argument 2 moet >=2 en <= 36 zijn" + +#~ msgid "long int not supported in this build" +#~ msgstr "long int wordt niet ondersteund in deze build" + +#~ msgid "slice step cannot be zero" +#~ msgstr "segmentstap mag niet nul zijn" + +#~ msgid "step must be non-zero" +#~ msgstr "step mag geen nul zijn" + +#~ msgid "string indices must be integers, not %q" +#~ msgstr "string indices moeten integers zijn, geen %q" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time() accepteert een 9-rij" + +#~ msgid "zero step" +#~ msgstr "nul-stap" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "%q indexen moeten integers zijn, niet %s" + +#~ msgid "WatchDogTimer.timeout must be greater than 0" +#~ msgstr "WatchDogTimer.timeout moet groter dan 0 zijn" + +#~ msgid "indices must be integers" +#~ msgstr "indices moeten integers zijn" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "gevraagde lengte is %d maar object heeft lengte %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "enkele '}' aangetroffen in formaat tekenreeks (string)" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "drempelwaarde moet in het bereik 0-65536 liggen" + +#~ msgid "timeout must be 0.0-100.0 seconds" +#~ msgstr "timeout moet tussen 0.0 en 100.0 seconden zijn" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "tuple of lijst heeft onjuiste lengte" + +#~ msgid "unmatched '{' in format" +#~ msgstr "'{' zonder overeenkomst in formaat" + +#~ msgid "watchdog timeout must be greater than 0" +#~ msgstr "watchdog time-out moet groter zijn dan 0" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "Om te beëindigen, reset het bord zonder " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "Je hebt aangeven de veilige modus te starten door " + +#~ msgid "pressing boot button at start up.\n" +#~ msgstr "druk bootknop in bij opstarten.\n" + +#~ msgid "pressing both buttons at start up.\n" +#~ msgstr "druk beide knoppen in bij opstarten.\n" + +#~ msgid "Firmware image is invalid" +#~ msgstr "Firmware image is ongeldig" + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Stream mist readinto() of write() methode." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q moet >= 0 zijn" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q moet >= 1 zijn" + +#~ msgid "address out of bounds" +#~ msgstr "adres buiten bereik" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "" +#~ "destination_lengte moest een int groter dan of gelijk zijn aan 0 zijn" + +#~ msgid "type object 'generator' has no attribute '__await__'" +#~ msgstr "het type object 'generator' heeft geen attribuut '__await__'" + +#~ msgid "color should be an int" +#~ msgstr "kleur moet een int zijn" + +#~ msgid "end_x should be an int" +#~ msgstr "end_x moet een int zijn" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_index moet een int zijn" + +#~ msgid "start_x should be an int" +#~ msgstr "start_x moet een int zijn" + +#~ msgid "y should be an int" +#~ msgstr "y moet een int zijn" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "sample_source buffer moet een bytearray of array van type 'h', 'H', 'b' " +#~ "of 'B' zijn" + +#~ msgid "Expected an alarm" +#~ msgstr "Verwachtte een alarm" + +#~ msgid "Failed to init wifi" +#~ msgstr "Kon WiFi niet initialiseren" + #~ msgid "input must be a tensor of rank 2" #~ msgstr "invoer moet een tensor van rang 2 zijn" @@ -4894,12 +5121,6 @@ msgstr "zi moet vorm (n_section, 2) hebben" #~ msgid "can only save bytecode" #~ msgstr "kan alleen byte-code opslaan" -#~ msgid "invalid cert" -#~ msgstr "ongeldig certificaat" - -#~ msgid "invalid key" -#~ msgstr "ongeldige sleutel" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Viper-functies ondersteunen momenteel niet meer dan 4 argumenten" diff --git a/locale/pl.po b/locale/pl.po index 3041284599..b48ca01b81 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -30,15 +30,32 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" "\n" -"Zgłoś problem z zawartością dysku CIRCUITPY pod adresem\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -65,19 +82,32 @@ msgstr " wyjście:\n" msgid "%%c requires int or char" msgstr "%%c wymaga int lub char" +#: main.c +#, c-format +msgid "%02X" +msgstr "" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -97,23 +127,34 @@ msgstr "" msgid "%q failure: %d" msgstr "%q niepowodzenie: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q w użyciu" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "%q poza zakresem" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q indeks musi być liczbą całkowitą, a nie %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "" @@ -129,10 +170,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -153,28 +190,25 @@ msgstr "" msgid "%q must be >= %d" msgstr "" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q musi być >= 0" - -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q musi być >= 1" - -#: py/argcheck.c -msgid "%q must be a string" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/argcheck.c -msgid "%q must be an int" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -194,12 +228,8 @@ msgstr "" msgid "%q out of range" msgstr "%q poza zakresem" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "nieprawidłowy pin %q" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" #: py/bc.c py/objnamedtuple.c @@ -210,11 +240,11 @@ msgstr "%q() bierze %d argumentów pozycyjnych, lecz podano %d" msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -399,12 +429,16 @@ msgstr "ADC2 jest używany przez WiFi" msgid "Address must be %d bytes long" msgstr "Adres musi mieć %d bajtów" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Wszystkie peryferia I2C w użyciu" @@ -426,7 +460,6 @@ msgid "All SPI peripherals are in use" msgstr "Wszystkie peryferia SPI w użyciu" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Wszystkie peryferia UART w użyciu" @@ -479,15 +512,22 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "" @@ -501,23 +541,16 @@ msgstr "Wysyłanie jest już w toku" msgid "Array must contain halfwords (type 'H')" msgstr "Tablica musi zawierać pół-słowa (typ 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Wartości powinny być bajtami." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Próba przydzielenia %d bloków" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "" @@ -568,7 +601,7 @@ msgid "Bitmap size and bits per value must match" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." +msgid "Boot device must be first (interface #0)." msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -652,7 +685,7 @@ msgstr "Bloki CBC muszą być wielokrotnościami 16 bajtów" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "" @@ -770,10 +803,6 @@ msgstr "Pisanie do CharacteristicBuffer niewspierane" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPython nie mógł przydzielić sterty." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Rozciągnięcie zegara zbyt duże" @@ -790,6 +819,14 @@ msgstr "" "Połączenie zostało rozłączone i nie można go już używać. Utwórz nowe " "połączenie." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Uszkodzony plik .mpy" @@ -814,10 +851,6 @@ msgstr "Nie można rozpocząć przerwania, RX jest zajęty" msgid "Couldn't allocate decoder" msgstr "Nie udało się przydzielić dekodera" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "" - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Błąd inicjalizacji kanału DAC" @@ -872,10 +905,18 @@ msgstr "Wyświetlacz musi mieć 16-bitową przestrzeń kolorów." msgid "Display rotation must be in 90 degree increments" msgstr "Wyświetlacz można obracać co 90 stopni" +#: main.c +msgid "Done" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "Tryb sterowania nieużywany w trybie wejścia." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "ECB działa tylko na 16 bajtach naraz" @@ -901,19 +942,16 @@ msgstr "" msgid "Error in regex" msgstr "Błąd w regex" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Oczekiwano %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -967,10 +1005,6 @@ msgstr "Nie udało się połączyć: błąd wewnętrzny" msgid "Failed to connect: timeout" msgstr "Nie udało się połączyć: upłynął limit czasu" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Nie można przeanalizować pliku MP3" @@ -985,13 +1019,17 @@ msgid "Failed to write internal flash." msgstr "Nie udało się zapisać wewnętrznej pamięci flash." #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "Plik istnieje" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -999,7 +1037,15 @@ msgid "Filters too complex" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" +msgid "Firmware is duplicate" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" #: shared-bindings/bitmaptools/__init__.c @@ -1032,13 +1078,15 @@ msgstr "Funkcja wymaga blokady" msgid "GNSS init" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Grupa już używana" @@ -1059,6 +1107,15 @@ msgstr "Sprzęt zajęty, wypróbuj alternatywne piny" msgid "Hardware in use, try alternative pins" msgstr "Sprzęt w użyciu, wypróbuj alternatywne piny" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "Operacja I/O na zamkniętym pliku" @@ -1068,6 +1125,7 @@ msgid "I2C init error" msgstr "" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "" @@ -1075,11 +1133,6 @@ msgstr "" msgid "I2SOut not available" msgstr "I2SOut niedostępne" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV musi mieć długość %d bajtów" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "" @@ -1166,6 +1219,7 @@ msgid "Internal define error" msgstr "" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "" @@ -1178,10 +1232,16 @@ msgstr "Błąd wewnętrzny #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "Nieprawidłowe %q" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Zła nóżka %q" @@ -1203,7 +1263,7 @@ msgstr "" msgid "Invalid MAC address" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Zły argument" @@ -1212,6 +1272,11 @@ msgstr "Zły argument" msgid "Invalid bits per value" msgstr "Zła liczba bitów wartości" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1221,34 +1286,35 @@ msgstr "" msgid "Invalid format chunk size" msgstr "Zła wielkość fragmentu formatu" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Nieprawidłowy dostęp do pamięci." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Złe nóżki" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "Nieprawidłowy rozmiar" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "Nieprawidłowy stan" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "Klucz musi mieć długość 16, 24 lub 32 bajtów" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1265,7 +1331,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "" @@ -1355,6 +1421,10 @@ msgstr "" msgid "NVS Error" msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "Za długa nazwa" @@ -1469,11 +1539,6 @@ msgstr "Nie określono klucza" msgid "No long integer support" msgstr "" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "" @@ -1509,10 +1574,6 @@ msgstr "Brak pliku/katalogu" msgid "No timer available" msgstr "Brak dostępnego timera" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1532,10 +1593,6 @@ msgstr "Nie podłączono" msgid "Not playing" msgstr "Nic nie jest odtwarzane" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1550,16 +1607,26 @@ msgstr "Obiekt został zwolniony i nie można go już używać. Utwórz nowy obi msgid "Odd parity is not supported" msgstr "Nieparzysta parzystość nie jest wspierana" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Tylko 8 lub 16 bitów mono z " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "" @@ -1589,10 +1656,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1615,19 +1687,24 @@ msgstr "W danym momencie przezroczysty może być tylko jeden kolor" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "Brak pamięci" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1682,7 +1759,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "" @@ -1746,6 +1822,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Podciągnięcie nieużywane w trybie wyjścia." @@ -1785,8 +1865,9 @@ msgstr "Brak obsługi RTC" msgid "Random number generation error" msgstr "Błąd generowania liczb losowych" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Tylko do odczytu" @@ -1794,14 +1875,14 @@ msgstr "Tylko do odczytu" msgid "Read-only filesystem" msgstr "System plików tylko do odczytu" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "Obiekt tylko do odczytu" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "Otrzymana odpowiedź była nieprawidłowa" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "Zbyt wczesne odświeżenie" @@ -1814,7 +1895,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "Żądany tryb AES nie jest obsługiwany" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "Nie znaleziono żądanego zasobu" @@ -1886,7 +1967,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Fragment i wartość są różnych długości." @@ -1898,6 +1980,7 @@ msgid "Slices not supported" msgstr "Fragmenty nieobsługiwane" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1921,13 +2004,9 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Strumień nie ma metod readinto() lub write()." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Podaj co najmniej jeden pin UART" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -1942,15 +2021,11 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1958,10 +2033,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1980,6 +2052,10 @@ msgstr "Sample rate nie pasuje do miksera" msgid "The sample's signedness does not match the mixer's" msgstr "Znak nie pasuje do miksera" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2012,10 +2088,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "By wyjść, proszę zresetować płytkę bez " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2060,6 +2132,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2068,6 +2144,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2103,6 +2183,15 @@ msgstr "UUID nie jest typu str, int lub bytes" msgid "Unable to allocate buffers for signed conversion" msgstr "Nie udała się alokacja buforów do konwersji ze znakiem" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2121,14 +2210,29 @@ msgstr "Brak wolnego GCLK" msgid "Unable to init parser" msgstr "Błąd ustawienia parsera" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "Nie można odczytać danych palety" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Błąd zapisu do NVM." @@ -2191,7 +2295,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "Zła liczba obiektów po prawej stronie (oczekiwano %d, jest %d)." @@ -2236,7 +2346,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2262,10 +2372,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "WatchDogTimer.timeout musi być większe od 0" - #: py/builtinhelp.c #, c-format msgid "" @@ -2280,6 +2386,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2289,18 +2407,57 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "Zażądano trybu bezpieczeństwa przez " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "" #: py/objtype.c msgid "__init__() should return None" @@ -2318,11 +2475,7 @@ msgstr "Argument __new__ musi być typu użytkownika" msgid "a bytes-like object is required" msgstr "wymagany obiekt typu bytes" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "adres poza zakresem" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "adres jest pusty" @@ -2375,8 +2528,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "tablica/bytes wymagane po prawej stronie" @@ -2469,10 +2626,6 @@ msgstr "zbyt mały bufor" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2514,15 +2667,10 @@ msgstr "przypisanie do wyrażenia" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "nie można dokonać konwersji %q na %q" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2600,10 +2748,14 @@ msgstr "świeżo stworzony generator może tylko przyjąć None" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "nie można ustawić atrybutu" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "nie można zapisać '%q'" @@ -2702,18 +2854,10 @@ msgstr "bufor kolorów musi być bytearray lub tablicą typu 'b' lub 'B'" msgid "color must be between 0x000000 and 0xffffff" msgstr "kolor musi być pomiędzy 0x000000 a 0xffffff" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "kolor powinien być liczbą całkowitą" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "zespolone dzielenie przez zero" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "wartości zespolone nieobsługiwane" @@ -2797,10 +2941,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "bufor docelowy musi być tablicą typu 'H' dla bit_depth = 16" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "destination_length musi być nieujemną liczbą całkowitą" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "sekwencja ma złą długość" @@ -2821,12 +2961,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "dzielenie przez zero" @@ -2858,10 +2997,6 @@ msgstr "pusta sekwencja" msgid "end of format while looking for conversion specifier" msgstr "koniec formatu przy szukaniu specyfikacji konwersji" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "end_x powinien być całkowity" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2871,18 +3006,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "błąd = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "wyjątki muszą dziedziczyć po BaseException" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "oczekiwano ':' po specyfikacji formatu" @@ -2981,10 +3114,6 @@ msgstr "font musi mieć 2048 bajtów długości" msgid "format requires a dict" msgstr "format wymaga słownika" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "pełny" @@ -3097,16 +3226,16 @@ msgstr "złe wypełnienie" msgid "index is out of bounds" msgstr "indeks jest poza zakresem" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "indeks poza zakresem" -#: py/obj.c -msgid "indices must be integers" -msgstr "indeksy muszą być całkowite" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "" @@ -3200,10 +3329,6 @@ msgstr "wektory wejściowe muszą być równej długości" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "argument 2 do int() busi być pomiędzy 2 a 36" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3222,6 +3347,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "zły ceryfikat" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3248,10 +3377,18 @@ msgstr "zła specyfikacja formatu" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "zły klucz" + #: py/compile.c msgid "invalid micropython decorator" msgstr "zły dekorator micropythona" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "zły krok" @@ -3273,10 +3410,6 @@ msgstr "zła składnia dla liczby całkowitej w bazie %d" msgid "invalid syntax for number" msgstr "zła składnia dla liczby" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "argument 1 dla issubclass() musi być klasą" @@ -3333,19 +3466,17 @@ msgstr "local '%q' użyty zanim typ jest znany" msgid "local variable referenced before assignment" msgstr "zmienna lokalna użyta przed przypisaniem" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "long int jest nieobsługiwany" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3474,6 +3605,10 @@ msgstr "ujemna potęga, ale brak obsługi liczb zmiennoprzecinkowych" msgid "negative shift count" msgstr "ujemne przesunięcie" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3507,14 +3642,10 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "nie ma takiego atrybutu" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3639,15 +3770,30 @@ msgid "offset out of bounds" msgstr "offset poza zakresem" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "obsługiwane jest tylko bit_depth=16" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "obsługiwane jest tylko sample_rate=16000" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "tylko fragmenty ze step=1 (lub None) są wspierane" @@ -3718,10 +3864,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "paleta musi mieć 32 bajty długości" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_index powinien być całkowity" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "parametry muszą być rejestrami w kolejności a2 do a5" @@ -3772,28 +3914,6 @@ msgstr "trzeci argument pow() nie może być 0" msgid "pow() with 3 arguments requires integers" msgstr "trzyargumentowe pow() wymaga liczb całkowitych" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3814,11 +3934,6 @@ msgstr "rzeczywiste i urojone części muszą mieć jednakową długość" msgid "relative import" msgstr "relatywny import" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "zażądano długości %d ale obiekt ma długość %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3849,13 +3964,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"bufor sample_source musi być bytearray lub tablicą typu 'h', 'H', 'b' lub 'B'" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3889,10 +3997,6 @@ msgstr "znak jest niedopuszczalny w specyfikacji formatu łańcucha" msgid "sign not allowed with integer format specifier 'c'" msgstr "znak jest niedopuszczalny w specyfikacji 'c'" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "pojedynczy '}' w specyfikacji formatu" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3905,10 +4009,6 @@ msgstr "okres snu musi być nieujemny" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "zerowy krok" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3957,14 +4057,6 @@ msgstr "" msgid "start/end indices" msgstr "początkowe/końcowe indeksy" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "start_x powinien być całkowity" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "step nie może być zerowe" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "stop nie jest osiągalne ze start" @@ -3973,10 +4065,6 @@ msgstr "stop nie jest osiągalne ze start" msgid "stream operation not supported" msgstr "operacja na strumieniu nieobsługiwana" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "łańcuchy nieobsługiwane; użyj bytes lub bytearray" @@ -4009,14 +4097,6 @@ msgstr "błąd składni w JSON" msgid "syntax error in uctypes descriptor" msgstr "błąd składni w deskryptorze uctypes" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "threshold musi być w zakresie 0-65536" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time() wymaga 9-elementowej sekwencji" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4024,10 +4104,6 @@ msgstr "time.struct_time() wymaga 9-elementowej sekwencji" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4081,10 +4157,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "krotka/lista ma złą długość" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4095,8 +4167,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx i rx nie mogą być oba None" @@ -4109,14 +4179,10 @@ msgstr "typ '%q' nie może być bazowy" msgid "type is not an acceptable base type" msgstr "typ nie może być bazowy" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "typ '%q' nie ma atrybutu '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "type wymaga 1 lub 3 argumentów" @@ -4137,7 +4203,7 @@ msgstr "złe wcięcie" msgid "unexpected keyword argument" msgstr "zły argument nazwany" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "zły argument nazwany '%q'" @@ -4167,15 +4233,15 @@ msgid "unknown type '%q'" msgstr "zły typ '%q'" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "niepasujące '{' for formacie" +#, c-format +msgid "unmatched '%c' in format" +msgstr "" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "nieczytelny atrybut" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "zły typ %q" @@ -4239,18 +4305,19 @@ msgstr "value_count musi być > 0" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "szerokość musi być większa niż zero" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" @@ -4305,18 +4372,10 @@ msgstr "x poza zakresem" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y powinno być całkowite" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "y poza zakresem" -#: py/objrange.c -msgid "zero step" -msgstr "zerowy krok" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "" @@ -4329,6 +4388,129 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Podaj co najmniej jeden pin UART" + +#~ msgid "%q pin invalid" +#~ msgstr "nieprawidłowy pin %q" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Zgłoś problem z zawartością dysku CIRCUITPY pod adresem\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPython nie mógł przydzielić sterty." + +#~ msgid "Invalid memory access." +#~ msgstr "Nieprawidłowy dostęp do pamięci." + +#~ msgid "Expected a %q" +#~ msgstr "Oczekiwano %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV musi mieć długość %d bajtów" + +#~ msgid "Read-only object" +#~ msgstr "Obiekt tylko do odczytu" + +#~ msgid "Invalid pins" +#~ msgstr "Złe nóżki" + +#~ msgid "complex division by zero" +#~ msgstr "zespolone dzielenie przez zero" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "argument 2 do int() busi być pomiędzy 2 a 36" + +#~ msgid "long int not supported in this build" +#~ msgstr "long int jest nieobsługiwany" + +#~ msgid "slice step cannot be zero" +#~ msgstr "zerowy krok" + +#~ msgid "step must be non-zero" +#~ msgstr "step nie może być zerowe" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time() wymaga 9-elementowej sekwencji" + +#~ msgid "zero step" +#~ msgstr "zerowy krok" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "%q indeks musi być liczbą całkowitą, a nie %s" + +#~ msgid "WatchDogTimer.timeout must be greater than 0" +#~ msgstr "WatchDogTimer.timeout musi być większe od 0" + +#~ msgid "indices must be integers" +#~ msgstr "indeksy muszą być całkowite" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "zażądano długości %d ale obiekt ma długość %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "pojedynczy '}' w specyfikacji formatu" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "threshold musi być w zakresie 0-65536" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "krotka/lista ma złą długość" + +#~ msgid "unmatched '{' in format" +#~ msgstr "niepasujące '{' for formacie" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "By wyjść, proszę zresetować płytkę bez " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "Zażądano trybu bezpieczeństwa przez " + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Strumień nie ma metod readinto() lub write()." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q musi być >= 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q musi być >= 1" + +#~ msgid "address out of bounds" +#~ msgstr "adres poza zakresem" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "destination_length musi być nieujemną liczbą całkowitą" + +#~ msgid "color should be an int" +#~ msgstr "kolor powinien być liczbą całkowitą" + +#~ msgid "end_x should be an int" +#~ msgstr "end_x powinien być całkowity" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_index powinien być całkowity" + +#~ msgid "start_x should be an int" +#~ msgstr "start_x powinien być całkowity" + +#~ msgid "y should be an int" +#~ msgstr "y powinno być całkowite" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "bufor sample_source musi być bytearray lub tablicą typu 'h', 'H', 'b' lub " +#~ "'B'" + #~ msgid "%q must be a tuple of length 2" #~ msgstr "%q musi być krotką o długości 2" @@ -4702,12 +4884,6 @@ msgstr "" #~ msgid "can only save bytecode" #~ msgstr "można zapisać tylko bytecode" -#~ msgid "invalid cert" -#~ msgstr "zły ceryfikat" - -#~ msgid "invalid key" -#~ msgstr "zły klucz" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Funkcje Viper nie obsługują obecnie więcej niż 4 argumentów" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 5d9c4517ec..618f8c6379 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2022-07-15 21:21+0000\n" +"PO-Revision-Date: 2023-03-08 07:10+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.14-dev\n" +"X-Generator: Weblate 4.16.2-dev\n" #: main.c msgid "" @@ -32,15 +32,43 @@ msgstr "" "\n" "O código parou pela recarga automática. Recarregando em breve.\n" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" +"\n" +"CIRCUITPY_PYSTACK_SIZE inválido\n" +"\n" +"\n" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" "\n" -"Registre um problema com o conteúdo do seu controlador no CIRCUITPY\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Relate o problema com seu programa em https://github.com/adafruit/" +"circuitpython/issues." + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" +"\n" +"Pressione reset para sair do modo de segurança.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" +"\n" +"Você está no modo de segurança porque:\n" #: py/obj.c msgid " File \"%q\"" @@ -67,6 +95,16 @@ msgstr " saída:\n" msgid "%%c requires int or char" msgstr "%%c requer int ou char" +#: main.c +#, c-format +msgid "%02X" +msgstr "%02X" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -75,13 +113,16 @@ msgstr "" "%d pinos de endereço, %d pinos rgb e %d blocos indicam uma altura com %d, " "não %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -101,23 +142,34 @@ msgstr "%q contém pinos duplicados" msgid "%q failure: %d" msgstr "%q falha: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q em %q deve ser do tipo %q e não %q" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q em uso" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "O índice %q está fora do intervalo" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "Os índices %q devem ser inteiros, e não %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "a inicialização do %q falhou" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q é %q" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q é de somente leitura para esta placa" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "O comprimento de %q deve ser %d" @@ -133,10 +185,6 @@ msgstr "o comprimento de %q deve ser <= %d" msgid "%q length must be >= %d" msgstr "o comprimento de %q deve ser >= %d" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "o comprimento %q deve ser >=1" - #: py/argcheck.c msgid "%q must be %d" msgstr "%q deve ser %d" @@ -157,29 +205,26 @@ msgstr "%q deve ser <= %d" msgid "%q must be >= %d" msgstr "o %q deve ser >= %d" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q deve ser >= 0" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "%q deve ser uma matriz do tipo 'H'" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q deve ser >= 1" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q deve ser um bytearray ou uma matriz do tipo 'H' ou 'B'" -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q deve ser uma string" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q deve ser um bytearray ou uma matriz do tipo 'h', 'H', 'b', ou 'B'" -#: py/argcheck.c -msgid "%q must be an int" -msgstr "%q deve ser um inteiro" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q deve ser do tipo %q ou %q e não %q" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "%q deve ser do tipo %q" - -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q deve ser do tipo %q ou nenhum" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" +msgstr "%q deve ser do tipo %q e não %q" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" @@ -198,13 +243,9 @@ msgstr "%q fora dos limites" msgid "%q out of range" msgstr "%q fora do alcance" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "%q pino inválido" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" -msgstr "%q com um relatório com ID de 0 deve ter comprimento 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "A etapa %q não pode ser zero" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -214,11 +255,11 @@ msgstr "%q() recebe %d argumentos posicionais, porém %d foram informados" msgid "%q, %q, and %q must all be the same length" msgstr "todos os %q, %q, e %q devem ter mesmo comprimento" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s erro 0x%x" @@ -407,12 +448,16 @@ msgstr "O ADC2 está sendo usado pelo WiFi" msgid "Address must be %d bytes long" msgstr "O endereço deve ter %d bytes de comprimento" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "Intervalo de endereços não permitido" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "Todos os periféricos CAN estão em uso" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Todos os periféricos I2C estão em uso" @@ -434,7 +479,6 @@ msgid "All SPI peripherals are in use" msgstr "Todos os periféricos SPI estão em uso" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Todos os periféricos UART estão em uso" @@ -487,15 +531,22 @@ msgstr "Já está anunciando." msgid "Already have all-matches listener" msgstr "Já há um ouvinte com todas as correspondências" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Já está em execução" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Já está em busca das redes de wifi" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "Ocorreu um erro ao recuperar '%s':\n" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "Um outro PWMAudioOut já está ativo" @@ -509,24 +560,16 @@ msgstr "Outro envio já está ativo" msgid "Array must contain halfwords (type 'H')" msgstr "Array deve conter meias palavras (tipo 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Os valores das matrizes devem ser bytes simples." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "Pelo menos %d %q pode ser definido (não %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Tentativa de alocar %d blocos" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "" -"Tentativa de alocação das pilhas quando o VM não estiver em funcionamento." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "A conversão de áudio ainda não foi implementada" @@ -579,10 +622,8 @@ msgid "Bitmap size and bits per value must match" msgstr "O tamanho do bitmap e os bits por valor devem coincidir" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "" -"O dispositivo de inicialização deve ser o primeiro dispositivo (interface " -"#0)." +msgid "Boot device must be first (interface #0)." +msgstr "O dispositivo de inicialização deve ser o primeiro (interface #0)." #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" @@ -665,7 +706,7 @@ msgstr "Os blocos CBC devem ter múltiplos de 16 bytes" msgid "CIRCUITPY drive could not be found or created." msgstr "A unidade CIRCUITPY não pôde ser encontrada nem criada." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "CRC ou checksum inválido" @@ -789,10 +830,6 @@ msgstr "Escrita CharacteristicBuffer não informada" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "O núcleo principal do CircuitPython falhou feio. Ops!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "O CircuitPython não conseguiu alocar o heap." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Clock se estendeu por tempo demais" @@ -808,6 +845,14 @@ msgid "" msgstr "" "A conexão foi desconectada e não pode mais ser usada. Crie uma nova conexão." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "As coordenadas das matrizes possuem comprimentos diferentes" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "Os tipos das coordenadas das matrizes possuem tamanhos diferentes" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Arquivo .mpy corrompido" @@ -832,10 +877,6 @@ msgstr "Não foi possível iniciar a interrupção, RX ocupado" msgid "Couldn't allocate decoder" msgstr "Não foi possível alocar o decodificador" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Falha no HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Erro de Inicialização do Canal DAC" @@ -890,10 +931,18 @@ msgstr "O monitor deve ter um espaço de cores com 16 bits." msgid "Display rotation must be in 90 degree increments" msgstr "A rotação da tela deve estar em incrementos de 90 graus" +#: main.c +msgid "Done" +msgstr "Feito" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "O modo do controlador não é usado quando a direção for inserida." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "Outra exceção ocorreu durante o tratamento da exceção acima:" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "O BCE opera apenas com 16 bytes por vez" @@ -919,20 +968,17 @@ msgstr "Houve um erro no fluxo MIDI na posição %d" msgid "Error in regex" msgstr "Erro no regex" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "Erro no safemode.py." + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "Erro: Falha na vinculação" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Esperado um" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" -msgstr "Um alarme era esperado" +msgid "Expected a kind of %q" +msgstr "Era esperado uma espécie de %q" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -985,10 +1031,6 @@ msgstr "Falha ao conectar: erro interno" msgid "Failed to connect: timeout" msgstr "Falha ao conectar: tempo limite" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "Houve uma falha ao iniciar o wifi" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Falha ao analisar o arquivo MP3" @@ -1003,13 +1045,17 @@ msgid "Failed to write internal flash." msgstr "Falha ao gravar o flash interno." #: supervisor/shared/safe_mode.c -msgid "Fatal error." -msgstr "Erro fatal." +msgid "Fault detected by hardware." +msgstr "Falha detectada pelo hardware." #: py/moduerrno.c msgid "File exists" msgstr "Arquivo já existe" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "Arquivo não encontrado" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1017,8 +1063,16 @@ msgid "Filters too complex" msgstr "Os filtros são muito complexos" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "A imagem do firmware é invalida" +msgid "Firmware is duplicate" +msgstr "O firmware está duplicado" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "O firmware é inválido" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "O firmware é muito grande" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" @@ -1054,13 +1108,15 @@ msgstr "A função requer bloqueio" msgid "GNSS init" msgstr "Inicialização do GNSS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "Falha Genérica" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "O grupo já está em uso" @@ -1081,6 +1137,17 @@ msgstr "O hardware está ocupado, tente os pinos alternativos" msgid "Hardware in use, try alternative pins" msgstr "O hardware está em uso, tente os pinos alternativos" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "Alocação dinâmica de variáveis quando a VM não estiver funcionando." + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" +"A área de alocação dinâmica de variáveis foi corrompida porque a pilha de " +"funções era muito pequena. Aumente o tamanho da pilha." + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "Operação I/O no arquivo fechado" @@ -1090,6 +1157,7 @@ msgid "I2C init error" msgstr "Erro de inicialização do I2C" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "Periférico I2C em uso" @@ -1097,11 +1165,6 @@ msgstr "Periférico I2C em uso" msgid "I2SOut not available" msgstr "O I2SOut não está disponível" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "O IV deve ter %d bytes de comprimento" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "Os elementos In-buffer devem ter um comprimento de <= 4 bytes" @@ -1194,6 +1257,7 @@ msgid "Internal define error" msgstr "Erro interno de definição" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "Erro interno" @@ -1206,10 +1270,16 @@ msgstr "Erro interno #%d" msgid "Internal watchdog timer expired." msgstr "O temporizador do watchdog interno expirou." -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Erro de interrupção." + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "%q Inválido" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Pino do %q inválido" @@ -1231,7 +1301,7 @@ msgstr "BSSID Inválido" msgid "Invalid MAC address" msgstr "Endereço MAC inválido" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Argumento inválido" @@ -1240,6 +1310,11 @@ msgstr "Argumento inválido" msgid "Invalid bits per value" msgstr "Os valores por bits são inválidos" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "Byte %.*s inválido" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1249,34 +1324,35 @@ msgstr "data_pins[%d] inválido" msgid "Invalid format chunk size" msgstr "Tamanho do pedaço de formato inválido" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "O acesso da memória é inválido." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Endereço MAC multicast inválido" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Pinos inválidos" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "Tamanho inválido" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "Soquete inválido para o TLS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "Estado inválido" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "Escape unicode inválido" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "A chave deve ter 16, 24 ou 32 bytes de comprimento" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "Chave não encontrada" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "Os mapeamentos do led devem corresponder ao tamanho do display" @@ -1293,7 +1369,7 @@ msgstr "Camada já está num grupo" msgid "Layer must be a Group or TileGrid subclass" msgstr "A camada deve ser uma subclasse Group ou TileGrid" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "Endereço MAC inválido" @@ -1383,6 +1459,10 @@ msgstr "O salto NLR falhou. Possível corrupção da memória." msgid "NVS Error" msgstr "Erro NVS" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "Nome ou serviço desconhecido" + #: py/qstr.c msgid "Name too long" msgstr "Nome muito longo" @@ -1497,11 +1577,6 @@ msgstr "Nenhuma chave foi definida" msgid "No long integer support" msgstr "Não há compatibilidade com inteiro longo" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "Não são permitidos mais do que %d dispositivos HID" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "Não há rede com este ssid" @@ -1539,10 +1614,6 @@ msgstr "Este arquivo/diretório não existe" msgid "No timer available" msgstr "Não há um temporizador disponível" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "Declaração de falha do firmware do sistema nórdico." - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "O firmware do sistema nórdico está sem memória" @@ -1562,10 +1633,6 @@ msgstr "Não Conectado" msgid "Not playing" msgstr "Não está jogando" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "Não configurável" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1581,16 +1648,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "A paridade ímpar não é compatível" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "Desligado" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "Ok" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Apenas mono com 8 ou 16 bits com " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Somente os endereços IPv4 são suportados" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "Apenas soquetes IPv4 são suportados" @@ -1624,10 +1701,15 @@ msgstr "" "16bpp ou superior: determinado %d bpp" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." -msgstr "Apenas um TouchAlarm pode ser colocado em deep sleep." +msgid "Only one %q can be set in deep sleep." +msgstr "Apenas um %q pode ser colocado em hibernação profunda." -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "Apenas um %q pode ser definido." + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "Apenas um endereço é permitido" @@ -1650,19 +1732,24 @@ msgstr "Apenas uma cor pode ser transparente de cada vez" msgid "Operation not permitted" msgstr "A operação não é permitida" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "A operação ou o recurso não é suportado" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "A operação expirou" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "Sem slots do serviço MDNS" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "Sem memória" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Sem soquetes" @@ -1719,7 +1806,6 @@ msgid "Pin interrupt already in use" msgstr "A interrupção do pino já está em uso" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "Apenas o pino de entrada" @@ -1791,6 +1877,10 @@ msgstr "O programa faz OUT sem carregar o OSR" msgid "Program size invalid" msgstr "O tamanho do programa é inválido" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "Programa muito longo" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "O Pull não foi usado quando a direção for gerada." @@ -1830,8 +1920,9 @@ msgstr "O RTC não é suportado nesta placa" msgid "Random number generation error" msgstr "Houve um erro na geração do número aleatório" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Somente leitura" @@ -1839,14 +1930,14 @@ msgstr "Somente leitura" msgid "Read-only filesystem" msgstr "Sistema de arquivos somente leitura" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "Objeto de leitura apenas" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "A resposta recebida foi inválida" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "Reconectando" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "A recarga foi cedo demais" @@ -1859,7 +1950,7 @@ msgstr "As requisições de transmissões remotas é limitada a 8 bytes" msgid "Requested AES mode is unsupported" msgstr "O modo AES solicitado não é compatível" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "O recurso solicitado não foi encontrado" @@ -1931,7 +2022,8 @@ msgstr "O tamanho não é suportado" msgid "Sleep Memory not available" msgstr "Sleep memory não está disponível" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Fatie e avalie os diferentes comprimentos." @@ -1943,6 +2035,7 @@ msgid "Slices not supported" msgstr "Fatiamento não compatível" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "O SocketPool só pode ser usado com rádio wifi.radio" @@ -1966,13 +2059,9 @@ msgstr "O estéreo à esquerda deve estar no canal PWM A" msgid "Stereo right must be on PWM channel B" msgstr "O estéreo à direita deve estar no canal PWM B" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Transmita o método ausente readinto() ou write()." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Forneça pelo menos um pino UART" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "Não há suporte para a interrupção do AP." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -1987,36 +2076,22 @@ msgid "Temperature read timed out" msgstr "A leitura da temperatura expirou" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -"A área de alocação dinâmica de variáveis (heap) do CircuitPython foi " -"corrompido pois a pilha era muito pequena.\n" -"Aumente o tamanho da pilha se souber como. Senão:" +"O módulo `microcontroller` foi usado para inicializar em modo de segurança." -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." -msgstr "" -"O módulo `microcontrolador` foi utilizado para iniciar em modo seguro. " -"Pressione reset para encerrar do modo de segurança." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" +msgstr "A exceção acima foi a causa direta da seguinte exceção:" #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "O comprimento dos rgb_pins devem ser 6, 12, 18, 24, ou 30" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" -"O alimentação do micro controlador diminuiu. Certifique-se de que a sua " -"fonte de alimentação fornece\n" -"corrente suficiente para todo o circuito e pressione reset (depois de ejetar " -"o CIRCUITPY)." +"A alimentação foi reduzida. Certifique-se de fornecer energia suficiente." #: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" @@ -2034,6 +2109,10 @@ msgstr "A taxa de amostragem da amostra não coincide com a do mixer" msgid "The sample's signedness does not match the mixer's" msgstr "A amostragem \"signedness\" não coincide com a do mixer" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "Erro fatal no firmware de terceiros." + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "Este microcontrolador não tem suporte para captura contínua." @@ -2070,10 +2149,6 @@ msgstr "" "O tempo limite é long demais: O comprimento máximo do tempo limite é de %d " "segundos" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "Para sair, por favor, reinicie a placa sem " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "Muitos canais na amostra" @@ -2118,6 +2193,10 @@ msgstr "descontinuar o início UART" msgid "UART init" msgstr "inicialização do UART" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "Periférico UART em uso" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "Reinicialização do UART" @@ -2126,6 +2205,10 @@ msgstr "Reinicialização do UART" msgid "UART write" msgstr "Escrita UART" +#: main.c +msgid "UID:" +msgstr "UID:" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "USB ocupado" @@ -2162,6 +2245,15 @@ msgstr "O valor UUID não é um buffer str, int ou byte" msgid "Unable to allocate buffers for signed conversion" msgstr "Não é possível alocar buffers para conversão assinada" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "Não é possível alocar a área de alocação dinâmica de variáveis." + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "Não foi possível configurar o controlador ADC DMA, ErrorCode:%d" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "Não é possível criar um lock" @@ -2180,14 +2272,29 @@ msgstr "Não é possível encontrar GCLK livre" msgid "Unable to init parser" msgstr "Não foi possível iniciar o analisador" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "Não foi possível inicializar o controlador ADC DMA, ErrorCode:%d" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "Não foi possível ler os dados da paleta de cores" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "Não foi possível iniciar o controlador ADC DMA, ErrorCode:%d" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "Não é possível iniciar a consulta mDNS" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "Não é possível gravar no endereço." + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Não é possível gravar no nvm." @@ -2250,7 +2357,13 @@ msgstr "Erro desconhecido do firmware: %04x" msgid "Unknown system firmware error: %d" msgstr "Ocorreu um erro desconhecido no firmware do sistema: %d" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "Código de erro desconhecido %d" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "Quantidade inigualável de itens no RHS (%d esperado, obteve %d)." @@ -2297,7 +2410,7 @@ msgstr "Comprimento do valor != comprimento fixo necessário" msgid "Value length > max_length" msgstr "O comprimento do valor é > max_length" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "A versão era inválida" @@ -2327,10 +2440,6 @@ msgstr "" "O WatchDogTimer.mode não pode ser alterado uma vez definido para " "WatchDogMode.RESET" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "O WatchDogTimer.timeout deve ser maior que 0" - #: py/builtinhelp.c #, c-format msgid "" @@ -2350,6 +2459,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "Wi-Fi: " +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "O Wi-Fi está em modo de ponto de acesso." + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "O Wi-Fi está em modo estação." + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "O Wi-Fi não está ativado" + #: main.c msgid "Woken up by alarm.\n" msgstr "Foi despertado através do alarme.\n" @@ -2359,20 +2480,57 @@ msgstr "Foi despertado através do alarme.\n" msgid "Writes not supported on Characteristic" msgstr "A escrita não é compatível na Característica" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" -msgstr "Você está no modo de segurança pois:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "Você pressionou os dois botões durante a inicialização." + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." +msgstr "Você pressionou o botão A na inicialização." #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." -msgstr "" -"Você pressionou o botão reset durante a inicialização. Pressione-o novamente " -"para sair do modo de segurança." +msgid "You pressed the BOOT button at start up" +msgstr "Você pressionou o botão BOOT na inicialização" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "Você pressionou o botão GPIO0 durante a inicialização." + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "Você pressionou o botão Rec durante a inicialização." + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "Você pressionou o botão SW38 na inicialização." + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "Você pressionou o botão VOLUME na inicialização." + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "Você pressionou o botão central na inicialização." + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "Você pressionou o botão esquerdo na inicialização." #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "Você solicitou o início do modo de segurança através do " +msgid "You pressed the reset button during boot." +msgstr "Você pressionou o botão de reinicialização durante a inicialização." + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "[truncado devido ao comprimento]" #: py/objtype.c msgid "__init__() should return None" @@ -2390,11 +2548,7 @@ msgstr "O argumento __new__ deve ser um tipo usuário" msgid "a bytes-like object is required" msgstr "é necessário objetos tipo bytes" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "endereço fora dos limites" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "os endereços estão vazios" @@ -2447,8 +2601,12 @@ msgstr "a matriz e comprimento do índice devem ser iguais" msgid "array has too many dimensions" msgstr "a matriz possui muitas dimensões" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "a array é grande demais" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "matriz/bytes são necessários no lado direito" @@ -2541,10 +2699,6 @@ msgstr "o buffer é muito pequeno" msgid "buffer too small for requested bytes" msgstr "o buffer é pequeno demais para os bytes requisitados" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "a ordem dos bytes não é uma cadeia de caracteres" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "o comprimento dos bytes não é um múltiplo do tamanho do item" @@ -2586,15 +2740,10 @@ msgstr "a expressão não pode ser atribuída" msgid "can't cancel self" msgstr "não é possível cancelar a si mesmo" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "não é possível converter %q para %q" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "Não é possível converter %q para int" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2674,10 +2823,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "não é possível definir o tamanho de 512 blocos" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "não é possível definir o atributo" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "não é possível definir o atributo '%q'" + #: py/emitnative.c msgid "can't store '%q'" msgstr "não é possível armazenar '%q'" @@ -2780,18 +2933,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "cor deve estar entre 0x000000 e 0xffffff" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "cor deve ser um int" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "comparação de int e uint" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "divisão complexa por zero" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "os valores complexos não compatíveis" @@ -2877,10 +3022,6 @@ msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" "o buffer do destino deve ser uma matriz do tipo 'H' para bit_depth = 16" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "destination_length deve ser um int >= 0" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "sequência da atualização dict tem o comprimento errado" @@ -2901,12 +3042,11 @@ msgstr "as dimensões não coincidem" msgid "div/mod not implemented for uint" msgstr "div/mod não implementado para uint" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "divido por zero" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "divisão por zero" @@ -2938,10 +3078,6 @@ msgstr "seqüência vazia" msgid "end of format while looking for conversion specifier" msgstr "final de formato enquanto procura pelo especificador de conversão" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "end_x deve ser um int" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "O epoch_time não é compatível com esta placa" @@ -2951,18 +3087,18 @@ msgstr "O epoch_time não é compatível com esta placa" msgid "error = 0x%08lX" msgstr "erro = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" +"O espcamera.Camera requer que o PSRAM seja reservado para que possa ser " +"configurado. Consulte a documentação para obter mais informações." + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "as exceções devem derivar a partir do BaseException" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "o retorno esperado era '%q', porém obteve '%q'" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "o retorno esperado era '%q' ou '%q', porém obteve '%q'" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "é esperado ':' após o especificador do formato" @@ -3061,10 +3197,6 @@ msgstr "a fonte deve ter 2048 bytes de comprimento" msgid "format requires a dict" msgstr "formato requer um dict" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "nesta placa, a frequência é de apenas leitura" - #: py/objdeque.c msgid "full" msgstr "cheio" @@ -3177,16 +3309,16 @@ msgstr "preenchimento incorreto" msgid "index is out of bounds" msgstr "o índice está fora dos limites" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "o índice deve ser tupla ou int" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "Índice fora do intervalo" -#: py/obj.c -msgid "indices must be integers" -msgstr "os índices devem ser inteiros" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "os índices devem ser números inteiros, fatias ou listas booleanas" @@ -3281,10 +3413,6 @@ msgstr "os vetores da entrada devem ter o mesmo comprimento" msgid "inputs are not iterable" msgstr "as entradas não são iteráveis" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "int() arg 2 deve ser >= 2 e <= 36" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "o interp é definido para iteráveis 1D com comprimento igual" @@ -3303,6 +3431,10 @@ msgstr "arquitetura inválida" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "bits_per_pixel %d inválido, deve ser, 1, 2, 4, 8, 16, 24, ou 32" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "certificado inválido" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3329,10 +3461,18 @@ msgstr "o especificador do formato é inválido" msgid "invalid hostname" msgstr "o nome do host é inválido" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "chave inválida" + #: py/compile.c msgid "invalid micropython decorator" msgstr "o decorador micropython é inválido" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "configuração inválida" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "passo inválido" @@ -3354,10 +3494,6 @@ msgstr "sintaxe inválida para o número inteiro com base %d" msgid "invalid syntax for number" msgstr "sintaxe inválida para o número" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "rastreamento inválido" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 deve ser uma classe" @@ -3417,19 +3553,17 @@ msgstr "o local '%q' usado antes do tipo conhecido" msgid "local variable referenced before assignment" msgstr "a variável local referenciada antes da atribuição" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "o long int não é suportado nesta compilação" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "o loopback + o modo silencioso não é suportado pelo periférico" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "O mDNS já foi inicializado" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "O mDNS só funciona com WiFi integrado" @@ -3560,6 +3694,10 @@ msgstr "potência negativa sem suporte de flutuação" msgid "negative shift count" msgstr "contagem de turnos negativos" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "o índice aninhado deve ser int" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "nenhum cartão SD" @@ -3593,14 +3731,10 @@ msgstr "nenhum pino de redefinição está disponível" msgid "no response from SD card" msgstr "não houve resposta do cartão SD" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "não há tal atributo" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "não dispositivo em %q" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3725,15 +3859,30 @@ msgid "offset out of bounds" msgstr "desvio fora dos limites" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "apenas bit_depth = 16 é compatível" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "Apenas o mono é compatível" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "somente os ndarrays podem ser concatenados" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "apenas oversample=64 é compatível" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "apenas sample_rate = 16000 é compatível" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" "apenas fatias com a etapa=1 (também conhecida como Nenhuma) são compatíveis" @@ -3809,10 +3958,6 @@ msgstr "o pacote previa %d itens para a empacotamento (obteve %d)" msgid "palette must be 32 bytes long" msgstr "a paleta deve ter 32 bytes de comprimento" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_index deve ser um int" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "os parâmetros devem ser registradores na sequência a2 até a5" @@ -3862,28 +4007,6 @@ msgstr "O terceiro argumento pow() não pode ser 0" msgid "pow() with 3 arguments requires integers" msgstr "o pow() com 3 argumentos requer números inteiros" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "pressionando o botão SW38 na inicialização.\n" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "pressionando o botão de boot na inicialização.\n" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "pressionando ambos os botões durante a inicialização.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "pressionando o botão esquerdo durante a inicialização\n" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "puxe as máscaras em conflito com as máscaras de direção" @@ -3904,11 +4027,6 @@ msgstr "partes reais e imaginárias devem ter o mesmo comprimento" msgid "relative import" msgstr "importação relativa" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "o comprimento solicitado %d, porém o objeto tem comprimento %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "os resultados não podem ser lançados para um determinado tipo" @@ -3939,14 +4057,6 @@ msgstr "argumento de enrolar deve ser um ndarray" msgid "rsplit(None,n)" msgstr "rsplit(Nenhum,n)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"O buffer sample_source deve ser um bytearray ou matriz do tipo 'h', 'H', 'b' " -"ou 'B'" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3980,10 +4090,6 @@ msgstr "sinal não permitido no especificador do formato da sequência" msgid "sign not allowed with integer format specifier 'c'" msgstr "sinal não permitido com o especificador no formato inteiro 'c'" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "único '}' encontrado na string do formato" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "o tamanho é definido apenas para os ndarrays" @@ -3996,10 +4102,6 @@ msgstr "a duração do sleep não deve ser negativo" msgid "slice step can't be zero" msgstr "a etapa da fatia não pode ser zero" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "a etapa da fatia não pode ser zero" - #: py/nativeglue.c msgid "slice unsupported" msgstr "fatia não suportada" @@ -4048,14 +4150,6 @@ msgstr "o source_bitmap deve ter o value_count de 8" msgid "start/end indices" msgstr "os índices de início/fim" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "start_x deve ser um int" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "o passo deve ser diferente de zero" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "stop não está acessível a partir do início" @@ -4064,10 +4158,6 @@ msgstr "stop não está acessível a partir do início" msgid "stream operation not supported" msgstr "a operação do fluxo não é compatível" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "a sequência dos índices devem ser inteiros, não %q" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "a string não é compatível; use bytes ou bytearray" @@ -4100,14 +4190,6 @@ msgstr "erro de sintaxe no JSON" msgid "syntax error in uctypes descriptor" msgstr "houve um erro de sintaxe no descritor uctypes" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "Limite deve estar no alcance de 0-65536" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time() leva uma sequência com 9" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4115,10 +4197,6 @@ msgstr "time.struct_time() leva uma sequência com 9" msgid "timeout duration exceeded the maximum supported value" msgstr "a duração do tempo limite excedeu o valor máximo suportado" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "o tempo limite deve ser entre 0.0 a 100.0 segundos" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "o tempo limite deve ser < 655.35 seg" @@ -4172,10 +4250,6 @@ msgstr "o trapz está definido para 1D arrays de igual tamanho" msgid "trapz is defined for 1D iterables" msgstr "o trapz é definido para iteráveis 1D" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "a tupla/lista está com tamanho incorreto" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4186,8 +4260,6 @@ msgstr "o twai_driver_install retornou um erro esp-idf #%d" msgid "twai_start returned esp-idf error #%d" msgstr "o twai_start retornou um erro esp-idf #%d" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "TX e RX não podem ser ambos" @@ -4200,14 +4272,10 @@ msgstr "o tipo '%q' não é um tipo base aceitável" msgid "type is not an acceptable base type" msgstr "tipo não é um tipo base aceitável" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "o objeto tipo '%q' não possuí atributo '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "o tipo do objeto 'generator' não possui qualquer atributo '__await__'" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "o tipo usa 1 ou 3 argumentos" @@ -4228,7 +4296,7 @@ msgstr "recuo inesperado" msgid "unexpected keyword argument" msgstr "argumento inesperado da palavra-chave" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "argumento inesperado da palavra-chave '%q'" @@ -4258,15 +4326,15 @@ msgid "unknown type '%q'" msgstr "tipo desconhecido '%q'" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "um '{' sem par no formato" +#, c-format +msgid "unmatched '%c' in format" +msgstr "'%c' sem correspondência no formato" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "atributo ilegível" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo %q não suportado" @@ -4330,18 +4398,19 @@ msgstr "o value_count deve ser > 0" msgid "watchdog not initialized" msgstr "o watchdog não foi inicializado" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "o tempo limite do watchdog deve ser maior que 0" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "a largura deve ser maior que zero" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "o wifi não está ativo" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "O wifi.Monitor não está disponível" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "a janela deve ser <= intervalo" @@ -4396,18 +4465,10 @@ msgstr "o valor x está fora dos limites" msgid "xTaskCreate failed" msgstr "o xTaskCreate falhou" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y deve ser um int" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "o valor y está fora dos limites" -#: py/objrange.c -msgid "zero step" -msgstr "passo zero" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "zi deve ser um ndarray" @@ -4420,6 +4481,325 @@ msgstr "zi deve ser de um tipo float" msgid "zi must be of shape (n_section, 2)" msgstr "zi deve estar na forma (n_section, 2)" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Forneça pelo menos um pino UART" + +#~ msgid "%q pin invalid" +#~ msgstr "%q pino inválido" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Registre um problema com o conteúdo do seu controlador no CIRCUITPY\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "" +#~ "Tentativa de alocação das pilhas quando o VM não estiver em funcionamento." + +#~ msgid "Boot device must be first device (interface #0)." +#~ msgstr "" +#~ "O dispositivo de inicialização deve ser o primeiro dispositivo (interface " +#~ "#0)." + +#~ msgid "Both buttons were pressed at start up.\n" +#~ msgstr "Ambos os botões foram pressionados na inicialização.\n" + +#~ msgid "Button A was pressed at start up.\n" +#~ msgstr "O botão A foi pressionado na inicialização.\n" + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "O CircuitPython não conseguiu alocar o heap." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Falha no HardFault_Handler." + +#~ msgid "Fatal error." +#~ msgstr "Erro fatal." + +#~ msgid "Invalid memory access." +#~ msgstr "O acesso da memória é inválido." + +#~ msgid "Nordic system firmware failure assertion." +#~ msgstr "Declaração de falha do firmware do sistema nórdico." + +#~ msgid "The BOOT button was pressed at start up.\n" +#~ msgstr "O botão BOOT foi pressionado na inicialização.\n" + +#~ msgid "" +#~ "The CircuitPython heap was corrupted because the stack was too small.\n" +#~ "Increase the stack size if you know how. If not:" +#~ msgstr "" +#~ "A área de alocação dinâmica de variáveis (heap) do CircuitPython foi " +#~ "corrompido pois a pilha era muito pequena.\n" +#~ "Aumente o tamanho da pilha se souber como. Senão:" + +#~ msgid "The SW38 button was pressed at start up.\n" +#~ msgstr "O botão SW38 foi pressionado na inicialização.\n" + +#~ msgid "The VOLUME button was pressed at start up.\n" +#~ msgstr "O botão VOLUME foi pressionado na inicialização.\n" + +#~ msgid "" +#~ "The `microcontroller` module was used to boot into safe mode. Press reset " +#~ "to exit safe mode." +#~ msgstr "" +#~ "O módulo `microcontrolador` foi utilizado para iniciar em modo seguro. " +#~ "Pressione reset para encerrar do modo de segurança." + +#~ msgid "The central button was pressed at start up.\n" +#~ msgstr "O botão central foi pressionado na inicialização.\n" + +#~ msgid "The left button was pressed at start up.\n" +#~ msgstr "O botão esquerdo foi pressionado na inicialização.\n" + +#~ msgid "" +#~ "The microcontroller's power dipped. Make sure your power supply provides\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY)." +#~ msgstr "" +#~ "O alimentação do micro controlador diminuiu. Certifique-se de que a sua " +#~ "fonte de alimentação fornece\n" +#~ "corrente suficiente para todo o circuito e pressione reset (depois de " +#~ "ejetar o CIRCUITPY)." + +#~ msgid "To exit, please reset the board without requesting safe mode." +#~ msgstr "Para sair, reinicie a placa sem solicitar o modo de segurança." + +#~ msgid "You are in safe mode because:\n" +#~ msgstr "Você está no modo de segurança pois:\n" + +#~ msgid "" +#~ "You pressed the reset button during boot. Press again to exit safe mode." +#~ msgstr "" +#~ "Você pressionou o botão reset durante a inicialização. Pressione-o " +#~ "novamente para sair do modo de segurança." + +#~ msgid "" +#~ "esp32_camera.Camera requires reserved PSRAM to be configured. See the " +#~ "documentation for instructions." +#~ msgstr "" +#~ "esp32_camera.Camera requer que uma reserva PSRAM seja configurada. " +#~ "Consulte a documentação para obter mais informações." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q deve ser do tipo %q" + +#~ msgid "%q must be of type %q or None" +#~ msgstr "%q deve ser do tipo %q ou nenhum" + +#~ msgid "Expected a %q" +#~ msgstr "Esperado um" + +#~ msgid "Expected a %q or %q" +#~ msgstr "Era esperado um %q ou %q" + +#~ msgid "Expected an %q" +#~ msgstr "Esperava-se um(a) %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "O IV deve ter %d bytes de comprimento" + +#~ msgid "Not settable" +#~ msgstr "Não configurável" + +#~ msgid "expected '%q' but got '%q'" +#~ msgstr "o retorno esperado era '%q', porém obteve '%q'" + +#~ msgid "expected '%q' or '%q' but got '%q'" +#~ msgstr "o retorno esperado era '%q' ou '%q', porém obteve '%q'" + +#~ msgid "Read-only object" +#~ msgstr "Objeto de leitura apenas" + +#~ msgid "frequency is read-only for this board" +#~ msgstr "nesta placa, a frequência é de apenas leitura" + +#~ msgid "Pins 21+ not supported from ULP" +#~ msgstr "Os pinos 21+ não são suportados pelo ULP" + +#~ msgid "Unable to write" +#~ msgstr "Não é possível escrever" + +#~ msgid "%q length must be >= 1" +#~ msgstr "o comprimento %q deve ser >=1" + +#~ msgid "%q must be a string" +#~ msgstr "%q deve ser uma string" + +#~ msgid "%q must be an int" +#~ msgstr "%q deve ser um inteiro" + +#~ msgid "%q with a report ID of 0 must be of length 1" +#~ msgstr "%q com um relatório com ID de 0 deve ter comprimento 1" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Pelo menos %d %q pode ser definido (não %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Pinos inválidos" + +#, c-format +#~ msgid "No more than %d HID devices allowed" +#~ msgstr "Não são permitidos mais do que %d dispositivos HID" + +#~ msgid "byteorder is not a string" +#~ msgstr "a ordem dos bytes não é uma cadeia de caracteres" + +#~ msgid "can't convert %q to int" +#~ msgstr "Não é possível converter %q para int" + +#~ msgid "complex division by zero" +#~ msgstr "divisão complexa por zero" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "int() arg 2 deve ser >= 2 e <= 36" + +#~ msgid "long int not supported in this build" +#~ msgstr "o long int não é suportado nesta compilação" + +#~ msgid "slice step cannot be zero" +#~ msgstr "a etapa da fatia não pode ser zero" + +#~ msgid "step must be non-zero" +#~ msgstr "o passo deve ser diferente de zero" + +#~ msgid "string indices must be integers, not %q" +#~ msgstr "a sequência dos índices devem ser inteiros, não %q" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time() leva uma sequência com 9" + +#~ msgid "zero step" +#~ msgstr "passo zero" + +#~ msgid "invalid traceback" +#~ msgstr "rastreamento inválido" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "Os índices %q devem ser inteiros, e não %s" + +#~ msgid "WatchDogTimer.timeout must be greater than 0" +#~ msgstr "O WatchDogTimer.timeout deve ser maior que 0" + +#~ msgid "indices must be integers" +#~ msgstr "os índices devem ser inteiros" + +#~ msgid "non-Device in %q" +#~ msgstr "não dispositivo em %q" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "o comprimento solicitado %d, porém o objeto tem comprimento %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "único '}' encontrado na string do formato" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "Limite deve estar no alcance de 0-65536" + +#~ msgid "timeout must be 0.0-100.0 seconds" +#~ msgstr "o tempo limite deve ser entre 0.0 a 100.0 segundos" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "a tupla/lista está com tamanho incorreto" + +#~ msgid "unmatched '{' in format" +#~ msgstr "um '{' sem par no formato" + +#~ msgid "watchdog timeout must be greater than 0" +#~ msgstr "o tempo limite do watchdog deve ser maior que 0" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "Para sair, por favor, reinicie a placa sem " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "Você solicitou o início do modo de segurança através do " + +#~ msgid "pressing BOOT button at start up.\n" +#~ msgstr "pressionando o botão BOOT na inicialização.\n" + +#~ msgid "pressing SW38 button at start up.\n" +#~ msgstr "pressionando o botão SW38 na inicialização.\n" + +#~ msgid "pressing VOLUME button at start up.\n" +#~ msgstr "pressionando o botão VOLUME na inicialização.\n" + +#~ msgid "pressing boot button at start up.\n" +#~ msgstr "pressionando o botão de boot na inicialização.\n" + +#~ msgid "pressing both buttons at start up.\n" +#~ msgstr "pressionando ambos os botões durante a inicialização.\n" + +#~ msgid "pressing central button at start up.\n" +#~ msgstr "pressionando o botão central na inicialização.\n" + +#~ msgid "pressing button A at start up.\n" +#~ msgstr "pressionando o botão A na inicialização.\n" + +#~ msgid "pressing the left button at start up\n" +#~ msgstr "pressionando o botão esquerdo durante a inicialização\n" + +#~ msgid "Only one TouchAlarm can be set in deep sleep." +#~ msgstr "Apenas um TouchAlarm pode ser colocado em deep sleep." + +#~ msgid "Firmware image is invalid" +#~ msgstr "A imagem do firmware é invalida" + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Transmita o método ausente readinto() ou write()." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q deve ser >= 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q deve ser >= 1" + +#~ msgid "address out of bounds" +#~ msgstr "endereço fora dos limites" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "destination_length deve ser um int >= 0" + +#~ msgid "type object 'generator' has no attribute '__await__'" +#~ msgstr "" +#~ "o tipo do objeto 'generator' não possui qualquer atributo '__await__'" + +#~ msgid "color should be an int" +#~ msgstr "cor deve ser um int" + +#~ msgid "end_x should be an int" +#~ msgstr "end_x deve ser um int" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_index deve ser um int" + +#~ msgid "start_x should be an int" +#~ msgstr "start_x deve ser um int" + +#~ msgid "y should be an int" +#~ msgstr "y deve ser um int" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "O buffer sample_source deve ser um bytearray ou matriz do tipo 'h', 'H', " +#~ "'b' ou 'B'" + +#~ msgid "Expected an alarm" +#~ msgstr "Um alarme era esperado" + +#~ msgid "All I2C targets are in use" +#~ msgstr "Todos os alvos I2C já estão em uso" + +#~ msgid "Failed to init wifi" +#~ msgstr "Houve uma falha ao iniciar o wifi" + #~ msgid "input must be a tensor of rank 2" #~ msgstr "a entrada dos dados deve ser um tensor de nível 2" @@ -5114,12 +5494,6 @@ msgstr "zi deve estar na forma (n_section, 2)" #~ msgid "can only save bytecode" #~ msgstr "apenas o bytecode pode ser salvo" -#~ msgid "invalid cert" -#~ msgstr "certificado inválido" - -#~ msgid "invalid key" -#~ msgstr "chave inválida" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Atualmente, as funções do Viper não suportam mais de 4 argumentos" diff --git a/locale/ru.po b/locale/ru.po index e993d00aec..50249c621d 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2022-04-06 13:37+0000\n" -"Last-Translator: Jeff Epler \n" +"PO-Revision-Date: 2022-12-27 17:42+0000\n" +"Last-Translator: Clay \n" "Language-Team: none\n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.12-dev\n" +"X-Generator: Weblate 4.15.1-dev\n" #: main.c msgid "" @@ -31,17 +31,35 @@ msgid "" "\n" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +"\n" +"Программа остановлена автоматической перезагрузкой. Скоро перезагрузка.\n" + +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" "\n" -"Пожалуйста, сообщите о проблеме, приложив содержимое вашего диска CIRCUITPY " -"на\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -68,21 +86,35 @@ msgstr " вывод:\n" msgid "%%c requires int or char" msgstr "%%c требует int или char" +#: main.c +#, c-format +msgid "%02X" +msgstr "%02X" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" -msgstr "%d адресные пины, %d rgb пины и %d плитки указывают высоту %d а не %d" +msgstr "" +"%d адресных пинов, %d rgb пинов и %d тайлов указывают высоту %d а не %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" -msgstr "" +msgstr "%q" #: shared-bindings/microcontroller/Pin.c msgid "%q and %q contain duplicate pins" @@ -90,7 +122,7 @@ msgstr "%q и %q содержат пины-дупликаты" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "%q and %q must be different" -msgstr "" +msgstr "%q и %q должны быть разными" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -100,25 +132,36 @@ msgstr "%q содержит пины-дупликаты" msgid "%q failure: %d" msgstr "%q сбой: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q используется" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "Индекс %q вне диапазона" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "Индексы %q должны быть целыми числами, а не %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" +msgstr "Инициализация %q не удалась" + +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q является %q" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" msgstr "" -#: py/argcheck.c +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" -msgstr "" +msgstr "Длинна %q должна быть %d" #: py/argcheck.c msgid "%q length must be %d-%d" @@ -126,58 +169,51 @@ msgstr "Длинна %q должна быть %d-%d" #: py/argcheck.c msgid "%q length must be <= %d" -msgstr "" +msgstr "Длинна %q должна быть <= %d" #: py/argcheck.c msgid "%q length must be >= %d" -msgstr "" - -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "Длинна %q должна быть >= 1" +msgstr "Длинна %q должна быть >= %d" #: py/argcheck.c msgid "%q must be %d" -msgstr "" +msgstr "%q должно быть %d" #: py/argcheck.c msgid "%q must be %d-%d" -msgstr "%q должен быть %d-%d" +msgstr "%q должно быть %d-%d" #: shared-bindings/displayio/Display.c msgid "%q must be 1 when %q is True" -msgstr "" +msgstr "%q должно быть 1 когда %q is True" #: py/argcheck.c shared-bindings/gifio/GifWriter.c msgid "%q must be <= %d" -msgstr "%q должен быть <= %d" +msgstr "%q должно быть <= %d" #: py/argcheck.c msgid "%q must be >= %d" -msgstr "%q должен быть >= %d" +msgstr "%q должно быть >= %d" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q должен быть >= 0" - -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q должен быть >= 1" - -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q должен быть строкой" - -#: py/argcheck.c -msgid "%q must be an int" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "%q должен быть типа %q" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q должно быть bytearray или array типа 'H' или 'B'" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q должно быть bytearray или array типа 'h', 'H', 'b', или 'B'" + +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c @@ -197,13 +233,9 @@ msgstr "%q за пределом" msgid "%q out of range" msgstr "%q вне диапазона" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "Пин %q не допустим" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" -msgstr "%q с идентификатором отчёта 0 должен иметь длину 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "Шаг %q не может быть нулём" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -213,11 +245,11 @@ msgstr "%q() принимает %d позиционных аргументов, msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, и %q должны быть одной длинны" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s ошибка 0x%x" @@ -349,7 +381,7 @@ msgstr "'data' требует как минимум 2 аргумента" #: py/compile.c msgid "'data' requires integer arguments" -msgstr "'data' требует целочисленных аргументов" +msgstr "'data' требует целочисленные аргументы" #: py/compile.c msgid "'label' requires 1 argument" @@ -402,12 +434,16 @@ msgstr "ADC2 используется WiFi" msgid "Address must be %d bytes long" msgstr "Адрес должен быть длиной %d байт" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "Диапазон адресов не разрешен" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "Все периферийные устройства CAN уже используются" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Все периферийные устройства I2C уже используются" @@ -429,7 +465,6 @@ msgid "All SPI peripherals are in use" msgstr "Все периферийные устройства SPI уже используются" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Все периферийные устройства UART уже используются" @@ -482,15 +517,22 @@ msgstr "Уже объявляемся (advertising)." msgid "Already have all-matches listener" msgstr "Уже есть универсальный слушатель" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Уже запущен" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Поиск сетей wifi уже происходит" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "Другой PWMAudioOut уже активен" @@ -504,23 +546,16 @@ msgstr "Другая передача уже активна" msgid "Array must contain halfwords (type 'H')" msgstr "Массив должен содержать полуслова (тип 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Значения массива должны быть однобайтовыми." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "Может быть указано не более %d %q (не %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Попытка выделения %d блоков" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "Попытка выделения heap пока виртуальная машина не запущена." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "Преобразование звука не реализовано" @@ -575,8 +610,8 @@ msgid "Bitmap size and bits per value must match" msgstr "Размер bitmap и количество бит-на-значение должны совпадать" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "Загрузочное устройство должно быть первым устройством (интерфейс #0)." +msgid "Boot device must be first (interface #0)." +msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" @@ -657,9 +692,9 @@ msgstr "Блоки CBC должны быть кратны 16 байтам" #: supervisor/shared/safe_mode.c msgid "CIRCUITPY drive could not be found or created." -msgstr "" +msgstr "Не удалось найти или создать диск CIRCUITPY." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "CRC или контрольная сумма неправильная" @@ -669,7 +704,7 @@ msgstr "Вызовите super().__init__() перед обращением к #: ports/cxd56/common-hal/camera/Camera.c msgid "Camera init" -msgstr "" +msgstr "Иницализация камеры" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on RTC IO from deep sleep." @@ -741,7 +776,7 @@ msgstr "Невозможно перемонтировать '/' пока он в #: ports/cxd56/common-hal/microcontroller/__init__.c #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c msgid "Cannot reset into bootloader because no bootloader is present" -msgstr "" +msgstr "Не удалось перезагрузится в загрузчик так как загрузчик отсутствует" #: ports/espressif/common-hal/socketpool/Socket.c msgid "Cannot set socket options" @@ -762,15 +797,18 @@ msgstr "Срез субкласса невозможен" #: shared-module/bitbangio/SPI.c msgid "Cannot transfer without MOSI and MISO pins" -msgstr "" +msgstr "Невозможно передать данные без пинов MOSI и MISO" #: shared-bindings/pwmio/PWMOut.c msgid "Cannot vary frequency on a timer that is already in use" msgstr "Невозможно изменить частоту на таймере, который уже используется" #: ports/nrf/common-hal/alarm/pin/PinAlarm.c +#, fuzzy msgid "Cannot wake on pin edge, only level" msgstr "" +"Невозможно проснуться по изменению логического уровня (CHANGE), только по " +"уровню (LEVEL)" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." @@ -784,10 +822,6 @@ msgstr "Запись в CharacteristicBuffer не предусмотрена" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "Код ядра CircuitPython сильно крашнулся. Упс!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPython не смог выделить heap." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Длинна такта слишком велика" @@ -804,6 +838,14 @@ msgstr "" "Соединение было отключено и больше не может использоваться. Создайте новое " "соединение." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Файл .mpy поврежден" @@ -828,10 +870,6 @@ msgstr "Не удалось запустить прерывание, RX заня msgid "Couldn't allocate decoder" msgstr "Не удалось выделить место для декодера" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Крашнулся в HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Ошибка инициализации канала ЦАП" @@ -888,10 +926,20 @@ msgstr "Дисплей должен иметь 16-битное цветовое msgid "Display rotation must be in 90 degree increments" msgstr "Поворот дисплея должен осуществляться с шагом 90 градусов" +#: main.c +msgid "Done" +msgstr "Выполнено" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "Drive mode не используется, когда направление является входным." +#: py/obj.c +#, fuzzy +msgid "During handling of the above exception, another exception occurred:" +msgstr "" +"Во время обработки вышеупомянутого исключения произошло другое исключение:" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "ECB работает только с 16 байтами за раз" @@ -917,20 +965,17 @@ msgstr "Ошибка в MIDI-потоке на позиции %d" msgid "Error in regex" msgstr "Ошибка в регулярном выражении(regex)" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "" + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "Ошибка: Сбой привязки" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Ожидалось(ся) %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" -msgstr "Ожидался сигнал" +msgid "Expected a kind of %q" +msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -960,7 +1005,7 @@ msgstr "Не удалось получить mutex, ошибка 0x%04x" #: shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" -msgstr "" +msgstr "Не удалось выделить буфер %q" #: ports/espressif/common-hal/wifi/__init__.c msgid "Failed to allocate Wifi memory" @@ -983,10 +1028,6 @@ msgstr "Не удалось подключиться: внутренняя ош msgid "Failed to connect: timeout" msgstr "Не удалось подключиться: тайм-аут" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "Не удалось инициировать wifi" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Не удалось распарсить файл MP3" @@ -1001,13 +1042,17 @@ msgid "Failed to write internal flash." msgstr "Не удалось записать внутреннюю флэш-память." #: supervisor/shared/safe_mode.c -msgid "Fatal error." -msgstr "Фатальная ошибка." +msgid "Fault detected by hardware." +msgstr "" #: py/moduerrno.c msgid "File exists" msgstr "Файл существует" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "Файл не найден" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1015,8 +1060,18 @@ msgid "Filters too complex" msgstr "Фильтры слишком сложные" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "Образ прошивки неправильный" +#, fuzzy +msgid "Firmware is duplicate" +msgstr "Прошивка является дубликатом" + +#: ports/espressif/common-hal/dualbank/__init__.c +#, fuzzy +msgid "Firmware is invalid" +msgstr "Прошивка является неправильной" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "Прошивка слишком большая" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" @@ -1036,6 +1091,8 @@ msgstr "Формат не поддерживается" msgid "" "Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" msgstr "" +"Частота должна быть 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 или 1008 " +"МГц" #: shared-bindings/pwmio/PWMOut.c msgid "Frequency must match existing PWMOut using this timer" @@ -1050,15 +1107,17 @@ msgstr "Функция требует блокировки" #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" -msgstr "" +msgstr "Инициализация GNSS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "Общий сбой" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Группа уже используется" @@ -1067,7 +1126,7 @@ msgstr "Группа уже используется" #: ports/mimxrt10xx/common-hal/busio/SPI.c ports/nrf/common-hal/busio/SPI.c #: ports/raspberrypi/common-hal/busio/SPI.c msgid "Half duplex SPI is not implemented" -msgstr "" +msgstr "Полудуплексный SPI не реализован" #: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c #: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/canio/CAN.c @@ -1079,15 +1138,25 @@ msgstr "Оборудование занято, попробуйте исполь msgid "Hardware in use, try alternative pins" msgstr "Оборудование используется, попробуйте использовать другие пины" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "Операция ввода-вывода на закрытом файле" #: ports/stm/common-hal/busio/I2C.c msgid "I2C init error" -msgstr "" +msgstr "Ошибка инициализации I2C" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "Периферийное устройство I2C уже используется" @@ -1095,11 +1164,6 @@ msgstr "Периферийное устройство I2C уже использ msgid "I2SOut not available" msgstr "I2SOut недоступен" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV должен быть длиной %d байт" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "Элементы буфера должны быть длиной <= 4 байта" @@ -1191,6 +1255,7 @@ msgid "Internal define error" msgstr "Внутренняя ошибка определения" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "Внутренняя ошибка" @@ -1200,13 +1265,20 @@ msgid "Internal error #%d" msgstr "Внутренняя ошибка #%d" #: supervisor/shared/safe_mode.c +#, fuzzy msgid "Internal watchdog timer expired." +msgstr "Внутренний сторожевой таймер истек." + +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." msgstr "" -#: py/argcheck.c +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "Недопустимый %q" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Недопустимый пин %q" @@ -1228,7 +1300,7 @@ msgstr "Неверный BSSID" msgid "Invalid MAC address" msgstr "Неверный MAC-адрес" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Недопустимый аргумент" @@ -1237,6 +1309,11 @@ msgstr "Недопустимый аргумент" msgid "Invalid bits per value" msgstr "Недопустимое бит-на-значение" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "Неверный байт %.*s" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1246,34 +1323,35 @@ msgstr "Неверный data_pins[%d]" msgid "Invalid format chunk size" msgstr "Неверный размер блока формата" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Неправильный доступ к памяти." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Неверный MAC-адрес multicast" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Недопустимые пины" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "Неверный размер" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "Неверный сокет для TLS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "Неверное состояние" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "Ключ должен быть длинной 16, 24 или 32 байта" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "Ключ не найден" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "" @@ -1283,14 +1361,16 @@ msgid "LHS of keyword arg must be an id" msgstr "LHS ключевого слова arg должен быть идентификатором(id)" #: shared-module/displayio/Group.c +#, fuzzy msgid "Layer already in a group" -msgstr "" +msgstr "Слой уже в группе (Group)" #: shared-module/displayio/Group.c +#, fuzzy msgid "Layer must be a Group or TileGrid subclass" -msgstr "" +msgstr "Слой должен быть группой (Group) или субклассом TileGrid." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "MAC адрес был недействительным" @@ -1310,11 +1390,11 @@ msgstr "Задержка включения микрофона должна бы #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" -msgstr "" +msgstr "Размер данных различается" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched swap flag" -msgstr "" +msgstr "Несоответствие флага swap" #: ports/mimxrt10xx/common-hal/busio/SPI.c msgid "Missing MISO or MOSI Pin" @@ -1322,7 +1402,7 @@ msgstr "Отсутствует пин MISO или MOSI" #: ports/stm/common-hal/busio/SPI.c msgid "Missing MISO or MOSI pin" -msgstr "" +msgstr "Отсутствует пин MISO или MOSI" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format @@ -1381,13 +1461,17 @@ msgstr "Не удалось выполнить NLR jump. Вероятно, по msgid "NVS Error" msgstr "Ошибка NVS" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "" + #: py/qstr.c msgid "Name too long" msgstr "Имя слишком длинное" #: shared-bindings/displayio/TileGrid.c msgid "New bitmap must be same size as old bitmap" -msgstr "" +msgstr "Новый bitmap должен быть того же размера что и старый" #: ports/espressif/common-hal/_bleio/__init__.c msgid "Nimble out of memory" @@ -1415,13 +1499,13 @@ msgid "No DMA pacing timer found" msgstr "" #: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c -#, c-format +#, fuzzy, c-format msgid "No I2C device at address: 0x%x" -msgstr "" +msgstr "Не найдено устройство I2C по адресу: %x" #: supervisor/shared/web_workflow/web_workflow.c msgid "No IP" -msgstr "" +msgstr "Нет IP" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c @@ -1430,7 +1514,7 @@ msgstr "Нет пина MISO" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MISO pin" -msgstr "" +msgstr "Нет пина MISO" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c @@ -1439,7 +1523,7 @@ msgstr "Нет пина MOSI" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MOSI pin" -msgstr "" +msgstr "Нет пина MOSI" #: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c @@ -1495,11 +1579,6 @@ msgstr "Ключ не был указан" msgid "No long integer support" msgstr "Нет поддержки длинных целых чисел (long integer)" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "Допускается не более %d HID устройств" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "Нет сети с этим ssid" @@ -1525,8 +1604,9 @@ msgid "No space left on device" msgstr "На устройстве не осталось свободного места" #: py/moduerrno.c +#, fuzzy msgid "No such device" -msgstr "" +msgstr "Нет такого устройства" #: py/moduerrno.c msgid "No such file/directory" @@ -1536,10 +1616,6 @@ msgstr "Файл/директория не существует" msgid "No timer available" msgstr "Нет доступного таймера" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1556,12 +1632,9 @@ msgstr "Не подключено" #: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c #: shared-bindings/audiopwmio/PWMAudioOut.c +#, fuzzy msgid "Not playing" -msgstr "Не играет" - -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "Не устанавливается" +msgstr "Не воспроизводится (Not playing)" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format @@ -1579,16 +1652,27 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "Выключено" + +#: supervisor/shared/bluetooth/bluetooth.c +#, fuzzy +msgid "Ok" +msgstr "Ok" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Только 8- или 16-битное моно с " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Поддерживаются только адреса IPv4" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "Поддерживаются только сокеты IPv4" @@ -1620,10 +1704,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." +msgstr "Только один %q может быть погружен в глубокий сон." + +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1646,19 +1735,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1713,7 +1807,6 @@ msgid "Pin interrupt already in use" msgstr "Прерывание пина уже используется" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "Пин является только входом" @@ -1782,6 +1875,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1821,8 +1918,9 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "" @@ -1830,12 +1928,12 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +msgid "Received response was invalid" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c -msgid "Received response was invalid" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" #: shared-bindings/displayio/EPaperDisplay.c @@ -1850,7 +1948,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1922,7 +2020,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1934,6 +2033,7 @@ msgid "Slices not supported" msgstr "" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1957,14 +2057,10 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." msgstr "" -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Предоставьте хотяб один пин UART" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -1978,15 +2074,11 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1994,10 +2086,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "Длина rgb_pins должна быть 6, 12, 18, 24 или 30" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -2016,6 +2105,10 @@ msgstr "" msgid "The sample's signedness does not match the mixer's" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2050,10 +2143,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2098,6 +2187,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2106,6 +2199,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2141,6 +2238,15 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2159,14 +2265,29 @@ msgstr "" msgid "Unable to init parser" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "" @@ -2229,7 +2350,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2274,7 +2401,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2300,10 +2427,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -2318,6 +2441,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2327,17 +2462,56 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2356,11 +2530,7 @@ msgstr "" msgid "a bytes-like object is required" msgstr "" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "" @@ -2413,8 +2583,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "" @@ -2507,10 +2681,6 @@ msgstr "" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2552,15 +2722,10 @@ msgstr "" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2638,10 +2803,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "" @@ -2740,18 +2909,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "" @@ -2834,10 +2995,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "" @@ -2858,12 +3015,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "" @@ -2895,10 +3051,6 @@ msgstr "" msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2908,18 +3060,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -3018,10 +3168,6 @@ msgstr "" msgid "format requires a dict" msgstr "" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "" @@ -3134,14 +3280,14 @@ msgstr "" msgid "index is out of bounds" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" msgstr "" #: extmod/ulab/code/ndarray.c @@ -3237,10 +3383,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3259,6 +3401,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3285,10 +3431,18 @@ msgstr "" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "" + #: py/compile.c msgid "invalid micropython decorator" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "" @@ -3310,10 +3464,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3370,19 +3520,17 @@ msgstr "" msgid "local variable referenced before assignment" msgstr "" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3511,6 +3659,10 @@ msgstr "" msgid "negative shift count" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3544,14 +3696,10 @@ msgstr "нет доступного контакта сброса" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3676,15 +3824,30 @@ msgid "offset out of bounds" msgstr "" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" @@ -3755,10 +3918,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "" @@ -3808,28 +3967,6 @@ msgstr "" msgid "pow() with 3 arguments requires integers" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3850,11 +3987,6 @@ msgstr "" msgid "relative import" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3885,12 +4017,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3924,10 +4050,6 @@ msgstr "" msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3940,10 +4062,6 @@ msgstr "" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3992,14 +4110,6 @@ msgstr "" msgid "start/end indices" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "" @@ -4008,10 +4118,6 @@ msgstr "" msgid "stream operation not supported" msgstr "" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" @@ -4044,14 +4150,6 @@ msgstr "" msgid "syntax error in uctypes descriptor" msgstr "" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4059,10 +4157,6 @@ msgstr "" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4116,10 +4210,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4130,8 +4220,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" @@ -4144,14 +4232,10 @@ msgstr "" msgid "type is not an acceptable base type" msgstr "" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "" @@ -4172,7 +4256,7 @@ msgstr "" msgid "unexpected keyword argument" msgstr "" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "" @@ -4202,7 +4286,8 @@ msgid "unknown type '%q'" msgstr "" #: py/objstr.c -msgid "unmatched '{' in format" +#, c-format +msgid "unmatched '%c' in format" msgstr "" #: py/objtype.c py/runtime.c @@ -4210,7 +4295,6 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" @@ -4274,18 +4358,19 @@ msgstr "" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" @@ -4330,7 +4415,7 @@ msgstr "" #: extmod/ulab/code/numpy/vector.c msgid "wrong output type" -msgstr "" +msgstr "неверный тип вывода" #: shared-module/displayio/Shape.c msgid "x value out of bounds" @@ -4338,23 +4423,15 @@ msgstr "" #: ports/espressif/common-hal/audiobusio/__init__.c msgid "xTaskCreate failed" -msgstr "" - -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "" +msgstr "xTaskCreate провалился" #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "" -#: py/objrange.c -msgid "zero step" -msgstr "" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" -msgstr "" +msgstr "zi должен быть bytearray" #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be of float type" @@ -4364,6 +4441,115 @@ msgstr "zi должно быть типа float" msgid "zi must be of shape (n_section, 2)" msgstr "zi должен иметь форму (n_section, 2)" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Предоставьте хотяб один пин UART" + +#~ msgid "%q pin invalid" +#~ msgstr "Пин %q не допустим" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Пожалуйста, сообщите о проблеме, приложив содержимое вашего диска " +#~ "CIRCUITPY на\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "Попытка выделения heap пока виртуальная машина не запущена." + +#~ msgid "Boot device must be first device (interface #0)." +#~ msgstr "" +#~ "Загрузочное устройство должно быть первым устройством (интерфейс #0)." + +#~ msgid "Both buttons were pressed at start up.\n" +#~ msgstr "Обе кнопки были нажаты при загрузке.\n" + +#~ msgid "Button A was pressed at start up.\n" +#~ msgstr "Кнопка A была нажата при загрузке\n" + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPython не смог выделить heap." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Крашнулся в HardFault_Handler." + +#~ msgid "Fatal error." +#~ msgstr "Фатальная ошибка." + +#~ msgid "Invalid memory access." +#~ msgstr "Неправильный доступ к памяти." + +#, fuzzy +#~ msgid "Nordic system firmware failure assertion." +#~ msgstr "Сбой системной прошивки Nordic (assertion)." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q должно быть типа %q" + +#~ msgid "%q must be of type %q or None" +#~ msgstr "%q должно быть типа %q или None" + +#~ msgid "Expected a %q" +#~ msgstr "Ожидалось(ся) %q" + +#~ msgid "Expected a %q or %q" +#~ msgstr "Ожидалось %q или %q" + +#, fuzzy +#~ msgid "Expected an %q" +#~ msgstr "Ожидалось %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV должен быть длиной %d байт" + +#, fuzzy +#~ msgid "Not settable" +#~ msgstr "Невозможно установить" + +#~ msgid "%q length must be >= 1" +#~ msgstr "Длинна %q должна быть >= 1" + +#~ msgid "%q must be a string" +#~ msgstr "%q должно быть строкой" + +#~ msgid "%q must be an int" +#~ msgstr "%q должно быть int" + +#~ msgid "%q with a report ID of 0 must be of length 1" +#~ msgstr "%q с идентификатором отчёта 0 должен иметь длину 1" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Может быть указано не более %d %q (не %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Недопустимые пины" + +#, c-format +#~ msgid "No more than %d HID devices allowed" +#~ msgstr "Допускается не более %d HID устройств" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "Индексы %q должны быть целыми числами, а не %s" + +#~ msgid "Firmware image is invalid" +#~ msgstr "Образ прошивки неправильный" + +#~ msgid "%q must be >= 0" +#~ msgstr "%q должен быть >= 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q должен быть >= 1" + +#~ msgid "Expected an alarm" +#~ msgstr "Ожидался сигнал" + +#~ msgid "Failed to init wifi" +#~ msgstr "Не удалось инициировать wifi" + #~ msgid "%q must be a tuple of length 2" #~ msgstr "%q должен быть кортежем длинной 2" diff --git a/locale/sv.po b/locale/sv.po index 4a53d9bcda..6ba1cdc1a2 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2022-07-14 18:05+0000\n" +"PO-Revision-Date: 2023-03-08 07:10+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" "Language: sv\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14-dev\n" +"X-Generator: Weblate 4.16.2-dev\n" #: main.c msgid "" @@ -32,15 +32,43 @@ msgstr "" "\n" "Koden stoppades av automatisk laddning. Omladdning sker strax.\n" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" +"\n" +"Ogiltig CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\n" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" "\n" -"Vänligen skapa ett ärende med innehållet i din CIRCUITPY-enhet på\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Skicka in ett ärende med ditt program till https://github.com/adafruit/" +"circuitpython/issues." + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" +"\n" +"Tryck reset för att lämna säkert läge.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" +"\n" +"Du är i säkert läge eftersom:\n" #: py/obj.c msgid " File \"%q\"" @@ -67,6 +95,16 @@ msgstr " utdata:\n" msgid "%%c requires int or char" msgstr "%%c kräver int eller char" +#: main.c +#, c-format +msgid "%02X" +msgstr "%02X" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "%S" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -74,13 +112,16 @@ msgid "" msgstr "" "%d adresspinnar, %d rgb-pinnar och %d brickor anger en höjd på %d, inte %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -100,23 +141,34 @@ msgstr "%q innehåller dubblettstift" msgid "%q failure: %d" msgstr "%q-fel: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q i %q måste vara av typen %q, inte %q" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q används redan" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "Index %q ligger utanför intervallet" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "Indexet %q måste vara ett heltal, inte %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "%q init misslyckades" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q är %q" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q är skrivskyddad för det här kortet" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" msgstr "längden på %q måste vara %d" @@ -132,10 +184,6 @@ msgstr "längden på %q måste vara <= %d" msgid "%q length must be >= %d" msgstr "längden på %q måste vara >= %d" -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "längden på %q måste vara >= 1" - #: py/argcheck.c msgid "%q must be %d" msgstr "%q måste vara %d" @@ -156,29 +204,28 @@ msgstr "%q måste vara <= %d" msgid "%q must be >= %d" msgstr "%q måste vara >= %d" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q måste vara >= 0" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "%q måste vara en array av typen 'H'" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q måste vara >= 1" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q måste vara en bytearray eller array av typen 'H' eller 'B'" -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q måste vara en sträng" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "" +"%q måste vara en bytearray eller en array av typen \"h\", \"H\", \"b\" eller " +"\"B\"" -#: py/argcheck.c -msgid "%q must be an int" -msgstr "%q måste vara en int" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q måste vara av typen %q eller %q, inte %q" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "%q måste vara av typen %q" - -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q måste vara av typen %q eller None" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" +msgstr "%q måste vara av typen %q, inte %q" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" @@ -197,13 +244,9 @@ msgstr "%q är utanför gränserna" msgid "%q out of range" msgstr "%q utanför intervallet" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "Pinne %q ogiltig" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" -msgstr "%q med report-ID 0 måste ha längd 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "%q steg kan inte vara noll" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -213,11 +256,11 @@ msgstr "% q() tar %d positionsargument men %d gavs" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q och %q måste vara lika långa" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s fel 0x%x" @@ -402,12 +445,16 @@ msgstr "ADC2 används av WiFi" msgid "Address must be %d bytes long" msgstr "Adressen måste vara %d byte lång" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "Adressintervallet är inte tillåtet" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "All I2C-kringutrustning används" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "All I2C-kringutrustning används" @@ -429,7 +476,6 @@ msgid "All SPI peripherals are in use" msgstr "All SPI-kringutrustning används" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Alla UART-kringutrustning används" @@ -482,14 +528,21 @@ msgstr "Annonserar redan." msgid "Already have all-matches listener" msgstr "Har redan lyssnare för all-matchningar" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Kör redan" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" -msgstr "Skannar redan efter wifi-nätverk" +msgstr "Skannar redan efter WiFi-nätverk" + +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "Ett fel uppstod vid hämtning av '%s':\n" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" @@ -504,23 +557,16 @@ msgstr "En annan send är redan aktiv" msgid "Array must contain halfwords (type 'H')" msgstr "Matrisen måste innehålla halfwords (typ \"H\")" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Matrisvärden ska bestå av enstaka bytes." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "Högst %d %q kan anges (inte %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "Försök att tilldela %d block" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "Försök till heap-allokering när den virtuella maskinen inte är igång." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "Ljudkonvertering inte implementerad" @@ -571,8 +617,8 @@ msgid "Bitmap size and bits per value must match" msgstr "Bitmappstorlek och bitar per värde måste överensstämma" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "Startenheten måste vara den första enheten (gränssnitt #0)." +msgid "Boot device must be first (interface #0)." +msgstr "Boot-enhet måste vara först (gränssnitt #0)." #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" @@ -655,7 +701,7 @@ msgstr "CBC-block måste vara multiplar om 16 byte" msgid "CIRCUITPY drive could not be found or created." msgstr "CIRCUITPY-enheten kunde inte hittas eller skapas." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "CRC eller checksumma var ogiltig" @@ -775,10 +821,6 @@ msgstr "Skrivning för CharacteristicBuffer är inte tillhandahållen" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "CircuitPython kärnkod kraschade hårt. Hoppsan!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPython kunde inte allokera heap." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" msgstr "Klockförlängning för lång" @@ -795,6 +837,14 @@ msgstr "" "Anslutningen har kopplats bort och kan inte längre användas. Skapa en ny " "anslutning." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "Arrayer för koordinater har olika längd" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "Arrayer för koordinater har olika storlek" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Skadad .mpy-fil" @@ -819,10 +869,6 @@ msgstr "Det gick inte att starta avbrott, RX upptagen" msgid "Couldn't allocate decoder" msgstr "Det gick inte att allokera avkodaren" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Krasch in i HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Initieringsfel för DAC-kanal" @@ -877,10 +923,19 @@ msgstr "Displayen måste ha en 16-bitars färgrymd." msgid "Display rotation must be in 90 degree increments" msgstr "Displayens rotation måste vara i steg om 90 grader" +#: main.c +msgid "Done" +msgstr "Klar" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "Drivläge används inte när riktning är input." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" +"Under hanteringen av ovanstående undantag inträffade ett annat undantag:" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "ECB arbetar endast på 16 byte åt gången" @@ -906,20 +961,17 @@ msgstr "Fel i MIDI-ström vid position %d" msgid "Error in regex" msgstr "Fel i regex" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "Fel i safemode.py." + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "Fel: Bind misslyckades" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Förväntade %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" -msgstr "Förväntade ett larm" +msgid "Expected a kind of %q" +msgstr "Förväntade en typ av %q" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -972,10 +1024,6 @@ msgstr "Det gick inte att ansluta: internt fel" msgid "Failed to connect: timeout" msgstr "Det gick inte att ansluta: timeout" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "Kunde inte initiera WiFi" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Det gick inte att tolka MP3-filen" @@ -990,13 +1038,17 @@ msgid "Failed to write internal flash." msgstr "Det gick inte att skriva till intern flash." #: supervisor/shared/safe_mode.c -msgid "Fatal error." -msgstr "Fatalt fel." +msgid "Fault detected by hardware." +msgstr "Fel upptäckt av hårdvara." #: py/moduerrno.c msgid "File exists" msgstr "Filen finns redan" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "Filen hittades inte" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1004,8 +1056,16 @@ msgid "Filters too complex" msgstr "Filter för komplexa" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "Firmware-avbilden är ogiltig" +msgid "Firmware is duplicate" +msgstr "Firmware är en dubblett" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "Firmware är ogiltig" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "Firmware är för stor" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" @@ -1039,13 +1099,15 @@ msgstr "Funktionen kräver lås" msgid "GNSS init" msgstr "GNSS start" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "Allmänt fel" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Grupp används redan" @@ -1066,6 +1128,15 @@ msgstr "Hårdvaran är upptagen, prova alternativa pinnar" msgid "Hardware in use, try alternative pins" msgstr "Hårdvaran används redan, prova alternativa pinnar" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "Heap-allokering när VM inte körs." + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "Heap skadades eftersom stacken var för liten. Öka stackstorlek." + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "I/O-operation på stängd fil" @@ -1075,6 +1146,7 @@ msgid "I2C init error" msgstr "I2C-initieringsfel" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "I2C-enhet används redan" @@ -1082,11 +1154,6 @@ msgstr "I2C-enhet används redan" msgid "I2SOut not available" msgstr "I2SOut är inte tillgängligt" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV måste vara %d byte lång" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "Antal element i buffert måste vara <= 4 byte" @@ -1175,6 +1242,7 @@ msgid "Internal define error" msgstr "Internt define-fel" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "Internt fel" @@ -1187,10 +1255,16 @@ msgstr "Internt fel #%d" msgid "Internal watchdog timer expired." msgstr "Intern watchdog-timer har löpt ut." -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Interrupt-fel." + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "Ogiltig %q" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Ogiltig %q-pinne" @@ -1212,7 +1286,7 @@ msgstr "Ogiltig BSSID" msgid "Invalid MAC address" msgstr "Ogiltig MAC-adress" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Ogiltigt argument" @@ -1221,6 +1295,11 @@ msgstr "Ogiltigt argument" msgid "Invalid bits per value" msgstr "Ogiltigt värde för bitar per värde" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "Ogiltig byte %.*s" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1230,34 +1309,35 @@ msgstr "Ogiltig data_pins[%d]" msgid "Invalid format chunk size" msgstr "Ogiltig formatsegmentstorlek" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Ogiltig minnesåtkomst." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Ogiltig MAC-adress för multicast" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Ogiltiga pinnar" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "Ogiltig storlek" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "Ogiltig socket för TLS" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "Ogiltigt tillstånd" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "Ogiltig unicode escape" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "Nyckeln måste vara 16, 24 eller 32 byte lång" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "Nyckeln hittades inte" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "LED-mappning måste matcha displaystorlek" @@ -1274,7 +1354,7 @@ msgstr "Layer är redan med i en grupp" msgid "Layer must be a Group or TileGrid subclass" msgstr "Layer måste vara en underklass av Group eller TileGrid" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "MAC-adressen var ogiltig" @@ -1365,6 +1445,10 @@ msgstr "NLR jump misslyckades. Troligen korrupt minne." msgid "NVS Error" msgstr "NVS-fel" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "Namn eller tjänst inte känd" + #: py/qstr.c msgid "Name too long" msgstr "Name är för långt" @@ -1479,11 +1563,6 @@ msgstr "Ingen nyckel angavs" msgid "No long integer support" msgstr "Inget stöd för långt heltal" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "Högst %d HID-enheter är tillåtna" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "Inget nätverk med sådant ssid" @@ -1519,10 +1598,6 @@ msgstr "Ingen sådan fil/katalog" msgid "No timer available" msgstr "Ingen timer tillgänglig" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "Felaktigt tillstånd i Nordic systemfirmware." - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "Nordic systemfirmware fick slut på minne" @@ -1542,10 +1617,6 @@ msgstr "Inte ansluten" msgid "Not playing" msgstr "Ingen uppspelning" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "Går inte sätta" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1562,16 +1633,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "Udda paritet stöds inte" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "Av" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "OK" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Endast 8 eller 16 bitars mono med " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Endast IPv4-adresser stöds" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "Endast IPv4-socket stöds" @@ -1604,10 +1685,15 @@ msgstr "" "stöds: %d bpp angiven" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." -msgstr "Endast ett TouchAlarm kan ställas in för djupsömn." +msgid "Only one %q can be set in deep sleep." +msgstr "Endast en %q kan sättas i djup sömn." -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "Endast en %q kan ställas in." + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "Endast en adress är tillåten" @@ -1630,19 +1716,24 @@ msgstr "Bara en färg kan vara genomskinlig i taget" msgid "Operation not permitted" msgstr "Åtgärden inte tillåten" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "Operation eller funktion stöds inte" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "Åtgärden orsakade timeout" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "Slut på MDNS-serviceplatser" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "Slut på minne" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Slut på sockets" @@ -1699,7 +1790,6 @@ msgid "Pin interrupt already in use" msgstr "Pinnavbrott används redan" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "Pinnen är enbart ingång" @@ -1768,6 +1858,10 @@ msgstr "Program gör OUT utan att läsa in OSR" msgid "Program size invalid" msgstr "Programstorlek ogiltig" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "Programmet är för långt" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull används inte när riktningen är output." @@ -1807,8 +1901,9 @@ msgstr "RTC stöds inte av detta kort" msgid "Random number generation error" msgstr "Fel vid generering av slumptal" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Skrivskyddad" @@ -1816,14 +1911,14 @@ msgstr "Skrivskyddad" msgid "Read-only filesystem" msgstr "Skrivskyddat filsystem" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "Skrivskyddat objekt" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "Mottaget svar var ogiltigt" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "Återansluter" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "Uppdaterad för tidigt" @@ -1836,7 +1931,7 @@ msgstr "RemoteTransmissionRequests begränsad till 8 byte" msgid "Requested AES mode is unsupported" msgstr "Det begärda AES-läget stöds inte" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "Begärd resurs hittades inte" @@ -1908,7 +2003,8 @@ msgstr "Storleken stöds inte" msgid "Sleep Memory not available" msgstr "Sömnminne inte tillgängligt" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Slice och värde har olika längd." @@ -1920,6 +2016,7 @@ msgid "Slices not supported" msgstr "Slice stöds inte" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool kan endast användas med wifi.radio" @@ -1943,13 +2040,9 @@ msgstr "Vänster stereokanal måste använda PWM kanal A" msgid "Stereo right must be on PWM channel B" msgstr "Höger stereokanal måste använda PWM kanal B" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Stream saknar readinto() eller write() metod." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Ange minst en UART-pinne" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "Stoppa AP stöds inte." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -1964,35 +2057,20 @@ msgid "Temperature read timed out" msgstr "Temperaturavläsning tog för lång tid" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" -msgstr "" -"CircuitPython-heapen blev korrupt eftersom stacken är för liten.\n" -"Öka stackstorleken om du vet hur, eller om inte:" +msgid "The `microcontroller` module was used to boot into safe mode." +msgstr "Modulen `microcontroller` användes för att starta i felsäkert läge." -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." -msgstr "" -"Modulen `microcontroller` användes för att starta upp i felsäkert läge. " -"Tryck på reset för att avsluta felsäkert läget." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" +msgstr "Ovanstående undantag var den direkta orsaken till följande undantag:" #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "Längden på rgb_pins vara 6, 12, 18, 24 eller 30" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." -msgstr "" -"Mikrokontrollerns matningsspänning sjönk. Se till att strömförsörjningen " -"ger\n" -"tillräckligt med ström för hela kretsen och tryck på reset (efter utmatning " -"av CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." +msgstr "Spänningen sjönk. Se till att du ger tillräckligt med ström." #: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" @@ -2010,6 +2088,10 @@ msgstr "Samplingens frekvens matchar inte mixerns" msgid "The sample's signedness does not match the mixer's" msgstr "Samplingens signerad/osignerad stämmer inte med mixern" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "Fel från firmware från tredje part." + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "Den här mikrokontrollern stöder inte kontinuerlig insamling." @@ -2044,10 +2126,6 @@ msgstr "Tid har passerats." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Åtgärden tog för lång tid: Max väntetid är %d sekunder" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "För att avsluta, gör reset på kortet utan " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "För många kanaler i urvalet" @@ -2092,6 +2170,10 @@ msgstr "UART omstart" msgid "UART init" msgstr "UART start" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "UART-enhet används redan" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "UART omstart" @@ -2100,6 +2182,10 @@ msgstr "UART omstart" msgid "UART write" msgstr "UART-skrivning" +#: main.c +msgid "UID:" +msgstr "UID:" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "USB upptaget" @@ -2135,6 +2221,15 @@ msgstr "UUID-värdet är inte str, int eller byte-buffert" msgid "Unable to allocate buffers for signed conversion" msgstr "Det går inte att allokera buffert för signerad konvertering" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "Kan inte allokera heap." + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "Kan inte konfigurera ADC DMA controller, Felkod:%d" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "Kan inte skapa lås" @@ -2153,14 +2248,29 @@ msgstr "Det gick inte att hitta ledig GCLK" msgid "Unable to init parser" msgstr "Kan inte initiera tolken" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "Kan inte konfigurera ADC DMA controller, Felkod:%d" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "Det går inte att läsa färgpalettdata" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "Kan inte starta ADC DMA controller, Felkod:%d" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "Det gick inte att starta mDNS-frågan" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "Det går inte att skriva till adress." + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Det gick inte att skriva till nvm." @@ -2223,7 +2333,13 @@ msgstr "Okänt systemfirmwarefel: %04x" msgid "Unknown system firmware error: %d" msgstr "Okänt fel i systemets firmware: %d" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "Okänd felkod %d" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "Omatchat antal på RHS (förväntat %d, fick %d)." @@ -2270,7 +2386,7 @@ msgstr "Värdets längde ! = krävd fast längd" msgid "Value length > max_length" msgstr "Värdets längd > max_length" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "Versionen var ogiltig" @@ -2297,10 +2413,6 @@ msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" "WatchDogTimer.mode kan inte ändras när den är inställd på WatchDogMode.RESET" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "WatchDogTimer.timeout måste vara större än 0" - #: py/builtinhelp.c #, c-format msgid "" @@ -2320,6 +2432,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "Wi-Fi: " +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "WiFi är i accesspunktläge." + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "WiFi är i stationsläge." + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "WiFi är inte aktiverat" + #: main.c msgid "Woken up by alarm.\n" msgstr "Vaknade av larm.\n" @@ -2329,20 +2453,57 @@ msgstr "Vaknade av larm.\n" msgid "Writes not supported on Characteristic" msgstr "Skrivning stöds inte på karaktäristik" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" -msgstr "Du är i felsäkert läge eftersom:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "Du tryckte ner båda knapparna vid start." + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." +msgstr "Du tryckte ner knapp A vid start." #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." -msgstr "" -"Du tryckte på resetknappen under uppstarten. Tryck igen för att avsluta " -"felsäkert läge." +msgid "You pressed the BOOT button at start up" +msgstr "Du tryckte ner BOOT-knappen vid start" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "Du tryckte på GPIO0-knappen vid start." + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "Du tryckte ned Rec-knappen vid start." + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "Du tryckte ned SW38-knappen vid start." + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "Du tryckte ned VOLYM-knappen vid start." + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "Du tryckte ned mittknappen vid start." + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "Du tryckte ned vänster knapp vid start." #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "Du begärt att starta i felsäkert läge genom att " +msgid "You pressed the reset button during boot." +msgstr "Du tryckte på reset-knappen under uppstart." + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "[trunkerad på grund av längd]" #: py/objtype.c msgid "__init__() should return None" @@ -2360,11 +2521,7 @@ msgstr "__new__ arg måste vara en användartyp" msgid "a bytes-like object is required" msgstr "ett bytesliknande objekt krävs" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "adress utanför gränsen" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "adresserna är tomma" @@ -2417,8 +2574,12 @@ msgstr "array och indexlängd måste vara lika" msgid "array has too many dimensions" msgstr "array har för många dimensioner" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "matrisen är för stor" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "array/bytes krävs på höger sida" @@ -2511,10 +2672,6 @@ msgstr "buffert för liten" msgid "buffer too small for requested bytes" msgstr "buffert för liten för begärd längd" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "byteorder är inte en sträng" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "bytelängd inte en multipel av storlek" @@ -2556,15 +2713,10 @@ msgstr "kan inte tilldela uttryck" msgid "can't cancel self" msgstr "kan inte avbryta sig själv" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "kan inte konvertera %q till %q" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "kan inte konvertera %q till int" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2642,10 +2794,14 @@ msgstr "kan inte skicka icke-None värde till nystartad generator" msgid "can't set 512 block size" msgstr "kan inte sätta blockstorlek 512" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "kan inte att ange attribut" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "kan inte sätta attribut '%q'" + #: py/emitnative.c msgid "can't store '%q'" msgstr "kan inte lagra '%q'" @@ -2746,18 +2902,10 @@ msgstr "färgbuffert måste vara en bytearray eller matris av typ 'b' eller 'B'" msgid "color must be between 0x000000 and 0xffffff" msgstr "färg måste vara mellan 0x000000 och 0xffffff" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "color ska vara en int" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "jämförelse av int och uint" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "komplex division med noll" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "komplexa värden stöds inte" @@ -2843,10 +2991,6 @@ msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" "destinationsbufferten måste vara en matris av typen 'H' för bit_depth = 16" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "destination_length måste vara ett heltal >= 0" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "uppdateringssekvensen för dict har fel längd" @@ -2867,12 +3011,11 @@ msgstr "dimensioner matchar inte" msgid "div/mod not implemented for uint" msgstr "div/mod inte implementerat för uint" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "division med noll" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "division med noll" @@ -2904,10 +3047,6 @@ msgstr "tom sekvens" msgid "end of format while looking for conversion specifier" msgstr "slut på format vid sökning efter konverteringsspecificerare" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "color ska vara en int" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "epoch_time stöds inte av detta kort" @@ -2917,18 +3056,18 @@ msgstr "epoch_time stöds inte av detta kort" msgid "error = 0x%08lX" msgstr "fel = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" +"espcamera.Camera kräver reserverat PSRAM att vara konfigurerat. Se " +"dokumentationen för instruktioner." + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "exceptions måste ärvas från BaseException" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "förväntade '%q' men fick '%q'" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "förväntade '%q' eller '%q' men fick '%q'" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "förväntade ':' efter formatspecifikation" @@ -3027,10 +3166,6 @@ msgstr "typsnitt måste vara 2048 bytes långt" msgid "format requires a dict" msgstr "formatet kräver en dict" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "frekvens är skrivskyddad för detta kort" - #: py/objdeque.c msgid "full" msgstr "full" @@ -3143,16 +3278,16 @@ msgstr "felaktig utfyllnad" msgid "index is out of bounds" msgstr "index är utanför gränserna" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "index måste vara tuple eller int" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "index utanför intervallet" -#: py/obj.c -msgid "indices must be integers" -msgstr "index måste vara heltal" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "index måste vara heltal, slices, eller Boolean-listor" @@ -3246,10 +3381,6 @@ msgstr "indatavektorer måste ha samma längd" msgid "inputs are not iterable" msgstr "indata är inte iterbara" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "int() arg 2 måste vara >= 2 och <= 36" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "interp är definierad för 1D-iterabla med samma längd" @@ -3268,6 +3399,10 @@ msgstr "ogiltig arkitektur" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "ogiltig bits_per_pixel %d, måste vara, 1, 2, 4, 8, 16, 24 eller 32" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "ogiltigt certifikat" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3294,10 +3429,18 @@ msgstr "ogiltig formatspecificerare" msgid "invalid hostname" msgstr "Ogiltigt värdnamn" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "ogiltig nyckel" + #: py/compile.c msgid "invalid micropython decorator" msgstr "ogiltig mikropython-dekorator" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "ogiltig inställning" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "ogiltigt steg" @@ -3319,10 +3462,6 @@ msgstr "ogiltig syntax för heltal med bas %d" msgid "invalid syntax for number" msgstr "ogiltig syntax för tal" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "Ogilitig källspårning" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 måste vara en klass" @@ -3382,19 +3521,17 @@ msgstr "lokal '%q' används innan typen är känd" msgid "local variable referenced before assignment" msgstr "lokal variabel refererad före tilldelning" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "long int stöds inte i denna build" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "loopback + tyst läge stöds inte av kringutrustning" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "mDNS har redan initierats" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "mDNS fungerar bara med inbyggt WiFi" @@ -3523,6 +3660,10 @@ msgstr "negativ exponent utan stöd för flyttal" msgid "negative shift count" msgstr "negativt skiftantal" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "nästlat index måste vara en int" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "inget SD-kort" @@ -3556,14 +3697,10 @@ msgstr "ingen reset-pinne tillgänglig" msgid "no response from SD card" msgstr "inget svar från SD-kort" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "inget sådant attribut" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "icke-enhet i %q" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3688,15 +3825,30 @@ msgid "offset out of bounds" msgstr "offset utanför gränserna" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "bara bit_depth=16 stöds" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "endast mono stöds" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "endast ndarrays kan sammanfogas" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "endast oversample=64 stöds" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "enbart sample_rate=16000 stöds" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "endast segment med steg=1 (aka Ingen) stöds" @@ -3767,10 +3919,6 @@ msgstr "pack förväntade %d stycken för packning (fick %d)" msgid "palette must be 32 bytes long" msgstr "palette måste vara 32 bytes lång" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "palette_index ska vara en int" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "parametrarna måste registreras i följd a2-a5" @@ -3821,28 +3969,6 @@ msgstr "pow() 3: e argument kan inte vara 0" msgid "pow() with 3 arguments requires integers" msgstr "pow() med 3 argument kräver heltal" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "genom att trycka på SW38-knappen vid start.\n" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "trycka på startknappen vid start.\n" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "trycka båda knapparna vid uppstart.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "håll ner vänster knapp vid start\n" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "pull-mask är i konflikt med riktnings-mask" @@ -3863,11 +3989,6 @@ msgstr "verkliga och imaginära delar måste ha samma längd" msgid "relative import" msgstr "relativ import" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "begärd längd %d men objektet har längden %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "resultaten kan inte castas till angiven typ" @@ -3898,14 +4019,6 @@ msgstr "argumentet roll måste vara en ndarray" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"sample_source buffert måste vara en bytearray eller matris av typ 'h', 'H', " -"'b' eller 'B'" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3939,10 +4052,6 @@ msgstr "tecknet tillåts inte i strängformatspecificerare" msgid "sign not allowed with integer format specifier 'c'" msgstr "tecken tillåts inte med heltalsformatspecificeraren 'c'" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "Enkelt '}' påträffades i formatsträngen" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "storlek är enbart definierad ndarrays" @@ -3955,10 +4064,6 @@ msgstr "värdet för sleep måste vara positivt" msgid "slice step can't be zero" msgstr "segmentsteg kan inte vara noll" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "segmentsteg kan inte vara noll" - #: py/nativeglue.c msgid "slice unsupported" msgstr "slice stöds inte" @@ -4007,14 +4112,6 @@ msgstr "source_bitmap måste ha value_count av 8" msgid "start/end indices" msgstr "start-/slutindex" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "start_x ska vara en int" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "step måste vara icke-noll" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "stop kan inte nås från start" @@ -4023,10 +4120,6 @@ msgstr "stop kan inte nås från start" msgid "stream operation not supported" msgstr "stream-åtgärd stöds inte" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "strängindex måste vara heltal, inte %q" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "sträng stöds inte; använd bytes eller bytearray" @@ -4059,14 +4152,6 @@ msgstr "syntaxfel i JSON" msgid "syntax error in uctypes descriptor" msgstr "syntaxfel i uctypes deskriptor" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "tröskelvärdet måste ligga i intervallet 0-65536" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time() kräver en 9-sekvens" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4074,10 +4159,6 @@ msgstr "time.struct_time() kräver en 9-sekvens" msgid "timeout duration exceeded the maximum supported value" msgstr "timeout-längd överskred det maximala värde som stöds" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "timeout måste vara 0.0-100.0 sekunder" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "timeout måste vara < 655,35 sekunder" @@ -4131,10 +4212,6 @@ msgstr "trapz är definierad för 1D-matriser med samma längd" msgid "trapz is defined for 1D iterables" msgstr "trapz är definierat för 1D-iterabla" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "tupel/lista har fel längd" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4145,8 +4222,6 @@ msgstr "twai_driver_install returnerade esp-idf-fel #%d" msgid "twai_start returned esp-idf error #%d" msgstr "twai_start returnerade esp-idf-fel #%d" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx och rx kan inte båda vara None" @@ -4159,14 +4234,10 @@ msgstr "typ '%q' är inte en acceptabel bastyp" msgid "type is not an acceptable base type" msgstr "typ är inte en acceptabel bastyp" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "typobjektet '%q' har inget attribut '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "typobjekt 'generator' har inget attribut '__await__'" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "typen tar 1 eller 3 argument" @@ -4187,7 +4258,7 @@ msgstr "oväntat indrag" msgid "unexpected keyword argument" msgstr "oväntat nyckelordsargument" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "oväntat nyckelordsargument '%q'" @@ -4217,15 +4288,15 @@ msgid "unknown type '%q'" msgstr "okänd typ '%q'" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "omatchad '{' i format" +#, c-format +msgid "unmatched '%c' in format" +msgstr "Omatchad '%c' i format" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "attribut kan inte läsas" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "typ %q stöds inte" @@ -4289,17 +4360,18 @@ msgstr "value_count måste vara > 0" msgid "watchdog not initialized" msgstr "watchdog är inte initierad" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "watchdog timeout måste vara större än 0" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "width måste vara större än noll" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" -msgstr "wifi är inte aktiverat" +msgstr "WiFi är inte aktiverat" + +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "wifi.Monitor är inte tillgänglig" #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" @@ -4355,18 +4427,10 @@ msgstr "x-värde utanför intervall" msgid "xTaskCreate failed" msgstr "xTaskCreate misslyckades" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y ska vara en int" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "y-värde utanför intervall" -#: py/objrange.c -msgid "zero step" -msgstr "noll steg" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "zi måste vara en ndarray" @@ -4379,6 +4443,326 @@ msgstr "zi måste vara av typ float" msgid "zi must be of shape (n_section, 2)" msgstr "zi måste vara i formen (n_section, 2)" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Ange minst en UART-pinne" + +#~ msgid "%q pin invalid" +#~ msgstr "Pinne %q ogiltig" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Vänligen skapa ett ärende med innehållet i din CIRCUITPY-enhet på\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "" +#~ "Försök till heap-allokering när den virtuella maskinen inte är igång." + +#~ msgid "Boot device must be first device (interface #0)." +#~ msgstr "Startenheten måste vara den första enheten (gränssnitt #0)." + +#~ msgid "Both buttons were pressed at start up.\n" +#~ msgstr "Båda knapparna trycktes ned vid start.\n" + +#~ msgid "Button A was pressed at start up.\n" +#~ msgstr "Knapp A trycktes ned vid start.\n" + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPython kunde inte allokera heap." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "Krasch in i HardFault_Handler." + +#~ msgid "Fatal error." +#~ msgstr "Fatalt fel." + +#~ msgid "Invalid memory access." +#~ msgstr "Ogiltig minnesåtkomst." + +#~ msgid "Nordic system firmware failure assertion." +#~ msgstr "Felaktigt tillstånd i Nordic systemfirmware." + +#~ msgid "The BOOT button was pressed at start up.\n" +#~ msgstr "BOOT-knappen trycktes ner vid start.\n" + +#~ msgid "" +#~ "The CircuitPython heap was corrupted because the stack was too small.\n" +#~ "Increase the stack size if you know how. If not:" +#~ msgstr "" +#~ "CircuitPython-heapen blev korrupt eftersom stacken är för liten.\n" +#~ "Öka stackstorleken om du vet hur, eller om inte:" + +#~ msgid "The SW38 button was pressed at start up.\n" +#~ msgstr "SW38-knappen trycktes ned vid start.\n" + +#~ msgid "The VOLUME button was pressed at start up.\n" +#~ msgstr "VOLUME-knappen trycktes ned vid start.\n" + +#~ msgid "" +#~ "The `microcontroller` module was used to boot into safe mode. Press reset " +#~ "to exit safe mode." +#~ msgstr "" +#~ "Modulen `microcontroller` användes för att starta upp i felsäkert läge. " +#~ "Tryck på reset för att avsluta felsäkert läget." + +#~ msgid "The central button was pressed at start up.\n" +#~ msgstr "Mittknappen trycktes in vid start.\n" + +#~ msgid "The left button was pressed at start up.\n" +#~ msgstr "Den vänstra knappen trycktes ned vid start.\n" + +#~ msgid "" +#~ "The microcontroller's power dipped. Make sure your power supply provides\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY)." +#~ msgstr "" +#~ "Mikrokontrollerns matningsspänning sjönk. Se till att strömförsörjningen " +#~ "ger\n" +#~ "tillräckligt med ström för hela kretsen och tryck på reset (efter " +#~ "utmatning av CIRCUITPY)." + +#~ msgid "To exit, please reset the board without requesting safe mode." +#~ msgstr "För att avsluta, återställ kortet utan att begära säkert läge." + +#~ msgid "You are in safe mode because:\n" +#~ msgstr "Du är i felsäkert läge eftersom:\n" + +#~ msgid "" +#~ "You pressed the reset button during boot. Press again to exit safe mode." +#~ msgstr "" +#~ "Du tryckte på resetknappen under uppstarten. Tryck igen för att avsluta " +#~ "felsäkert läge." + +#~ msgid "" +#~ "esp32_camera.Camera requires reserved PSRAM to be configured. See the " +#~ "documentation for instructions." +#~ msgstr "" +#~ "esp32_camera.Camera kräver reserverad PSRAM att konfigureras. Se " +#~ "dokumentationen för instruktioner." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q måste vara av typen %q" + +#~ msgid "%q must be of type %q or None" +#~ msgstr "%q måste vara av typen %q eller None" + +#~ msgid "Expected a %q" +#~ msgstr "Förväntade %q" + +#~ msgid "Expected a %q or %q" +#~ msgstr "Förväntade %q eller %q" + +#~ msgid "Expected an %q" +#~ msgstr "Förväntade en %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV måste vara %d byte lång" + +#~ msgid "Not settable" +#~ msgstr "Går inte sätta" + +#~ msgid "expected '%q' but got '%q'" +#~ msgstr "förväntade '%q' men fick '%q'" + +#~ msgid "expected '%q' or '%q' but got '%q'" +#~ msgstr "förväntade '%q' eller '%q' men fick '%q'" + +#~ msgid "Read-only object" +#~ msgstr "Skrivskyddat objekt" + +#~ msgid "frequency is read-only for this board" +#~ msgstr "frekvens är skrivskyddad för detta kort" + +#~ msgid "Pins 21+ not supported from ULP" +#~ msgstr "Pins 21+ stöds inte av ULP" + +#~ msgid "Unable to write" +#~ msgstr "Kan inte skriva" + +#~ msgid "%q length must be >= 1" +#~ msgstr "längden på %q måste vara >= 1" + +#~ msgid "%q must be a string" +#~ msgstr "%q måste vara en sträng" + +#~ msgid "%q must be an int" +#~ msgstr "%q måste vara en int" + +#~ msgid "%q with a report ID of 0 must be of length 1" +#~ msgstr "%q med report-ID 0 måste ha längd 1" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "Högst %d %q kan anges (inte %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Ogiltiga pinnar" + +#, c-format +#~ msgid "No more than %d HID devices allowed" +#~ msgstr "Högst %d HID-enheter är tillåtna" + +#~ msgid "byteorder is not a string" +#~ msgstr "byteorder är inte en sträng" + +#~ msgid "can't convert %q to int" +#~ msgstr "kan inte konvertera %q till int" + +#~ msgid "complex division by zero" +#~ msgstr "komplex division med noll" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "int() arg 2 måste vara >= 2 och <= 36" + +#~ msgid "long int not supported in this build" +#~ msgstr "long int stöds inte i denna build" + +#~ msgid "slice step cannot be zero" +#~ msgstr "segmentsteg kan inte vara noll" + +#~ msgid "step must be non-zero" +#~ msgstr "step måste vara icke-noll" + +#~ msgid "string indices must be integers, not %q" +#~ msgstr "strängindex måste vara heltal, inte %q" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time() kräver en 9-sekvens" + +#~ msgid "zero step" +#~ msgstr "noll steg" + +#~ msgid "invalid traceback" +#~ msgstr "Ogilitig källspårning" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "Indexet %q måste vara ett heltal, inte %s" + +#~ msgid "WatchDogTimer.timeout must be greater than 0" +#~ msgstr "WatchDogTimer.timeout måste vara större än 0" + +#~ msgid "indices must be integers" +#~ msgstr "index måste vara heltal" + +#~ msgid "non-Device in %q" +#~ msgstr "icke-enhet i %q" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "begärd längd %d men objektet har längden %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "Enkelt '}' påträffades i formatsträngen" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "tröskelvärdet måste ligga i intervallet 0-65536" + +#~ msgid "timeout must be 0.0-100.0 seconds" +#~ msgstr "timeout måste vara 0.0-100.0 sekunder" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "tupel/lista har fel längd" + +#~ msgid "unmatched '{' in format" +#~ msgstr "omatchad '{' i format" + +#~ msgid "watchdog timeout must be greater than 0" +#~ msgstr "watchdog timeout måste vara större än 0" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "För att avsluta, gör reset på kortet utan " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "Du begärt att starta i felsäkert läge genom att " + +#~ msgid "pressing BOOT button at start up.\n" +#~ msgstr "genom att trycka på BOOT-knappen vid start.\n" + +#~ msgid "pressing SW38 button at start up.\n" +#~ msgstr "genom att trycka på SW38-knappen vid start.\n" + +#~ msgid "pressing VOLUME button at start up.\n" +#~ msgstr "genom att trycka på VOLUME-knappen vid start.\n" + +#~ msgid "pressing boot button at start up.\n" +#~ msgstr "genom att trycka på startknappen vid start.\n" + +#~ msgid "pressing both buttons at start up.\n" +#~ msgstr "genom att trycka båda knapparna vid uppstart.\n" + +#~ msgid "pressing central button at start up.\n" +#~ msgstr "trycka på mittknappen vid start.\n" + +#~ msgid "pressing button A at start up.\n" +#~ msgstr "genom att tryck på knappen A vid start.\n" + +#~ msgid "pressing the left button at start up\n" +#~ msgstr "genom att håll ner vänster knapp vid start\n" + +#~ msgid "Only one TouchAlarm can be set in deep sleep." +#~ msgstr "Endast ett TouchAlarm kan ställas in för djupsömn." + +#~ msgid "Firmware image is invalid" +#~ msgstr "Firmware-avbilden är ogiltig" + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Stream saknar readinto() eller write() metod." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q måste vara >= 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q måste vara >= 1" + +#~ msgid "address out of bounds" +#~ msgstr "adress utanför gränsen" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "destination_length måste vara ett heltal >= 0" + +#~ msgid "type object 'generator' has no attribute '__await__'" +#~ msgstr "typobjekt 'generator' har inget attribut '__await__'" + +#~ msgid "color should be an int" +#~ msgstr "color ska vara en int" + +#~ msgid "end_x should be an int" +#~ msgstr "color ska vara en int" + +#~ msgid "palette_index should be an int" +#~ msgstr "palette_index ska vara en int" + +#~ msgid "start_x should be an int" +#~ msgstr "start_x ska vara en int" + +#~ msgid "y should be an int" +#~ msgstr "y ska vara en int" + +#~ msgid "%q ``must`` be a bytearray or array of type 'h', 'H', 'b' or 'B'" +#~ msgstr "" +#~ "%q ``måste`` vara en bytearray eller matris av typen 'h', 'H', 'b' eller " +#~ "'B'" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "sample_source buffert måste vara en bytearray eller matris av typ 'h', " +#~ "'H', 'b' eller 'B'" + +#~ msgid "Expected an alarm" +#~ msgstr "Förväntade ett larm" + +#~ msgid "All I2C targets are in use" +#~ msgstr "Alla I2C-mål används" + +#~ msgid "Failed to init wifi" +#~ msgstr "Kunde inte initiera WiFi" + #~ msgid "input must be a tensor of rank 2" #~ msgstr "indata måste vara en tensor av rank 2" @@ -5066,12 +5450,6 @@ msgstr "zi måste vara i formen (n_section, 2)" #~ msgid "can only save bytecode" #~ msgstr "kan bara spara bytecode" -#~ msgid "invalid cert" -#~ msgstr "ogiltigt certifikat" - -#~ msgid "invalid key" -#~ msgstr "ogiltig nyckel" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Viper-funktioner stöder för närvarande inte mer än fyra argument" diff --git a/locale/tr.po b/locale/tr.po index a2d8d41ea7..74e44c2d8d 100644 --- a/locale/tr.po +++ b/locale/tr.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2022-04-19 17:07+0000\n" -"Last-Translator: Siyabend Ürün \n" +"PO-Revision-Date: 2022-12-05 21:48+0000\n" +"Last-Translator: Boran Roni \n" "Language-Team: none\n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.12-dev\n" +"X-Generator: Weblate 4.15-dev\n" #: main.c msgid "" @@ -34,16 +34,32 @@ msgstr "" "Program otomatik yeniden yükleme tarafından durduruldu. Birazdan tekrar " "yüklenecek.\n" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" "\n" -"Lütfen, şu adrese CIRCUITPY sürücünüzün içerikleri ile beraber bir hata/konu " -"kaydı ekleyin\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Press reset to exit safe mode.\n" +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -70,6 +86,16 @@ msgstr " çıktı:\n" msgid "%%c requires int or char" msgstr "%%c int veya char tipine ihtiyaç duyar" +#: main.c +#, c-format +msgid "%02X" +msgstr "%02X" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -78,15 +104,18 @@ msgstr "" "%d adres pinleri, %d RGB pinleri ve %d döşemeleri %d'nin yüksekliği " "gösterir, %d'nin değil" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" -msgstr "" +msgstr "%q" #: shared-bindings/microcontroller/Pin.c msgid "%q and %q contain duplicate pins" @@ -94,7 +123,7 @@ msgstr "%q ve %q yinelenen pinler içeriyor" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "%q and %q must be different" -msgstr "" +msgstr "%q ve %q farklı olmalılar" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -104,25 +133,36 @@ msgstr "%q yinelenen pinler içeriyor" msgid "%q failure: %d" msgstr "%q hata: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q kullanımda" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "%q indeksi aralık dışında" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q indeksleri integer olmalı, %s değil" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" +msgstr "%q init başarısız oldu" + +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q %q dir" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" msgstr "" -#: py/argcheck.c +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" -msgstr "" +msgstr "%q boyutu %d olmalıdır" #: py/argcheck.c msgid "%q length must be %d-%d" @@ -130,19 +170,15 @@ msgstr "%q boyutları %d-%d olmalıdır" #: py/argcheck.c msgid "%q length must be <= %d" -msgstr "" +msgstr "%q boyutu <= %d olmalıdır" #: py/argcheck.c msgid "%q length must be >= %d" -msgstr "" - -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "%q boyutu >=1 olmalıdır" +msgstr "%q boyutu >= %d olmalıdır" #: py/argcheck.c msgid "%q must be %d" -msgstr "" +msgstr "%q, %d olmalıdır" #: py/argcheck.c msgid "%q must be %d-%d" @@ -150,7 +186,7 @@ msgstr "%q, %d-%d olmalıdır" #: shared-bindings/displayio/Display.c msgid "%q must be 1 when %q is True" -msgstr "" +msgstr "%q 1 olmalı, %q True olduğu zaman" #: py/argcheck.c shared-bindings/gifio/GifWriter.c msgid "%q must be <= %d" @@ -160,29 +196,26 @@ msgstr "%q <= %d olmalıdır" msgid "%q must be >= %d" msgstr "%q >= %d olmalıdır" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q >= 0 olmalıdır" - -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q >= 1 olmalıdır" - -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q bir string olmalıdır" - -#: py/argcheck.c -msgid "%q must be an int" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "%q, %q türünde olmalıdır" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q 'H' ya da 'B' tipi bir bytearray ya da array olmalıdır" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q, %q ya da None türünde olmalıdır" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q 'h', 'H', 'b' ya da 'B' tipi bir bytearray ya da array olmalı" + +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" +msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" @@ -201,13 +234,9 @@ msgstr "%q sınırların dışında" msgid "%q out of range" msgstr "%q aralık dışında" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "%q pini geçersiz" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" -msgstr "Rapor kimliği 0 olan %q, 1 uzunluğunda olmalıdır" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "%q sıfır olamaz" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -217,11 +246,11 @@ msgstr "%q(), %d konumsal argümanını alır ancak %d verildi" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q ve %q aynı uzunlukta olmalıdır" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s hatası 0x%x" @@ -316,7 +345,6 @@ msgid "'%s' object isn't subscriptable" msgstr "'%s' nesnesi subscriptable özelliğe sahip değil" #: py/objstr.c -#, fuzzy msgid "'=' alignment not allowed in string format specifier" msgstr "'=' hizalamasına string biçiminde izin verilmez" @@ -375,7 +403,7 @@ msgstr "fonksiyon dışında 'yield'" #: py/compile.c msgid "*x must be assignment target" -msgstr "" +msgstr "*x atama hedefi olmalıdır" #: py/obj.c msgid ", in %q\n" @@ -408,12 +436,16 @@ msgstr "ADC2, WiFi tarafından kullanılmaktadır" msgid "Address must be %d bytes long" msgstr "Adres %d byte uzunluğunda olmalıdır" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "Tüm CAN çevre birimleri kullanımda" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "Tüm I2C çevre birimleri kullanımda" @@ -435,7 +467,6 @@ msgid "All SPI peripherals are in use" msgstr "Tüm SPI çevre birimleri kullanımda" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Tüm UART çevre birimleri kullanımda" @@ -486,17 +517,24 @@ msgstr "Halihazırda duyuruluyor." #: ports/atmel-samd/common-hal/canio/Listener.c msgid "Already have all-matches listener" -msgstr "" +msgstr "Tüm eşleşmelerle eşleşen dinleyiciniz var" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "Halihazırda çalışıyor" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Halihazırda wifi ağları için tarama yapılıyor" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "Başka bir PWMAudioOut zaten aktif durumda" @@ -510,23 +548,16 @@ msgstr "Başka bir gönderme zaten aktif" msgid "Array must contain halfwords (type 'H')" msgstr "Dizi yarımsözcüklere sahip olmalıdır (tip 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "Dizi değerleri tekil bytelar olmalıdır." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "En az %d %q belirtilmeli (%d değil)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "%d bloğun ayrılması girişimi" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "VM çalışmazken heap'ten alan tahsis edilmeye çalışıldı." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "Ses dönüşümü implemente edilmedi" @@ -562,24 +593,23 @@ msgstr "Minimum kare hızından altında" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Bit clock and word select must be sequential pins" -msgstr "" +msgstr "Bit saati ve kelime seçimi pinleri sıralı olmalıdır" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Bit clock and word select must share a clock unit" -msgstr "" +msgstr "Bit saati ve kelime seçimi, bir saat birimini paylaşmalıdır" #: shared-bindings/audiobusio/PDMIn.c msgid "Bit depth must be multiple of 8." msgstr "Bit derinliği 8'in katı olacak şekilde olmalı." #: shared-bindings/bitmaptools/__init__.c -#, fuzzy msgid "Bitmap size and bits per value must match" msgstr "Bitmap boyutu ve bit başına değer uyuşmalı" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "Önyükleme cihazı ilk cihaz olmalı (arayüz #0)." +msgid "Boot device must be first (interface #0)." +msgstr "" #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" @@ -587,7 +617,7 @@ msgstr "Hem RX hem de TX akış kontrolü için gerekli" #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" -msgstr "" +msgstr "Her iki pin de donanım kesintilerini desteklemelidir" #: shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c @@ -604,15 +634,15 @@ msgstr "Parlaklık ayarlanabilir değil" #: shared-bindings/_bleio/UUID.c #, c-format msgid "Buffer + offset too small %d %d %d" -msgstr "" +msgstr "Buffer + offset çok küçük %d %d %d" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Buffer elements must be 4 bytes long or less" -msgstr "" +msgstr "Buffer elementleri 4 bit olmak zorunda" #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." -msgstr "Arabellek bayt dizisi değil" +msgstr "Buffer bir bytearray değil." #: ports/cxd56/common-hal/camera/Camera.c shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c @@ -631,12 +661,12 @@ msgstr "Arabellek boyutu 512'nin katı olmalı" #: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c msgid "Buffer must be a multiple of 512 bytes" -msgstr "" +msgstr "Buffer 512 bitin katı olmalı" #: shared-bindings/_bleio/PacketBuffer.c #, c-format msgid "Buffer too short by %d bytes" -msgstr "" +msgstr "Buffer bitten %d daha az" #: ports/espressif/common-hal/imagecapture/ParallelImageCapture.c msgid "Buffers must be same size" @@ -652,7 +682,7 @@ msgstr "Veriyolu pini %d kullanımda" #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." -msgstr "" +msgstr "Bit buffer'ı 16bit olmalı." #: shared-bindings/aesio/aes.c msgid "CBC blocks must be multiples of 16 bytes" @@ -660,15 +690,15 @@ msgstr "CBC blokları 16 baytın katları şeklinde olmalı" #: supervisor/shared/safe_mode.c msgid "CIRCUITPY drive could not be found or created." -msgstr "CIRCUITPY sürücüsü bulunamadı veya oluşturulamadı" +msgstr "CIRCUITPY sürücüsü bulunamadı veya oluşturulamadı." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" -msgstr "" +msgstr "CRC yada checksum geçersiz" #: py/objtype.c msgid "Call super().__init__() before accessing native object." -msgstr "" +msgstr "Yerel nesneye erişmeden önce super().__init__() fonksiyonunu çağırın." #: ports/cxd56/common-hal/camera/Camera.c msgid "Camera init" @@ -698,7 +728,7 @@ msgstr "USB aygıtları şu an değiştirilemez" #: shared-bindings/_bleio/Adapter.c msgid "Cannot create a new Adapter; use _bleio.adapter;" -msgstr "Yeni Adapter oluşturulamaz, _bleio.adapter; kullanın" +msgstr "yeni Adaptör oluşturulamadı, _bleio.adapter kullanın" #: shared-bindings/displayio/Bitmap.c #: shared-bindings/memorymonitor/AllocationSize.c @@ -711,15 +741,16 @@ msgstr "Değerler silinemez" #: ports/nrf/common-hal/digitalio/DigitalInOut.c #: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c msgid "Cannot get pull while in output mode" -msgstr "" +msgstr "Çıkış modundayken çekme alınamıyor" #: ports/nrf/common-hal/microcontroller/Processor.c msgid "Cannot get temperature" -msgstr "" +msgstr "Isı okunamadı" #: shared-bindings/_bleio/Adapter.c +#, fuzzy msgid "Cannot have scan responses for extended, connectable advertisements." -msgstr "" +msgstr "Genişletilmiş, bağlanabilir reklamlar için tarama yanıtları yapılamaz." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot pull on input-only pin." @@ -727,30 +758,30 @@ msgstr "" #: shared-bindings/audiobusio/PDMIn.c msgid "Cannot record to a file" -msgstr "" +msgstr "Dosyaya kayıt yapılamıyor" #: shared-module/storage/__init__.c msgid "Cannot remount '/' when visible via USB." -msgstr "" +msgstr "'/' USB ile görünür olduğunda, yeniden bağlanamaz." #: ports/atmel-samd/common-hal/microcontroller/__init__.c #: ports/cxd56/common-hal/microcontroller/__init__.c #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c msgid "Cannot reset into bootloader because no bootloader is present" -msgstr "" +msgstr "Hiçbir bootloader bulunmadığından bootloader sıfırlanamıyor" #: ports/espressif/common-hal/socketpool/Socket.c msgid "Cannot set socket options" -msgstr "" +msgstr "Soket seçenekleri ayarlanamıyor" #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." -msgstr "" +msgstr "Yön, giriş olduğunda değer ayarlanamıyor." #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Cannot specify RTS or CTS in RS485 mode" -msgstr "" +msgstr "RS485 modunda RTS veya CTS belirtilemez" #: py/objslice.c msgid "Cannot subclass slice" @@ -758,11 +789,11 @@ msgstr "" #: shared-module/bitbangio/SPI.c msgid "Cannot transfer without MOSI and MISO pins" -msgstr "" +msgstr "MOSI ve MISO pinleri olmadan transfer edilemiyor" #: shared-bindings/pwmio/PWMOut.c msgid "Cannot vary frequency on a timer that is already in use" -msgstr "" +msgstr "Kullanımda olan bir zamanlayıcının frekansı değiştirilemez" #: ports/nrf/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" @@ -774,33 +805,37 @@ msgstr "" #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" -msgstr "" +msgstr "CharacteristicBuffer yazılmı sağlanmadı" #: supervisor/shared/safe_mode.c msgid "CircuitPython core code crashed hard. Whoops!\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "" +msgstr "CircuitPython kor kodu patladı. Haydaaa!\n" #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" -msgstr "" +msgstr "Saat uzatması çok uzun" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Clock unit in use" -msgstr "" +msgstr "Saat ünitesi kullanımda" #: shared-bindings/_bleio/Connection.c msgid "" "Connection has been disconnected and can no longer be used. Create a new " "connection." +msgstr "Bağlantı koparıldı ve tekrar kullanılamaz. Yeni bir bağlantı kurun." + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" msgstr "" #: py/persistentcode.c msgid "Corrupt .mpy file" -msgstr "" +msgstr "Bozuk .mpy dosyası" #: ports/espressif/common-hal/neopixel_write/__init__.c msgid "Could not retrieve clock" @@ -808,24 +843,20 @@ msgstr "" #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" -msgstr "" +msgstr "Adres ayarlanamadı" #: shared-bindings/pwmio/PWMOut.c msgid "Could not start PWM" -msgstr "" +msgstr "PWM başlatılamadı" #: ports/stm/common-hal/busio/UART.c msgid "Could not start interrupt, RX busy" -msgstr "" +msgstr "Kesinti başlatılamadı, RX kullanımda" #: shared-module/audiomp3/MP3Decoder.c msgid "Couldn't allocate decoder" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "" - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "" @@ -836,16 +867,16 @@ msgstr "" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "DAC already in use" -msgstr "" +msgstr "DAC zaten kullanımda" #: ports/atmel-samd/common-hal/paralleldisplay/ParallelBus.c #: ports/nrf/common-hal/paralleldisplay/ParallelBus.c msgid "Data 0 pin must be byte aligned" -msgstr "" +msgstr "Data 0 pini bite hizalı olmalı" #: shared-module/audiocore/WaveFile.c msgid "Data chunk must follow fmt chunk" -msgstr "" +msgstr "Veri öbeği, fmt yığınını takip etmelidir" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -863,30 +894,38 @@ msgstr "" #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." -msgstr "" +msgstr "Hedef kapasitesi, hedef_uzunluğundan daha küçük." #: ports/nrf/common-hal/audiobusio/I2SOut.c msgid "Device in use" -msgstr "" +msgstr "Cihaz kullanımda" #: shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." -msgstr "" +msgstr "Ekran 16 bitlik bir renk uzayına sahip olmalıdır." #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" -msgstr "" +msgstr "Ekran dönüşü 90 derecelik artışlarla olmalıdır" + +#: main.c +msgid "Done" +msgstr "Tamamlandı" #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." -msgstr "" +msgstr "Yön, giriş olduğunda sürüş modu kullanılmaz." + +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "Yukarıdaki hatanın işlenmesi sırasında başka bir hata oluştu:" #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" -msgstr "" +msgstr "ECB aynı anda yalnızca 16 baytla çalışır" #: ports/espressif/common-hal/busio/SPI.c #: ports/espressif/common-hal/canio/CAN.c @@ -898,30 +937,27 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" -msgstr "" +msgstr "EXTINT kanalı zaten kullanımda" #: shared-module/synthio/MidiTrack.c #, c-format msgid "Error in MIDI stream at position %d" -msgstr "" +msgstr "%d konumundaki MIDI akışında hata" #: extmod/modure.c msgid "Error in regex" +msgstr "regex'te hata" + +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" -msgstr "" - -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "" +msgstr "Hata: Bağlanamadı" #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -931,24 +967,24 @@ msgstr "" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "FFT is defined for ndarrays only" -msgstr "" +msgstr "FFT sadece ndarrays'te tanımlandı" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "FFT is implemented for linear arrays only" -msgstr "" +msgstr "FFT yalnızca doğrusal diziler için uygulanır" #: ports/espressif/common-hal/ssl/SSLSocket.c msgid "Failed SSL handshake" -msgstr "" +msgstr "SSL el sıkışma hatası" #: shared-bindings/ps2io/Ps2.c msgid "Failed sending command." -msgstr "" +msgstr "Komut gönderilemedi." #: ports/nrf/sd_mutex.c #, c-format msgid "Failed to acquire mutex, err 0x%04x" -msgstr "" +msgstr "Muteks alınamadı, err 0x%04x" #: shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" @@ -969,86 +1005,100 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to connect: internal error" -msgstr "" +msgstr "Bağlantı kurulamadı: internal error" #: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to connect: timeout" -msgstr "" - -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "" +msgstr "Bağlantı kurulamadı: timeout" #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" -msgstr "" +msgstr "MP3 dosyası ayrıştırılamadı" #: ports/nrf/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" -msgstr "" +msgstr "Muteks serbest bırakılamadı, err 0x%04x" #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." -msgstr "" +msgstr "Dahili flaş yazılamadı." #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c msgid "File exists" +msgstr "Dosya var" + +#: shared-module/os/getenv.c +msgid "File not found" msgstr "" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" +msgstr "Filtreler çok karmaşık" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is duplicate" msgstr "" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "" +msgid "Firmware is invalid" +msgstr "Yazılım geçersiz" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "Yazılım çok büyük" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" msgstr "" +"L8 renk uzayı için, giriş bitmap'i piksel başına 8 bayta sahip olmalıdır" #: shared-bindings/bitmaptools/__init__.c msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" +"RGB renk uzayı için, giriş bitmap'i piksel başına 16 bayta sahip olmalıdır" #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" -msgstr "" +msgstr "Format desteklenmiyor" #: ports/mimxrt10xx/common-hal/microcontroller/Processor.c msgid "" "Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" msgstr "" +"Frekans 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 ya da 1008 Mhz " +"olmalıdır" #: shared-bindings/pwmio/PWMOut.c msgid "Frequency must match existing PWMOut using this timer" -msgstr "" +msgstr "Frekans, bu zamanlayıcıyı kullanan mevcut PWMOut ile eşleşmelidir" #: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c #: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c msgid "Function requires lock" -msgstr "" +msgstr "Fonksiyon kilit gerektirir" #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" -msgstr "" +msgstr "GNSS init" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" -msgstr "" +msgstr "Grup zaten kullanılıyor" #: ports/atmel-samd/common-hal/busio/SPI.c ports/cxd56/common-hal/busio/SPI.c #: ports/espressif/common-hal/busio/SPI.c @@ -1061,203 +1111,224 @@ msgstr "" #: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/canio/CAN.c #: ports/stm/common-hal/sdioio/SDCard.c msgid "Hardware busy, try alternative pins" -msgstr "" +msgstr "Donanım meşgul, alternatif pinleri deneyin" #: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "Hardware in use, try alternative pins" +msgstr "Donanım kullanımda, alternatif pinleri deneyin" + +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "" + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." msgstr "" #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" -msgstr "" +msgstr "Kapalı dosyada I/O işlemi" #: ports/stm/common-hal/busio/I2C.c msgid "I2C init error" -msgstr "" +msgstr "I2C init hatası" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" -msgstr "" +msgstr "I2C çevre cihazı kullanımda" #: shared-bindings/audiobusio/I2SOut.c msgid "I2SOut not available" -msgstr "" - -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "" +msgstr "I2SOut uygundeğil" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" -msgstr "" +msgstr "Buffer öğeleri <=4 bayt uzunluğunda olmalı" #: py/persistentcode.c msgid "" "Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" "mpy-update for more info." msgstr "" +"Uyumsuz .mpy dosyası. Lütfen tüm .mpy dosyalarını güncelleyin. Daha fazla " +"bilgi için http://adafru.it/mpy-update ." #: shared-bindings/_pew/PewPew.c msgid "Incorrect buffer size" -msgstr "" +msgstr "Yanlış buffer size" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Init program size invalid" -msgstr "" +msgstr "Init program boyutu geçersiz" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Initial set pin direction conflicts with initial out pin direction" -msgstr "" +msgstr "İlk pin yönü, ilk çıkış pin yönüyle çakışıyor" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Initial set pin state conflicts with initial out pin state" -msgstr "" +msgstr "İlk pinin durumu, ilk çıkış pininin durumu ile çakışıyor" #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "Initialization failed due to lack of memory" -msgstr "" +msgstr "Bellek yetersizliği nedeniyle başlatma başarısız oldu" #: shared-bindings/bitops/__init__.c #, c-format msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" -msgstr "" +msgstr "Giriş buffer uzunluğu (%d) strand sayımının (%d) katı olmalıdır" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" -msgstr "" +msgstr "Giriş çok uzun sürüyor" #: ports/espressif/common-hal/neopixel_write/__init__.c py/moduerrno.c msgid "Input/output error" -msgstr "" +msgstr "Giriş/çıkış hatası" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" -msgstr "" +msgstr "Komut %d pin sayısından daha fazla bit içe kaydırıyor" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts out more bits than pin count" -msgstr "" +msgstr "Komut %d pin sayısından daha fazla bit dışa kaydırıyor" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d uses extra pin" -msgstr "" +msgstr "Komut %d extra pin kullanıyor" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d waits on input outside of count" -msgstr "" +msgstr "Komut %d sayım dışında, girişte bekler" #: ports/nrf/common-hal/_bleio/__init__.c msgid "Insufficient authentication" -msgstr "" +msgstr "Yetersiz kimlik doğrulama" #: ports/nrf/common-hal/_bleio/__init__.c msgid "Insufficient encryption" -msgstr "" +msgstr "Yetersiz şifreleme" #: ports/espressif/common-hal/wifi/Radio.c msgid "Interface must be started" -msgstr "" +msgstr "Arayüz başlatılmalıdır" #: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c msgid "Internal audio buffer too small" -msgstr "" +msgstr "Dahili ses arabelleği çok küçük" #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" -msgstr "" +msgstr "Dahili tanımlama hatası" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" -msgstr "" +msgstr "Dahili hata" #: shared-module/rgbmatrix/RGBMatrix.c #, c-format msgid "Internal error #%d" -msgstr "" +msgstr "Dahili hata #%d" #: supervisor/shared/safe_mode.c msgid "Internal watchdog timer expired." +msgstr "Dahili bekçi zamanlayıcısının süresi doldu." + +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." msgstr "" -#: py/argcheck.c +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" -msgstr "" +msgstr "Geçersiz %q" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" -msgstr "" +msgstr "Geersi %q pin" #: ports/stm/common-hal/analogio/AnalogIn.c msgid "Invalid ADC Unit value" -msgstr "" +msgstr "Geçersiz ADC Ünite değeri" #: ports/espressif/common-hal/_bleio/__init__.c #: ports/nrf/common-hal/_bleio/__init__.c msgid "Invalid BLE parameter" -msgstr "" +msgstr "Geçersiz BLE parametresi" #: shared-bindings/wifi/Radio.c msgid "Invalid BSSID" -msgstr "" +msgstr "Geçersiz BSSID" #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" -msgstr "" +msgstr "Geçersiz MAC adresi" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" -msgstr "" +msgstr "Geçersiz argüman" #: shared-module/displayio/Bitmap.c +#, fuzzy msgid "Invalid bits per value" +msgstr "Geçersiz bit başına değer" + +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" msgstr "" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" -msgstr "" +msgstr "Geçersiz veri_pini [%d]" #: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "" +msgstr "Geçersiz biçim yığın boyutu" #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" -msgstr "" +msgstr "Geçersiz multicast MAC adresi" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" -msgstr "" +msgstr "Geçersiz boyut" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" -msgstr "" +msgstr "TLS için geçersiz soket" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" +msgstr "Geçersiz durum" + +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" msgstr "" #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" +msgstr "Anahtar 16, 24 veya 32 bayt uzunluğunda olmalıdır" + +#: shared-module/os/getenv.c +msgid "Key not found" msgstr "" #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" -msgstr "" +msgstr "LED eşlemeleri ekran boyutuyla eşleşmelidir" #: py/compile.c msgid "LHS of keyword arg must be an id" @@ -1265,24 +1336,24 @@ msgstr "" #: shared-module/displayio/Group.c msgid "Layer already in a group" -msgstr "" +msgstr "Katman zaten bir grupta" #: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass" -msgstr "" +msgstr "Katman, bir Grup ya da TileGrid alt sınıfı olmalıdır" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" -msgstr "" +msgstr "MAC adresi geçersiz" #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" -msgstr "" +msgstr "Map tuple olmalıdır" #: shared-module/displayio/Shape.c #, c-format msgid "Maximum x value when mirrored is %d" -msgstr "" +msgstr "İkizlendiğinde maksimum x değeri %d'dir" #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" @@ -1299,11 +1370,11 @@ msgstr "" #: ports/mimxrt10xx/common-hal/busio/SPI.c msgid "Missing MISO or MOSI Pin" -msgstr "" +msgstr "Eksik MISO veya MOSI pini" #: ports/stm/common-hal/busio/SPI.c msgid "Missing MISO or MOSI pin" -msgstr "" +msgstr "Eksik MISO veya MOSI pini" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format @@ -1359,11 +1430,15 @@ msgstr "" #: ports/espressif/common-hal/nvm/ByteArray.c msgid "NVS Error" +msgstr "NVS hatası" + +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" msgstr "" #: py/qstr.c msgid "Name too long" -msgstr "" +msgstr "İsim çok uzun" #: shared-bindings/displayio/TileGrid.c msgid "New bitmap must be same size as old bitmap" @@ -1401,43 +1476,43 @@ msgstr "" #: supervisor/shared/web_workflow/web_workflow.c msgid "No IP" -msgstr "" +msgstr "IP yok" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c msgid "No MISO Pin" -msgstr "" +msgstr "MISO pini yok" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MISO pin" -msgstr "" +msgstr "MISO pini yok" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c msgid "No MOSI Pin" -msgstr "" +msgstr "MOSI pini yok" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MOSI pin" -msgstr "" +msgstr "MOSI pini yok" #: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "No RX pin" -msgstr "" +msgstr "RX pini yok" #: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "No TX pin" -msgstr "" +msgstr "TX pini yok" #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c msgid "No available clocks" -msgstr "" +msgstr "Kullanılabilir saat yok" #: ports/espressif/common-hal/imagecapture/ParallelImageCapture.c msgid "No capture in progress" @@ -1475,11 +1550,6 @@ msgstr "" msgid "No long integer support" msgstr "" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "" @@ -1515,10 +1585,6 @@ msgstr "" msgid "No timer available" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "" - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1538,10 +1604,6 @@ msgstr "" msgid "Not playing" msgstr "" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1556,16 +1618,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "" #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "" @@ -1595,10 +1667,15 @@ msgid "" msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "" + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "" @@ -1621,19 +1698,24 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1688,7 +1770,6 @@ msgid "Pin interrupt already in use" msgstr "" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "" @@ -1755,6 +1836,10 @@ msgstr "" msgid "Program size invalid" msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1794,8 +1879,9 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "" @@ -1803,12 +1889,12 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +msgid "Received response was invalid" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c -msgid "Received response was invalid" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" #: shared-bindings/displayio/EPaperDisplay.c @@ -1823,7 +1909,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "" @@ -1895,7 +1981,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1907,6 +1994,7 @@ msgid "Slices not supported" msgstr "" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1930,12 +2018,8 @@ msgstr "" msgid "Stereo right must be on PWM channel B" msgstr "" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "" - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." msgstr "" #: shared-bindings/alarm/time/TimeAlarm.c @@ -1951,15 +2035,11 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1967,10 +2047,7 @@ msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." +msgid "The power dipped. Make sure you are providing enough power." msgstr "" #: shared-module/audiomixer/MixerVoice.c @@ -1989,6 +2066,10 @@ msgstr "" msgid "The sample's signedness does not match the mixer's" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "" + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "" @@ -2021,10 +2102,6 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2069,6 +2146,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" @@ -2077,6 +2158,10 @@ msgstr "" msgid "UART write" msgstr "" +#: main.c +msgid "UID:" +msgstr "" + #: shared-module/usb_hid/Device.c msgid "USB busy" msgstr "" @@ -2112,6 +2197,15 @@ msgstr "" msgid "Unable to allocate buffers for signed conversion" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "" + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "" @@ -2130,14 +2224,29 @@ msgstr "" msgid "Unable to init parser" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "" @@ -2200,7 +2309,13 @@ msgstr "" msgid "Unknown system firmware error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" @@ -2245,7 +2360,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "" @@ -2271,10 +2386,6 @@ msgstr "" msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -2289,6 +2400,18 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "" + #: main.c msgid "Woken up by alarm.\n" msgstr "" @@ -2298,17 +2421,56 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." +msgid "You pressed the BOOT button at start up" +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2327,11 +2489,7 @@ msgstr "" msgid "a bytes-like object is required" msgstr "" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "" @@ -2384,8 +2542,12 @@ msgstr "" msgid "array has too many dimensions" msgstr "" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "" @@ -2478,10 +2640,6 @@ msgstr "" msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2523,15 +2681,10 @@ msgstr "" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2609,10 +2762,14 @@ msgstr "" msgid "can't set 512 block size" msgstr "" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "" + #: py/emitnative.c msgid "can't store '%q'" msgstr "" @@ -2711,18 +2868,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "" @@ -2805,10 +2954,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "" @@ -2829,12 +2974,11 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "" @@ -2866,10 +3010,6 @@ msgstr "" msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "" @@ -2879,18 +3019,16 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" @@ -2989,10 +3127,6 @@ msgstr "" msgid "format requires a dict" msgstr "" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "" - #: py/objdeque.c msgid "full" msgstr "" @@ -3105,14 +3239,14 @@ msgstr "" msgid "index is out of bounds" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" msgstr "" #: extmod/ulab/code/ndarray.c @@ -3208,10 +3342,6 @@ msgstr "" msgid "inputs are not iterable" msgstr "" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "" @@ -3230,6 +3360,10 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3256,10 +3390,18 @@ msgstr "" msgid "invalid hostname" msgstr "" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "" + #: py/compile.c msgid "invalid micropython decorator" msgstr "" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "" @@ -3281,10 +3423,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3341,19 +3479,17 @@ msgstr "" msgid "local variable referenced before assignment" msgstr "" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "" @@ -3482,6 +3618,10 @@ msgstr "" msgid "negative shift count" msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "" @@ -3515,14 +3655,10 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3647,15 +3783,30 @@ msgid "offset out of bounds" msgstr "" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" @@ -3726,10 +3877,6 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "" @@ -3779,28 +3926,6 @@ msgstr "" msgid "pow() with 3 arguments requires integers" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -3821,11 +3946,6 @@ msgstr "" msgid "relative import" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -3856,12 +3976,6 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3895,10 +4009,6 @@ msgstr "" msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "" @@ -3911,10 +4021,6 @@ msgstr "" msgid "slice step can't be zero" msgstr "" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "" - #: py/nativeglue.c msgid "slice unsupported" msgstr "" @@ -3963,14 +4069,6 @@ msgstr "" msgid "start/end indices" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "" @@ -3979,10 +4077,6 @@ msgstr "" msgid "stream operation not supported" msgstr "" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" @@ -4015,14 +4109,6 @@ msgstr "" msgid "syntax error in uctypes descriptor" msgstr "" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4030,10 +4116,6 @@ msgstr "" msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "" @@ -4087,10 +4169,6 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4101,8 +4179,6 @@ msgstr "" msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "" @@ -4115,14 +4191,10 @@ msgstr "" msgid "type is not an acceptable base type" msgstr "" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "" @@ -4143,7 +4215,7 @@ msgstr "" msgid "unexpected keyword argument" msgstr "" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "" @@ -4173,7 +4245,8 @@ msgid "unknown type '%q'" msgstr "" #: py/objstr.c -msgid "unmatched '{' in format" +#, c-format +msgid "unmatched '%c' in format" msgstr "" #: py/objtype.c py/runtime.c @@ -4181,7 +4254,6 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" @@ -4245,18 +4317,19 @@ msgstr "" msgid "watchdog not initialized" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "" @@ -4311,18 +4384,10 @@ msgstr "" msgid "xTaskCreate failed" msgstr "" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "" -#: py/objrange.c -msgid "zero step" -msgstr "" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "" @@ -4335,6 +4400,80 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "%q pin invalid" +#~ msgstr "%q pini geçersiz" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Lütfen, şu adrese CIRCUITPY sürücünüzün içerikleri ile beraber bir hata/" +#~ "konu kaydı ekleyin\n" +#~ "https://github.com/adafruit/circuitpython/issues\n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "VM çalışmazken heap'ten alan tahsis edilmeye çalışıldı." + +#~ msgid "Boot device must be first device (interface #0)." +#~ msgstr "Önyükleme cihazı ilk cihaz olmalı (arayüz #0)." + +#~ msgid "Both buttons were pressed at start up.\n" +#~ msgstr "Başlatma sırasında her iki düğmeye de basıldı.\n" + +#~ msgid "Button A was pressed at start up.\n" +#~ msgstr "Başlatma sırasında A düğmesine basıldı.\n" + +#~ msgid "Invalid memory access." +#~ msgstr "Geçersiz bellek erişimi." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q, %q türünde olmalıdır" + +#~ msgid "%q must be of type %q or None" +#~ msgstr "%q, %q ya da None türünde olmalıdır" + +#~ msgid "Expected a %q" +#~ msgstr "%q bekleniyor" + +#~ msgid "Expected a %q or %q" +#~ msgstr "%q yada %q bekleniyor" + +#~ msgid "Expected an %q" +#~ msgstr "%q bekleniyor" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV %d bayt uzunluğunda olmalı" + +#~ msgid "%q length must be >= 1" +#~ msgstr "%q boyutu >=1 olmalıdır" + +#~ msgid "%q must be a string" +#~ msgstr "%q bir string olmalıdır" + +#~ msgid "%q must be an int" +#~ msgstr "%q bir tam sayı olmalıdır" + +#~ msgid "%q with a report ID of 0 must be of length 1" +#~ msgstr "Rapor kimliği 0 olan %q, 1 uzunluğunda olmalıdır" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "En az %d %q belirtilmeli (%d değil)" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "%q indeksleri integer olmalı, %s değil" + +#~ msgid "%q must be >= 0" +#~ msgstr "%q >= 0 olmalıdır" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q >= 1 olmalıdır" + +#~ msgid "All I2C targets are in use" +#~ msgstr "Tüm I2C hedefleri kullanımda" + #~ msgid "%q must be a tuple of length 2" #~ msgstr "%q, boyutu 2 olan bir tuple olmalıdır" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 5985e012b0..ea9fa2fc68 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2022-04-23 21:13+0000\n" +"PO-Revision-Date: 2023-03-01 17:39+0000\n" "Last-Translator: hexthat \n" "Language-Team: Chinese Hanyu Pinyin\n" "Language: zh_Latn_pinyin\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.12.1-dev\n" +"X-Generator: Weblate 4.16\n" #: main.c msgid "" @@ -34,15 +34,43 @@ msgstr "" "dài mǎ yīn zì dòng chóng xīn jiā zǎi ér tíng zhǐ. jí jiāng chóng xīn jiā " "zǎi.\n" +#: main.c +msgid "" +"\n" +"Invalid CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\r" +msgstr "" +"\n" +"wú xiào CIRCUITPY_PYSTACK_SIZE\n" +"\n" +"\n" + #: supervisor/shared/safe_mode.c msgid "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." msgstr "" "\n" -"Qǐng tōngguò https://github.com/adafruit/circuitpython/issues\n" -"tíjiāo yǒuguān nín de CIRCUITPY qūdòngqì nèiróng de wèntí \n" +"qǐng zài https://github.com/adafruit/circuitpython/issues tí jiāo nín de " +"chéng xù wèn tí." + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" +"\n" +"àn chóng zhì tuì chū ān quán mó shì.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" +"\n" +"nín chǔ yú ān quán mó shì, yīn wéi:\n" #: py/obj.c msgid " File \"%q\"" @@ -69,6 +97,16 @@ msgstr " shūchū:\n" msgid "%%c requires int or char" msgstr "%%c xūyào zhěngshù huòzhě zìfú" +#: main.c +#, c-format +msgid "%02X" +msgstr "%02X" + +#: shared-module/os/getenv.c +#, c-format +msgid "%S" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -77,15 +115,18 @@ msgstr "" "%d de zhǐ yǐn jiǎo, %d rgb yǐn jiǎo hé %d qiē piàn biǎo shì %d de gāo dù, ér " "bù shì %d" +#: ports/atmel-samd/common-hal/alarm/__init__.c #: ports/cxd56/common-hal/analogio/AnalogOut.c ports/cxd56/common-hal/rtc/RTC.c #: ports/espressif/common-hal/rtc/RTC.c #: ports/mimxrt10xx/common-hal/analogio/AnalogOut.c -#: ports/mimxrt10xx/common-hal/rtc/RTC.c +#: ports/mimxrt10xx/common-hal/rtc/RTC.c ports/nrf/common-hal/alarm/__init__.c #: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/alarm/__init__.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c -#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c +#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/alarm/__init__.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" -msgstr "" +msgstr "%q" #: shared-bindings/microcontroller/Pin.c msgid "%q and %q contain duplicate pins" @@ -93,7 +134,7 @@ msgstr "%q hé %q bāo hán chóng fù yǐn jiǎo" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "%q and %q must be different" -msgstr "" +msgstr "%q hé %q bìxū bùtóng" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -103,25 +144,36 @@ msgstr "%q bāo hán chóng fù de yǐn jiǎo" msgid "%q failure: %d" msgstr "%q Shībài: %d" +#: py/argcheck.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q zhōng de %q bì xū shì %q lèi xíng, ér bù shì %q" + +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q zhèngzài bèi shǐyòng" -#: py/obj.c py/objstr.c py/objstrunicode.c +#: py/objstr.c py/objstrunicode.c msgid "%q index out of range" msgstr "%q suǒyǐn chāochū fànwéi" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q suǒyǐn bìxū shì zhěngshù, ér bùshì %s" - #: shared-module/bitbangio/SPI.c msgid "%q init failed" -msgstr "" +msgstr "%q chūshǐhuà shībài" -#: py/argcheck.c +#: shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q shì %q" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q duì yú cǐ bǎn shì zhǐ dú de" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" -msgstr "" +msgstr "%q de chángdù bìxū shì %d" #: py/argcheck.c msgid "%q length must be %d-%d" @@ -129,19 +181,15 @@ msgstr "%q cháng dù bì xū wéi %d-%d" #: py/argcheck.c msgid "%q length must be <= %d" -msgstr "" +msgstr "%q chángdù bìxū <= %d" #: py/argcheck.c msgid "%q length must be >= %d" -msgstr "" - -#: shared-bindings/busio/I2C.c -msgid "%q length must be >= 1" -msgstr "%q cháng dù bì xū >= 1" +msgstr "%q chángdù bìxū >= %d" #: py/argcheck.c msgid "%q must be %d" -msgstr "" +msgstr "%q bìxū %d" #: py/argcheck.c msgid "%q must be %d-%d" @@ -149,39 +197,37 @@ msgstr "%q bì xū wéi %d-%d" #: shared-bindings/displayio/Display.c msgid "%q must be 1 when %q is True" -msgstr "" +msgstr "sāng %q wèi True shí, %q bìxū wèi 1" #: py/argcheck.c shared-bindings/gifio/GifWriter.c msgid "%q must be <= %d" -msgstr "%q bì xū <= %d" +msgstr "%q bìxū <= %d" #: py/argcheck.c msgid "%q must be >= %d" -msgstr "%q bì xū >= %d" +msgstr "%q bìxū >= %d" -#: py/argcheck.c -msgid "%q must be >= 0" -msgstr "%q Bìxū > = 0" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "%q bì xū shì lèi xíng wéi 'H' de shù zǔ" -#: shared-bindings/vectorio/Circle.c shared-bindings/vectorio/Rectangle.c -msgid "%q must be >= 1" -msgstr "%q bìxū >= 1" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q bì xū shì zì jié shù zǔ huò lèi xíng wéi 'H' huò 'B' de shù zǔ" -#: py/argcheck.c -msgid "%q must be a string" -msgstr "%q bì xū shì yí gè zì fú chuàn" - -#: py/argcheck.c -msgid "%q must be an int" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" +"%q bì xū shì zì jié shù zǔ huò lèi xíng wéi 'h', 'H', 'b', huò 'B' de shù zǔ" -#: py/argcheck.c -msgid "%q must be of type %q" -msgstr "%q bì xū shì %q lèi xíng" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q de lèi xíng bì xū shì %q huò %q, ér bù shì %q" -#: shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q lèi xíng bì xū wéi %q huò wú" +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" +msgstr "%q de lèi xíng bì xū shì %q, ér bù shì %q" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" @@ -200,13 +246,9 @@ msgstr "%q chāo chū jiè xiàn" msgid "%q out of range" msgstr "%q chāochū fànwéi" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "%q yǐn jiǎo wúxiào" - -#: shared-bindings/usb_hid/Device.c -msgid "%q with a report ID of 0 must be of length 1" -msgstr "bào gào ID shì 0 de %q bì xū cháng dù wéi 1" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "%q bù cháng bù néng wéi líng" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -216,11 +258,11 @@ msgstr "%q() yāoqiú shūrù %d gè wèizhì cānshù, dàn mùqián shūrù le msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, hé %q bì xū cháng dù xiāng tóng" -#: py/objint.c +#: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #, c-format msgid "%s error 0x%x" msgstr "%s cuò wù 0x%x" @@ -405,12 +447,16 @@ msgstr "ADC2 zhèngzài bèi WiFi shǐ yòng" msgid "Address must be %d bytes long" msgstr "dìzhǐ chángdù bìxū shì %d zìjié" +#: ports/espressif/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "bù yǔn xǔ de dì zhǐ fàn wéi" + #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "suǒyǒu CAN wàishè dōu zài shǐyòng zhōng" #: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" msgstr "suǒyǒu I2C wàishè dōu zài shǐyòng zhōng" @@ -432,7 +478,6 @@ msgid "All SPI peripherals are in use" msgstr "suǒyǒu SPI wàishè dōu zài shǐyòng zhōng" #: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "suǒyǒu UART wàishè dōu zài shǐyòng zhōng" @@ -482,19 +527,25 @@ msgid "Already advertising." msgstr "Mùqián zhèngzài guǎngbō." #: ports/atmel-samd/common-hal/canio/Listener.c -#, fuzzy msgid "Already have all-matches listener" -msgstr "yǐjīng yǒu all-matches jiāntīngqì" +msgstr "yǐjīng yǒu all-matches jiāntīng qì" +#: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" msgstr "yǐjīng zài yùnxíng" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "yǐjīng zài sǎomiáo WIFI wǎngluò" +#: shared-module/os/getenv.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "jiǎn suǒ '%s' shí chū cuò:\n" + #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" msgstr "lìng yí gè PWMAudioOut yǐ jīng zài gōngzuò" @@ -508,23 +559,16 @@ msgstr "Lìng yīgè fāsòng (send) yǐjīng zài gōngzuò" msgid "Array must contain halfwords (type 'H')" msgstr "Shùzǔ bìxū bāohán halfwords (type 'H')" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "shùzǔ de zhí yīnggāi shì dān'gè zìjié." -#: shared-bindings/microcontroller/Pin.c -msgid "At most %d %q may be specified (not %d)" -msgstr "zuìduō kěyǐ zhǐdìng %d gè %q (érbúshì %d)" - #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" msgstr "shìtú fēnpèi %d blocks" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "shìtú zài xūnǐjī (VM) yùn xíng shí fēnpèi duī (heap)." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "yīnpín zhuǎnhuàn wèi bèi shíxiàn" @@ -559,27 +603,24 @@ msgid "Below minimum frame rate" msgstr "dīyú zuìdī zhēnlǜ" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#, fuzzy msgid "Bit clock and word select must be sequential pins" -msgstr "wèi shí zhōng hé dān cí xuǎn zé bì xū shì shùn xù yǐn jiǎo" +msgstr "wèi shízhōng hé zì xuǎnzé bìxū shì liánxù de yǐn jiǎo" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#, fuzzy msgid "Bit clock and word select must share a clock unit" -msgstr "Bǐtè shízhōng hé dānzì xuǎnzé bìxū gòngxiǎng shízhōng dānwèi" +msgstr "wèi shízhōng hé zì xuǎnzé bìxū gòngxiǎng yīgè shízhōng dānyuán" #: shared-bindings/audiobusio/PDMIn.c msgid "Bit depth must be multiple of 8." msgstr "wèi shēndù bìxū shì 8 de zhěngshùbèi." #: shared-bindings/bitmaptools/__init__.c -#, fuzzy msgid "Bitmap size and bits per value must match" -msgstr "wèitú dàxiǎo hé měigè zhí de wèi bìxū pǐpèi" +msgstr "wèi tú dàxiǎo hé měi gè zhí de wèi shù bìxū pǐpèi" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "yǐndǎo shèbèi bìxū shì dìyī tái shèbèi (interface #0)." +msgid "Boot device must be first (interface #0)." +msgstr "yǐn dǎo shè bèi bì xū shì dì yī gè (jiē kǒu #0)." #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" @@ -634,9 +675,9 @@ msgid "Buffer must be a multiple of 512 bytes" msgstr "Huǎnchōngqū bìxū shì 512 zìjié de bèishù" #: shared-bindings/_bleio/PacketBuffer.c -#, fuzzy, c-format +#, c-format msgid "Buffer too short by %d bytes" -msgstr "Huǎn chōng qū tài duǎn , àn %d zì jié" +msgstr "Huǎnchōngqū tàiduǎn , mùqián zhǐyǒu %d zìjié" #: ports/espressif/common-hal/imagecapture/ParallelImageCapture.c msgid "Buffers must be same size" @@ -662,7 +703,7 @@ msgstr "CBC kuài bìxū shì 16 zìjié de bèishù" msgid "CIRCUITPY drive could not be found or created." msgstr "zhǎo bú dào huò chuàng jiàn CIRCUITPY qū dòng qì." -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "CRC or checksum was invalid" msgstr "CRC huò jiàoyàn hé wúxiào" @@ -672,24 +713,22 @@ msgstr "Zài fǎngwèn yuánshēn dùixiàng zhīqián diàoyòng super().__init #: ports/cxd56/common-hal/camera/Camera.c msgid "Camera init" -msgstr "" +msgstr "xiàngjī chūshǐhuà" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c -#, fuzzy msgid "Can only alarm on RTC IO from deep sleep." -msgstr "zhǐ néng zài RTC IO shàng cóng shēndù shuìmián zhōng bào jǐng." +msgstr "Zhǐ néng cóng shēndù shuìmián zhōng duì RTC IO jìnxíng bàojǐng." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c -#, fuzzy msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" -"Zhǐ néng zài yīgè dī diàn píng yǐn jiǎo shàng fāchū jǐngbào, ér qítā yǐn " -"jiǎo cóng shēndù shuìmián zhōng fāchū gāo diàn píng jǐngbào." +"Zhǐ néng zài yīgè dī yǐn jiǎo shàng bàojǐng, ér qítā yǐn jiǎo cóng shēndù " +"shuìmián zhōng fāchū gāo diàn píng bàojǐng." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c -#, fuzzy msgid "Can only alarm on two low pins from deep sleep." -msgstr "zhǐ néng cóng shēn dù shuì mián zhōng bào jǐng liǎng gè dī yǐn jiǎo." +msgstr "" +"Zhǐ néng cóng shēndù shuìmián zhōng de liǎng gè dī yǐn jiǎo shàng bàojǐng." #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nrf/common-hal/_bleio/Characteristic.c @@ -724,11 +763,11 @@ msgstr "Wúfǎ huòqǔ wēndù" #: shared-bindings/_bleio/Adapter.c msgid "Cannot have scan responses for extended, connectable advertisements." -msgstr "Nín wúfǎ sǎomiáo kuòzhǎn de, kě liánjiē de guǎnggào." +msgstr "Quē fá duì tuī guǎng, kě lián jiē guǎng gào de dá fù." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot pull on input-only pin." -msgstr "wú fǎ lā dòng jǐn shū rù yǐn jiǎo." +msgstr "wúfǎ lādòng jǐn shūrù yǐnjiǎo." #: shared-bindings/audiobusio/PDMIn.c msgid "Cannot record to a file" @@ -736,66 +775,62 @@ msgstr "Wúfǎ jìlù dào wénjiàn" #: shared-module/storage/__init__.c msgid "Cannot remount '/' when visible via USB." -msgstr "tōng guò USB kě jiàn shí wú fǎ chóng xīn ān zhuāng '/'." +msgstr "tōngguò USB kějiàn shí wúfǎ chóngxīn ānzhuāng '/'." #: ports/atmel-samd/common-hal/microcontroller/__init__.c #: ports/cxd56/common-hal/microcontroller/__init__.c #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c msgid "Cannot reset into bootloader because no bootloader is present" -msgstr "" +msgstr "wúfǎ chóngxīn qǐdòng dào yǐdǎo chéngxù, yīnwéi yǐdǎo chéngxù bù cúnzài" #: ports/espressif/common-hal/socketpool/Socket.c msgid "Cannot set socket options" -msgstr "wú fǎ shè zhì tào jiē zì xuǎn xiàng" +msgstr "wúfǎ shèzhì tàojiēzì xuǎnxiàng" #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." -msgstr "Dāng fāngxiàng xiàng nèi shí, bùnéng shèzhì gāi zhí." +msgstr "Dāng fāngxiàng wéi shūrù shí, bùnéng shèzhì zhí." #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Cannot specify RTS or CTS in RS485 mode" -msgstr "wú fǎ zài RS485 mó shì xià zhǐ dìng RTS huò CTS" +msgstr "wúfǎ zài RS485 móshì xià zhǐdìng RTS huò CTS" #: py/objslice.c msgid "Cannot subclass slice" -msgstr "Wúfǎ zi fēnlèi" +msgstr "bùnéng zǐlèihuà qiēpiàn" #: shared-module/bitbangio/SPI.c msgid "Cannot transfer without MOSI and MISO pins" -msgstr "" +msgstr "méiyǒu MOSI hé MISO yǐnjiǎo, wúfǎ chuánshū" #: shared-bindings/pwmio/PWMOut.c msgid "Cannot vary frequency on a timer that is already in use" -msgstr "Wúfǎ gēnggǎi yǐ zài shǐyòng de jìshí qì shàng de pínlǜ" +msgstr "Wúfǎ zài shǐyòng zhōng de jìshí qì shàng gēnggǎi pínlǜ" #: ports/nrf/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" -msgstr "" +msgstr "wúfǎ shǐyòng biānyuán huànxǐng, zhǐnéng shǐyòng diànpíng" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." -msgstr "wú fǎ zài yǐn jiǎo biān yuán huàn xǐng. jǐn jí bié." +msgstr "wúfǎ shǐyòng biānyuán huànxǐng. zhǐnéng shǐyòng diànpíng." #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" -msgstr "Wèi tígōng zìfú huǎncún xiě rù" +msgstr "Wèi tígōng zìfú huǎncún xiěrù" #: supervisor/shared/safe_mode.c msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "CircuitPython de héxīn chūxiàn gùzhàng. Āiyā!\n" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython was unable to allocate the heap." -msgstr "CircuitPython wúfǎ fēnpèi duī." - #: shared-module/bitbangio/I2C.c msgid "Clock stretch too long" -msgstr "Shízhōng shēnzhǎn tài zhǎng" +msgstr "shízhōng yánzhǎn guòcháng" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Clock unit in use" -msgstr "Shǐyòng shízhōng dānwèi" +msgstr "shízhōng dānyuán zhèngzài shǐyòng zhōng" #: shared-bindings/_bleio/Connection.c msgid "" @@ -803,17 +838,25 @@ msgid "" "connection." msgstr "Liánjiē yǐ duàn kāi, wúfǎ zài shǐyòng. Chuàngjiàn yīgè xīn de liánjiē." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" -msgstr "Fǔbài de .mpy wénjiàn" +msgstr "sǔnhuài de .mpy wénjiàn" #: ports/espressif/common-hal/neopixel_write/__init__.c msgid "Could not retrieve clock" -msgstr "Wúfǎ huòqǔ shízhōng" +msgstr "wúfǎ jiǎnsuǒ shízhōng" #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" -msgstr "wú fǎ shè zhì dì zhǐ" +msgstr "wúfǎ shèzhì dìzhǐ" #: shared-bindings/pwmio/PWMOut.c msgid "Could not start PWM" @@ -825,11 +868,7 @@ msgstr "Wúfǎ qǐdòng zhōngduàn,RX máng" #: shared-module/audiomp3/MP3Decoder.c msgid "Couldn't allocate decoder" -msgstr "Zhǎo bù dào jiěmǎ qì" - -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "Zhuìhuǐ. Shūrù HardFault_Handler." +msgstr "wúfǎ fēnpèi jiěmǎ qì" #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" @@ -841,12 +880,12 @@ msgstr "DAC shèbèi chūshǐhuà cuòwù" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "DAC already in use" -msgstr "Fā yuán huì yǐjīng shǐyòng" +msgstr "DAC zhèngzài bèi shǐyòng" #: ports/atmel-samd/common-hal/paralleldisplay/ParallelBus.c #: ports/nrf/common-hal/paralleldisplay/ParallelBus.c msgid "Data 0 pin must be byte aligned" -msgstr "Shùjù 0 de yǐn jiǎo bìxū shì zì jié duìqí" +msgstr "shù jù 0 yǐn jiǎo bì xū shì zì jié duì qí de" #: shared-module/audiocore/WaveFile.c msgid "Data chunk must follow fmt chunk" @@ -855,7 +894,7 @@ msgstr "Shùjù kuài bìxū zūnxún fmt qū kuài" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c msgid "Data not supported with directed advertising" -msgstr "bù zhī chí dìng xiàng guǎng gào de shù jù" +msgstr "wèi xiàng guǎng gào tí gòng zhī zhù de shù jù" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -886,10 +925,19 @@ msgstr "Xiǎnshì bìxū jùyǒu 16 wèi yánsè kōngjiān." msgid "Display rotation must be in 90 degree increments" msgstr "Xiǎnshì xuánzhuǎn bìxū 90 dù jiā xīn" +#: main.c +msgid "Done" +msgstr "zuò" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." msgstr "Fāngxiàng shūrù shí qūdòng móshì méiyǒu shǐyòng." +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" +"zài chǔ lǐ shàng shù yì cháng qī jiān, fā shēng le lìng yí gè yì cháng:" + #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" msgstr "ECB yí cì zhǐ shǐ yòng 16 gè zì jié" @@ -915,20 +963,17 @@ msgstr "wèi yú %d wèi zhì de MIDI liú zhōng de cuò wù" msgid "Error in regex" msgstr "Zhèngzé biǎodá shì cuòwù" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "safemode.py cuò wù." + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "cuò wù: bǎng dìng shī bài" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Yùqí %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an alarm" -msgstr "yù qī yǒu jǐng bào" +msgid "Expected a kind of %q" +msgstr "yù qī yì zhǒng %q" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -958,7 +1003,7 @@ msgstr "Wúfǎ huòdé mutex, err 0x%04x" #: shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" -msgstr "" +msgstr "wèi néng fēnpèi %q huǎnchōng qū" #: ports/espressif/common-hal/wifi/__init__.c msgid "Failed to allocate Wifi memory" @@ -981,10 +1026,6 @@ msgstr "Liánjiē shībài: Nèibù cuòwù" msgid "Failed to connect: timeout" msgstr "Liánjiē shībài: Chāoshí" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to init wifi" -msgstr "Wúfǎ chūshǐhuà wifi" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Wúfǎ jiěxī MP3 wénjiàn" @@ -999,13 +1040,17 @@ msgid "Failed to write internal flash." msgstr "Wúfǎ xiě rù nèibù shǎncún." #: supervisor/shared/safe_mode.c -msgid "Fatal error." -msgstr "zhì mìng cuò wù." +msgid "Fault detected by hardware." +msgstr "yìng jiàn jiǎn cè dào gù zhàng." #: py/moduerrno.c msgid "File exists" msgstr "Wénjiàn cúnzài" +#: shared-module/os/getenv.c +msgid "File not found" +msgstr "zhǎo bú dào wén jiàn" + #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c @@ -1013,8 +1058,16 @@ msgid "Filters too complex" msgstr "guò lǜ qì tài fù zá" #: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware image is invalid" -msgstr "gù jiàn yìng xiàng wú xiào" +msgid "Firmware is duplicate" +msgstr "gù jiàn chóng fù" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "gù jiàn wú xiào" + +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "gù jiàn tài dà" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" @@ -1048,15 +1101,17 @@ msgstr "Hánshù xūyào suǒdìng" #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" -msgstr "" +msgstr "GNSS chūshǐhuà" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Generic Failure" msgstr "tōng yòng gù zhàng" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Jítuán yǐjīng shǐyòngguò" @@ -1077,15 +1132,25 @@ msgstr "Yìngjiàn máng, qǐng chángshì qítā zhēnjiǎo" msgid "Hardware in use, try alternative pins" msgstr "Shǐyòng de yìngjiàn, qǐng chángshì qítā yǐn jiǎo" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "VM wèi yùn xíng shí de duī fēn pèi." + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "duī yǐ sǔn huài, yīn wéi duī zhàn tài xiǎo. zēng jiā duī zhàn dà xiǎo." + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "Wénjiàn shàng de I/ O cāozuò" #: ports/stm/common-hal/busio/I2C.c msgid "I2C init error" -msgstr "" +msgstr "I2C qǐdòng cuòwù" #: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" msgstr "I2C wài shè zhèng zài shǐ yòng zhōng" @@ -1093,11 +1158,6 @@ msgstr "I2C wài shè zhèng zài shǐ yòng zhōng" msgid "I2SOut not available" msgstr "I2SOut bù kě yòng" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV bì xū wéi %d zì jié cháng" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "huǎn chōng nèi yuán sù bì xū <= 4 zì jié cháng" @@ -1189,6 +1249,7 @@ msgid "Internal define error" msgstr "Nèibù dìngyì cuòwù" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c +#: shared-module/os/getenv.c msgid "Internal error" msgstr "nèi bù cuò wù" @@ -1199,12 +1260,18 @@ msgstr "nèi bù cuò wù #%d" #: supervisor/shared/safe_mode.c msgid "Internal watchdog timer expired." -msgstr "" +msgstr "Nèibù kān mén gǒu dìngshí qì chāoshí." -#: py/argcheck.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "zhōng duàn cuò wù." + +#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "wú xiào %q" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Wúxiào de %q yǐn jiǎo" @@ -1226,7 +1293,7 @@ msgstr "Wúxiào de BSSID" msgid "Invalid MAC address" msgstr "wú xiào de MAC dì zhǐ" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: py/moduerrno.c msgid "Invalid argument" msgstr "Wúxiào de cānshù" @@ -1235,6 +1302,11 @@ msgstr "Wúxiào de cānshù" msgid "Invalid bits per value" msgstr "Měi gè zhí de wèi wúxiào" +#: shared-module/os/getenv.c +#, c-format +msgid "Invalid byte %.*s" +msgstr "wú xiào zì jié %.*s" + #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" @@ -1244,34 +1316,35 @@ msgstr "wú xiào data_pins[%d]" msgid "Invalid format chunk size" msgstr "Géshì kuài dàxiǎo wúxiào" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Wúxiào de nèicún fǎngwèn." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "wú xiào de duō bō MAC dì zhǐ" -#: shared-bindings/busio/UART.c -msgid "Invalid pins" -msgstr "Wúxiào de yǐn jiǎo" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid size" msgstr "dà xiǎo wú xiào" #: ports/espressif/common-hal/ssl/SSLContext.c +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "TLS de chā zuò wú xiào" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Invalid state" msgstr "wú xiào zhuàng tài" +#: shared-module/os/getenv.c +msgid "Invalid unicode escape" +msgstr "wú xiào de unicode zhuǎn yì" + #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" msgstr "mì yào bì xū wéi 16, 24 huò 32 zì jié cháng" +#: shared-module/os/getenv.c +msgid "Key not found" +msgstr "wèi zhǎo dào mì yào" + #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" msgstr "LED yìng shè bì xū yǔ xiǎn shì píng chǐ cùn pǐ pèi" @@ -1282,13 +1355,13 @@ msgstr "Guānjiàn zì arg de LHS bìxū shì id" #: shared-module/displayio/Group.c msgid "Layer already in a group" -msgstr "" +msgstr "tú céng yǐ zài zǔ zhōng" #: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass" -msgstr "" +msgstr "tú céng bìxū shì zǔ huò píng pū wǎng gé zi lèi" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "MAC address was invalid" msgstr "MAC dì zhǐ wú xiào" @@ -1308,11 +1381,11 @@ msgstr "Màikèfēng qǐdòng yánchí bìxū zài 0.0 Dào 1.0 De fànwéi nèi #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" -msgstr "" +msgstr "shùjù dàxiǎo bù pǐpèi" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched swap flag" -msgstr "" +msgstr "jiāohuàn biāozhì bù pǐpèi" #: ports/mimxrt10xx/common-hal/busio/SPI.c msgid "Missing MISO or MOSI Pin" @@ -1320,7 +1393,7 @@ msgstr "Quēshǎo MISO huò MOSI yǐn jiǎo" #: ports/stm/common-hal/busio/SPI.c msgid "Missing MISO or MOSI pin" -msgstr "" +msgstr "quēshǎo MISO huò MOSI yǐn jiǎo" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format @@ -1379,13 +1452,17 @@ msgstr "NLR tiào zhuǎn shī bài. kě néng shì nèi cún sǔn huài." msgid "NVS Error" msgstr "NVS cuò wù" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "míng chēng huò fú wù wèi zhī" + #: py/qstr.c msgid "Name too long" msgstr "Míngchēng tài zhǎng" #: shared-bindings/displayio/TileGrid.c msgid "New bitmap must be same size as old bitmap" -msgstr "" +msgstr "xīn wèi tú de dàxiǎo bìxū yǔ jiù wèi tú xiāngtóng" #: ports/espressif/common-hal/_bleio/__init__.c msgid "Nimble out of memory" @@ -1419,7 +1496,7 @@ msgstr "dì zhǐ: 0x%x shí méi yǒu I2C qì jiàn" #: supervisor/shared/web_workflow/web_workflow.c msgid "No IP" -msgstr "" +msgstr "wú IP" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c @@ -1428,7 +1505,7 @@ msgstr "Méiyǒu MISO yǐn jiǎo" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MISO pin" -msgstr "" +msgstr "wú MISO pin" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c @@ -1437,7 +1514,7 @@ msgstr "Méiyǒu MOSI yǐn jiǎo" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MOSI pin" -msgstr "" +msgstr "wú MOSI pin" #: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c @@ -1493,11 +1570,6 @@ msgstr "Wèi zhǐdìng mì yào" msgid "No long integer support" msgstr "Méiyǒu zhǎng zhěngshù zhīchí" -#: shared-module/usb_hid/__init__.c -#, c-format -msgid "No more than %d HID devices allowed" -msgstr "bù yǔn xǔ chāo guò %d HID shè bèi" - #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" msgstr "Méiyǒu wǎngluò yǔ gāi ssid" @@ -1523,7 +1595,7 @@ msgstr "Shèbèi shàng méiyǒu kònggé" #: py/moduerrno.c msgid "No such device" -msgstr "" +msgstr "wú cǐ shèbèi" #: py/moduerrno.c msgid "No such file/directory" @@ -1533,10 +1605,6 @@ msgstr "Méiyǒu cǐ lèi wénjiàn/mùlù" msgid "No timer available" msgstr "Méiyǒu jìshí qì" -#: supervisor/shared/safe_mode.c -msgid "Nordic system firmware failure assertion." -msgstr "běi ōu xì tǒng gù jiàn gù zhàng duàn yán." - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "běi ōu xì tǒng gù jiàn chū nèi cún" @@ -1556,10 +1624,6 @@ msgstr "Wèi liánjiē" msgid "Not playing" msgstr "Wèi bòfàng" -#: shared-bindings/_bleio/__init__.c -msgid "Not settable" -msgstr "bù kě shè zhì" - #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #, c-format msgid "Number of data_pins must be 8 or 16, not %d" @@ -1575,16 +1639,26 @@ msgstr "" msgid "Odd parity is not supported" msgstr "Bù zhīchí jīshù" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "guānbì" + +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "hái hǎo" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " msgstr "Zhǐyǒu 8 huò 16 wèi dānwèi " #: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" msgstr "Jǐn zhīchí IPv4 dìzhǐ" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" msgstr "jǐn zhī chí IPv4 tào jiē zì" @@ -1618,10 +1692,15 @@ msgstr "" "Gěi chū %d bpp" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one TouchAlarm can be set in deep sleep." -msgstr "zhǐ yǒu yí gè chù mō bì kě yǐ shè zhì zài shēn dù shuì mián." +msgid "Only one %q can be set in deep sleep." +msgstr "zài shēn dù shuì mián zhōng zhǐ néng shè zhì yí gè %q." -#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "zhǐ néng shè zhì yí gè %q." + +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" msgstr "zhǐ yǔn xǔ yí gè dì zhǐ" @@ -1629,7 +1708,7 @@ msgstr "zhǐ yǔn xǔ yí gè dì zhǐ" #: ports/nrf/common-hal/alarm/time/TimeAlarm.c #: ports/stm/common-hal/alarm/time/TimeAlarm.c msgid "Only one alarm.time alarm can be set" -msgstr "" +msgstr "zhǐ néng shèzhì yīgè nào líng shíjiān nào líng" #: ports/espressif/common-hal/alarm/time/TimeAlarm.c #: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c @@ -1642,21 +1721,26 @@ msgstr "Yīcì zhǐ néng yǒuyī zhǒng yánsè shì tòumíng de" #: py/moduerrno.c msgid "Operation not permitted" -msgstr "" +msgstr "bù yǔnxǔ cāozuò" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation or feature not supported" msgstr "bù zhī chí cāo zuò huò gōng néng" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Operation timed out" msgstr "cāo zuò yǐ fēn shí" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "chāo chū MDNS fú wù chā cáo" + +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Out of memory" msgstr "nèi cún bù zú" -#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "tào jiē zì wài" @@ -1679,7 +1763,7 @@ msgstr "Dāng biànliàng_pínlǜ shì False zài jiànzhú shí PWM pínlǜ bù #: ports/stm/common-hal/pwmio/PWMOut.c msgid "PWM restart" -msgstr "" +msgstr "PWM chóngqǐ" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "PWM slice already in use" @@ -1711,7 +1795,6 @@ msgid "Pin interrupt already in use" msgstr "yǐn jiǎo zhōng duàn yǐ zài shǐ yòng zhōng" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -#: shared-bindings/digitalio/DigitalInOut.c msgid "Pin is input only" msgstr "Yǐn jiǎo jǐn shūrù" @@ -1780,6 +1863,10 @@ msgstr "chéng xù zài bù jiā zǎi Osr de qíng kuàng xià zhí xíng OUT" msgid "Program size invalid" msgstr "chéng xù dà xiǎo wú xiào" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "chéng xù tài cháng" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Fāngxiàng shūchū shí Pull méiyǒu shǐyòng." @@ -1804,7 +1891,7 @@ msgstr "RNG chūshǐhuà cuòwù" #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nrf/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" -msgstr "" +msgstr "RS485" #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1819,8 +1906,9 @@ msgstr "Cǐ bǎn bù zhīchí RTC" msgid "Random number generation error" msgstr "Suíjī shù shēngchéng cuòwù" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" msgstr "Zhǐ dú" @@ -1828,14 +1916,14 @@ msgstr "Zhǐ dú" msgid "Read-only filesystem" msgstr "Zhǐ dú wénjiàn xìtǒng" -#: shared-module/displayio/Bitmap.c -msgid "Read-only object" -msgstr "Zhǐ dú duìxiàng" - -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Received response was invalid" msgstr "shōu dào de xiǎng yìng wú xiào" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "chóngxīn liánjiē" + #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" msgstr "Shuāxīn tài kuàile" @@ -1848,7 +1936,7 @@ msgstr "RemoteTransmissionRequests xiànzhì wèi 8 gè zì jié" msgid "Requested AES mode is unsupported" msgstr "Qǐngqiú de AES móshì bù shòu zhīchí" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Requested resource not found" msgstr "wèi zhǎo dào qǐng qiú de zī yuán" @@ -1866,7 +1954,7 @@ msgstr "Bù zhīchí SD kǎ CSD géshì" #: ports/cxd56/common-hal/sdioio/SDCard.c msgid "SDCard init" -msgstr "" +msgstr "SDCard chūshǐhuà" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format @@ -1884,7 +1972,7 @@ msgstr "SPI pèi zhì shī bài" #: ports/stm/common-hal/busio/SPI.c msgid "SPI init error" -msgstr "" +msgstr "SPI chūshǐhuà cuòwù" #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" @@ -1892,7 +1980,7 @@ msgstr "SPI wài shè zhèng zài shǐ yòng zhōng" #: ports/stm/common-hal/busio/SPI.c msgid "SPI re-init" -msgstr "" +msgstr "SPI chóngxīn qǐdòng" #: shared-bindings/is31fl3741/FrameBuffer.c msgid "Scale dimensions must divide by 3" @@ -1920,7 +2008,8 @@ msgstr "bù zhī chí dà xiǎo" msgid "Sleep Memory not available" msgstr "shuì mián jì yì bù kě yòng" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "Qiēpiàn hé zhí bùtóng chángdù." @@ -1932,6 +2021,7 @@ msgid "Slices not supported" msgstr "Qiēpiàn bù shòu zhīchí" #: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool zhǐ néng yǔ wifi.Radio yīqǐ shǐyòng" @@ -1955,13 +2045,9 @@ msgstr "lì tǐ shēng zuǒ bì xū shì zài PWM tōng dào A" msgid "Stereo right must be on PWM channel B" msgstr "lì tǐ shēng yòu cè bì xū zài PWM tōng dào B shàng" -#: shared-bindings/multiterminal/__init__.c -msgid "Stream missing readinto() or write() method." -msgstr "Liú quēshǎo readinto() huò write() fāngfǎ." - -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "Supply at least one UART pin" -msgstr "Dìngyì zhìshǎo yīgè UART yǐn jiǎo" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Stopping AP is not supported." +msgstr "bù zhī chí tíng zhǐ AP." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -1976,34 +2062,20 @@ msgid "Temperature read timed out" msgstr "Wēndù dòu qǔ chāoshí" #: supervisor/shared/safe_mode.c -msgid "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" -msgstr "" -"diàn lù dàn duī bèi sǔn huài, yīn wéi duī zhàn tài xiǎo.\n" -"rú guǒ nín zhī dào rú hé zēng jiā duī zhàn dà xiǎo. rú guǒ méi yǒu:" +msgid "The `microcontroller` module was used to boot into safe mode." +msgstr "`microcontroller` mó kuài yòng yú qǐ dòng dào ān quán mó shì." -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." -msgstr "" -"`wēi kòng zhì qì` mó kuài yòng yú qǐ dòng dào ān quán mó shì. àn chóng zhì " -"tuì chū ān quán mó shì." +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" +msgstr "shàng shù yì cháng shì yǐ xià yì cháng de zhí jiē yuán yīn:" #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "Rgb_pins de chángdù bìxū wèi 6,12,18,24 huò 30" #: supervisor/shared/safe_mode.c -msgid "" -"The microcontroller's power dipped. Make sure your power supply provides\n" -"enough power for the whole circuit and press reset (after ejecting " -"CIRCUITPY)." -msgstr "" -"wēi kòng zhì qì de gōng lǜ xià jiàng. què bǎo diàn yuán tí gòng\n" -"zú gòu de gōng lǜ yòng yú zhěng gè diàn lù hé àn chóng zhì (tán chū " -"CIRCUITPY hòu)." +msgid "The power dipped. Make sure you are providing enough power." +msgstr "lì liàng xià jiàng le. què bǎo nín tí gòng zú gòu de diàn lì." #: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" @@ -2021,6 +2093,10 @@ msgstr "Yàngběn de yàngběn sùdù yǔ hǔn yīn qì de xiāngchà bù pǐpè msgid "The sample's signedness does not match the mixer's" msgstr "Yàngběn de qiānmíng yǔ hǔn yīn qì de qiānmíng bù pǐpèi" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "dì sān fāng gù jiàn zhì mìng cuò wù." + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." msgstr "cǐ wēi kòng zhì qì bù zhī chí lián xù bǔ huò." @@ -2055,13 +2131,9 @@ msgstr "shí jiān yǐ jīng guò qù." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Chāoshí shíjiān tài zhǎng: Zuìdà chāoshí shíjiān wèi%d miǎo" -#: supervisor/shared/safe_mode.c -msgid "To exit, please reset the board without " -msgstr "Yào tuìchū, qǐng chóng zhì bǎnkuài ér bùyòng " - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" -msgstr "" +msgstr "yàngběn zhōng de tōngdào tài duō" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." @@ -2096,20 +2168,28 @@ msgstr "Xūyào Tuple huò struct_time cānshù" #: ports/stm/common-hal/busio/UART.c msgid "UART de-init" -msgstr "" +msgstr "UART qù chūshǐhuà" #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "UART init" -msgstr "" +msgstr "UART chūshǐhuà" + +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "UART wài shè shǐ yòng zhōng" #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" -msgstr "" +msgstr "UART chóngxīn qǐdòng" #: ports/stm/common-hal/busio/UART.c msgid "UART write" -msgstr "" +msgstr "UART xiě rù" + +#: main.c +msgid "UID:" +msgstr "UID:" #: shared-module/usb_hid/Device.c msgid "USB busy" @@ -2146,6 +2226,15 @@ msgstr "UUID zhí bùshì str,int huò zì jié huǎnchōng qū" msgid "Unable to allocate buffers for signed conversion" msgstr "Wúfǎ fēnpèi huǎnchōng qū yòng yú qiānmíng zhuǎnhuàn" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate the heap." +msgstr "wú fǎ fēn pèi duī." + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "wú fǎ pèi zhì ADC DMA kòng zhì qì, cuò wù dài mǎ:%d" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "Wúfǎ chuàngjiàn suǒ" @@ -2164,14 +2253,29 @@ msgstr "Wúfǎ zhǎodào miǎnfèi de GCLK" msgid "Unable to init parser" msgstr "Wúfǎ chūshǐhuà jiěxī qì" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to initialize ADC DMA controller, ErrorCode:%d" +msgstr "wú fǎ chū shǐ huà ADC DMA kòng zhì qì, cuò wù dài mǎ:%d" + #: shared-module/displayio/OnDiskBitmap.c msgid "Unable to read color palette data" msgstr "Wúfǎ dúqǔ tiáosèbǎn shùjù" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to start ADC DMA controller, ErrorCode:%d" +msgstr "wú fǎ qǐ dòng ADC DMA kòng zhì qì, cuò wù dài mǎ:%d" + #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" msgstr "wú fǎ qǐ dòng mDNS chá xún" +#: shared-bindings/memorymap/AddressRange.c +msgid "Unable to write to address." +msgstr "Wú fǎ xiě rù dì zhǐ." + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "Wúfǎ xiě rù nvm." @@ -2234,7 +2338,13 @@ msgstr "wèi zhī xì tǒng gù jiàn cuò wù: %04x" msgid "Unknown system firmware error: %d" msgstr "wèi zhī de xì tǒng gù jiàn cuò wù: %d" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unkown error code %d" +msgstr "wèi zhī cuò wù dài %d" + #: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "RHS (yùqí %d, huòdé %d) shàng wèi pǐpèi de xiàngmù." @@ -2261,7 +2371,7 @@ msgstr "Bù zhīchí de géshì" #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" -msgstr "" +msgstr "bù zhīchí de hā xī suànfǎ" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Update Failed" @@ -2281,7 +2391,7 @@ msgstr "Zhí chángdù != Suǒ xū de gùdìng chángdù" msgid "Value length > max_length" msgstr "Zhí chángdù > zuìdà chángdù" -#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c msgid "Version was invalid" msgstr "bǎn běn wú xiào" @@ -2308,10 +2418,6 @@ msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" msgstr "" "Yīdàn shèzhì wèi WatchDogMode.RESET, zé bùnéng gēnggǎi WatchDogTimer.Mode" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.timeout must be greater than 0" -msgstr "WatchDogTimer.Timeout bìxū dàyú 0" - #: py/builtinhelp.c #, c-format msgid "" @@ -2329,7 +2435,19 @@ msgstr "" #: supervisor/shared/web_workflow/web_workflow.c msgid "Wi-Fi: " -msgstr "" +msgstr "Wi-Fi: " + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in access point mode." +msgstr "Wú xiàn wǎng luò chǔ yú jiē rù diǎn mó shì." + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is in station mode." +msgstr "Wú xiàn wǎng luò chǔ yú gōng zuò zhàn mó shì." + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "Wifi is not enabled" +msgstr "wú xiàn wǎng luò wèi qǐ yòng" #: main.c msgid "Woken up by alarm.\n" @@ -2340,20 +2458,57 @@ msgstr "bèi jǐng bào chǎo xǐng.\n" msgid "Writes not supported on Characteristic" msgstr "Tèzhēng bù zhīchí xiě rù" -#: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" -msgstr "nín chǔ yú ān quán mó shì, yīn wéi:\n" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "nín zài qǐ dòng shí àn xià le liǎng gè àn niǔ." + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +msgid "You pressed button A at start up." +msgstr "nín zài qǐ dòng shí àn xià le àn niǔ A." #: supervisor/shared/safe_mode.c -msgid "" -"You pressed the reset button during boot. Press again to exit safe mode." -msgstr "" -"zài qǐ dòng guò chéng zhōng, nín àn xià le chóng zhì àn niǔ. zài cì àn xià " -"yǐ tuì chū ān quán mó shì." +msgid "You pressed the BOOT button at start up" +msgstr "nín zài qǐ dòng shí àn xià le qǐ dòng àn niǔ" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "nín zài qǐ dòng shí àn xià le GPIO0 àn niǔ." + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "nín zài qǐ dòng shí àn xià le lù zhì àn niǔ." + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "nín zài qǐ dòng shí àn xià le SW38 àn niǔ." + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "nín zài qǐ dòng shí àn xià le yīn liàng àn niǔ." + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "nín zài qǐ dòng shí àn xià le zhōng yāng àn niǔ." + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "nín zài qǐ dòng shí àn xià le zuǒ àn niǔ." #: supervisor/shared/safe_mode.c -msgid "You requested starting safe mode by " -msgstr "Nín qǐngqiú qǐdòng ānquán móshì " +msgid "You pressed the reset button during boot." +msgstr "nín zài qǐ dòng guò chéng zhōng àn xià le chóng zhì àn niǔ." + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "[yīn cháng dù ér jié duàn]" #: py/objtype.c msgid "__init__() should return None" @@ -2371,11 +2526,7 @@ msgstr "__new__ cānshù bìxū shì yònghù lèixíng" msgid "a bytes-like object is required" msgstr "xūyào yīgè zì jié lèi duìxiàng" -#: shared-bindings/i2cperipheral/I2CPeripheral.c -msgid "address out of bounds" -msgstr "dìzhǐ chāochū biānjiè" - -#: shared-bindings/i2cperipheral/I2CPeripheral.c +#: shared-bindings/i2ctarget/I2CTarget.c msgid "addresses is empty" msgstr "dìzhǐ wèi kōng" @@ -2426,10 +2577,14 @@ msgstr "shù zǔ hé suǒ yǐn cháng dù bì xū xiāng děng" #: extmod/ulab/code/numpy/io/io.c msgid "array has too many dimensions" -msgstr "" +msgstr "shùzǔ yǒu tài duō wéidù" + +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "zhèn liè tài dà" #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "yòu cè xūyào shùzǔ/zì jié" @@ -2522,10 +2677,6 @@ msgstr "huǎnchōng qū tài xiǎo" msgid "buffer too small for requested bytes" msgstr "huǎn chōng qū tài xiǎo, duì yú qǐng qiú de zì jié" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -msgid "byteorder is not a string" -msgstr "byteorder bùshì zìfú chuàn" - #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "zì jié chángdù, bùshì xiàngmù dàxiǎo de bèishù" @@ -2545,7 +2696,7 @@ msgstr "jiàozhǔn zhǐ dú dào" #: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c #: shared-module/vectorio/Rectangle.c msgid "can only have one parent" -msgstr "" +msgstr "zhǐ néng yǒu yīgè fù xiàng" #: py/emitinlinethumb.c msgid "can only have up to 4 parameters to Thumb assembly" @@ -2567,15 +2718,10 @@ msgstr "bùnéng fēnpèi dào biǎodá shì" msgid "can't cancel self" msgstr "bù néng qǔ xiāo zì wǒ" -#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "Wúfǎ jiāng %q zhuǎnhuàn wèi %q" -#: py/runtime.c -msgid "can't convert %q to int" -msgstr "wú fǎ jiāng %q zhuǎn huàn wéi nèi zài" - #: py/obj.c #, c-format msgid "can't convert %s to complex" @@ -2653,10 +2799,14 @@ msgstr "wúfǎ xiàng gānggāng qǐdòng de shēngchéng qì fāsòng fēi zhí msgid "can't set 512 block size" msgstr "wúfǎ shèzhì 512 kuài dàxiǎo" -#: py/objnamedtuple.c +#: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" msgstr "wúfǎ shèzhì shǔxìng" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "wú fǎ shè zhì shǔ xìng '%q'" + #: py/emitnative.c msgid "can't store '%q'" msgstr "wúfǎ cúnchú '%q'" @@ -2718,7 +2868,7 @@ msgstr "tóuyǐng" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "channel re-init" -msgstr "" +msgstr "tōngdào chóngxīn chūshǐhuà" #: shared-bindings/_stage/Text.c msgid "chars buffer too small" @@ -2759,18 +2909,10 @@ msgstr "" msgid "color must be between 0x000000 and 0xffffff" msgstr "yánsè bìxū jiè yú 0x000000 hé 0xffffff zhī jiān" -#: shared-bindings/displayio/ColorConverter.c -msgid "color should be an int" -msgstr "yánsè yīng wèi zhěngshù" - #: py/emitnative.c msgid "comparison of int and uint" msgstr "yīn tè hé wū yīn tè de bǐ jiào" -#: py/objcomplex.c -msgid "complex division by zero" -msgstr "fùzá de fēngé wèi 0" - #: py/objfloat.c py/parsenum.c msgid "complex values not supported" msgstr "bù zhīchí fùzá de zhí" @@ -2801,7 +2943,7 @@ msgstr "juàn jī cān shǔ bùnéng wéi kōng" #: extmod/ulab/code/numpy/io/io.c msgid "corrupted file" -msgstr "" +msgstr "wénjiàn sǔnhuài" #: extmod/ulab/code/numpy/poly.c msgid "could not invert Vandermonde matrix" @@ -2855,10 +2997,6 @@ msgstr "" msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "mùbiāo huǎnchōng qū bìxū shì wèi shēndù'H' lèixíng de shùzǔ = 16" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination_length must be an int >= 0" -msgstr "mùbiāo chángdù bìxū shì > = 0 de zhěngshù" - #: py/objdict.c msgid "dict update sequence has wrong length" msgstr "yǔfǎ gēngxīn xùliè de chángdù cuòwù" @@ -2879,12 +3017,11 @@ msgstr "chǐ cùn bù pǐ pèi" msgid "div/mod not implemented for uint" msgstr "div/ mó zǔ wèi wéi wèi shí xiàn" -#: py/objfloat.c py/objint_mpz.c +#: extmod/ulab/code/numpy/create.c msgid "divide by zero" msgstr "chú yǐ líng" -#: py/modmath.c py/objint_longlong.c py/runtime.c -#: shared-bindings/math/__init__.c +#: py/runtime.c msgid "division by zero" msgstr "bèi líng chú" @@ -2898,7 +3035,7 @@ msgstr "kòngxián" #: extmod/ulab/code/numpy/io/io.c msgid "empty file" -msgstr "" +msgstr "kōng de wénjiàn" #: extmod/moduasyncio.c extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" @@ -2916,10 +3053,6 @@ msgstr "kōng xùliè" msgid "end of format while looking for conversion specifier" msgstr "xúnzhǎo zhuǎnhuàn biāozhù géshì de jiéshù" -#: shared-bindings/displayio/Shape.c -msgid "end_x should be an int" -msgstr "jiéwěi_x yīnggāi shì yīgè zhěngshù" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" msgstr "epoch_time bǎn bù zhī chí cǐ bǎn běn" @@ -2929,18 +3062,18 @@ msgstr "epoch_time bǎn bù zhī chí cǐ bǎn běn" msgid "error = 0x%08lX" msgstr "cuòwù = 0x%08lX" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." +msgstr "" +"espcamera.Camera xū yào pèi zhì bǎo liú de PSRAM. yǒu guān shuō míng, qǐng " +"cān yuè wén dàng." + #: py/runtime.c msgid "exceptions must derive from BaseException" msgstr "lìwài bìxū láizì BaseException" -#: shared-bindings/canio/CAN.c -msgid "expected '%q' but got '%q'" -msgstr "yùqí wèi'%q'dàn dédàole'%q'" - -#: shared-bindings/canio/CAN.c -msgid "expected '%q' or '%q' but got '%q'" -msgstr "yùqí wèi'%q'huò'%q', dàn huòdéle'%q'" - #: py/objstr.c msgid "expected ':' after format specifier" msgstr "zài géshì shuōmíng fú zhīhòu yùqí ':'" @@ -3039,10 +3172,6 @@ msgstr "zìtǐ bìxū wèi 2048 zì jié" msgid "format requires a dict" msgstr "géshì yāoqiú yīgè yǔjù" -#: shared-bindings/microcontroller/Processor.c -msgid "frequency is read-only for this board" -msgstr "cǐ zhǔ bǎn de pín lǜ wéi zhǐ dú" - #: py/objdeque.c msgid "full" msgstr "chōngfèn" @@ -3155,23 +3284,23 @@ msgstr "bù zhèngquè de tiánchōng" msgid "index is out of bounds" msgstr "suǒyǐn chāochū fànwéi" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "suǒ yǐn bì xū shì yuán zǔ huò zhěng shù" + #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c py/obj.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" msgstr "suǒyǐn chāochū fànwéi" -#: py/obj.c -msgid "indices must be integers" -msgstr "suǒyǐn bìxū shì zhěngshù" - #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "suǒyǐn bìxū shì zhěngshù, qiēpiàn huò bù'ěr zhí lièbiǎo" #: ports/espressif/common-hal/busio/I2C.c msgid "init I2C" -msgstr "" +msgstr "chūshǐhuà I2C" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" @@ -3220,7 +3349,7 @@ msgstr "shūrù jǔzhèn shì qíyì de" #: extmod/ulab/code/numpy/create.c msgid "input must be 1- or 2-d" -msgstr "" +msgstr "shūrù bìxū shì 1- huò 2-d" #: extmod/ulab/code/numpy/carray/carray.c msgid "input must be a 1D ndarray" @@ -3258,10 +3387,6 @@ msgstr "shūrù xiàngliàng de chángdù bìxū xiāngděng" msgid "inputs are not iterable" msgstr "shū rù bù kě yí dòng" -#: py/parsenum.c -msgid "int() arg 2 must be >= 2 and <= 36" -msgstr "zhěngshù() cānshù 2 bìxū > = 2 qiě <= 36" - #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" msgstr "zhōng jiān wéi cháng dù xiāng děng de 1D kě yì jiāo qì dìng yì" @@ -3280,6 +3405,10 @@ msgstr "wú xiào de jià gòu" msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "wú xiào bits_per_pixel %d, bì xū shì, 1, 2, 4, 8, 16, 24, huò 32" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "zhèngshū wúxiào" + #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" @@ -3306,10 +3435,18 @@ msgstr "wúxiào de géshì biāozhù" msgid "invalid hostname" msgstr "wú xiào zhǔ jī míng" +#: ports/raspberrypi/common-hal/ssl/SSLSocket.c +msgid "invalid key" +msgstr "wúxiào de mì yào" + #: py/compile.c msgid "invalid micropython decorator" msgstr "wúxiào de MicroPython zhuāngshì qì" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "shèzhì wúxiào" + #: shared-bindings/random/__init__.c msgid "invalid step" msgstr "wúxiào bùzhòu" @@ -3331,10 +3468,6 @@ msgstr "jīshù wèi %d de zhěng shǔ de yǔfǎ wúxiào" msgid "invalid syntax for number" msgstr "wúxiào de hàomǎ yǔfǎ" -#: py/objexcept.c -msgid "invalid traceback" -msgstr "wú xiào zhuī sù" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() cānshù 1 bìxū shì yīgè lèi" @@ -3392,19 +3525,17 @@ msgstr "běndì '%q' zài zhī lèixíng zhīqián shǐyòng" msgid "local variable referenced before assignment" msgstr "fùzhí qián yǐnyòng de júbù biànliàng" -#: py/objint.c -msgid "long int not supported in this build" -msgstr "cǐ bǎnběn bù zhīchí zhǎng zhěngshù" - #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" msgstr "Wài shè bù zhī chí huán huí + jìng yīn mó shì" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" msgstr "mDNS yǐ chū shǐ huà" #: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" msgstr "mDNS jǐn shì yòng yú nèi zhì wú xiàn wǎng luò" @@ -3429,11 +3560,11 @@ msgstr "jǔzhèn bùshì zhèngdìng de" #: ports/nrf/common-hal/_bleio/Descriptor.c #, c-format msgid "max_length must be 0-%d when fixed_length is %s" -msgstr "dāng fixed_length de zhí wéi %s shí, max_length bì xū wéi 0-%d" +msgstr "max_length bìxū shì 0-%d, dāng fixed_length shì %s" #: extmod/ulab/code/ndarray.c msgid "maximum number of dimensions is " -msgstr "" +msgstr "zuìdà wéi shù shì " #: py/runtime.c msgid "maximum recursion depth exceeded" @@ -3533,6 +3664,10 @@ msgstr "méiyǒu fú diǎn zhīchí de xiāojí gōnglǜ" msgid "negative shift count" msgstr "fù zhuǎnyí jìshù" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "qiàn tào suǒ yǐn bì xū shì int" + #: shared-module/sdcardio/SDCard.c msgid "no SD card" msgstr "méiyǒu SD kǎ" @@ -3566,14 +3701,10 @@ msgstr "Méiyǒu kěyòng de fùwèi yǐn jiǎo" msgid "no response from SD card" msgstr "SD kǎ wú huíyīng" -#: py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "méiyǒu cǐ shǔxìng" -#: shared-bindings/usb_hid/__init__.c -msgid "non-Device in %q" -msgstr "fēi shè bèi zài %q" - #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" @@ -3679,7 +3810,7 @@ msgstr "jīshù zìfú chuàn" #: supervisor/shared/web_workflow/web_workflow.c msgid "off" -msgstr "" +msgstr "guānbì" #: extmod/ulab/code/utils/utils.c msgid "offset is too large" @@ -3698,15 +3829,30 @@ msgid "offset out of bounds" msgstr "piānlí biānjiè" #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" msgstr "Jǐn zhīchí wèi shēndù = 16" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "jǐn zhī chí dān shēng dào" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "zhǐ néng lián jiē ndarray (shù zì)" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "jǐn zhī chí guò cǎi yàng =64" + #: ports/nrf/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "Jǐn zhīchí cǎiyàng lǜ = 16000" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "jǐn zhīchí bù zhǎng = 1(jí wú) de qiēpiàn" @@ -3777,10 +3923,6 @@ msgstr "bāo zhuāng yù qī de %d bāo zhuāng xiàng mù (dé dào %d)" msgid "palette must be 32 bytes long" msgstr "yánsè bìxū shì 32 gè zì jié" -#: shared-bindings/displayio/Palette.c -msgid "palette_index should be an int" -msgstr "yánsè suǒyǐn yīnggāi shì yīgè zhěngshù" - #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" msgstr "cānshù bìxū shì xùliè a2 zhì a5 de dēngjì shù" @@ -3830,28 +3972,6 @@ msgstr "pow() 3 cān shǔ bùnéng wéi 0" msgid "pow() with 3 arguments requires integers" msgstr "pow() yǒu 3 cānshù xūyào zhěngshù" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "pressing SW38 button at start up.\n" -msgstr "" - -#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h -#: ports/espressif/boards/lolin_c3_mini/mpconfigboard.h -#: supervisor/shared/safe_mode.c -msgid "pressing boot button at start up.\n" -msgstr "Zài qǐdòng shí àn qǐdòng ànniǔ.\n" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "pressing both buttons at start up.\n" -msgstr "zài qǐdòng shí tóngshí àn xià liǎng gè ànniǔ.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "pressing the left button at start up\n" -msgstr "qǐ dòng shí àn xià zuǒ àn niǔ\n" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "lā kǒu zhào yǔ fāng xiàng miàn mó chōng tū" @@ -3872,11 +3992,6 @@ msgstr "shí bù hé xū bù bìxū děng zhǎng" msgid "relative import" msgstr "xiāngduì dǎorù" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "qǐngqiú chángdù %d dàn duìxiàng chángdù %d" - #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "wú fǎ jiāng jié guǒ qiáng zhì zhuǎn huàn dào zhǐ dìng lèi xíng" @@ -3907,14 +4022,6 @@ msgstr "gǔn dòng cān shù bì xū shì ndarray" msgid "rsplit(None,n)" msgstr "Rchāifēn(wú,N)" -#: shared-bindings/audiocore/RawSample.c -msgid "" -"sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " -"'B'" -msgstr "" -"yàngběn yuán_yuán huǎnchōng qū bìxū shì zì yǎnlèi huò lèixíng 'h', 'H', 'b' " -"huò 'B' de shùzǔ" - #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3948,10 +4055,6 @@ msgstr "zìfú chuàn géshì shuōmíng fú zhōng bù yǔnxǔ shǐyòng fúhà msgid "sign not allowed with integer format specifier 'c'" msgstr "zhěngshù géshì shuōmíng fú 'c' bù yǔnxǔ shǐyòng fúhào" -#: py/objstr.c -msgid "single '}' encountered in format string" -msgstr "zài géshì zìfú chuàn zhōng yù dào de dāngè '}'" - #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" msgstr "dàxiǎo jǐn wèi ndarrays dìngyì" @@ -3964,10 +4067,6 @@ msgstr "shuìmián chángdù bìxū shìfēi fùshù" msgid "slice step can't be zero" msgstr "qiēpiàn bù cháng bùnéng wéi líng" -#: py/objslice.c -msgid "slice step cannot be zero" -msgstr "qiēpiàn bù bùnéng wéi líng" - #: py/nativeglue.c msgid "slice unsupported" msgstr "qiē piàn bù shòu zhī chí" @@ -4019,14 +4118,6 @@ msgstr "yuán wèi tú (source_bitmap) de zhí de shù mù (value_count) bì xū msgid "start/end indices" msgstr "kāishǐ/jiéshù zhǐshù" -#: shared-bindings/displayio/Shape.c -msgid "start_x should be an int" -msgstr "kāishǐ_x yīnggāi shì yīgè zhěngshù" - -#: shared-bindings/random/__init__.c -msgid "step must be non-zero" -msgstr "bùzhòu bìxū shìfēi líng" - #: shared-bindings/random/__init__.c msgid "stop not reachable from start" msgstr "tíngzhǐ wúfǎ cóng kāishǐ zhōng zhǎodào" @@ -4035,10 +4126,6 @@ msgstr "tíngzhǐ wúfǎ cóng kāishǐ zhōng zhǎodào" msgid "stream operation not supported" msgstr "bù zhīchí liú cāozuò" -#: py/objstrunicode.c -msgid "string indices must be integers, not %q" -msgstr "zìfú chuàn suǒyǐn bìxū shì zhěngshù, ér bùshì %q" - #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "zìfú chuàn bù zhīchí; shǐyòng zì jié huò zì jié zǔ" @@ -4071,14 +4158,6 @@ msgstr "JSON yǔfǎ cuòwù" msgid "syntax error in uctypes descriptor" msgstr "uctypes miáoshù fú zhōng de yǔfǎ cuòwù" -#: shared-bindings/touchio/TouchIn.c -msgid "threshold must be in the range 0-65536" -msgstr "yùzhí bìxū zài fànwéi 0-65536" - -#: shared-bindings/time/__init__.c -msgid "time.struct_time() takes a 9-sequence" -msgstr "time.struct_time() xūyào 9 xùliè" - #: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -4086,10 +4165,6 @@ msgstr "time.struct_time() xūyào 9 xùliè" msgid "timeout duration exceeded the maximum supported value" msgstr "chāoshí shíjiān chāoguò zuìdà zhīchí zhí" -#: shared-bindings/busio/UART.c -msgid "timeout must be 0.0-100.0 seconds" -msgstr "Chāo shí shíjiān bìxū wèi 0.0 Dào 100.0 Miǎo" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" msgstr "chāo shí bì xū < 655.35 miǎo" @@ -4104,7 +4179,7 @@ msgstr "děngdài v2 kǎ chāoshí" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "timer re-init" -msgstr "" +msgstr "dìngshí qì chóngxīn chūshǐhuà" #: shared-bindings/time/__init__.c msgid "timestamp out of range for platform time_t" @@ -4143,10 +4218,6 @@ msgstr "Trapz shì wèi děng zhǎng de 1D shùzǔ dìngyì de" msgid "trapz is defined for 1D iterables" msgstr "tī xíng dìng yì wéi yì wéi kě dié dài duì xiàng" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "yuán zǔ/lièbiǎo chángdù cuòwù" - #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" @@ -4157,8 +4228,6 @@ msgstr "twai_driver_install fǎn huí esp-idf cuò wù #%d" msgid "twai_start returned esp-idf error #%d" msgstr "twai_start fǎn huí esp -idf cuò wù #%d" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx hé rx bùnéng dōu shì wú" @@ -4171,14 +4240,10 @@ msgstr "lèixíng '%q' bùshì kě jiēshòu de jīchǔ lèixíng" msgid "type is not an acceptable base type" msgstr "lèixíng bùshì kě jiēshòu de jīchǔ lèixíng" -#: py/runtime.c +#: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" msgstr "lèixíng duìxiàng '%q' méiyǒu shǔxìng '%q'" -#: py/objgenerator.c -msgid "type object 'generator' has no attribute '__await__'" -msgstr "lèi xíng duì xiàng 'generator' méi yǒu shǔ xìng '__await__'" - #: py/objtype.c msgid "type takes 1 or 3 arguments" msgstr "lèixíng wèi 1 huò 3 gè cānshù" @@ -4199,7 +4264,7 @@ msgstr "wèi yùliào de suō jìn" msgid "unexpected keyword argument" msgstr "yìwài de guānjiàn cí cānshù" -#: py/bc.c py/objnamedtuple.c +#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "yìwài de guānjiàn cí cānshù '%q'" @@ -4229,15 +4294,15 @@ msgid "unknown type '%q'" msgstr "wèizhī lèixíng '%q'" #: py/objstr.c -msgid "unmatched '{' in format" -msgstr "géshì wèi pǐpèi '{'" +#, c-format +msgid "unmatched '%c' in format" +msgstr "gé shì bù pǐ pèi de '%c'" #: py/objtype.c py/runtime.c msgid "unreadable attribute" msgstr "bùkě dú shǔxìng" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "bù zhīchí %q lèixíng" @@ -4278,11 +4343,11 @@ msgstr "%q bù zhīchí de lèixíng: '%q', '%q'" #: extmod/ulab/code/numpy/io/io.c msgid "usecols is too high" -msgstr "" +msgstr "Usecols tài gāo" #: extmod/ulab/code/numpy/io/io.c msgid "usecols keyword must be specified" -msgstr "" +msgstr "bìxū zhǐdìng usecols guānjiàn zì" #: py/objint.c #, c-format @@ -4301,18 +4366,19 @@ msgstr "zhí jìshù bìxū wèi > 0" msgid "watchdog not initialized" msgstr "wèi chū shǐ huà jiān shì qì" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "watchdog timeout must be greater than 0" -msgstr "kān mén gǒu chāoshí bìxū dàyú 0" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "kuāndù bìxū dàyú líng" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c msgid "wifi is not enabled" msgstr "wèi qǐ yòng WIFI" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "wú xiàn wǎng luò xiǎn shì qì bù kě yòng" + #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" msgstr "Chuāngkǒu bìxū shì <= jiàngé" @@ -4327,7 +4393,7 @@ msgstr "zhǐ dìng de zhóu cuò wù" #: extmod/ulab/code/numpy/io/io.c msgid "wrong dtype" -msgstr "" +msgstr "cuòwù de shùjù lèixíng" #: extmod/ulab/code/numpy/transform.c msgid "wrong index type" @@ -4345,7 +4411,7 @@ msgstr "tiáo jiàn shù zǔ de cháng dù cuò wù" #: extmod/ulab/code/numpy/transform.c msgid "wrong length of index array" -msgstr "" +msgstr "suǒyǐn shùzǔ de chángdù cuòwù" #: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c msgid "wrong number of arguments" @@ -4367,18 +4433,10 @@ msgstr "x zhí chāochū biānjiè" msgid "xTaskCreate failed" msgstr "xTaskCreate shī bài" -#: shared-bindings/displayio/Shape.c -msgid "y should be an int" -msgstr "y yīnggāi shì yīgè zhěngshù" - #: shared-module/displayio/Shape.c msgid "y value out of bounds" msgstr "y zhí chāochū biānjiè" -#: py/objrange.c -msgid "zero step" -msgstr "líng bù" - #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" msgstr "zi bìxū shì ndarray" @@ -4391,6 +4449,312 @@ msgstr "zi bìxū wèi fú diǎn xíng" msgid "zi must be of shape (n_section, 2)" msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" +#~ msgid "Supply at least one UART pin" +#~ msgstr "Dìngyì zhìshǎo yīgè UART yǐn jiǎo" + +#~ msgid "%q pin invalid" +#~ msgstr "%q yǐn jiǎo wúxiào" + +#~ msgid "" +#~ "\n" +#~ "Please file an issue with the contents of your CIRCUITPY drive at \n" +#~ "https://github.com/adafruit/circuitpython/issues\n" +#~ msgstr "" +#~ "\n" +#~ "Qǐng tōngguò https://github.com/adafruit/circuitpython/issues\n" +#~ "tíjiāo yǒuguān nín de CIRCUITPY qūdòngqì nèiróng de wèntí \n" + +#~ msgid "Attempted heap allocation when VM not running." +#~ msgstr "shìtú zài xūnǐjī (VM) yùn xíng shí fēnpèi duī (heap)." + +#~ msgid "Boot device must be first device (interface #0)." +#~ msgstr "yǐndǎo shèbèi bìxū shì dìyī tái shèbèi (interface #0)." + +#~ msgid "Both buttons were pressed at start up.\n" +#~ msgstr "qǐ dòng shí àn xià le liǎng gè àn niǔ.\n" + +#~ msgid "Button A was pressed at start up.\n" +#~ msgstr "qǐ dòng shí àn xià àn niǔ A.\n" + +#~ msgid "CircuitPython was unable to allocate the heap." +#~ msgstr "CircuitPython wúfǎ fēnpèi duī." + +#~ msgid "Crash into the HardFault_Handler." +#~ msgstr "gu4zhang4, jin4ru4 HardFault_Handler." + +#~ msgid "Fatal error." +#~ msgstr "zhì mìng cuò wù." + +#~ msgid "Invalid memory access." +#~ msgstr "Wúxiào de nèicún fǎngwèn." + +#~ msgid "Nordic system firmware failure assertion." +#~ msgstr "běi ōu xì tǒng gù jiàn gù zhàng duàn yán." + +#~ msgid "The BOOT button was pressed at start up.\n" +#~ msgstr "qǐ dòng shí àn xià le yǐn dǎo àn niǔ.\n" + +#~ msgid "" +#~ "The CircuitPython heap was corrupted because the stack was too small.\n" +#~ "Increase the stack size if you know how. If not:" +#~ msgstr "" +#~ "diàn lù dàn duī bèi sǔn huài, yīn wéi duī zhàn tài xiǎo.\n" +#~ "rú guǒ nín zhī dào rú hé zēng jiā duī zhàn dà xiǎo. rú guǒ méi yǒu:" + +#~ msgid "The SW38 button was pressed at start up.\n" +#~ msgstr "qǐ dòng shí àn xià le SW38 àn niǔ .\n" + +#~ msgid "The VOLUME button was pressed at start up.\n" +#~ msgstr "qǐ dòng shí àn xià yīn liàng àn niǔ.\n" + +#~ msgid "" +#~ "The `microcontroller` module was used to boot into safe mode. Press reset " +#~ "to exit safe mode." +#~ msgstr "" +#~ "`wēi kòng zhì qì` mó kuài yòng yú qǐ dòng dào ān quán mó shì. àn chóng " +#~ "zhì tuì chū ān quán mó shì." + +#~ msgid "The central button was pressed at start up.\n" +#~ msgstr "qǐ dòng shí àn xià zhōng yāng àn niǔ.\n" + +#~ msgid "The left button was pressed at start up.\n" +#~ msgstr "qǐ dòng shí àn xià zuǒ àn niǔ.\n" + +#~ msgid "" +#~ "The microcontroller's power dipped. Make sure your power supply provides\n" +#~ "enough power for the whole circuit and press reset (after ejecting " +#~ "CIRCUITPY)." +#~ msgstr "" +#~ "wēi kòng zhì qì de gōng lǜ xià jiàng. què bǎo diàn yuán tí gòng\n" +#~ "zú gòu de gōng lǜ yòng yú zhěng gè diàn lù hé àn chóng zhì (tán chū " +#~ "CIRCUITPY hòu)." + +#~ msgid "To exit, please reset the board without requesting safe mode." +#~ msgstr "" +#~ "yào tuì chū, qǐng zài bù qǐng qiú ān quán mó shì de qíng kuàng xià chóng " +#~ "zhì zhǔ bǎn." + +#~ msgid "You are in safe mode because:\n" +#~ msgstr "nín chǔ yú ān quán mó shì, yīn wéi:\n" + +#~ msgid "" +#~ "You pressed the reset button during boot. Press again to exit safe mode." +#~ msgstr "" +#~ "zài qǐ dòng guò chéng zhōng, nín àn xià le chóng zhì àn niǔ. zài cì àn " +#~ "xià yǐ tuì chū ān quán mó shì." + +#~ msgid "" +#~ "esp32_camera.Camera requires reserved PSRAM to be configured. See the " +#~ "documentation for instructions." +#~ msgstr "" +#~ "esp32_camera. shè xiàng jī xū yào pèi zhì yù liú de PSRAM. yǒu guān shuō " +#~ "míng, qǐng cān yuè wén dàng." + +#~ msgid "%q must be of type %q" +#~ msgstr "%q bì xū shì %q lèi xíng" + +#~ msgid "%q must be of type %q or None" +#~ msgstr "%q lèi xíng bì xū wéi %q huò wú" + +#~ msgid "Expected a %q" +#~ msgstr "Yù qí %q" + +#~ msgid "Expected a %q or %q" +#~ msgstr "yù qī wéi %q huò %q" + +#~ msgid "Expected an %q" +#~ msgstr "yù qī wéi %q" + +#, c-format +#~ msgid "IV must be %d bytes long" +#~ msgstr "IV bì xū wéi %d zì jié cháng" + +#~ msgid "Not settable" +#~ msgstr "bù kě shè zhì" + +#~ msgid "expected '%q' but got '%q'" +#~ msgstr "yùqí wèi'%q'dàn dédàole'%q'" + +#~ msgid "expected '%q' or '%q' but got '%q'" +#~ msgstr "yùqí wèi'%q'huò'%q', dàn huòdéle'%q'" + +#~ msgid "Read-only object" +#~ msgstr "Zhǐ dú duìxiàng" + +#~ msgid "frequency is read-only for this board" +#~ msgstr "cǐ zhǔ bǎn de pín lǜ wéi zhǐ dú" + +#~ msgid "Unable to write" +#~ msgstr "wú fǎ xiě rù" + +#~ msgid "%q length must be >= 1" +#~ msgstr "%q cháng dù bìxū >= 1" + +#~ msgid "%q must be a string" +#~ msgstr "%q bìxū shì yí gè zì fú chuàn" + +#~ msgid "%q must be an int" +#~ msgstr "%q bìxū shì zhěng xíng" + +#~ msgid "%q with a report ID of 0 must be of length 1" +#~ msgstr "bào gào ID shì 0 de %q bì xū cháng dù wéi 1" + +#~ msgid "At most %d %q may be specified (not %d)" +#~ msgstr "zuìduō kěyǐ zhǐdìng %d gè %q (érbúshì %d)" + +#~ msgid "Invalid pins" +#~ msgstr "Wúxiào de yǐn jiǎo" + +#, c-format +#~ msgid "No more than %d HID devices allowed" +#~ msgstr "bù yǔn xǔ chāo guò %d HID shè bèi" + +#~ msgid "byteorder is not a string" +#~ msgstr "byteorder bùshì zìfú chuàn" + +#~ msgid "can't convert %q to int" +#~ msgstr "wú fǎ jiāng %q zhuǎn huàn wéi nèi zài" + +#~ msgid "complex division by zero" +#~ msgstr "fùzá de fēngé wèi 0" + +#~ msgid "int() arg 2 must be >= 2 and <= 36" +#~ msgstr "zhěngshù() cānshù 2 bìxū > = 2 qiě <= 36" + +#~ msgid "long int not supported in this build" +#~ msgstr "cǐ bǎnběn bù zhīchí zhǎng zhěngshù" + +#~ msgid "slice step cannot be zero" +#~ msgstr "qiēpiàn bù bùnéng wéi líng" + +#~ msgid "step must be non-zero" +#~ msgstr "bùzhòu bìxū shìfēi líng" + +#~ msgid "string indices must be integers, not %q" +#~ msgstr "zìfú chuàn suǒyǐn bìxū shì zhěngshù, ér bùshì %q" + +#~ msgid "time.struct_time() takes a 9-sequence" +#~ msgstr "time.struct_time() xūyào 9 xùliè" + +#~ msgid "zero step" +#~ msgstr "líng bù" + +#~ msgid "invalid traceback" +#~ msgstr "wú xiào zhuī sù" + +#~ msgid "%q indices must be integers, not %s" +#~ msgstr "%q suǒyǐn bìxū shì zhěngshù, ér bùshì %s" + +#~ msgid "WatchDogTimer.timeout must be greater than 0" +#~ msgstr "WatchDogTimer.Timeout bìxū dàyú 0" + +#~ msgid "indices must be integers" +#~ msgstr "suǒyǐn bìxū shì zhěngshù" + +#~ msgid "non-Device in %q" +#~ msgstr "fēi shè bèi zài %q" + +#, c-format +#~ msgid "requested length %d but object has length %d" +#~ msgstr "qǐngqiú chángdù %d dàn duìxiàng chángdù %d" + +#~ msgid "single '}' encountered in format string" +#~ msgstr "zài géshì zìfú chuàn zhōng yù dào de dāngè '}'" + +#~ msgid "threshold must be in the range 0-65536" +#~ msgstr "yùzhí bìxū zài fànwéi 0-65536" + +#~ msgid "timeout must be 0.0-100.0 seconds" +#~ msgstr "Chāo shí shíjiān bìxū wèi 0.0 Dào 100.0 Miǎo" + +#~ msgid "tuple/list has wrong length" +#~ msgstr "yuán zǔ/lièbiǎo chángdù cuòwù" + +#~ msgid "unmatched '{' in format" +#~ msgstr "géshì wèi pǐpèi '{'" + +#~ msgid "watchdog timeout must be greater than 0" +#~ msgstr "kān mén gǒu chāoshí bìxū dàyú 0" + +#~ msgid "To exit, please reset the board without " +#~ msgstr "Yào tuìchū, qǐng chóng zhì bǎnkuài ér bùyòng " + +#~ msgid "You requested starting safe mode by " +#~ msgstr "Nín qǐngqiú qǐdòng ānquán móshì " + +#~ msgid "pressing BOOT button at start up.\n" +#~ msgstr "zài qǐdòng shí àn BOOT ànniǔ.\n" + +#~ msgid "pressing SW38 button at start up.\n" +#~ msgstr "zài qǐdòng shí àn SW38 ànniǔ.\n" + +#~ msgid "pressing VOLUME button at start up.\n" +#~ msgstr "zài qǐdòng shí àn SW38 ànniǔ.\n" + +#~ msgid "pressing boot button at start up.\n" +#~ msgstr "Zài qǐdòng shí àn qǐdòng ànniǔ.\n" + +#~ msgid "pressing both buttons at start up.\n" +#~ msgstr "zài qǐdòng shí tóngshí àn xià liǎng gè ànniǔ.\n" + +#~ msgid "pressing the left button at start up\n" +#~ msgstr "qǐ dòng shí àn xià zuǒ àn niǔ\n" + +#~ msgid "Only one TouchAlarm can be set in deep sleep." +#~ msgstr "zhǐ yǒu yí gè chù mō bì kě yǐ shè zhì zài shēn dù shuì mián." + +#~ msgid "Firmware image is invalid" +#~ msgstr "gù jiàn yìng xiàng wú xiào" + +#~ msgid "Stream missing readinto() or write() method." +#~ msgstr "Liú quēshǎo readinto() huò write() fāngfǎ." + +#~ msgid "%q must be >= 0" +#~ msgstr "%q bìxū > = 0" + +#~ msgid "%q must be >= 1" +#~ msgstr "%q bìxū >= 1" + +#~ msgid "address out of bounds" +#~ msgstr "dìzhǐ chāochū biānjiè" + +#~ msgid "destination_length must be an int >= 0" +#~ msgstr "mùbiāo chángdù bìxū shì > = 0 de zhěngshù" + +#~ msgid "type object 'generator' has no attribute '__await__'" +#~ msgstr "lèi xíng duì xiàng 'generator' méi yǒu shǔ xìng '__await__'" + +#~ msgid "color should be an int" +#~ msgstr "yánsè yīng wèi zhěngshù" + +#~ msgid "end_x should be an int" +#~ msgstr "jiéwěi_x yīnggāi shì yīgè zhěngshù" + +#~ msgid "palette_index should be an int" +#~ msgstr "yánsè suǒyǐn yīnggāi shì yīgè zhěngshù" + +#~ msgid "start_x should be an int" +#~ msgstr "kāishǐ_x yīnggāi shì yīgè zhěngshù" + +#~ msgid "y should be an int" +#~ msgstr "y yīnggāi shì yīgè zhěngshù" + +#~ msgid "" +#~ "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' " +#~ "or 'B'" +#~ msgstr "" +#~ "yàngběn yuán_yuán huǎnchōng qū bìxū shì zì yǎnlèi huò lèixíng 'h', 'H', " +#~ "'b' huò 'B' de shùzǔ" + +#~ msgid "Expected an alarm" +#~ msgstr "yù qī yǒu jǐng bào" + +#~ msgid "All I2C targets are in use" +#~ msgstr "suǒyǒu I2C mùbiāo dōu zài shǐyòng zhōng" + +#~ msgid "Failed to init wifi" +#~ msgstr "Wúfǎ chūshǐhuà wifi" + #~ msgid "input must be a tensor of rank 2" #~ msgstr "shū rù bì xū shì děng jí 2 de zhāng liàng" @@ -5061,12 +5425,6 @@ msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" #~ msgid "can only save bytecode" #~ msgstr "zhǐ néng bǎocún zì jié mǎ jìlù" -#~ msgid "invalid cert" -#~ msgstr "zhèngshū wúxiào" - -#~ msgid "invalid key" -#~ msgstr "wúxiào de mì yào" - #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Viper hánshù mùqián bù zhīchí chāoguò 4 gè cānshù" diff --git a/main.c b/main.c index 5fcb2d61a6..002c97c167 100644 --- a/main.c +++ b/main.c @@ -105,6 +105,10 @@ #include "shared-bindings/socketpool/__init__.h" #endif +#if CIRCUITPY_STATUS_BAR +#include "supervisor/shared/status_bar.h" +#endif + #if CIRCUITPY_USB_HID #include "shared-module/usb_hid/__init__.h" #endif @@ -118,8 +122,8 @@ uint8_t value_out = 0; #endif -#if MICROPY_ENABLE_PYSTACK -static size_t PLACE_IN_DTCM_BSS(_pystack[CIRCUITPY_PYSTACK_SIZE / sizeof(size_t)]); +#if MICROPY_ENABLE_PYSTACK && CIRCUITPY_OS_GETENV +#include "shared-module/os/__init__.h" #endif static void reset_devices(void) { @@ -128,7 +132,32 @@ static void reset_devices(void) { #endif } -STATIC void start_mp(supervisor_allocation *heap, bool first_run) { +#if MICROPY_ENABLE_PYSTACK +STATIC supervisor_allocation *allocate_pystack(safe_mode_t safe_mode) { + mp_int_t pystack_size = CIRCUITPY_PYSTACK_SIZE; + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SETTABLE_PYSTACK + // Fetch value if exists from settings.toml + // Leaves size to build default on any failure + if (safe_mode == SAFE_MODE_NONE || safe_mode == SAFE_MODE_USER) { + (void)common_hal_os_getenv_int("CIRCUITPY_PYSTACK_SIZE", &pystack_size); + // Check if value is valid + pystack_size = pystack_size - pystack_size % sizeof(size_t); // Round down to multiple of 4. + if ((pystack_size < 384) || (pystack_size > 900000)) { + serial_write_compressed(translate("\nInvalid CIRCUITPY_PYSTACK_SIZE\n\n\r")); + pystack_size = CIRCUITPY_PYSTACK_SIZE; // Reset + } + } + #endif + supervisor_allocation *pystack = allocate_memory(pystack_size, false, false); + if (pystack == NULL) { + serial_write_compressed(translate("\nInvalid CIRCUITPY_PYSTACK_SIZE\n\n\r")); + pystack = allocate_memory(CIRCUITPY_PYSTACK_SIZE, false, false); + } + return pystack; +} +#endif + +STATIC void start_mp(supervisor_allocation *heap, supervisor_allocation *pystack) { supervisor_workflow_reset(); // Stack limit should be less than real stack size, so we have a chance @@ -156,7 +185,7 @@ STATIC void start_mp(supervisor_allocation *heap, bool first_run) { readline_init0(); #if MICROPY_ENABLE_PYSTACK - mp_pystack_init(_pystack, _pystack + (sizeof(_pystack) / sizeof(size_t))); + mp_pystack_init(pystack->ptr, pystack->ptr + get_allocation_length(pystack) / sizeof(size_t)); #endif #if MICROPY_ENABLE_GC @@ -172,14 +201,6 @@ STATIC void start_mp(supervisor_allocation *heap, bool first_run) { mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_init((mp_obj_list_t *)mp_sys_argv, 0); - - #if CIRCUITPY_ALARM - // Record which alarm woke us up, if any. An object may be created so the heap must be functional. - // There is no alarm if this is not the first time code.py or the REPL has been run. - shared_alarm_save_wake_alarm(first_run ? common_hal_alarm_create_wake_alarm() : mp_const_none); - // Reset alarm module only after we retrieved the wakeup alarm. - alarm_reset(); - #endif } STATIC void stop_mp(void) { @@ -203,12 +224,29 @@ STATIC void stop_mp(void) { gc_deinit(); } -#define STRING_LIST(...) {__VA_ARGS__, ""} +STATIC const char *_current_executing_filename = NULL; + +STATIC pyexec_result_t _exec_result = {0, MP_OBJ_NULL, 0}; + +#if CIRCUITPY_STATUS_BAR +void supervisor_execution_status(void) { + mp_obj_exception_t *exception = MP_OBJ_TO_PTR(_exec_result.exception); + if (_current_executing_filename != NULL) { + serial_write(_current_executing_filename); + } else if ((_exec_result.return_code & PYEXEC_EXCEPTION) != 0 && + _exec_result.exception_line > 0 && + exception != NULL) { + mp_printf(&mp_plat_print, "%d@%s %q", _exec_result.exception_line, _exec_result.exception_filename, exception->base.type->name); + } else { + serial_write_compressed(translate("Done")); + } +} +#endif // Look for the first file that exists in the list of filenames, using mp_import_stat(). // Return its index. If no file found, return -1. -STATIC const char *first_existing_file_in_list(const char *const *filenames) { - for (int i = 0; filenames[i] != (char *)""; i++) { +STATIC const char *first_existing_file_in_list(const char *const *filenames, size_t n_filenames) { + for (size_t i = 0; i < n_filenames; i++) { mp_import_stat_t stat = mp_import_stat(filenames[i]); if (stat == MP_IMPORT_STAT_FILE) { return filenames[i]; @@ -217,17 +255,33 @@ STATIC const char *first_existing_file_in_list(const char *const *filenames) { return NULL; } -STATIC bool maybe_run_list(const char *const *filenames, pyexec_result_t *exec_result) { - const char *filename = first_existing_file_in_list(filenames); - if (filename == NULL) { +STATIC bool maybe_run_list(const char *const *filenames, size_t n_filenames) { + _exec_result.return_code = 0; + _exec_result.exception = MP_OBJ_NULL; + _exec_result.exception_line = 0; + _current_executing_filename = first_existing_file_in_list(filenames, n_filenames); + if (_current_executing_filename == NULL) { return false; } - mp_hal_stdout_tx_str(filename); + mp_hal_stdout_tx_str(_current_executing_filename); serial_write_compressed(translate(" output:\n")); - pyexec_file(filename, exec_result); - #if CIRCUITPY_ATEXIT - shared_module_atexit_execute(exec_result); + + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_update(); #endif + + pyexec_file(_current_executing_filename, &_exec_result); + + #if CIRCUITPY_ATEXIT + shared_module_atexit_execute(&_exec_result); + #endif + + _current_executing_filename = NULL; + + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_update(); + #endif + return true; } @@ -235,7 +289,7 @@ STATIC void count_strn(void *data, const char *str, size_t len) { *(size_t *)data += len; } -STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) { +STATIC void cleanup_after_vm(supervisor_allocation *heap, supervisor_allocation *pystack, mp_obj_t exception) { // Get the traceback of any exception from this run off the heap. // MP_OBJ_SENTINEL means "this run does not contribute to traceback storage, don't touch it" // MP_OBJ_NULL (=0) means "this run completed successfully, clear any stored traceback" @@ -316,6 +370,9 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) { filesystem_flush(); stop_mp(); free_memory(heap); + #if MICROPY_ENABLE_PYSTACK + free_memory(pystack); + #endif supervisor_move_memory(); // Let the workflows know we've reset in case they want to restart. @@ -329,12 +386,12 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) { } else { serial_write_compressed(translate("Auto-reload is off.\n")); } - if (safe_mode != NO_SAFE_MODE) { + if (safe_mode != SAFE_MODE_NONE) { serial_write_compressed(translate("Running in safe mode! Not running saved code.\n")); } } -STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_reset) { +STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) { bool serial_connected_at_start = serial_connected(); bool printed_safe_mode_message = false; #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0 @@ -346,12 +403,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re } #endif - pyexec_result_t result; - - result.return_code = 0; - result.exception = MP_OBJ_NULL; - result.exception_line = 0; - bool skip_repl = false; bool skip_wait = false; bool found_main = false; @@ -361,23 +412,27 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re // Do the filesystem flush check before reload in case another write comes // in while we're doing the flush. - if (safe_mode == NO_SAFE_MODE) { + if (safe_mode == SAFE_MODE_NONE) { stack_resize(); filesystem_flush(); } - if (safe_mode == NO_SAFE_MODE && !autoreload_pending()) { - static const char *const supported_filenames[] = STRING_LIST( - "code.txt", "code.py", "main.py", "main.txt"); + if (safe_mode == SAFE_MODE_NONE && !autoreload_pending()) { + static const char *const supported_filenames[] = { + "code.txt", "code.py", "main.py", "main.txt" + }; #if CIRCUITPY_FULL_BUILD - static const char *const double_extension_filenames[] = STRING_LIST( + static const char *const double_extension_filenames[] = { "code.txt.py", "code.py.txt", "code.txt.txt","code.py.py", - "main.txt.py", "main.py.txt", "main.txt.txt","main.py.py"); + "main.txt.py", "main.py.txt", "main.txt.txt","main.py.py" + }; #endif + supervisor_allocation *pystack = NULL; + #if MICROPY_ENABLE_PYSTACK + pystack = allocate_pystack(safe_mode); + #endif supervisor_allocation *heap = allocate_remaining_memory(); - - // Prepare the VM state. Includes an alarm check/reset for sleep. - start_mp(heap, first_run); + start_mp(heap, pystack); #if CIRCUITPY_USB usb_setup_with_vm(); @@ -385,14 +440,15 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re // Check if a different run file has been allocated if (next_code_allocation) { - ((next_code_info_t *)next_code_allocation->ptr)->options &= ~SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; - next_code_options = ((next_code_info_t *)next_code_allocation->ptr)->options; - if (((next_code_info_t *)next_code_allocation->ptr)->filename[0] != '\0') { - const char *next_list[] = {((next_code_info_t *)next_code_allocation->ptr)->filename, ""}; + next_code_info_t *info = ((next_code_info_t *)next_code_allocation->ptr); + info->options &= ~SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; + next_code_options = info->options; + if (info->filename[0] != '\0') { // This is where the user's python code is actually executed: - found_main = maybe_run_list(next_list, &result); + const char *const filenames[] = { info->filename }; + found_main = maybe_run_list(filenames, MP_ARRAY_SIZE(filenames)); if (!found_main) { - serial_write(((next_code_info_t *)next_code_allocation->ptr)->filename); + serial_write(info->filename); serial_write_compressed(translate(" not found.\n")); } } @@ -400,11 +456,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re // Otherwise, default to the standard list of filenames if (!found_main) { // This is where the user's python code is actually executed: - found_main = maybe_run_list(supported_filenames, &result); + found_main = maybe_run_list(supported_filenames, MP_ARRAY_SIZE(supported_filenames)); // If that didn't work, double check the extensions #if CIRCUITPY_FULL_BUILD if (!found_main) { - found_main = maybe_run_list(double_extension_filenames, &result); + found_main = maybe_run_list(double_extension_filenames, MP_ARRAY_SIZE(double_extension_filenames)); if (found_main) { serial_write_compressed(translate("WARNING: Your code filename has two extensions\n")); } @@ -416,7 +472,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re // Print done before resetting everything so that we get the message over // BLE before it is reset and we have a delay before reconnect. - if ((result.return_code & PYEXEC_RELOAD) && supervisor_get_run_reason() == RUN_REASON_AUTO_RELOAD) { + if ((_exec_result.return_code & PYEXEC_RELOAD) && supervisor_get_run_reason() == RUN_REASON_AUTO_RELOAD) { serial_write_compressed(translate("\nCode stopped by auto-reload. Reloading soon.\n")); } else { serial_write_compressed(translate("\nCode done running.\n")); @@ -424,7 +480,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re // Finished executing python code. Cleanup includes filesystem flush and a board reset. - cleanup_after_vm(heap, result.exception); + cleanup_after_vm(heap, pystack, _exec_result.exception); + _exec_result.exception = NULL; // If a new next code file was set, that is a reason to keep it (obviously). Stuff this into // the options because it can be treated like any other reason-for-stickiness bit. The @@ -435,7 +492,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re next_code_options |= SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; } - if (result.return_code & PYEXEC_RELOAD) { + if (_exec_result.return_code & PYEXEC_RELOAD) { next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD; // Reload immediately unless the reload is due to autoreload. In that // case, we wait below to see if any other writes occur. @@ -443,7 +500,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re skip_repl = true; skip_wait = true; } - } else if (result.return_code == 0) { + } else if (_exec_result.return_code == 0) { next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS; if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS) { skip_repl = true; @@ -454,12 +511,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re // Deep sleep cannot be skipped // TODO: settings in deep sleep should persist, using a new sleep memory API if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_ERROR - && !(result.return_code & PYEXEC_DEEP_SLEEP)) { + && !(_exec_result.return_code & PYEXEC_DEEP_SLEEP)) { skip_repl = true; skip_wait = true; } } - if (result.return_code & PYEXEC_FORCED_EXIT) { + if (_exec_result.return_code & PYEXEC_FORCED_EXIT) { skip_repl = false; skip_wait = true; } @@ -477,13 +534,13 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re uint8_t blink_count; bool led_active = false; #if CIRCUITPY_ALARM - if (result.return_code & PYEXEC_DEEP_SLEEP) { + if (_exec_result.return_code & PYEXEC_DEEP_SLEEP) { color = BLACK; blink_count = 0; } else #endif - if (result.return_code != PYEXEC_EXCEPTION) { - if (safe_mode == NO_SAFE_MODE) { + if (_exec_result.return_code != PYEXEC_EXCEPTION) { + if (safe_mode == SAFE_MODE_NONE) { color = ALL_DONE; blink_count = ALL_DONE_BLINKS; } else { @@ -525,7 +582,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re } // If interrupted by keyboard, return - if (serial_connected() && serial_bytes_available()) { + if (serial_connected() && serial_bytes_available() && !autoreload_pending()) { // Skip REPL if reload was requested. skip_repl = serial_read() == CHAR_CTRL_D; if (skip_repl) { @@ -567,7 +624,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re // Sleep until our next interrupt. #if CIRCUITPY_ALARM - if (result.return_code & PYEXEC_DEEP_SLEEP) { + if (_exec_result.return_code & PYEXEC_DEEP_SLEEP) { const bool awoke_from_true_deep_sleep = common_hal_mcu_processor_get_reset_reason() == RESET_REASON_DEEP_SLEEP_ALARM; @@ -703,8 +760,38 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re vstr_t *boot_output; +#if CIRCUITPY_SAFEMODE_PY +STATIC void __attribute__ ((noinline)) run_safemode_py(safe_mode_t safe_mode) { + // Don't run if we aren't in safe mode or we won't be able to find safemode.py. + // Also don't run if it's a user-initiated safemode (pressing button(s) during boot), + // since that's deliberate. + if (safe_mode == SAFE_MODE_NONE || safe_mode == SAFE_MODE_USER || !filesystem_present()) { + return; + } + + supervisor_allocation *pystack = NULL; + #if MICROPY_ENABLE_PYSTACK + pystack = allocate_pystack(safe_mode); + #endif + supervisor_allocation *heap = allocate_remaining_memory(); + start_mp(heap, pystack); + + static const char *const safemode_py_filenames[] = {"safemode.py", "safemode.txt"}; + maybe_run_list(safemode_py_filenames, MP_ARRAY_SIZE(safemode_py_filenames)); + + // If safemode.py itself caused an error, change the safe_mode state to indicate that. + if (_exec_result.exception != MP_OBJ_NULL && + _exec_result.exception != MP_OBJ_SENTINEL) { + set_safe_mode(SAFE_MODE_SAFEMODE_PY_ERROR); + } + + cleanup_after_vm(heap, pystack, _exec_result.exception); + _exec_result.exception = NULL; +} +#endif + STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { - if (safe_mode == NO_HEAP) { + if (safe_mode == SAFE_MODE_NO_HEAP) { return; } @@ -712,27 +799,31 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { // There is USB setup to do even if boot.py is not actually run. const bool ok_to_run = filesystem_present() - && safe_mode == NO_SAFE_MODE + && safe_mode == SAFE_MODE_NONE && MP_STATE_VM(vfs_mount_table) != NULL; - static const char *const boot_py_filenames[] = STRING_LIST("boot.py", "boot.txt"); + static const char *const boot_py_filenames[] = {"boot.py", "boot.txt"}; // Do USB setup even if boot.py is not run. + supervisor_allocation *pystack = NULL; + #if MICROPY_ENABLE_PYSTACK + pystack = allocate_pystack(safe_mode); + #endif supervisor_allocation *heap = allocate_remaining_memory(); - - // true means this is the first set of VM's after a hard reset. - start_mp(heap, true); + start_mp(heap, pystack); #if CIRCUITPY_USB // Set up default USB values after boot.py VM starts but before running boot.py. usb_set_defaults(); #endif - pyexec_result_t result = {0, MP_OBJ_NULL, 0}; - if (ok_to_run) { #ifdef CIRCUITPY_BOOT_OUTPUT_FILE + #if CIRCUITPY_STATUS_BAR + // Turn off status bar updates when writing out to boot_out.txt. + supervisor_status_bar_suspend(); + #endif vstr_t boot_text; vstr_init(&boot_text, 512); boot_output = &boot_text; @@ -740,8 +831,18 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { // Write version info mp_printf(&mp_plat_print, "%s\nBoard ID:%s\n", MICROPY_FULL_VERSION_INFO, CIRCUITPY_BOARD_ID); + #if CIRCUITPY_MICROCONTROLLER && COMMON_HAL_MCU_PROCESSOR_UID_LENGTH > 0 + uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; + common_hal_mcu_processor_get_uid(raw_id); + mp_cprintf(&mp_plat_print, translate("UID:")); + for (size_t i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) { + mp_cprintf(&mp_plat_print, translate("%02X"), raw_id[i]); + } + mp_printf(&mp_plat_print, "\n"); + port_boot_info(); + #endif - bool found_boot = maybe_run_list(boot_py_filenames, &result); + bool found_boot = maybe_run_list(boot_py_filenames, MP_ARRAY_SIZE(boot_py_filenames)); (void)found_boot; @@ -751,6 +852,9 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { FATFS *fs = &vfs->fatfs; boot_output = NULL; + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_resume(); + #endif bool write_boot_output = true; FIL boot_output_file; if (f_open(fs, &boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_READ) == FR_OK) { @@ -791,7 +895,12 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { usb_get_boot_py_data(usb_boot_py_data, size); #endif - cleanup_after_vm(heap, result.exception); + port_post_boot_py(true); + + cleanup_after_vm(heap, pystack, _exec_result.exception); + _exec_result.exception = NULL; + + port_post_boot_py(false); #if CIRCUITPY_USB // Now give back the data we saved from the heap going away. @@ -799,12 +908,16 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { #endif } -STATIC int run_repl(bool first_run) { +STATIC int run_repl(safe_mode_t safe_mode) { int exit_code = PYEXEC_FORCED_EXIT; stack_resize(); filesystem_flush(); + supervisor_allocation *pystack = NULL; + #if MICROPY_ENABLE_PYSTACK + pystack = allocate_pystack(safe_mode); + #endif supervisor_allocation *heap = allocate_remaining_memory(); - start_mp(heap, first_run); + start_mp(heap, pystack); #if CIRCUITPY_USB usb_setup_with_vm(); @@ -822,9 +935,23 @@ STATIC int run_repl(bool first_run) { status_led_deinit(); #endif if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_suspend(); + #endif exit_code = pyexec_raw_repl(); + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_resume(); + #endif } else { + _current_executing_filename = "REPL"; + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_update(); + #endif exit_code = pyexec_friendly_repl(); + _current_executing_filename = NULL; + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_update(); + #endif } #if CIRCUITPY_ATEXIT pyexec_result_t result; @@ -833,7 +960,14 @@ STATIC int run_repl(bool first_run) { exit_code = PYEXEC_DEEP_SLEEP; } #endif - cleanup_after_vm(heap, MP_OBJ_SENTINEL); + cleanup_after_vm(heap, pystack, MP_OBJ_SENTINEL); + + // Also reset bleio. The above call omits it in case workflows should continue. In this case, + // we're switching straight to another VM so we want to reset. + #if CIRCUITPY_BLEIO + bleio_reset(); + #endif + #if CIRCUITPY_STATUS_LED status_led_init(); new_status_color(BLACK); @@ -845,8 +979,9 @@ STATIC int run_repl(bool first_run) { } int __attribute__((used)) main(void) { + // initialise the cpu and peripherals - safe_mode_t safe_mode = port_init(); + set_safe_mode(port_init()); // Turn on RX and TX LEDs if we have them. init_rxtx_leds(); @@ -858,21 +993,25 @@ int __attribute__((used)) main(void) { common_hal_nvm_bytearray_set_bytes(&common_hal_mcu_nvm_obj,0,&value_out,1); #endif + // Start the debug serial + serial_early_init(); + // Wait briefly to give a reset window where we'll enter safe mode after the reset. - if (safe_mode == NO_SAFE_MODE) { - safe_mode = wait_for_safe_mode_reset(); + if (get_safe_mode() == SAFE_MODE_NONE) { + set_safe_mode(wait_for_safe_mode_reset()); } stack_init(); + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_init(); + #endif + #if CIRCUITPY_BLEIO // Early init so that a reset press can cause BLE public advertising. supervisor_bluetooth_init(); #endif - // Start the debug serial - serial_early_init(); - #if !INTERNAL_FLASH_FILESYSTEM // Set up anything that might need to get done before we try to use SPI flash // This is needed for some boards where flash relies on GPIO setup to work @@ -885,12 +1024,18 @@ int __attribute__((used)) main(void) { // Check whether CIRCUITPY is available. No need to reset to get safe mode // since we haven't run user code yet. - if (!filesystem_init(safe_mode == NO_SAFE_MODE, false)) { - safe_mode = NO_CIRCUITPY; + if (!filesystem_init(get_safe_mode() == SAFE_MODE_NONE, false)) { + set_safe_mode(SAFE_MODE_NO_CIRCUITPY); } - // displays init after filesystem, since they could share the flash SPI - board_init(); + #if CIRCUITPY_ALARM + // Record which alarm woke us up, if any. + // common_hal_alarm_record_wake_alarm() should return a static, non-heap object + shared_alarm_save_wake_alarm(common_hal_alarm_record_wake_alarm()); + // Then reset the alarm system. It's not reset in reset_port(), because that's also called + // on VM teardown, which would clear any alarm setup. + alarm_reset(); + #endif // Reset everything and prep MicroPython to run boot.py. reset_port(); @@ -898,40 +1043,56 @@ int __attribute__((used)) main(void) { reset_devices(); reset_board(); + // displays init after filesystem, since they could share the flash SPI + board_init(); + // This is first time we are running CircuitPython after a reset or power-up. supervisor_set_run_reason(RUN_REASON_STARTUP); // If not in safe mode turn on autoreload by default but before boot.py in case it wants to change it. - if (safe_mode == NO_SAFE_MODE) { + if (get_safe_mode() == SAFE_MODE_NONE) { autoreload_enable(); } // By default our internal flash is readonly to local python code and - // writable over USB. Set it here so that boot.py can change it. + // writable over USB. Set it here so that safemode.py or boot.py can change it. filesystem_set_internal_concurrent_write_protection(true); filesystem_set_internal_writable_by_usb(CIRCUITPY_USB == 1); - run_boot_py(safe_mode); + #if CIRCUITPY_SAFEMODE_PY + // Run safemode.py if we ARE in safe mode. + // If safemode.py does not do a hard reset, and exits normally, we will continue on + // and report the safe mode as usual. + run_safemode_py(get_safe_mode()); + #endif + + run_boot_py(get_safe_mode()); supervisor_workflow_start(); + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_request_update(true); + #endif + // Boot script is finished, so now go into REPL or run code.py. int exit_code = PYEXEC_FORCED_EXIT; bool skip_repl = true; - bool first_run = true; - bool simulate_reset; + bool simulate_reset = true; for (;;) { - simulate_reset = false; if (!skip_repl) { - exit_code = run_repl(first_run); + exit_code = run_repl(get_safe_mode()); supervisor_set_run_reason(RUN_REASON_REPL_RELOAD); } if (exit_code == PYEXEC_FORCED_EXIT) { - if (!first_run) { + if (!simulate_reset) { serial_write_compressed(translate("soft reboot\n")); } + simulate_reset = false; if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { - skip_repl = run_code_py(safe_mode, first_run, &simulate_reset); + // If code.py did a fake deep sleep, pretend that we + // are running code.py for the first time after a hard + // reset. This will preserve any alarm information. + skip_repl = run_code_py(get_safe_mode(), &simulate_reset); } else { skip_repl = false; } @@ -939,10 +1100,10 @@ int __attribute__((used)) main(void) { break; } - // Either the REPL or code.py has run and finished. - // If code.py did a fake deep sleep, pretend that we are running code.py for - // the first time after a hard reset. This will preserve any alarm information. - first_run = simulate_reset; + #if CIRCUITPY_ALARM + shared_alarm_save_wake_alarm(simulate_reset ? common_hal_alarm_record_wake_alarm() : mp_const_none); + alarm_reset(); + #endif } mp_deinit(); return 0; @@ -991,14 +1152,14 @@ void gc_collect(void) { } void NORETURN nlr_jump_fail(void *val) { - reset_into_safe_mode(MICROPY_NLR_JUMP_FAIL); + reset_into_safe_mode(SAFE_MODE_NLR_JUMP_FAIL); while (true) { } } #ifndef NDEBUG static void NORETURN __fatal_error(const char *msg) { - reset_into_safe_mode(MICROPY_FATAL_ERROR); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { } } diff --git a/mpy-cross/Makefile b/mpy-cross/Makefile index 6e4d7ef316..4858cb25c7 100644 --- a/mpy-cross/Makefile +++ b/mpy-cross/Makefile @@ -20,3 +20,5 @@ override undefine PROG endif include mpy-cross.mk +CFLAGS += -g +STRIP = : diff --git a/mpy-cross/Makefile.m1 b/mpy-cross/Makefile.m1 index 34e9841540..13431f708b 100644 --- a/mpy-cross/Makefile.m1 +++ b/mpy-cross/Makefile.m1 @@ -7,4 +7,4 @@ BUILD=build-arm64 include mpy-cross.mk # Because mpy-cross.mk unconditionally overwrites CC for Darwin, we must set it BELOW the inclusion -CC := $(shell xcrun --sdk macosx11.1 --find clang) -isysroot $(shell xcrun --sdk macosx11.1 --show-sdk-path) -target arm64-apple-macos11 +CC := $(shell xcrun --find clang) -isysroot $(shell xcrun --show-sdk-path) -target arm64-apple-macos11 diff --git a/ports/atmel-samd/.gitignore b/ports/atmel-samd/.gitignore deleted file mode 100644 index 414487d53e..0000000000 --- a/ports/atmel-samd/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build-*/ diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index a0a211edb0..0ac326d3cc 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -22,36 +22,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Select the board to build for. -ifeq ($(BOARD),) - $(error You must provide a BOARD parameter) -else - ifeq ($(wildcard boards/$(BOARD)/.),) - $(error Invalid BOARD specified) - endif -endif - -# If the build directory is not given, make it reflect the board name. -BUILD ?= build-$(BOARD) - -include ../../py/mkenv.mk -# Board-specific -include boards/$(BOARD)/mpconfigboard.mk -# Port-specific -include mpconfigport.mk -# CircuitPython-specific -include $(TOP)/py/circuitpy_mpconfig.mk - -# qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h - -# include py core make definitions -include $(TOP)/py/py.mk - -include $(TOP)/supervisor/supervisor.mk - -# Include make rules and variables common across CircuitPython builds. -include $(TOP)/py/circuitpy_defns.mk +include ../../py/circuitpy_mkenv.mk CROSS_COMPILE = arm-none-eabi- @@ -108,7 +79,7 @@ endif ifeq ($(CHIP_FAMILY), same54) PERIPHERALS_CHIP_FAMILY=sam_d5x_e5x -OPTIMIZATION_FLAGS ?= -O2 +OPTIMIZATION_FLAGS ?= -Os # TinyUSB defines CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAME5X -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024 endif @@ -164,6 +135,9 @@ CFLAGS += \ -msoft-float \ -mfloat-abi=soft \ -DSAMD21 +LIBS := libs/libgcc-12.1.0-Os-v6-m-nofp.a -lc +else +LIBS := -lgcc -lc endif ifeq ($(CHIP_FAMILY), samd51) CFLAGS += \ @@ -200,7 +174,6 @@ endif CFLAGS += -Wno-stringop-overread -Wno-stringop-overflow LDFLAGS = $(CFLAGS) -nostartfiles -Wl,-nostdlib -Wl,-T,$(GENERATED_LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs -LIBS := -lgcc -lc # Use toolchain libm if we're not using our own. ifndef INTERNAL_LIBM @@ -320,7 +293,6 @@ SRC_C += \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ eic_handler.c \ - fatfs_port.c \ lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \ mphalport.c \ reset.c \ @@ -395,7 +367,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(GENERATED_LD_FILE) $(STEPECHO) "LINK $@" $(Q)echo $(OBJ) > $(BUILD)/firmware.objs $(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--start-group $(LIBS) -Wl,--end-group - $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(GENERATED_LD_FILE) + $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(GENERATED_LD_FILE) $(BUILD) $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(STEPECHO) "Create $@" diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 9dcedf3f9b..6e1dc71d85 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -57,5 +57,8 @@ void port_finish_background_task(void) { } #endif +void port_background_tick(void) { +} + void port_background_task(void) { } diff --git a/ports/atmel-samd/bindings/samd/Clock.c b/ports/atmel-samd/bindings/samd/Clock.c index 7c405d464d..00c1959ccf 100644 --- a/ports/atmel-samd/bindings/samd/Clock.c +++ b/ports/atmel-samd/bindings/samd/Clock.c @@ -33,8 +33,8 @@ //| class Clock: //| """Identifies a clock on the microcontroller. //| -//| They are fixed by the hardware so they cannot be constructed on demand. Instead, use -//| ``samd.clock`` to reference the desired clock.""" +//| They are fixed by the hardware so they cannot be constructed on demand. Instead, use +//| ``samd.clock`` to reference the desired clock.""" //| STATIC void samd_clock_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { @@ -45,7 +45,6 @@ STATIC void samd_clock_print(const mp_print_t *print, mp_obj_t self_in, mp_print //| enabled: bool //| """Is the clock enabled? (read-only)""" -//| STATIC mp_obj_t samd_clock_get_enabled(mp_obj_t self_in) { samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(clock_get_enabled(self->type, self->index)); @@ -58,7 +57,6 @@ MP_PROPERTY_GETTER(samd_clock_enabled_obj, //| parent: Union[Clock, None] //| """Clock parent. (read-only)""" -//| STATIC mp_obj_t samd_clock_get_parent(mp_obj_t self_in) { samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); uint8_t p_type, p_index; @@ -83,7 +81,6 @@ MP_PROPERTY_GETTER(samd_clock_parent_obj, //| frequency: int //| """Clock frequency in Herz. (read-only)""" -//| STATIC mp_obj_t samd_clock_get_frequency(mp_obj_t self_in) { samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int_from_uint(clock_get_frequency(self->type, self->index)); diff --git a/ports/atmel-samd/bindings/samd/__init__.c b/ports/atmel-samd/bindings/samd/__init__.c index b5c618108d..29d12357d1 100644 --- a/ports/atmel-samd/bindings/samd/__init__.c +++ b/ports/atmel-samd/bindings/samd/__init__.c @@ -40,7 +40,6 @@ //| :platform: SAMD21 //| //| References to clocks as named by the microcontroller""" -//| const mp_obj_module_t samd_clock_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&samd_clock_globals, diff --git a/ports/atmel-samd/boards/8086_commander/board.c b/ports/atmel-samd/boards/8086_commander/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/8086_commander/board.c +++ b/ports/atmel-samd/boards/8086_commander/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/board.c index ba0cf06ebc..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/board.c +++ b/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/board.c @@ -25,19 +25,5 @@ */ #include "supervisor/board.h" -#include "common-hal/microcontroller/Pin.h" -#include "supervisor/shared/board.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c index 8804c3c324..e0f8bda171 100644 --- a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c @@ -27,18 +27,9 @@ #include "supervisor/board.h" #include "common-hal/microcontroller/Pin.h" #include "supervisor/shared/board.h" -#include "hal/include/hal_gpio.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} void reset_board(void) { board_reset_user_neopixels(&pin_PA15, 2); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/board.c index ba0cf06ebc..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/board.c +++ b/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/board.c @@ -25,19 +25,5 @@ */ #include "supervisor/board.h" -#include "common-hal/microcontroller/Pin.h" -#include "supervisor/shared/board.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c index 0c829a4a55..0d885160e9 100644 --- a/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c +++ b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c @@ -29,16 +29,8 @@ #include "supervisor/shared/board.h" #include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { board_reset_user_neopixels(&pin_PA04, 2); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/aloriumtech_evo_m51/board.c b/ports/atmel-samd/boards/aloriumtech_evo_m51/board.c index 1c79675305..80e8b909a7 100644 --- a/ports/atmel-samd/boards/aloriumtech_evo_m51/board.c +++ b/ports/atmel-samd/boards/aloriumtech_evo_m51/board.c @@ -50,12 +50,4 @@ void board_init(void) { } } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/arduino_mkr1300/board.c b/ports/atmel-samd/boards/arduino_mkr1300/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/arduino_mkr1300/board.c +++ b/ports/atmel-samd/boards/arduino_mkr1300/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk index c3d75202bf..5d02fe3824 100644 --- a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk @@ -6,6 +6,10 @@ USB_MANUFACTURER = "Arduino" CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 + +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/arduino_mkrzero/board.c b/ports/atmel-samd/boards/arduino_mkrzero/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/arduino_mkrzero/board.c +++ b/ports/atmel-samd/boards/arduino_mkrzero/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk index eea3a27f13..4f058e4f2a 100644 --- a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk @@ -6,6 +6,8 @@ USB_MANUFACTURER = "Arduino" CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 diff --git a/ports/atmel-samd/boards/arduino_nano_33_iot/board.c b/ports/atmel-samd/boards/arduino_nano_33_iot/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/arduino_nano_33_iot/board.c +++ b/ports/atmel-samd/boards/arduino_nano_33_iot/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.mk index 895c027ee5..7ef2af6ddb 100644 --- a/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.mk @@ -6,6 +6,10 @@ USB_MANUFACTURER = "Arduino" CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 + +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/arduino_zero/board.c b/ports/atmel-samd/boards/arduino_zero/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/arduino_zero/board.c +++ b/ports/atmel-samd/boards/arduino_zero/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk index f1c3631dcb..0c2df96c5d 100644 --- a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk @@ -6,8 +6,10 @@ USB_MANUFACTURER = "Arduino" CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 -CIRCUITPY_ONEWIREIO = 0 +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/bast_pro_mini_m0/board.c b/ports/atmel-samd/boards/bast_pro_mini_m0/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/bast_pro_mini_m0/board.c +++ b/ports/atmel-samd/boards/bast_pro_mini_m0/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/bdmicro_vina_d21/board.c b/ports/atmel-samd/boards/bdmicro_vina_d21/board.c index 5725a67dcc..f56275c016 100644 --- a/ports/atmel-samd/boards/bdmicro_vina_d21/board.c +++ b/ports/atmel-samd/boards/bdmicro_vina_d21/board.c @@ -39,12 +39,4 @@ void board_init(void) { // port_pin_set_output_level(MICROPY_HW_LED_RX, true); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/bdmicro_vina_d21/mpconfigboard.mk b/ports/atmel-samd/boards/bdmicro_vina_d21/mpconfigboard.mk index f0857ce6d2..1a8cddfda7 100644 --- a/ports/atmel-samd/boards/bdmicro_vina_d21/mpconfigboard.mk +++ b/ports/atmel-samd/boards/bdmicro_vina_d21/mpconfigboard.mk @@ -9,5 +9,3 @@ CHIP_FAMILY = samd21 SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "MX25L51245G","GD25S512MD" LONGINT_IMPL = MPZ - -CIRCUITPY_ONEWIREIO = 0 diff --git a/ports/atmel-samd/boards/bdmicro_vina_d51/board.c b/ports/atmel-samd/boards/bdmicro_vina_d51/board.c index e0a7487bd2..1bba99ac06 100644 --- a/ports/atmel-samd/boards/bdmicro_vina_d51/board.c +++ b/ports/atmel-samd/boards/bdmicro_vina_d51/board.c @@ -28,15 +28,4 @@ #include "mpconfigboard.h" #include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/bdmicro_vina_d51_pcb7/board.c b/ports/atmel-samd/boards/bdmicro_vina_d51_pcb7/board.c index 5725a67dcc..f56275c016 100644 --- a/ports/atmel-samd/boards/bdmicro_vina_d51_pcb7/board.c +++ b/ports/atmel-samd/boards/bdmicro_vina_d51_pcb7/board.c @@ -39,12 +39,4 @@ void board_init(void) { // port_pin_set_output_level(MICROPY_HW_LED_RX, true); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/blm_badge/board.c b/ports/atmel-samd/boards/blm_badge/board.c index 40e66b947e..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/blm_badge/board.c +++ b/ports/atmel-samd/boards/blm_badge/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "supervisor/shared/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - board_reset_user_neopixels(&pin_PA05, 10); -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/board.c b/ports/atmel-samd/boards/capablerobot_usbhub/board.c index d421db8b25..711b2cf766 100644 --- a/ports/atmel-samd/boards/capablerobot_usbhub/board.c +++ b/ports/atmel-samd/boards/capablerobot_usbhub/board.c @@ -29,15 +29,4 @@ #include "hal/include/hal_gpio.h" #include "common-hal/microcontroller/Pin.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/catwan_usbstick/board.c b/ports/atmel-samd/boards/catwan_usbstick/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/catwan_usbstick/board.c +++ b/ports/atmel-samd/boards/catwan_usbstick/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/board.c b/ports/atmel-samd/boards/circuitbrains_basic_m0/board.c index 1e5a53751a..a28d51be4f 100755 --- a/ports/atmel-samd/boards/circuitbrains_basic_m0/board.c +++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/board.c @@ -26,18 +26,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/board.c b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/board.c index 1e5a53751a..a28d51be4f 100755 --- a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/board.c +++ b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/board.c @@ -26,18 +26,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/circuitplayground_express/board.c b/ports/atmel-samd/boards/circuitplayground_express/board.c index 113db13085..bda4f7520b 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/board.c +++ b/ports/atmel-samd/boards/circuitplayground_express/board.c @@ -31,9 +31,6 @@ #include "supervisor/shared/board.h" #include "hal/include/hal_gpio.h" -void board_init(void) { -} - // Check the status of the two buttons on CircuitPlayground Express. If both are // pressed, then boot into user safe mode. bool board_requests_safe_mode(void) { @@ -55,5 +52,4 @@ void reset_board(void) { board_reset_user_neopixels(&pin_PB23, 10); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h index 9020c243b1..d7ca2a107c 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -23,7 +23,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION translate("pressing both buttons at start up.\n") +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed both buttons at start up.") // Increase stack size slightly due to CPX library import nesting #define CIRCUITPY_DEFAULT_STACK_SIZE (4248) // divisible by 8 diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c b/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c index d419813df3..bd9eba93cc 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/board.c @@ -31,9 +31,6 @@ #include "hal/include/hal_gpio.h" #include "supervisor/shared/board.h" -void board_init(void) { -} - // Check the status of the two buttons on CircuitPlayground Express. If both are // pressed, then boot into user safe mode. bool board_requests_safe_mode(void) { @@ -55,5 +52,4 @@ void reset_board(void) { board_reset_user_neopixels(&pin_PB23, 10); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h index 5073c5e403..6ee5e0504b 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h @@ -23,7 +23,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION translate("pressing both buttons at start up.\n") +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed both buttons at start up.") // Increase stack size slightly due to CPX library import nesting #define CIRCUITPY_DEFAULT_STACK_SIZE (4248) // divisible by 8 diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk index 975d892b9a..c108a90250 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk @@ -15,7 +15,6 @@ LONGINT_IMPL = NONE CIRCUITPY_BUSDEVICE = 1 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_KEYPAD = 0 -CIRCUITPY_ONEWIREIO = 0 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground/frozen_cpx diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/board.c b/ports/atmel-samd/boards/circuitplayground_express_displayio/board.c index d419813df3..bd9eba93cc 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/board.c +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/board.c @@ -31,9 +31,6 @@ #include "hal/include/hal_gpio.h" #include "supervisor/shared/board.h" -void board_init(void) { -} - // Check the status of the two buttons on CircuitPlayground Express. If both are // pressed, then boot into user safe mode. bool board_requests_safe_mode(void) { @@ -55,5 +52,4 @@ void reset_board(void) { board_reset_user_neopixels(&pin_PB23, 10); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h index 20cfc617a2..c0f2d07e9d 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h @@ -23,7 +23,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION translate("pressing both buttons at start up.\n") +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed both buttons at start up.") // Increase stack size slightly due to CPX library import nesting. #define CIRCUITPY_DEFAULT_STACK_SIZE (4248) // divisible by 8 diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk index 4338fe3e1e..cc125e1ffb 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk @@ -12,7 +12,6 @@ EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" # Turn off features and optimizations for displayio build to make room for additional frozen libs. LONGINT_IMPL = NONE CIRCUITPY_KEYPAD = 0 -CIRCUITPY_ONEWIREIO = 0 CIRCUITPY_PIXELBUF = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 diff --git a/ports/atmel-samd/boards/cp32-m4/board.c b/ports/atmel-samd/boards/cp32-m4/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/cp32-m4/board.c +++ b/ports/atmel-samd/boards/cp32-m4/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/cp_sapling_m0/board.c b/ports/atmel-samd/boards/cp_sapling_m0/board.c index ba0cf06ebc..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/cp_sapling_m0/board.c +++ b/ports/atmel-samd/boards/cp_sapling_m0/board.c @@ -25,19 +25,5 @@ */ #include "supervisor/board.h" -#include "common-hal/microcontroller/Pin.h" -#include "supervisor/shared/board.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/cp_sapling_m0_revb/board.c b/ports/atmel-samd/boards/cp_sapling_m0_revb/board.c index ba0cf06ebc..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/cp_sapling_m0_revb/board.c +++ b/ports/atmel-samd/boards/cp_sapling_m0_revb/board.c @@ -25,19 +25,5 @@ */ #include "supervisor/board.h" -#include "common-hal/microcontroller/Pin.h" -#include "supervisor/shared/board.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/cp_sapling_m0_spiflash/board.c b/ports/atmel-samd/boards/cp_sapling_m0_spiflash/board.c index ba0cf06ebc..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/cp_sapling_m0_spiflash/board.c +++ b/ports/atmel-samd/boards/cp_sapling_m0_spiflash/board.c @@ -25,19 +25,5 @@ */ #include "supervisor/board.h" -#include "common-hal/microcontroller/Pin.h" -#include "supervisor/shared/board.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/cytron_maker_zero_samd21/board.c b/ports/atmel-samd/boards/cytron_maker_zero_samd21/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/cytron_maker_zero_samd21/board.c +++ b/ports/atmel-samd/boards/cytron_maker_zero_samd21/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/datalore_ip_m4/board.c b/ports/atmel-samd/boards/datalore_ip_m4/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/board.c +++ b/ports/atmel-samd/boards/datalore_ip_m4/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/datum_distance/board.c b/ports/atmel-samd/boards/datum_distance/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/datum_distance/board.c +++ b/ports/atmel-samd/boards/datum_distance/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/datum_imu/board.c b/ports/atmel-samd/boards/datum_imu/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/datum_imu/board.c +++ b/ports/atmel-samd/boards/datum_imu/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/datum_light/board.c b/ports/atmel-samd/boards/datum_light/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/datum_light/board.c +++ b/ports/atmel-samd/boards/datum_light/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/datum_weather/board.c b/ports/atmel-samd/boards/datum_weather/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/datum_weather/board.c +++ b/ports/atmel-samd/boards/datum_weather/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/dynalora_usb/board.c b/ports/atmel-samd/boards/dynalora_usb/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/dynalora_usb/board.c +++ b/ports/atmel-samd/boards/dynalora_usb/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/dynossat_edu_eps/board.c b/ports/atmel-samd/boards/dynossat_edu_eps/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/dynossat_edu_eps/board.c +++ b/ports/atmel-samd/boards/dynossat_edu_eps/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/dynossat_edu_obc/board.c b/ports/atmel-samd/boards/dynossat_edu_obc/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/dynossat_edu_obc/board.c +++ b/ports/atmel-samd/boards/dynossat_edu_obc/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/escornabot_makech/board.c b/ports/atmel-samd/boards/escornabot_makech/board.c index bfc3bade9d..a3c19899e8 100644 --- a/ports/atmel-samd/boards/escornabot_makech/board.c +++ b/ports/atmel-samd/boards/escornabot_makech/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h index bb99c412ae..1886f9e233 100644 --- a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h +++ b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.h @@ -5,9 +5,6 @@ #define CALIBRATE_CRYSTALLESS 1 -// Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION translate("pressing both buttons at start up.\n") - #define DEFAULT_I2C_BUS_SCL (&pin_PA08) #define DEFAULT_I2C_BUS_SDA (&pin_PA09) diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/board.c b/ports/atmel-samd/boards/feather_m0_adalogger/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/board.c +++ b/ports/atmel-samd/boards/feather_m0_adalogger/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk index 62336ecf50..b0e01e43a5 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk @@ -6,6 +6,8 @@ USB_MANUFACTURER = "Adafruit Industries LLC" CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 diff --git a/ports/atmel-samd/boards/feather_m0_basic/board.c b/ports/atmel-samd/boards/feather_m0_basic/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/feather_m0_basic/board.c +++ b/ports/atmel-samd/boards/feather_m0_basic/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk index cfd1f63cb3..f54da83f11 100644 --- a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk @@ -6,6 +6,8 @@ USB_MANUFACTURER = "Adafruit Industries LLC" CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 diff --git a/ports/atmel-samd/boards/feather_m0_express/board.c b/ports/atmel-samd/boards/feather_m0_express/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/feather_m0_express/board.c +++ b/ports/atmel-samd/boards/feather_m0_express/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/board.c b/ports/atmel-samd/boards/feather_m0_express_crickit/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/feather_m0_express_crickit/board.c +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/board.c b/ports/atmel-samd/boards/feather_m0_rfm69/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/board.c +++ b/ports/atmel-samd/boards/feather_m0_rfm69/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk index 48c0f47064..aa9055a5e3 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk @@ -6,6 +6,8 @@ USB_MANUFACTURER = "Adafruit Industries LLC" CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 @@ -13,12 +15,13 @@ CIRCUITPY_FULL_BUILD = 0 # A number of modules are removed for RFM69 to make room for frozen libraries. # Many I/O functions are not available. CIRCUITPY_ANALOGIO = 1 +CIRCUITPY_BUSDEVICE = 1 +CIRCUITPY_RAINBOWIO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 +CIRCUITPY_TOUCHIO = 0 CIRCUITPY_USB_MIDI = 0 CIRCUITPY_USB_HID = 0 -CIRCUITPY_TOUCHIO = 0 -CIRCUITPY_BUSDEVICE = 1 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_RFM69 diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/board.c b/ports/atmel-samd/boards/feather_m0_rfm9x/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm9x/board.c +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk index 4003dd67f0..3bc3fa3ed0 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk @@ -6,6 +6,8 @@ USB_MANUFACTURER = "Adafruit Industries LLC" CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 diff --git a/ports/atmel-samd/boards/feather_m0_supersized/board.c b/ports/atmel-samd/boards/feather_m0_supersized/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/board.c +++ b/ports/atmel-samd/boards/feather_m0_supersized/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk index 9636c195dc..811336885b 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk @@ -9,5 +9,3 @@ CHIP_FAMILY = samd21 SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "S25FL064L" LONGINT_IMPL = MPZ - -CIRCUITPY_ONEWIREIO = 0 diff --git a/ports/atmel-samd/boards/feather_m4_can/board.c b/ports/atmel-samd/boards/feather_m4_can/board.c index 289d68af29..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/feather_m4_can/board.c +++ b/ports/atmel-samd/boards/feather_m4_can/board.c @@ -25,17 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/feather_m4_express/board.c b/ports/atmel-samd/boards/feather_m4_express/board.c index 289d68af29..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/feather_m4_express/board.c +++ b/ports/atmel-samd/boards/feather_m4_express/board.c @@ -25,17 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/fluff_m0/board.c b/ports/atmel-samd/boards/fluff_m0/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/fluff_m0/board.c +++ b/ports/atmel-samd/boards/fluff_m0/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/gemma_m0/board.c b/ports/atmel-samd/boards/gemma_m0/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/gemma_m0/board.c +++ b/ports/atmel-samd/boards/gemma_m0/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/board.c b/ports/atmel-samd/boards/grandcentral_m4_express/board.c index f72884ffe8..7180deb278 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/board.c +++ b/ports/atmel-samd/boards/grandcentral_m4_express/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c index b6ce037649..7641a9b630 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c +++ b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c @@ -58,77 +58,109 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB01) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB01) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TX3), MP_ROM_PTR(&pin_PB16) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB16) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RX3), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX3), MP_ROM_PTR(&pin_PB16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PB17) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_PC22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX3), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PC22) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_PC23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_PC22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PC23) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_PC23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PB12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_PB20) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_PB21) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB21) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_PD12) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_PA15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_PC17) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PC17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_PC16) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PC16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_PA12) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_DEN1), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_PA13) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_DEN2), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_PA14) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_CLK), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_PB19) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_XCLK), MP_ROM_PTR(&pin_PB19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_PA23) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D7), MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_PA22) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D6), MP_ROM_PTR(&pin_PA22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_PA21) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D5), MP_ROM_PTR(&pin_PA21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_PA20) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D4), MP_ROM_PTR(&pin_PA20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_PA19) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D3), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_PA18) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D2), MP_ROM_PTR(&pin_PA18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_PA17) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D1), MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_PA16) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D0), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_PB15) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D9), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_PB14) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D8), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_PC13) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D11), MP_ROM_PTR(&pin_PC13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_PC12) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D10), MP_ROM_PTR(&pin_PC12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_PC15) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D13), MP_ROM_PTR(&pin_PC15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_PC14) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PCC_D12), MP_ROM_PTR(&pin_PC14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_PC11) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D45), MP_ROM_PTR(&pin_PC10) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D46), MP_ROM_PTR(&pin_PC06) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D47), MP_ROM_PTR(&pin_PC07) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D48), MP_ROM_PTR(&pin_PC04) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D49), MP_ROM_PTR(&pin_PC05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D50), MP_ROM_PTR(&pin_PD11) }, { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PD11) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D51), MP_ROM_PTR(&pin_PD08) }, { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PD08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D52), MP_ROM_PTR(&pin_PD09) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PD09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D53), MP_ROM_PTR(&pin_PD10) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_PD10) }, diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index 5a6b43e475..701dc4a8ec 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -104,8 +104,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_PA00, NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -115,12 +114,4 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk index 6017b551f1..1c032f02c0 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -12,6 +12,7 @@ LONGINT_IMPL = NONE # To keep the build small CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_BUSDEVICE = 1 # lis3dh needs it CIRCUITPY_KEYPAD = 0 # Include these Python libraries in firmware. diff --git a/ports/atmel-samd/boards/hallowing_m4_express/board.c b/ports/atmel-samd/boards/hallowing_m4_express/board.c index d17835d0f8..5003c904bc 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m4_express/board.c @@ -84,8 +84,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_PB14, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -95,12 +94,4 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/huntercat_nfc/board.c b/ports/atmel-samd/boards/huntercat_nfc/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/huntercat_nfc/board.c +++ b/ports/atmel-samd/boards/huntercat_nfc/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/board.c b/ports/atmel-samd/boards/itsybitsy_m0_express/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/board.c +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/board.c b/ports/atmel-samd/boards/itsybitsy_m4_express/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/board.c +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/kicksat-sprite/board.c b/ports/atmel-samd/boards/kicksat-sprite/board.c index df7bd70dad..b22d8ae366 100644 --- a/ports/atmel-samd/boards/kicksat-sprite/board.c +++ b/ports/atmel-samd/boards/kicksat-sprite/board.c @@ -25,20 +25,6 @@ */ -#include - #include "supervisor/board.h" -#include "py/mpconfig.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk index 9bc50ab429..9ca9259747 100644 --- a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk +++ b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk @@ -20,11 +20,13 @@ CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 +CIRCUITPY_PIXELMAP = 0 CIRCUITPY_GETPASS = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_MSGPACK = 0 CIRCUITPY_PS2IO = 0 CIRCUITPY_RGBMATRIX = 0 +CIRCUITPY_RAINBOWIO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_USB_HID = 0 diff --git a/ports/atmel-samd/boards/loc_ber_m4_base_board/board.c b/ports/atmel-samd/boards/loc_ber_m4_base_board/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/loc_ber_m4_base_board/board.c +++ b/ports/atmel-samd/boards/loc_ber_m4_base_board/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/matrixportal_m4/board.c b/ports/atmel-samd/boards/matrixportal_m4/board.c index 1d9b33a40c..65d7297ed9 100644 --- a/ports/atmel-samd/boards/matrixportal_m4/board.c +++ b/ports/atmel-samd/boards/matrixportal_m4/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.mk b/ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.mk index e502f6b569..1f77c11931 100644 --- a/ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/matrixportal_m4/mpconfigboard.mk @@ -14,14 +14,12 @@ CIRCUITPY_LTO_PARTITION = one CIRCUITPY_AESIO = 0 CIRCUITPY_FLOPPYIO = 0 -CIRCUITPY_GIFIO = 0 -CIRCUITPY_ONEWIREIO = 0 CIRCUITPY_PARALLELDISPLAY = 0 -CIRCUITPY_SDCARDIO = 0 CIRCUITPY_SHARPDISPLAY = 0 -CIRCUITPY_ZLIB=0 +CIRCUITPY_ULAB = 0 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_PortalBase FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ESP32SPI FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/atmel-samd/boards/meowmeow/board.c b/ports/atmel-samd/boards/meowmeow/board.c index bfc3bade9d..a3c19899e8 100644 --- a/ports/atmel-samd/boards/meowmeow/board.c +++ b/ports/atmel-samd/boards/meowmeow/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h index 73853dab5d..ab5f652d1e 100644 --- a/ports/atmel-samd/boards/meowmeow/mpconfigboard.h +++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h @@ -6,7 +6,7 @@ #define CALIBRATE_CRYSTALLESS 1 // Explanation of how a user got into safe mode. -#define BOARD_USER_SAFE_MODE_ACTION translate("pressing both buttons at start up.\n") +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed both buttons at start up.") #define DEFAULT_I2C_BUS_SCL (&pin_PA01) #define DEFAULT_I2C_BUS_SDA (&pin_PA00) diff --git a/ports/atmel-samd/boards/metro_m0_express/board.c b/ports/atmel-samd/boards/metro_m0_express/board.c index 5725a67dcc..f56275c016 100644 --- a/ports/atmel-samd/boards/metro_m0_express/board.c +++ b/ports/atmel-samd/boards/metro_m0_express/board.c @@ -39,12 +39,4 @@ void board_init(void) { // port_pin_set_output_level(MICROPY_HW_LED_RX, true); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/board.c b/ports/atmel-samd/boards/metro_m4_airlift_lite/board.c index e0a7487bd2..1bba99ac06 100644 --- a/ports/atmel-samd/boards/metro_m4_airlift_lite/board.c +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/board.c @@ -28,15 +28,4 @@ #include "mpconfigboard.h" #include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/metro_m4_express/board.c b/ports/atmel-samd/boards/metro_m4_express/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/metro_m4_express/board.c +++ b/ports/atmel-samd/boards/metro_m4_express/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/mini_sam_m4/board.c b/ports/atmel-samd/boards/mini_sam_m4/board.c index e0a7487bd2..1bba99ac06 100644 --- a/ports/atmel-samd/boards/mini_sam_m4/board.c +++ b/ports/atmel-samd/boards/mini_sam_m4/board.c @@ -28,15 +28,4 @@ #include "mpconfigboard.h" #include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/monster_m4sk/board.c b/ports/atmel-samd/boards/monster_m4sk/board.c index e42721dee7..76c96bba82 100644 --- a/ports/atmel-samd/boards/monster_m4sk/board.c +++ b/ports/atmel-samd/boards/monster_m4sk/board.c @@ -85,8 +85,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_PA23, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -96,12 +95,4 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/ndgarage_ndbit6/board.c b/ports/atmel-samd/boards/ndgarage_ndbit6/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/ndgarage_ndbit6/board.c +++ b/ports/atmel-samd/boards/ndgarage_ndbit6/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/ndgarage_ndbit6_v2/board.c b/ports/atmel-samd/boards/ndgarage_ndbit6_v2/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/ndgarage_ndbit6_v2/board.c +++ b/ports/atmel-samd/boards/ndgarage_ndbit6_v2/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/neopixel_trinkey_m0/board.c b/ports/atmel-samd/boards/neopixel_trinkey_m0/board.c index f97d38a1a7..ed54817129 100644 --- a/ports/atmel-samd/boards/neopixel_trinkey_m0/board.c +++ b/ports/atmel-samd/boards/neopixel_trinkey_m0/board.c @@ -29,16 +29,8 @@ #include "supervisor/shared/board.h" #include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { board_reset_user_neopixels(&pin_PA05, 4); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/nfc_copy_cat/board.c b/ports/atmel-samd/boards/nfc_copy_cat/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/nfc_copy_cat/board.c +++ b/ports/atmel-samd/boards/nfc_copy_cat/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/openbook_m4/board.c b/ports/atmel-samd/boards/openbook_m4/board.c index 40512b9416..ec1ba9f956 100644 --- a/ports/atmel-samd/boards/openbook_m4/board.c +++ b/ports/atmel-samd/boards/openbook_m4/board.c @@ -52,6 +52,10 @@ uint8_t stop_sequence[] = { 0x02, 0x80, 0xf0 // Power off }; +uint8_t refresh_sequence[] = { + 0x12, 0x00 +}; + void board_init(void) { busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL, false); @@ -74,6 +78,7 @@ void board_init(void) { bus, start_sequence, sizeof(start_sequence), + 0, // start up time stop_sequence, sizeof(stop_sequence), 300, // width @@ -92,22 +97,16 @@ void board_init(void) { NO_COMMAND, // write_color_ram_command (can add this for grayscale eventually) false, // color_bits_inverted 0x000000, // highlight_color - 0x12, // refresh_display_command + refresh_sequence, // refresh_display_sequence + sizeof(refresh_sequence), 40, // refresh_time &pin_PA01, // busy_pin false, // busy_state 5, // seconds_per_frame false, // chip_select (don't always toggle chip select) false, // grayscale + false, // acep false); // two_byte_sequence_length } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pewpew10/board.c b/ports/atmel-samd/boards/pewpew10/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/pewpew10/board.c +++ b/ports/atmel-samd/boards/pewpew10/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pewpew_lcd/board.c b/ports/atmel-samd/boards/pewpew_lcd/board.c index 7f5cac5241..f4060571bf 100644 --- a/ports/atmel-samd/boards/pewpew_lcd/board.c +++ b/ports/atmel-samd/boards/pewpew_lcd/board.c @@ -84,7 +84,6 @@ void board_init(void) { NULL, // &pin_PA17, // brightness pin NO_BRIGHTNESS_COMMAND, 0.0f, // brightness - false, // auto_brightness false, // single_byte_bounds true, // data as commands true, // auto_refresh @@ -94,12 +93,4 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pewpew_lcd/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew_lcd/mpconfigboard.mk index 2bf4992e25..94d0530ce2 100644 --- a/ports/atmel-samd/boards/pewpew_lcd/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pewpew_lcd/mpconfigboard.mk @@ -33,7 +33,7 @@ CIRCUITPY_BLEIO = 0 CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_MSGPACK = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_NVM = 0 diff --git a/ports/atmel-samd/boards/pewpew_m4/board.c b/ports/atmel-samd/boards/pewpew_m4/board.c index 331056fb9f..c36388f933 100644 --- a/ports/atmel-samd/boards/pewpew_m4/board.c +++ b/ports/atmel-samd/boards/pewpew_m4/board.c @@ -137,8 +137,7 @@ void board_init(void) { sizeof(display_init_sequence), NULL, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands false, // auto_refresh @@ -148,12 +147,4 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk index cffbaf619a..f7e7be88d5 100644 --- a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk @@ -11,6 +11,7 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 +CIRCUITPY_ANALOGIO = 0 CIRCUITPY_ALARM = 0 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOMP3 = 0 @@ -18,23 +19,27 @@ CIRCUITPY_AUDIOPWMIO = 0 CIRCUITPY_BITBANGIO = 0 CIRCUITPY_BITBANG_APA102 = 0 CIRCUITPY_FREQUENCYIO = 0 -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_ONEWIREIO = 0 CIRCUITPY_PARALLELDISPLAY = 0 CIRCUITPY_PIXELBUF = 0 CIRCUITPY_PS2IO = 0 CIRCUITPY_PULSEIO = 0 CIRCUITPY_PWMIO = 0 +CIRCUITPY_RAINBOWIO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 CIRCUITPY_SAMD = 0 CIRCUITPY_TOUCHIO = 0 -CIRCUITPY_USB_CDC = 0 CIRCUITPY_USB_HID = 0 CIRCUITPY_USB_MIDI = 0 CIRCUITPY_VECTORIO = 0 +CIRCUITPY_BUSDEVICE = 0 +CIRCUITPY_BITMAPTOOLS = 0 +CIRCUITPY_GIFIO = 0 +CIRCUITPY_WATCHDOG = 0 -CIRCUITPY_ANALOGIO = 1 CIRCUITPY_AUDIOIO = 1 CIRCUITPY_AUDIOMIXER = 1 CIRCUITPY_DISPLAYIO = 1 @@ -42,9 +47,20 @@ CIRCUITPY_KEYPAD = 1 CIRCUITPY_MATH = 1 CIRCUITPY_STAGE = 1 CIRCUITPY_SYNTHIO = 1 +CIRCUITPY_ZLIB = 1 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pewpew_m4 CIRCUITPY_DISPLAY_FONT = $(TOP)/ports/atmel-samd/boards/ugame10/brutalist-6.bdf # Override optimization to keep binary small OPTIMIZATION_FLAGS = -Os + +# We don't have room for the fonts for terminalio for certain languages, +# so turn off terminalio, and if it's off and displayio is on, +# force a clean build. +# Note that we cannot test $(CIRCUITPY_DISPLAYIO) directly with an +# ifeq, because it's not set yet. +ifneq (,$(filter $(TRANSLATION),ja ko ru)) +CIRCUITPY_TERMINALIO = 0 +RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO) +endif diff --git a/ports/atmel-samd/boards/picoplanet/board.c b/ports/atmel-samd/boards/picoplanet/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/picoplanet/board.c +++ b/ports/atmel-samd/boards/picoplanet/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index b7646cabe1..a1cb3a0714 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -33,8 +33,6 @@ #include "shared-module/displayio/mipi_constants.h" #include "supervisor/shared/board.h" -displayio_fourwire_obj_t board_display_obj; - #define DELAY 0x80 uint8_t display_init_sequence[] = { @@ -107,8 +105,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_PA01, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -118,13 +115,8 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { board_reset_user_neopixels(&pin_PA15, 5); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pycubed/board.c b/ports/atmel-samd/boards/pycubed/board.c index 41e4655102..f0e84103e2 100644 --- a/ports/atmel-samd/boards/pycubed/board.c +++ b/ports/atmel-samd/boards/pycubed/board.c @@ -36,12 +36,4 @@ void board_init(void) { common_hal_pwmio_pwmout_never_reset(&pwm); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pycubed_mram/board.c b/ports/atmel-samd/boards/pycubed_mram/board.c index 41e4655102..f0e84103e2 100644 --- a/ports/atmel-samd/boards/pycubed_mram/board.c +++ b/ports/atmel-samd/boards/pycubed_mram/board.c @@ -36,12 +36,4 @@ void board_init(void) { common_hal_pwmio_pwmout_never_reset(&pwm); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pycubed_mram_v05/board.c b/ports/atmel-samd/boards/pycubed_mram_v05/board.c index 41e4655102..f0e84103e2 100644 --- a/ports/atmel-samd/boards/pycubed_mram_v05/board.c +++ b/ports/atmel-samd/boards/pycubed_mram_v05/board.c @@ -36,12 +36,4 @@ void board_init(void) { common_hal_pwmio_pwmout_never_reset(&pwm); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pycubed_v05/board.c b/ports/atmel-samd/boards/pycubed_v05/board.c index 41e4655102..f0e84103e2 100644 --- a/ports/atmel-samd/boards/pycubed_v05/board.c +++ b/ports/atmel-samd/boards/pycubed_v05/board.c @@ -36,12 +36,4 @@ void board_init(void) { common_hal_pwmio_pwmout_never_reset(&pwm); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c index a9041de305..8ff34f24c5 100644 --- a/ports/atmel-samd/boards/pygamer/board.c +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -107,8 +107,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_PA01, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -118,13 +117,8 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { board_reset_user_neopixels(&pin_PA15, 5); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index 8176d363c9..e304f6f24b 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -94,8 +94,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_PB31, // Backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -105,12 +104,4 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pyportal_titano/board.c b/ports/atmel-samd/boards/pyportal_titano/board.c index fcf8c5f44d..939a2dcc70 100644 --- a/ports/atmel-samd/boards/pyportal_titano/board.c +++ b/ports/atmel-samd/boards/pyportal_titano/board.c @@ -111,8 +111,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_PB31, // Backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -122,12 +121,4 @@ void board_init(void) { 500); // backlight_pwm_frequency } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/pyruler/board.c b/ports/atmel-samd/boards/pyruler/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/pyruler/board.c +++ b/ports/atmel-samd/boards/pyruler/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/qtpy_m0/board.c b/ports/atmel-samd/boards/qtpy_m0/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/qtpy_m0/board.c +++ b/ports/atmel-samd/boards/qtpy_m0/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/qtpy_m0_haxpress/board.c b/ports/atmel-samd/boards/qtpy_m0_haxpress/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/qtpy_m0_haxpress/board.c +++ b/ports/atmel-samd/boards/qtpy_m0_haxpress/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/robohatmm1_m4/board.c b/ports/atmel-samd/boards/robohatmm1_m4/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/robohatmm1_m4/board.c +++ b/ports/atmel-samd/boards/robohatmm1_m4/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/sam32/board.c b/ports/atmel-samd/boards/sam32/board.c index c6d8c45b1f..106159ae4d 100644 --- a/ports/atmel-samd/boards/sam32/board.c +++ b/ports/atmel-samd/boards/sam32/board.c @@ -34,13 +34,6 @@ #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/neopixel_write/__init__.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { uint8_t zeroes[96]; memset(zeroes, 0, 96); @@ -51,5 +44,4 @@ void reset_board(void) { common_hal_digitalio_digitalinout_deinit(&neopixel); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/same54_xplained/board.c b/ports/atmel-samd/boards/same54_xplained/board.c index f72884ffe8..7180deb278 100644 --- a/ports/atmel-samd/boards/same54_xplained/board.c +++ b/ports/atmel-samd/boards/same54_xplained/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c b/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c index 4a25ed64ec..2eddb41fd6 100644 --- a/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c +++ b/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c @@ -102,8 +102,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_PC05, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -134,13 +133,6 @@ void board_init(void) { reset_pin_number(pin_PA18.number); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - void board_deinit(void) { common_hal_displayio_release_displays(); common_hal_digitalio_digitalinout_deinit(&CTR_5V); @@ -151,3 +143,5 @@ void board_deinit(void) { // Pin state is kept during BACKUP sleep. gpio_set_pin_direction(pin_PA18.number, GPIO_DIRECTION_OUT); } + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/seeeduino_xiao/board.c b/ports/atmel-samd/boards/seeeduino_xiao/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/seeeduino_xiao/board.c +++ b/ports/atmel-samd/boards/seeeduino_xiao/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/seeeduino_xiao_kb/board.c b/ports/atmel-samd/boards/seeeduino_xiao_kb/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/seeeduino_xiao_kb/board.c +++ b/ports/atmel-samd/boards/seeeduino_xiao_kb/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/seeeduino_xiao_kb/mpconfigboard.mk b/ports/atmel-samd/boards/seeeduino_xiao_kb/mpconfigboard.mk index 7a67048e0b..d0ff1fa05c 100644 --- a/ports/atmel-samd/boards/seeeduino_xiao_kb/mpconfigboard.mk +++ b/ports/atmel-samd/boards/seeeduino_xiao_kb/mpconfigboard.mk @@ -22,8 +22,8 @@ CIRCUITPY_RTC = 0 CIRCUITPY_MATH = 0 #CIRCUITPY_RANDOM = 0 CIRCUITPY_ONEWIREIO = 0 -#CIRCUITPY_NEOPIXEL_WRITE = 1 # Needed fo RGB LEDs -#CIRCUITPY_RAINBOWIO = 1 # Needed fo RGB LEDs +CIRCUITPY_NEOPIXEL_WRITE = 1 # Needed for RGB LEDs +CIRCUITPY_RAINBOWIO = 1 # Needed for RGB LEDs # These are used in a keyboard or computer input device. CIRCUITPY_ROTARYIO = 1 CIRCUITPY_KEYPAD = 1 diff --git a/ports/atmel-samd/boards/sensebox_mcu/board.c b/ports/atmel-samd/boards/sensebox_mcu/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/sensebox_mcu/board.c +++ b/ports/atmel-samd/boards/sensebox_mcu/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk index 0fc15cb321..37c869e972 100644 --- a/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk @@ -11,5 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 # There are many pin definitions on this board; it doesn't quite fit on very large translations. -CIRCUITPY_ONEWIREIO = 0 CIRCUITPY_USB_MIDI = 0 diff --git a/ports/atmel-samd/boards/serpente/board.c b/ports/atmel-samd/boards/serpente/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/serpente/board.c +++ b/ports/atmel-samd/boards/serpente/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/shirtty/board.c b/ports/atmel-samd/boards/shirtty/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/shirtty/board.c +++ b/ports/atmel-samd/boards/shirtty/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/silicognition-m4-shim/board.c b/ports/atmel-samd/boards/silicognition-m4-shim/board.c index 289d68af29..f888faa2af 100644 --- a/ports/atmel-samd/boards/silicognition-m4-shim/board.c +++ b/ports/atmel-samd/boards/silicognition-m4-shim/board.c @@ -25,17 +25,7 @@ */ #include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. + #include "mpconfigboard.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} diff --git a/ports/atmel-samd/boards/snekboard/board.c b/ports/atmel-samd/boards/snekboard/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/snekboard/board.c +++ b/ports/atmel-samd/boards/snekboard/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/board.c b/ports/atmel-samd/boards/sparkfun_lumidrive/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/sparkfun_lumidrive/board.c +++ b/ports/atmel-samd/boards/sparkfun_lumidrive/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/board.c b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/board.c +++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/board.c b/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/board.c +++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_with_flash/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/board.c b/ports/atmel-samd/boards/sparkfun_redboard_turbo/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/sparkfun_redboard_turbo/board.c +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk index 7b97822bda..ef23e56022 100755 --- a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk @@ -10,4 +10,4 @@ SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q32FV" LONGINT_IMPL = MPZ -CIRCUITPY_ONEWIREIO = 0 +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_dev/board.c b/ports/atmel-samd/boards/sparkfun_samd21_dev/board.c index e0a7487bd2..1bba99ac06 100644 --- a/ports/atmel-samd/boards/sparkfun_samd21_dev/board.c +++ b/ports/atmel-samd/boards/sparkfun_samd21_dev/board.c @@ -28,15 +28,4 @@ #include "mpconfigboard.h" #include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c b/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/sparkfun_samd51_micromod/board.c b/ports/atmel-samd/boards/sparkfun_samd51_micromod/board.c index 9e862b3c01..b079679d33 100644 --- a/ports/atmel-samd/boards/sparkfun_samd51_micromod/board.c +++ b/ports/atmel-samd/boards/sparkfun_samd51_micromod/board.c @@ -30,19 +30,6 @@ #include "hal/include/hal_gpio.h" #include "supervisor/shared/external_flash/external_flash.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} - void external_flash_setup(void) { // Do not reset the external flash write-protect and hold pins high never_reset_pin_number(PIN_PB22); @@ -59,3 +46,5 @@ void external_flash_setup(void) { gpio_set_pin_direction(PIN_PB23, GPIO_DIRECTION_OUT); gpio_set_pin_level(PIN_PB23, true); } + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/sparkfun_samd51_thing_plus/board.c b/ports/atmel-samd/boards/sparkfun_samd51_thing_plus/board.c index 289d68af29..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/sparkfun_samd51_thing_plus/board.c +++ b/ports/atmel-samd/boards/sparkfun_samd51_thing_plus/board.c @@ -25,17 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/stackrduino_m0_pro/board.c b/ports/atmel-samd/boards/stackrduino_m0_pro/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/stackrduino_m0_pro/board.c +++ b/ports/atmel-samd/boards/stackrduino_m0_pro/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk b/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk index d65be3f800..1088ca1e8d 100644 --- a/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk +++ b/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk @@ -9,5 +9,3 @@ CHIP_FAMILY = samd21 SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" LONGINT_IMPL = MPZ - -CIRCUITPY_ONEWIREIO = 0 diff --git a/ports/atmel-samd/boards/stringcar_m0_express/board.c b/ports/atmel-samd/boards/stringcar_m0_express/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/stringcar_m0_express/board.c +++ b/ports/atmel-samd/boards/stringcar_m0_express/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/trellis_m4_express/board.c b/ports/atmel-samd/boards/trellis_m4_express/board.c index 3f735e4550..e0455e9344 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/board.c +++ b/ports/atmel-samd/boards/trellis_m4_express/board.c @@ -33,13 +33,6 @@ #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/neopixel_write/__init__.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { uint8_t zeroes[96]; memset(zeroes, 0, 96); @@ -50,5 +43,4 @@ void reset_board(void) { common_hal_digitalio_digitalinout_deinit(&neopixel); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/trinket_m0/board.c b/ports/atmel-samd/boards/trinket_m0/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/trinket_m0/board.c +++ b/ports/atmel-samd/boards/trinket_m0/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/board.c b/ports/atmel-samd/boards/trinket_m0_haxpress/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/board.c +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/uartlogger2/board.c b/ports/atmel-samd/boards/uartlogger2/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/uartlogger2/board.c +++ b/ports/atmel-samd/boards/uartlogger2/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/uchip/board.c b/ports/atmel-samd/boards/uchip/board.c index e739776ed1..66469e12ce 100644 --- a/ports/atmel-samd/boards/uchip/board.c +++ b/ports/atmel-samd/boards/uchip/board.c @@ -42,12 +42,4 @@ void board_init(void) { never_reset_pin_number(PIN_PA27); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/uchip/mpconfigboard.mk b/ports/atmel-samd/boards/uchip/mpconfigboard.mk index 90b5600dcb..543007ce11 100644 --- a/ports/atmel-samd/boards/uchip/mpconfigboard.mk +++ b/ports/atmel-samd/boards/uchip/mpconfigboard.mk @@ -6,6 +6,8 @@ USB_MANUFACTURER = "Itaca Innovation" CHIP_VARIANT = SAMD21E18A CHIP_FAMILY = samd21 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index 53bc613088..90cf9dff20 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -105,7 +105,6 @@ void board_init(void) { NULL, NO_BRIGHTNESS_COMMAND, 1.0f, // brightness - false, // auto_brightness false, // single_byte_bounds false, // data as commands true, // auto_refresh @@ -115,12 +114,4 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk index f942490f29..d129429ad6 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk @@ -15,14 +15,14 @@ CIRCUITPY_MATH = 1 CIRCUITPY_AUDIOIO = 1 CIRCUITPY_ANALOGIO = 1 CIRCUITPY_DISPLAYIO = 1 -CIRCUITPY_KEYPPAD = 1 +CIRCUITPY_KEYPAD = 1 CIRCUITPY_PULSEIO = 0 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_BITBANGIO = 0 CIRCUITPY_BITMAPTOOLS = 0 CIRCUITPY_FREQUENCYIO = 0 -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_PARALLELDISPLAY = 0 CIRCUITPY_PIXELBUF = 0 diff --git a/ports/atmel-samd/boards/winterbloom_big_honking_button/board.c b/ports/atmel-samd/boards/winterbloom_big_honking_button/board.c index 9f91617a17..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/winterbloom_big_honking_button/board.c +++ b/ports/atmel-samd/boards/winterbloom_big_honking_button/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk b/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk index 5bf70a9668..00b9b64a33 100644 --- a/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk +++ b/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk @@ -23,7 +23,7 @@ CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_BLEIO = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_KEYPAD = 0 -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_PS2IO = 0 diff --git a/ports/atmel-samd/boards/winterbloom_sol/board.c b/ports/atmel-samd/boards/winterbloom_sol/board.c index 289d68af29..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/winterbloom_sol/board.c +++ b/ports/atmel-samd/boards/winterbloom_sol/board.c @@ -25,17 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk index 653d2e6ed5..17638a0ebd 100644 --- a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk +++ b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk @@ -22,7 +22,7 @@ CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_KEYPAD = 0 -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_PS2IO = 0 diff --git a/ports/atmel-samd/boards/xinabox_cc03/board.c b/ports/atmel-samd/boards/xinabox_cc03/board.c index e0a7487bd2..fb1ce4fb83 100644 --- a/ports/atmel-samd/boards/xinabox_cc03/board.c +++ b/ports/atmel-samd/boards/xinabox_cc03/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/xinabox_cs11/board.c b/ports/atmel-samd/boards/xinabox_cs11/board.c index e0a7487bd2..1bba99ac06 100644 --- a/ports/atmel-samd/boards/xinabox_cs11/board.c +++ b/ports/atmel-samd/boards/xinabox_cs11/board.c @@ -28,15 +28,4 @@ #include "mpconfigboard.h" #include "hal/include/hal_gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/common-hal/alarm/SleepMemory.h b/ports/atmel-samd/common-hal/alarm/SleepMemory.h index 5fad5946e2..14848cd5a0 100644 --- a/ports/atmel-samd/common-hal/alarm/SleepMemory.h +++ b/ports/atmel-samd/common-hal/alarm/SleepMemory.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_SLEEPMEMORY_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_SLEEPMEMORY_H +#pragma once #include "py/obj.h" @@ -34,5 +33,3 @@ typedef struct { } alarm_sleep_memory_obj_t; extern void alarm_sleep_memory_reset(void); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_SLEEPMEMORY_H diff --git a/ports/atmel-samd/common-hal/alarm/__init__.c b/ports/atmel-samd/common-hal/alarm/__init__.c index 405bf9d573..96d6d9694a 100644 --- a/ports/atmel-samd/common-hal/alarm/__init__.c +++ b/ports/atmel-samd/common-hal/alarm/__init__.c @@ -48,6 +48,10 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = { }, }; +// Non-heap alarm object recording alarm (if any) that woke up CircuitPython after light or deep sleep. +// This object lives across VM instantiations, so none of these objects can contain references to the heap. +alarm_wake_alarm_union_t alarm_wake_alarm; + void alarm_reset(void) { // Reset the alarm flag alarm_pin_pinalarm_reset(); @@ -57,7 +61,7 @@ void alarm_reset(void) { void alarm_get_wakeup_cause(void) { // Called from rtc_init, just before SWRST of RTC. It is called // at an early stage of main(), to save TAMPID from SWRST. Later, - // common_hal_alarm_create_wake_alarm is called to make a wakeup + // common_hal_alarm_record_wake_alarm is called to make a wakeup // alarm from the deep sleep. TAMPID = RTC->MODE0.TAMPID.reg; @@ -67,7 +71,7 @@ bool common_hal_alarm_woken_from_sleep(void) { return alarm_pin_pinalarm_woke_this_cycle() || alarm_time_timealarm_woke_this_cycle(); } -mp_obj_t common_hal_alarm_create_wake_alarm(void) { +mp_obj_t common_hal_alarm_record_wake_alarm(void) { // Called from main.c on the first start up, just before alarm_reset. // Return a copy of wakeup alarm from deep sleep / fake deep sleep. // In case of fake sleep, status should be left in TimeAlarm/PinAlarm. @@ -76,13 +80,13 @@ mp_obj_t common_hal_alarm_create_wake_alarm(void) { if (alarm_pin_pinalarm_woke_this_cycle()) { TAMPID = RTC->MODE0.TAMPID.reg; RTC->MODE0.TAMPID.reg = TAMPID; // clear register - return alarm_pin_pinalarm_create_wakeup_alarm(TAMPID); + return alarm_pin_pinalarm_record_wake_alarm(TAMPID); } if (alarm_time_timealarm_woke_this_cycle() || (true_deep && TAMPID == 0)) { - return alarm_time_timealarm_create_wakeup_alarm(); + return alarm_time_timealarm_record_wake_alarm(); } if (true_deep) { - return alarm_pin_pinalarm_create_wakeup_alarm(TAMPID); + return alarm_pin_pinalarm_record_wake_alarm(TAMPID); } return mp_const_none; } @@ -142,7 +146,10 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj return wake_alarm; } -void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { +void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t **preserve_dios) { + if (n_dios > 0) { + mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_preserve_dios); + } _setup_sleep_alarms(true, n_alarms, alarms); } diff --git a/ports/atmel-samd/common-hal/alarm/__init__.h b/ports/atmel-samd/common-hal/alarm/__init__.h index 061775e568..3094811c27 100644 --- a/ports/atmel-samd/common-hal/alarm/__init__.h +++ b/ports/atmel-samd/common-hal/alarm/__init__.h @@ -24,10 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM__INIT__H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM__INIT__H +#pragma once #include "common-hal/alarm/SleepMemory.h" +#include "common-hal/alarm/pin/PinAlarm.h" +#include "common-hal/alarm/time/TimeAlarm.h" extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; @@ -53,8 +54,13 @@ typedef enum { SAMD_WAKEUP_RTC } samd_sleep_source_t; -extern void alarm_set_wakeup_reason(samd_sleep_source_t reason); -void alarm_get_wakeup_cause(void); -extern void alarm_reset(void); +typedef union { + alarm_pin_pinalarm_obj_t pin_alarm; + alarm_time_timealarm_obj_t time_alarm; +} alarm_wake_alarm_union_t; -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM__INIT__H +extern alarm_wake_alarm_union_t alarm_wake_alarm; + +extern void alarm_set_wakeup_reason(samd_sleep_source_t reason); +extern void alarm_get_wakeup_cause(void); +extern void alarm_reset(void); diff --git a/ports/atmel-samd/common-hal/alarm/coproc/CoprocAlarm.c b/ports/atmel-samd/common-hal/alarm/coproc/CoprocAlarm.c new file mode 100644 index 0000000000..4bd8276f34 --- /dev/null +++ b/ports/atmel-samd/common-hal/alarm/coproc/CoprocAlarm.c @@ -0,0 +1 @@ +// empty file diff --git a/ports/atmel-samd/common-hal/alarm/coproc/CoprocAlarm.h b/ports/atmel-samd/common-hal/alarm/coproc/CoprocAlarm.h new file mode 100644 index 0000000000..4bd8276f34 --- /dev/null +++ b/ports/atmel-samd/common-hal/alarm/coproc/CoprocAlarm.h @@ -0,0 +1 @@ +// empty file diff --git a/ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c b/ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c index 9289a66a87..dd2509b8c4 100644 --- a/ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +++ b/ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c @@ -31,9 +31,9 @@ #include "hal/include/hal_gpio.h" // #include +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/microcontroller/Pin.h" #include "common-hal/alarm/__init__.h" // This variable stores whether a PinAlarm woke in light sleep or fake deep sleep @@ -128,12 +128,11 @@ mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t return mp_const_none; } -mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(uint32_t TAMPID) { - // Create tamper alarm that caused wakeup from deep sleep +mp_obj_t alarm_pin_pinalarm_record_wake_alarm(uint32_t TAMPID) { + alarm_pin_pinalarm_obj_t *const alarm = &alarm_wake_alarm.pin_alarm; for (samd_tamper_pin_t *t = TAMPER_PINS; t->n >= 0; t++) { if (TAMPID & (1 << t->n)) { - alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t); alarm->base.type = &alarm_pin_pinalarm_type; alarm->pin = t->pin; return alarm; diff --git a/ports/atmel-samd/common-hal/alarm/pin/PinAlarm.h b/ports/atmel-samd/common-hal/alarm/pin/PinAlarm.h index 57dc7d6c65..ee9ea07b71 100644 --- a/ports/atmel-samd/common-hal/alarm/pin/PinAlarm.h +++ b/ports/atmel-samd/common-hal/alarm/pin/PinAlarm.h @@ -24,12 +24,13 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_PINALARM_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_PINALARM_H +#pragma once #include "py/obj.h" #include "py/objtuple.h" +#include "shared-bindings/microcontroller/Pin.h" + typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *pin; @@ -39,7 +40,7 @@ typedef struct { } alarm_pin_pinalarm_obj_t; mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(uint32_t TAMPID); +mp_obj_t alarm_pin_pinalarm_record_wake_alarm(uint32_t TAMPID); void pin_alarm_callback(uint8_t num); void alarm_pin_pinalarm_reset(void); @@ -47,5 +48,3 @@ void alarm_pin_pinalarm_deinit_alarms(size_t n_alarms, const mp_obj_t *alarms); void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); void alarm_pin_pinalarm_prepare_for_deep_sleep(void); bool alarm_pin_pinalarm_woke_this_cycle(void); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_PINALARM_H diff --git a/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c b/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c index 3f116f07e3..2ead87428b 100644 --- a/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c +++ b/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c @@ -27,9 +27,9 @@ #include "py/runtime.h" #include "hpl/pm/hpl_pm_base.h" +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/time/__init__.h" -#include "common-hal/alarm/__init__.h" #include "supervisor/port.h" STATIC volatile bool woke_up = false; @@ -58,13 +58,14 @@ mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj return mp_const_none; } -mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) { - alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t); - timer->base.type = &alarm_time_timealarm_type; +mp_obj_t alarm_time_timealarm_record_wake_alarm(void) { + alarm_time_timealarm_obj_t *const alarm = &alarm_wake_alarm.time_alarm; + + alarm->base.type = &alarm_time_timealarm_type; // TODO: Set monotonic_time based on the RTC state. // Or don't, most of the other ports don't have this either. - timer->monotonic_time = 0.0f; - return timer; + alarm->monotonic_time = 0.0f; + return alarm; } void time_alarm_callback(void) { diff --git a/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.h b/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.h index a6102dee6b..ee517e0236 100644 --- a/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.h +++ b/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_TIMEALARM_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_TIMEALARM_H +#pragma once #include "py/obj.h" @@ -35,12 +34,10 @@ typedef struct { } alarm_time_timealarm_obj_t; mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void); +mp_obj_t alarm_time_timealarm_record_wake_alarm(void); void time_alarm_callback(void); bool alarm_time_timealarm_woke_this_cycle(void); void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); void alarm_time_timealarm_reset(void); void alarm_time_timealarm_prepare_for_deep_sleep(void); - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_TIMEALARM_H diff --git a/ports/atmel-samd/common-hal/alarm/touch/TouchAlarm.h b/ports/atmel-samd/common-hal/alarm/touch/TouchAlarm.h index d7f0f8cf1d..59f202c69d 100644 --- a/ports/atmel-samd/common-hal/alarm/touch/TouchAlarm.h +++ b/ports/atmel-samd/common-hal/alarm/touch/TouchAlarm.h @@ -24,12 +24,9 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_TOUCHALARM_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_TOUCHALARM_H +#pragma once typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *pin; } alarm_touch_touchalarm_obj_t; - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ALARM_TOUCHALARM_H diff --git a/ports/atmel-samd/common-hal/analogio/AnalogOut.c b/ports/atmel-samd/common-hal/analogio/AnalogOut.c index b4d556429c..ec690e8ddb 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogOut.c +++ b/ports/atmel-samd/common-hal/analogio/AnalogOut.c @@ -45,8 +45,8 @@ #endif #define HAVE_ANALOGOUT ( \ - (defined(PIN_PA02) && !defined(IGNORE_PA02)) || \ - (defined(SAM_D5X_E5X) && defined(PIN_PA05) && !defined(IGNORE_PA05)) \ + (defined(PIN_PA02) && !defined(IGNORE_PIN_PA02)) || \ + (defined(SAM_D5X_E5X) && defined(PIN_PA05) && !defined(IGNORE_PIN_PA05)) \ ) void common_hal_analogio_analogout_construct(analogio_analogout_obj_t *self, diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c index a565a77042..7007672b3f 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.c +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -405,7 +405,13 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t *self, if (self->right_channel == &pin_PA02) { right_channel_reg = (uint32_t)&DAC->DATABUF[0].reg; } - if (right_channel_reg == left_channel_reg + 2 && audiosample_bits_per_sample(sample) == 16) { + + size_t num_channels = audiosample_channel_count(sample); + + if (num_channels == 2 && + // Are DAC channels sequential? + left_channel_reg + 2 == right_channel_reg && + audiosample_bits_per_sample(sample) == 16) { result = audio_dma_setup_playback(&self->left_dma, sample, loop, false, 0, false /* output unsigned */, left_channel_reg, @@ -415,7 +421,11 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t *self, false /* output unsigned */, left_channel_reg, left_channel_trigger); - if (right_channel_reg != 0 && result == AUDIO_DMA_OK) { + // Don't play back on right channel unless stereo. + // TODO possibility: Set up non-incrementing DMA on one channel so they use the same samples? + // Right now, playing back mono on both channels causes sample to play twice as fast. + if (num_channels == 2 && + right_channel_reg != 0 && result == AUDIO_DMA_OK) { result = audio_dma_setup_playback(&self->right_dma, sample, loop, true, 1, false /* output unsigned */, right_channel_reg, diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c index 2ca193c99f..902e696408 100644 --- a/ports/atmel-samd/common-hal/busio/I2C.c +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -123,10 +123,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, // The maximum frequency divisor gives a clock rate of around 48MHz/2/255 // but set_baudrate does not diagnose this problem. (This is not the // exact cutoff, but no frequency well under 100kHz is available) - if (frequency < 95000 && - i2c_m_sync_set_baudrate(&self->i2c_desc, 0, frequency / 1000) != ERR_NONE) { - reset_pin_number(sda->number); - reset_pin_number(scl->number); + if ((frequency < 95000) || + (i2c_m_sync_set_baudrate(&self->i2c_desc, 0, frequency / 1000) != ERR_NONE)) { common_hal_busio_i2c_deinit(self); mp_arg_error_invalid(MP_QSTR_frequency); } diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 3bb0cabf9e..02776928ca 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -268,7 +268,21 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self, } int32_t status; if (len >= 16) { - status = sercom_dma_write(self->spi_desc.dev.prvt, data, len); + size_t bytes_remaining = len; + + // Maximum DMA transfer is 65535 + while (1) { + size_t to_send = (bytes_remaining > 65535) ? 65535 : bytes_remaining; + status = sercom_dma_write(self->spi_desc.dev.prvt, data + (len - bytes_remaining), to_send); + bytes_remaining -= to_send; + if (bytes_remaining > 0) { + // Multi-part transfer; let other things run before doing the next chunk. + RUN_BACKGROUND_TASKS; + } else { + // All done. + break; + } + } } else { struct io_descriptor *spi_io; spi_m_sync_get_io_descriptor(&self->spi_desc, &spi_io); diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c index 3a9b628e0b..280e8d10b6 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#if CIRCUITPY_BUSIO_UART #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/busio/UART.h" @@ -57,6 +58,8 @@ static void usart_async_rxc_callback(const struct usart_async_descriptor *const // Nothing needs to be done by us. } +// shared-bindings validates that the tx and rx are not both missing, +// and that the pins are distinct. void common_hal_busio_uart_construct(busio_uart_obj_t *self, const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, @@ -91,10 +94,6 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, bool have_rts = rts != NULL; bool have_cts = cts != NULL; - if (!have_tx && !have_rx) { - mp_raise_ValueError(translate("tx and rx cannot both be None")); - } - if (have_rx && receiver_buffer_size > 0 && (receiver_buffer_size & (receiver_buffer_size - 1)) != 0) { mp_raise_ValueError_varg(translate("%q must be power of 2"), MP_QSTR_receiver_buffer_size); } @@ -106,6 +105,20 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // This assignment is only here because the usart_async routines take a *const argument. struct usart_async_descriptor *const usart_desc_p = (struct usart_async_descriptor *const)&self->usart_desc; + // Allowed pads for USART. See the SAMD21 and SAMx5x datasheets. + // TXPO: + // (both) 0x0: TX pad 0; no RTS/CTS + // (SAMD21) 0x1: TX pad 2; no RTS/CTS + // (SAMx5x) 0x1: reserved + // (both) 0x2: TX pad 0; RTS: pad 2, CTS: pad 3 + // (SAMD21) 0x3: reserved + // (SAMx5x) 0x3: TX pad 0; RTS: pad 2; no CTS + // RXPO: + // 0x0: RX pad 0 + // 0x1: RX pad 1 + // 0x2: RX pad 2 + // 0x3: RX pad 3 + for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { Sercom *potential_sercom = NULL; if (have_tx) { @@ -114,29 +127,71 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, continue; } potential_sercom = sercom_insts[sercom_index]; + + // SAMD21 and SAMx5x have different requirements. + #ifdef SAMD21 - if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 || - !(tx->sercom[i].pad == 0 || - tx->sercom[i].pad == 2)) { + if (potential_sercom->USART.CTRLA.bit.ENABLE != 0) { + // In use. continue; } + if (tx->sercom[i].pad != 0 && + tx->sercom[i].pad != 2) { + // TX must be on pad 0 or 2. + continue; + } + if (have_rts) { + if (rts->sercom[i].pad != 2 || + tx->sercom[i].pad == 2) { + // RTS pin must be on pad 2, so if TX is also on pad 2, not possible + continue; + } + } + if (have_cts) { + if (cts->sercom[i].pad != 3 || + (have_rx && rx->sercom[i].pad == 3)) { + // CTS pin must be on pad 3, so if RX is also on pad 3, not possible + continue; + } + } #endif + #ifdef SAM_D5X_E5X - if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 || - !(tx->sercom[i].pad == 0)) { + if (potential_sercom->USART.CTRLA.bit.ENABLE != 0) { + // In use. continue; } + if (tx->sercom[i].pad != 0) { + // TX must be on pad 0 + continue; + } + + if (have_rts && rts->sercom[i].pad != 2) { + // RTS pin must be on pad 2 + continue; + } + if (have_cts) { + if (cts->sercom[i].pad != 3 || + (have_rx && rx->sercom[i].pad == 3)) { + // CTS pin must be on pad 3, so if RX is also on pad 3, not possible + continue; + } + } #endif + tx_pinmux = PINMUX(tx->number, (i == 0) ? MUX_C : MUX_D); tx_pad = tx->sercom[i].pad; if (have_rts) { rts_pinmux = PINMUX(rts->number, (i == 0) ? MUX_C : MUX_D); } - if (rx == NULL) { + if (!have_rx) { + // TX only, so don't need to look further. sercom = potential_sercom; break; } } + + // Have TX, now look for RX match. We know have_rx is true at this point. for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { if (((!have_tx && rx->sercom[j].index < SERCOM_INST_NUM && sercom_insts[rx->sercom[j].index]->USART.CTRLA.bit.ENABLE == 0) || @@ -159,20 +214,10 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (sercom == NULL) { raise_ValueError_invalid_pins(); } - if (!have_tx) { - tx_pad = 0; - if (rx_pad == 0) { - tx_pad = 2; - } - } - if (!have_rx) { - rx_pad = (tx_pad + 1) % 4; - } - // Set up clocks on SERCOM. samd_peripherals_sercom_clock_init(sercom, sercom_index); - if (rx && receiver_buffer_size > 0) { + if (have_rx && receiver_buffer_size > 0) { self->buffer_length = receiver_buffer_size; if (NULL != receiver_buffer) { self->buffer = receiver_buffer; @@ -203,36 +248,41 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // which don't necessarily match what we need. After calling it, set the values // specific to this instantiation of UART. - // Set pads computed for this SERCOM. Refer to the datasheet for details on pads. - // TXPO: - // 0x0: TX pad 0; no RTS/CTS - // 0x1: reserved - // 0x2: TX pad 0; RTS: pad 2, CTS: pad 3 - // 0x3: TX pad 0; RTS: pad 2; no CTS - // RXPO: - // 0x0: RX pad 0 - // 0x1: RX pad 1 - // 0x2: RX pad 2 - // 0x3: RX pad 3 + // See the TXPO/RXPO table above for how RXPO and TXPO are chosen below. - // Default to TXPO with no RTS/CTS - uint8_t computed_txpo = 0; - // If we have both CTS (with or without RTS), use second pinout - if (have_cts) { - computed_txpo = 2; - } - // If we have RTS only, use the third pinout - if (have_rts && !have_cts) { - computed_txpo = 3; + // rxpo maps directly to rx_pad. + // Set to 0x0 if no RX, but it doesn't matter because RX will not be enabled. + const uint8_t rxpo = have_rx ? rx_pad : 0x0; + + #ifdef SAMD21 + // SAMD21 has only one txpo value when using either CTS or RTS or both. + // TX is on pad 0 or 2, or there is no TX. + // 0x0 for pad 0, 0x1 for pad 2. + uint8_t txpo; + if (tx_pad == 2) { + txpo = 0x1; + } else { + txpo = (have_cts || have_rts) ? 0x2 : 0x0; } + #endif + + #ifdef SAM_D5X_E5X + // SAMx5x has two different possibilities, per the chart above. + // We already know TX is on pad 0, or there is no TX. + + // Without RTS or CTS, txpo can be 0x0. + // It's not clear if 0x2 would cover all our cases, but this is known to be safe. + uint8_t txpo = (have_rts || have_cts) ? 0x2: 0x0; + #endif // Doing a group mask and set of the registers saves 60 bytes over setting the bitfields individually. sercom->USART.CTRLA.reg &= ~(SERCOM_USART_CTRLA_TXPO_Msk | SERCOM_USART_CTRLA_RXPO_Msk | SERCOM_USART_CTRLA_FORM_Msk); - sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(computed_txpo) | - SERCOM_USART_CTRLA_RXPO(rx_pad) | + // See chart above for TXPO values and RXPO values. + sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(txpo) | + SERCOM_USART_CTRLA_RXPO(rxpo) | (parity == BUSIO_UART_PARITY_NONE ? 0 : SERCOM_USART_CTRLA_FORM(1)); // Enable tx and/or rx based on whether the pins were specified. @@ -485,3 +535,4 @@ bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { usart_async_get_status(usart_desc_p, &async_status); return !(async_status.flags & USART_ASYNC_STATUS_BUSY); } +#endif diff --git a/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c b/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c index 8358ac4d87..dc770a2de3 100644 --- a/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +++ b/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c @@ -66,11 +66,12 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self self->pin = NULL; } -void common_hal_digitalio_digitalinout_switch_to_input( +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { self->output = false; // This also sets direction to input. common_hal_digitalio_digitalinout_set_pull(self, pull); + return DIGITALINOUT_OK; } digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( @@ -151,7 +152,7 @@ digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( } } -void common_hal_digitalio_digitalinout_set_pull( +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { enum gpio_pull_mode asf_pull = GPIO_PULL_OFF; switch (pull) { @@ -168,6 +169,7 @@ void common_hal_digitalio_digitalinout_set_pull( // Must set pull after setting direction. gpio_set_pin_direction(self->pin->number, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(self->pin->number, asf_pull); + return DIGITALINOUT_OK; } digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( diff --git a/ports/atmel-samd/common-hal/i2cperipheral/__init__.c b/ports/atmel-samd/common-hal/i2cperipheral/__init__.c deleted file mode 100644 index c67511c536..0000000000 --- a/ports/atmel-samd/common-hal/i2cperipheral/__init__.c +++ /dev/null @@ -1 +0,0 @@ -// No i2cperipheral module functions. diff --git a/ports/atmel-samd/common-hal/i2cperipheral/I2CPeripheral.c b/ports/atmel-samd/common-hal/i2ctarget/I2CTarget.c similarity index 83% rename from ports/atmel-samd/common-hal/i2cperipheral/I2CPeripheral.c rename to ports/atmel-samd/common-hal/i2ctarget/I2CTarget.c index ae118c1909..a687143281 100644 --- a/ports/atmel-samd/common-hal/i2cperipheral/I2CPeripheral.c +++ b/ports/atmel-samd/common-hal/i2ctarget/I2CTarget.c @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#include "shared-bindings/i2cperipheral/I2CPeripheral.h" +#include "shared-bindings/i2ctarget/I2CTarget.h" #include "shared-bindings/microcontroller/Pin.h" #include "common-hal/busio/I2C.h" @@ -36,7 +36,7 @@ #include "hal/include/hal_gpio.h" #include "peripherals/samd/sercom.h" -void common_hal_i2cperipheral_i2c_peripheral_construct(i2cperipheral_i2c_peripheral_obj_t *self, +void common_hal_i2ctarget_i2c_target_construct(i2ctarget_i2c_target_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint8_t *addresses, unsigned int num_addresses, bool smbus) { uint8_t sercom_index; @@ -100,12 +100,12 @@ void common_hal_i2cperipheral_i2c_peripheral_construct(i2cperipheral_i2c_periphe sercom->I2CS.CTRLA.bit.ENABLE = 1; } -bool common_hal_i2cperipheral_i2c_peripheral_deinited(i2cperipheral_i2c_peripheral_obj_t *self) { +bool common_hal_i2ctarget_i2c_target_deinited(i2ctarget_i2c_target_obj_t *self) { return self->sda_pin == NO_PIN; } -void common_hal_i2cperipheral_i2c_peripheral_deinit(i2cperipheral_i2c_peripheral_obj_t *self) { - if (common_hal_i2cperipheral_i2c_peripheral_deinited(self)) { +void common_hal_i2ctarget_i2c_target_deinit(i2ctarget_i2c_target_obj_t *self) { + if (common_hal_i2ctarget_i2c_target_deinited(self)) { return; } @@ -117,7 +117,7 @@ void common_hal_i2cperipheral_i2c_peripheral_deinit(i2cperipheral_i2c_peripheral self->scl_pin = NO_PIN; } -static int i2c_peripheral_check_error(i2cperipheral_i2c_peripheral_obj_t *self, bool raise) { +static int i2c_target_check_error(i2ctarget_i2c_target_obj_t *self, bool raise) { if (!self->sercom->I2CS.INTFLAG.bit.ERROR) { return 0; } @@ -136,8 +136,8 @@ static int i2c_peripheral_check_error(i2cperipheral_i2c_peripheral_obj_t *self, return -err; } -int common_hal_i2cperipheral_i2c_peripheral_is_addressed(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart) { - int err = i2c_peripheral_check_error(self, false); +int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart) { + int err = i2c_target_check_error(self, false); if (err) { return err; } @@ -154,22 +154,22 @@ int common_hal_i2cperipheral_i2c_peripheral_is_addressed(i2cperipheral_i2c_perip for (unsigned int i = 0; i < self->num_addresses; i++) { if (*address == self->addresses[i]) { - common_hal_i2cperipheral_i2c_peripheral_ack(self, true); + common_hal_i2ctarget_i2c_target_ack(self, true); return 1; } } // This should clear AMATCH, but it doesn't... - common_hal_i2cperipheral_i2c_peripheral_ack(self, false); + common_hal_i2ctarget_i2c_target_ack(self, false); return 0; } -int common_hal_i2cperipheral_i2c_peripheral_read_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t *data) { +int common_hal_i2ctarget_i2c_target_read_byte(i2ctarget_i2c_target_obj_t *self, uint8_t *data) { for (int t = 0; t < 100 && !self->sercom->I2CS.INTFLAG.reg; t++) { mp_hal_delay_us(10); } - i2c_peripheral_check_error(self, true); + i2c_target_check_error(self, true); if (!self->sercom->I2CS.INTFLAG.bit.DRDY || self->sercom->I2CS.INTFLAG.bit.PREC || @@ -181,12 +181,12 @@ int common_hal_i2cperipheral_i2c_peripheral_read_byte(i2cperipheral_i2c_peripher return 1; } -int common_hal_i2cperipheral_i2c_peripheral_write_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t data) { +int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self, uint8_t data) { for (int t = 0; !self->sercom->I2CS.INTFLAG.reg && t < 100; t++) { mp_hal_delay_us(10); } - i2c_peripheral_check_error(self, true); + i2c_target_check_error(self, true); if (self->sercom->I2CS.INTFLAG.bit.PREC) { return 0; @@ -208,12 +208,12 @@ int common_hal_i2cperipheral_i2c_peripheral_write_byte(i2cperipheral_i2c_periphe return 1; } -void common_hal_i2cperipheral_i2c_peripheral_ack(i2cperipheral_i2c_peripheral_obj_t *self, bool ack) { +void common_hal_i2ctarget_i2c_target_ack(i2ctarget_i2c_target_obj_t *self, bool ack) { self->sercom->I2CS.CTRLB.bit.ACKACT = !ack; self->sercom->I2CS.CTRLB.bit.CMD = 0x03; } -void common_hal_i2cperipheral_i2c_peripheral_close(i2cperipheral_i2c_peripheral_obj_t *self) { +void common_hal_i2ctarget_i2c_target_close(i2ctarget_i2c_target_obj_t *self) { for (int t = 0; !self->sercom->I2CS.INTFLAG.reg && t < 100; t++) { mp_hal_delay_us(10); } @@ -223,7 +223,7 @@ void common_hal_i2cperipheral_i2c_peripheral_close(i2cperipheral_i2c_peripheral_ } if (!self->sercom->I2CS.STATUS.bit.DIR) { - common_hal_i2cperipheral_i2c_peripheral_ack(self, false); + common_hal_i2ctarget_i2c_target_ack(self, false); } else { int i = 0; while (self->sercom->I2CS.INTFLAG.reg == SERCOM_I2CS_INTFLAG_DRDY) { diff --git a/ports/atmel-samd/common-hal/i2cperipheral/I2CPeripheral.h b/ports/atmel-samd/common-hal/i2ctarget/I2CTarget.h similarity index 85% rename from ports/atmel-samd/common-hal/i2cperipheral/I2CPeripheral.h rename to ports/atmel-samd/common-hal/i2ctarget/I2CTarget.h index 03ae3a2885..894961ab7b 100644 --- a/ports/atmel-samd/common-hal/i2cperipheral/I2CPeripheral.h +++ b/ports/atmel-samd/common-hal/i2ctarget/I2CTarget.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_TARGET_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_TARGET_H #include "common-hal/microcontroller/Pin.h" #include "py/obj.h" @@ -40,6 +40,6 @@ typedef struct { uint8_t scl_pin; uint8_t sda_pin; bool writing; -} i2cperipheral_i2c_peripheral_obj_t; +} i2ctarget_i2c_target_obj_t; -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_TARGET_H diff --git a/ports/atmel-samd/common-hal/i2ctarget/__init__.c b/ports/atmel-samd/common-hal/i2ctarget/__init__.c new file mode 100644 index 0000000000..4ec26465ad --- /dev/null +++ b/ports/atmel-samd/common-hal/i2ctarget/__init__.c @@ -0,0 +1 @@ +// No i2ctarget module functions. diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index b36286e5f2..d70de33618 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -211,5 +211,5 @@ mcu_pin_function_t *mcu_find_pin_function(mcu_pin_function_t *table, const mcu_p return table; } } - mp_raise_ValueError_varg(translate("%q pin invalid"), name); + mp_raise_ValueError_varg(translate("Invalid %q pin"), name); } diff --git a/ports/atmel-samd/common-hal/microcontroller/Processor.c b/ports/atmel-samd/common-hal/microcontroller/Processor.c index 29d6612ad8..d720399b98 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Processor.c +++ b/ports/atmel-samd/common-hal/microcontroller/Processor.c @@ -73,46 +73,37 @@ #include "peripheral_clk_config.h" #define ADC_TEMP_SAMPLE_LENGTH 4 -#define INT1V_VALUE_FLOAT 1.0 -#define INT1V_DIVIDER_1000 1000.0 -#define ADC_12BIT_FULL_SCALE_VALUE_FLOAT 4095.0 +#define INT1V_VALUE_FLOAT MICROPY_FLOAT_CONST(1.0) +#define INT1V_DIVIDER_1000 MICROPY_FLOAT_CONST(1000.0) +#define ADC_12BIT_FULL_SCALE_VALUE_FLOAT MICROPY_FLOAT_CONST(4095.0) // channel argument (ignored in calls below) #define IGNORED_CHANNEL 0 -// Decimal to fraction conversion. (adapted from ASF sample). -STATIC float convert_dec_to_frac(uint8_t val) { - float float_val = (float)val; - if (val < 10) { - return float_val / 10.0; - } else if (val < 100) { - return float_val / 100.0; - } else { - return float_val / 1000.0; - } -} // Extract the production calibration data information from NVM (adapted from ASF sample), // then calculate the temperature +// +// This code performs almost all operations with scaled integers. For +// instance, tempR is in units of 1/10°C, INT1VR is in units of 1mV, etc, +// This is important to reduce the code size of the function. The effect on +// precision is a ~.9°C difference vs the floating point algorithm on an +// approximate 0..60°C range with a difference of ~.5°C at 25°C. When the fine +// calculation step is skipped, the additional error approximately doubles. +// +// To save code size, rounding is neglected. However, trying to add back rounding +// (by computing (a + b/2) / b instead of just a / b) actually didn't help +// accuracy anyway. #ifdef SAMD21 STATIC float calculate_temperature(uint16_t raw_value) { - volatile uint32_t val1; /* Temperature Log Row Content first 32 bits */ - volatile uint32_t val2; /* Temperature Log Row Content another 32 bits */ - uint8_t room_temp_val_int; /* Integer part of room temperature in °C */ - uint8_t room_temp_val_dec; /* Decimal part of room temperature in °C */ - uint8_t hot_temp_val_int; /* Integer part of hot temperature in °C */ - uint8_t hot_temp_val_dec; /* Decimal part of hot temperature in °C */ - int8_t room_int1v_val; /* internal 1V reference drift at room temperature */ - int8_t hot_int1v_val; /* internal 1V reference drift at hot temperature*/ - - float tempR; // Production Room temperature - float tempH; // Production Hot temperature - float INT1VR; // Room temp 2's complement of the internal 1V reference value - float INT1VH; // Hot temp 2's complement of the internal 1V reference value - uint16_t ADCR; // Production Room temperature ADC value - uint16_t ADCH; // Production Hot temperature ADC value - float VADCR; // Room temperature ADC voltage - float VADCH; // Hot temperature ADC voltage + uint32_t val1; /* Temperature Log Row Content first 32 bits */ + uint32_t val2; /* Temperature Log Row Content another 32 bits */ + int room_temp_val_int; /* Integer part of room temperature in °C */ + int room_temp_val_dec; /* Decimal part of room temperature in °C */ + int hot_temp_val_int; /* Integer part of hot temperature in °C */ + int hot_temp_val_dec; /* Decimal part of hot temperature in °C */ + int room_int1v_val; /* internal 1V reference drift at room temperature */ + int hot_int1v_val; /* internal 1V reference drift at hot temperature*/ uint32_t *temp_log_row_ptr = (uint32_t *)NVMCTRL_TEMP_LOG; @@ -120,32 +111,29 @@ STATIC float calculate_temperature(uint16_t raw_value) { temp_log_row_ptr++; val2 = *temp_log_row_ptr; - room_temp_val_int = (uint8_t)((val1 & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos); - room_temp_val_dec = (uint8_t)((val1 & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos); + room_temp_val_int = ((val1 & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos); + room_temp_val_dec = ((val1 & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos); - hot_temp_val_int = (uint8_t)((val1 & FUSES_HOT_TEMP_VAL_INT_Msk) >> FUSES_HOT_TEMP_VAL_INT_Pos); - hot_temp_val_dec = (uint8_t)((val1 & FUSES_HOT_TEMP_VAL_DEC_Msk) >> FUSES_HOT_TEMP_VAL_DEC_Pos); + hot_temp_val_int = ((val1 & FUSES_HOT_TEMP_VAL_INT_Msk) >> FUSES_HOT_TEMP_VAL_INT_Pos); + hot_temp_val_dec = ((val1 & FUSES_HOT_TEMP_VAL_DEC_Msk) >> FUSES_HOT_TEMP_VAL_DEC_Pos); + // necessary casts: must interpret 8 bits as signed room_int1v_val = (int8_t)((val1 & FUSES_ROOM_INT1V_VAL_Msk) >> FUSES_ROOM_INT1V_VAL_Pos); hot_int1v_val = (int8_t)((val2 & FUSES_HOT_INT1V_VAL_Msk) >> FUSES_HOT_INT1V_VAL_Pos); - ADCR = (uint16_t)((val2 & FUSES_ROOM_ADC_VAL_Msk) >> FUSES_ROOM_ADC_VAL_Pos); - ADCH = (uint16_t)((val2 & FUSES_HOT_ADC_VAL_Msk) >> FUSES_HOT_ADC_VAL_Pos); + int ADCR = ((val2 & FUSES_ROOM_ADC_VAL_Msk) >> FUSES_ROOM_ADC_VAL_Pos); + int ADCH = ((val2 & FUSES_HOT_ADC_VAL_Msk) >> FUSES_HOT_ADC_VAL_Pos); - tempR = room_temp_val_int + convert_dec_to_frac(room_temp_val_dec); - tempH = hot_temp_val_int + convert_dec_to_frac(hot_temp_val_dec); + int tempR = 10 * room_temp_val_int + room_temp_val_dec; + int tempH = 10 * hot_temp_val_int + hot_temp_val_dec; - INT1VR = 1 - ((float)room_int1v_val / INT1V_DIVIDER_1000); - INT1VH = 1 - ((float)hot_int1v_val / INT1V_DIVIDER_1000); + int INT1VR = 1000 - room_int1v_val; + int INT1VH = 1000 - hot_int1v_val; - VADCR = ((float)ADCR * INT1VR) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT; - VADCH = ((float)ADCH * INT1VH) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT; + int VADCR = ADCR * INT1VR; + int VADCH = ADCH * INT1VH; - float VADC; /* Voltage calculation using ADC result for Coarse Temp calculation */ - float VADCM; /* Voltage calculation using ADC result for Fine Temp calculation. */ - float INT1VM; /* Voltage calculation for reality INT1V value during the ADC conversion */ - - VADC = ((float)raw_value * INT1V_VALUE_FLOAT) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT; + int VADC = raw_value * 1000; // Hopefully compiler will remove common subepxressions here. @@ -153,21 +141,31 @@ STATIC float calculate_temperature(uint16_t raw_value) { // 1b as mentioned in data sheet section "Temperature Sensor Characteristics" // of Electrical Characteristics. (adapted from ASF sample code). // Coarse Temp Calculation by assume INT1V=1V for this ADC conversion - float coarse_temp = tempR + (((tempH - tempR) / (VADCH - VADCR)) * (VADC - VADCR)); + int coarse_temp = tempR + (tempH - tempR) * (VADC - VADCR) / (VADCH - VADCR); + #if CIRCUITPY_FULL_BUILD // Calculation to find the real INT1V value during the ADC conversion + int INT1VM; /* Voltage calculation for reality INT1V value during the ADC conversion */ + INT1VM = INT1VR + (((INT1VH - INT1VR) * (coarse_temp - tempR)) / (tempH - tempR)); - VADCM = ((float)raw_value * INT1VM) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT; + int VADCM = raw_value * INT1VM; // Fine Temp Calculation by replace INT1V=1V by INT1V = INT1Vm for ADC conversion - float fine_temp = tempR + (((tempH - tempR) / (VADCH - VADCR)) * (VADCM - VADCR)); + float fine_temp = tempR + (((tempH - tempR) * (VADCM - VADCR)) / (VADCH - VADCR)); - return fine_temp; + return fine_temp / 10; + #else + return coarse_temp / 10.; + #endif } #endif // SAMD21 #ifdef SAM_D5X_E5X +// Decimal to fraction conversion. (adapted from ASF sample). +STATIC float convert_dec_to_frac(uint8_t val) { + return val / MICROPY_FLOAT_CONST(10.); +} STATIC float calculate_temperature(uint16_t TP, uint16_t TC) { uint32_t TLI = (*(uint32_t *)FUSES_ROOM_TEMP_VAL_INT_ADDR & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos; uint32_t TLD = (*(uint32_t *)FUSES_ROOM_TEMP_VAL_DEC_ADDR & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos; diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index 60b35a2c5c..d1c02b360f 100644 --- a/ports/atmel-samd/common-hal/microcontroller/__init__.c +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -51,9 +51,8 @@ void common_hal_mcu_disable_interrupts(void) { void common_hal_mcu_enable_interrupts(void) { if (nesting_count == 0) { - // This is very very bad because it means there was mismatched disable/enables so we - // "HardFault". - HardFault_Handler(); + // This is very very bad because it means there was mismatched disable/enables. + reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); } nesting_count--; if (nesting_count > 0) { @@ -76,7 +75,7 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { _bootloader_dbl_tap = DBL_TAP_MAGIC_QUICK_BOOT; } if (runmode == RUNMODE_SAFE_MODE) { - safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE); + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); } } diff --git a/ports/atmel-samd/common-hal/pwmio/PWMOut.c b/ports/atmel-samd/common-hal/pwmio/PWMOut.c index c6e9e07304..1bb955fce8 100644 --- a/ports/atmel-samd/common-hal/pwmio/PWMOut.c +++ b/ports/atmel-samd/common-hal/pwmio/PWMOut.c @@ -67,10 +67,6 @@ void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { never_reset_pin_number(self->pin->number); } -void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { - timer_reset_ok(self->timer->index, self->timer->is_tc); -} - void pwmout_reset(void) { // Reset all timers for (int i = 0; i < TCC_INST_NUM; i++) { @@ -267,6 +263,7 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { if (common_hal_pwmio_pwmout_deinited(self)) { return; } + timer_reset_ok(self->timer->index, self->timer->is_tc); const pin_timer_t *t = self->timer; if (t->is_tc) { Tc *tc = tc_insts[t->index]; diff --git a/ports/atmel-samd/common-hal/sdioio/SDCard.c b/ports/atmel-samd/common-hal/sdioio/SDCard.c index 7ce8a1e1b1..e641db75ac 100644 --- a/ports/atmel-samd/common-hal/sdioio/SDCard.c +++ b/ports/atmel-samd/common-hal/sdioio/SDCard.c @@ -114,8 +114,6 @@ CLK PA21 PCC_D? (D32) BROWN gpio_set_pin_pull_mode(functions[i]->pin, (i == 1 || i == 5) ? GPIO_PULL_OFF : GPIO_PULL_UP); gpio_set_pin_function(functions[i]->pin, GPIO_PIN_FUNCTION_SDIO); - - common_hal_never_reset_pin(functions[i]->obj); } self->num_data = num_data; @@ -145,6 +143,12 @@ CLK PA21 PCC_D? (D32) BROWN } if (result != SD_MMC_OK) { + for (size_t i = 0; i < MP_ARRAY_SIZE(functions); i++) { + if (!functions[i]->obj) { + break; + } + reset_pin_number(functions[i]->obj->number); + } mp_raise_OSError_msg_varg(translate("%q failure: %d"), MP_QSTR_sd_mmc_check, (int)result); } // sd_mmc_get_capacity() is in KiB, but our "capacity" is in 512-byte blocks diff --git a/ports/atmel-samd/libs/libgcc-12.1.0-Os-v6-m-nofp.a b/ports/atmel-samd/libs/libgcc-12.1.0-Os-v6-m-nofp.a new file mode 100644 index 0000000000..56692d5d05 Binary files /dev/null and b/ports/atmel-samd/libs/libgcc-12.1.0-Os-v6-m-nofp.a differ diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index 3ea6c44049..d4d1ff31a3 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -24,13 +24,13 @@ ifeq ($(CHIP_FAMILY),samd21) CIRCUITPY_AESIO ?= 0 CIRCUITPY_ATEXIT ?= 0 CIRCUITPY_AUDIOMIXER ?= 0 +CIRCUITPY_AUDIOMP3 ?= 0 CIRCUITPY_BINASCII ?= 0 CIRCUITPY_BITBANGIO ?= 0 CIRCUITPY_BITMAPTOOLS ?= 0 -CIRCUITPY_BUSDEVICE ?= 0 -CIRCUITPY_AUDIOMP3 ?= 0 CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_BUILTINS_POW3 ?= 0 +CIRCUITPY_BUSDEVICE ?= 0 CIRCUITPY_COMPUTED_GOTO_SAVE_SPACE ?= 1 CIRCUITPY_COUNTIO ?= 0 # Not enough RAM for framebuffers @@ -38,10 +38,12 @@ CIRCUITPY_FRAMEBUFFERIO ?= 0 CIRCUITPY_FREQUENCYIO ?= 0 CIRCUITPY_GETPASS ?= 0 CIRCUITPY_GIFIO ?= 0 -CIRCUITPY_I2CPERIPHERAL ?= 0 +CIRCUITPY_I2CTARGET ?= 0 CIRCUITPY_JSON ?= 0 CIRCUITPY_KEYPAD ?= 0 CIRCUITPY_MSGPACK ?= 0 +CIRCUITPY_OS_GETENV ?= 0 +CIRCUITPY_PIXELMAP ?= 0 CIRCUITPY_RE ?= 0 CIRCUITPY_SDCARDIO ?= 0 CIRCUITPY_SYNTHIO ?= 0 @@ -51,12 +53,12 @@ CIRCUITPY_ULAB = 0 CIRCUITPY_VECTORIO = 0 CIRCUITPY_ZLIB = 0 -# TODO: In CircuitPython 8.0, turn this back on, after `busio.OneWire` is removed. -# We'd like a smoother transition, but we can't afford the space to have both -# `busio.OneWire` and `onewireio.OneWire` present on these tiny builds. +# Turn off a few more things that don't fit in 192kB ifeq ($(INTERNAL_FLASH_FILESYSTEM),1) CIRCUITPY_ONEWIREIO ?= 0 +CIRCUITPY_SAFEMODE_PY ?= 0 +CIRCUITPY_USB_IDENTIFICATION ?= 0 endif MICROPY_PY_ASYNC_AWAIT = 0 @@ -76,10 +78,8 @@ SUPEROPT_VM = 0 CIRCUITPY_LTO_PARTITION = one -ifeq ($(CIRCUITPY_FULL_BUILD),0) -# On the smallest boards, this saves about 180 bytes. On other boards, it may -increase- space used. +# On smaller builds this saves about 180 bytes. On other boards, it may -increase- space used, so use with care. CFLAGS_BOARD = -fweb -frename-registers -endif endif # samd21 ###################################################################### @@ -133,3 +133,5 @@ CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FRAMEBUFFERIO) endif # same51 ###################################################################### + +CIRCUITPY_BUILD_EXTENSIONS ?= uf2 diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index 57133eefeb..baca4c0843 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit 57133eefeb077f73b5ac17ee044d9feaf566da8e +Subproject commit baca4c084334aa8625f525a4032d66a397199ea6 diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 424acece78..45b999f1a1 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -368,20 +368,20 @@ safe_mode_t port_init(void) { #ifdef SAMD21 if (PM->RCAUSE.bit.BOD33 == 1 || PM->RCAUSE.bit.BOD12 == 1) { - return BROWNOUT; + return SAFE_MODE_BROWNOUT; } #endif #ifdef SAM_D5X_E5X if (RSTC->RCAUSE.bit.BODVDD == 1 || RSTC->RCAUSE.bit.BODCORE == 1) { - return BROWNOUT; + return SAFE_MODE_BROWNOUT; } #endif if (board_requests_safe_mode()) { - return USER_SAFE_MODE; + return SAFE_MODE_USER; } - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } void reset_port(void) { @@ -644,6 +644,10 @@ void port_disable_tick(void) { RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_PER2; #endif #ifdef SAMD21 + if (_tick_event_channel == EVSYS_SYNCH_NUM) { + return; + } + if (_tick_event_channel >= 8) { uint8_t value = 1 << (_tick_event_channel - 8); EVSYS->INTENCLR.reg = EVSYS_INTENSET_EVDp8(value); @@ -651,6 +655,7 @@ void port_disable_tick(void) { uint8_t value = 1 << _tick_event_channel; EVSYS->INTENCLR.reg = EVSYS_INTENSET_EVD(value); } + disable_event_channel(_tick_event_channel); _tick_event_channel = EVSYS_SYNCH_NUM; #endif } @@ -715,7 +720,7 @@ __attribute__((used)) void HardFault_Handler(void) { REG_MTB_MASTER = 0x00000000 + 6; #endif - reset_into_safe_mode(HARD_CRASH); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } diff --git a/ports/broadcom/Makefile b/ports/broadcom/Makefile index 757e7f3450..b6dd62dedf 100644 --- a/ports/broadcom/Makefile +++ b/ports/broadcom/Makefile @@ -1,35 +1,28 @@ -# Select the board to build for. -BOARD?=raspberrypi_pi4b +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -ifeq ($(BOARD),) - $(error You must provide a BOARD parameter) -else - ifeq ($(wildcard boards/$(BOARD)/.),) - $(error Invalid BOARD "$(BOARD)" specified) - endif -endif - -# If the build directory is not given, make it reflect the board name. -BUILD ?= build-$(BOARD) - -include ../../py/mkenv.mk -# Board-specific -include boards/$(BOARD)/mpconfigboard.mk -# Port-specific -include mpconfigport.mk -# CircuitPython-specific -include $(TOP)/py/circuitpy_mpconfig.mk - -# qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h - -# include py core make definitions -include $(TOP)/py/py.mk - -include $(TOP)/supervisor/supervisor.mk - -# Include make rules and variables common across CircuitPython builds. -include $(TOP)/py/circuitpy_defns.mk +include ../../py/circuitpy_mkenv.mk ifeq ($(CHIP_VARIANT), "bcm2711") CFLAGS += -mcpu=cortex-a72 -DBCM_VERSION=2711 @@ -65,7 +58,6 @@ SRC_C += bindings/videocore/__init__.c \ boards/$(BOARD)/pins.c \ background.c \ common-hal/videocore/Framebuffer.c \ - fatfs_port.c \ mphalport.c \ lib/sdmmc/sdmmc_cmd.c \ lib/sdmmc/sdmmc_common.c \ diff --git a/ports/broadcom/background.c b/ports/broadcom/background.c index 4b5190aa27..5d92f1b8bf 100644 --- a/ports/broadcom/background.c +++ b/ports/broadcom/background.c @@ -33,5 +33,8 @@ void port_start_background_task(void) { void port_finish_background_task(void) { } +void port_background_tick(void) { +} + void port_background_task(void) { } diff --git a/ports/broadcom/bindings/videocore/Framebuffer.c b/ports/broadcom/bindings/videocore/Framebuffer.c index 4be55ee291..39c5e71467 100644 --- a/ports/broadcom/bindings/videocore/Framebuffer.c +++ b/ports/broadcom/bindings/videocore/Framebuffer.c @@ -46,7 +46,6 @@ //| //| A Framebuffer is often used in conjunction with a //| `framebufferio.FramebufferDisplay`.""" -//| STATIC mp_obj_t videocore_framebuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_width, ARG_height, }; @@ -72,7 +71,6 @@ STATIC mp_obj_t videocore_framebuffer_make_new(const mp_obj_type_t *type, size_t //| rgbmatrix instance. After deinitialization, no further operations //| may be performed.""" //| ... -//| STATIC mp_obj_t videocore_framebuffer_deinit(mp_obj_t self_in) { videocore_framebuffer_obj_t *self = (videocore_framebuffer_obj_t *)self_in; common_hal_videocore_framebuffer_deinit(self); @@ -89,7 +87,6 @@ static void check_for_deinit(videocore_framebuffer_obj_t *self) { //| width: int //| """The width of the display, in pixels""" -//| STATIC mp_obj_t videocore_framebuffer_get_width(mp_obj_t self_in) { videocore_framebuffer_obj_t *self = (videocore_framebuffer_obj_t *)self_in; check_for_deinit(self); diff --git a/ports/broadcom/bindings/videocore/__init__.c b/ports/broadcom/bindings/videocore/__init__.c index 94a483adb5..9ec345dae7 100644 --- a/ports/broadcom/bindings/videocore/__init__.c +++ b/ports/broadcom/bindings/videocore/__init__.c @@ -32,7 +32,6 @@ #include "bindings/videocore/Framebuffer.h" //| """Low-level routines for interacting with the Broadcom VideoCore GPU""" -//| STATIC const mp_rom_map_elem_t videocore_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_videocore) }, diff --git a/ports/broadcom/boards/diodes_delight_piunora/board.c b/ports/broadcom/boards/diodes_delight_piunora/board.c index 80bea7f8b6..e272a8cc3d 100644 --- a/ports/broadcom/boards/diodes_delight_piunora/board.c +++ b/ports/broadcom/boards/diodes_delight_piunora/board.c @@ -45,12 +45,4 @@ void board_init(void) { true); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/broadcom/boards/diodes_delight_piunora/mpconfigboard.h b/ports/broadcom/boards/diodes_delight_piunora/mpconfigboard.h index a3e318bb13..12a68201fa 100644 --- a/ports/broadcom/boards/diodes_delight_piunora/mpconfigboard.h +++ b/ports/broadcom/boards/diodes_delight_piunora/mpconfigboard.h @@ -4,3 +4,6 @@ #define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) #define MICROPY_HW_NEOPIXEL (&pin_GPIO12) + +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO4) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO5) diff --git a/ports/broadcom/boards/raspberrypi_cm4/board.c b/ports/broadcom/boards/raspberrypi_cm4/board.c index 80bea7f8b6..e272a8cc3d 100644 --- a/ports/broadcom/boards/raspberrypi_cm4/board.c +++ b/ports/broadcom/boards/raspberrypi_cm4/board.c @@ -45,12 +45,4 @@ void board_init(void) { true); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/broadcom/boards/raspberrypi_cm4io/board.c b/ports/broadcom/boards/raspberrypi_cm4io/board.c index 80bea7f8b6..e272a8cc3d 100644 --- a/ports/broadcom/boards/raspberrypi_cm4io/board.c +++ b/ports/broadcom/boards/raspberrypi_cm4io/board.c @@ -45,12 +45,4 @@ void board_init(void) { true); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/broadcom/boards/raspberrypi_cm4io/mpconfigboard.h b/ports/broadcom/boards/raspberrypi_cm4io/mpconfigboard.h index 9acfb32626..832a0b887b 100644 --- a/ports/broadcom/boards/raspberrypi_cm4io/mpconfigboard.h +++ b/ports/broadcom/boards/raspberrypi_cm4io/mpconfigboard.h @@ -4,3 +4,6 @@ #define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) #define MICROPY_HW_LED_STATUS (&pin_GPIO42) + +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO14) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO15) diff --git a/ports/broadcom/boards/raspberrypi_pi4b/board.c b/ports/broadcom/boards/raspberrypi_pi4b/board.c index 80bea7f8b6..e272a8cc3d 100644 --- a/ports/broadcom/boards/raspberrypi_pi4b/board.c +++ b/ports/broadcom/boards/raspberrypi_pi4b/board.c @@ -45,12 +45,4 @@ void board_init(void) { true); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/broadcom/boards/raspberrypi_pi4b/mpconfigboard.h b/ports/broadcom/boards/raspberrypi_pi4b/mpconfigboard.h index 2980b0f9a5..521c8fda25 100644 --- a/ports/broadcom/boards/raspberrypi_pi4b/mpconfigboard.h +++ b/ports/broadcom/boards/raspberrypi_pi4b/mpconfigboard.h @@ -4,3 +4,6 @@ #define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) #define MICROPY_HW_LED_STATUS (&pin_GPIO42) + +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO14) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO15) diff --git a/ports/broadcom/boards/raspberrypi_zero/board.c b/ports/broadcom/boards/raspberrypi_zero/board.c index 80bea7f8b6..e272a8cc3d 100644 --- a/ports/broadcom/boards/raspberrypi_zero/board.c +++ b/ports/broadcom/boards/raspberrypi_zero/board.c @@ -45,12 +45,4 @@ void board_init(void) { true); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/broadcom/boards/raspberrypi_zero/mpconfigboard.h b/ports/broadcom/boards/raspberrypi_zero/mpconfigboard.h index 1141520e06..c1566e8fc0 100644 --- a/ports/broadcom/boards/raspberrypi_zero/mpconfigboard.h +++ b/ports/broadcom/boards/raspberrypi_zero/mpconfigboard.h @@ -4,3 +4,6 @@ #define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) #define MICROPY_HW_LED_STATUS (&pin_GPIO47) + +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO14) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO15) diff --git a/ports/broadcom/boards/raspberrypi_zero/mpconfigboard.mk b/ports/broadcom/boards/raspberrypi_zero/mpconfigboard.mk index 74f8511c2d..b6adb5d6bb 100644 --- a/ports/broadcom/boards/raspberrypi_zero/mpconfigboard.mk +++ b/ports/broadcom/boards/raspberrypi_zero/mpconfigboard.mk @@ -4,3 +4,5 @@ USB_PRODUCT = "Zero" USB_MANUFACTURER = "Raspberry Pi" CHIP_VARIANT = "bcm2835" + +CIRCUITPY_BUILD_EXTENSIONS = disk.img.zip,kernel.img diff --git a/ports/broadcom/boards/raspberrypi_zero2w/board.c b/ports/broadcom/boards/raspberrypi_zero2w/board.c index 80bea7f8b6..e272a8cc3d 100644 --- a/ports/broadcom/boards/raspberrypi_zero2w/board.c +++ b/ports/broadcom/boards/raspberrypi_zero2w/board.c @@ -45,12 +45,4 @@ void board_init(void) { true); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/broadcom/boards/raspberrypi_zero2w/mpconfigboard.h b/ports/broadcom/boards/raspberrypi_zero2w/mpconfigboard.h index 11011268ae..e65bf5c163 100644 --- a/ports/broadcom/boards/raspberrypi_zero2w/mpconfigboard.h +++ b/ports/broadcom/boards/raspberrypi_zero2w/mpconfigboard.h @@ -2,3 +2,8 @@ #define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO29) + +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO14) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO15) diff --git a/ports/broadcom/boards/raspberrypi_zero2w/pins.c b/ports/broadcom/boards/raspberrypi_zero2w/pins.c index bb6632b923..5e12613b3f 100644 --- a/ports/broadcom/boards/raspberrypi_zero2w/pins.c +++ b/ports/broadcom/boards/raspberrypi_zero2w/pins.c @@ -55,6 +55,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, diff --git a/ports/broadcom/boards/raspberrypi_zero_w/board.c b/ports/broadcom/boards/raspberrypi_zero_w/board.c index 80bea7f8b6..e272a8cc3d 100644 --- a/ports/broadcom/boards/raspberrypi_zero_w/board.c +++ b/ports/broadcom/boards/raspberrypi_zero_w/board.c @@ -45,12 +45,4 @@ void board_init(void) { true); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/broadcom/boards/raspberrypi_zero_w/mpconfigboard.h b/ports/broadcom/boards/raspberrypi_zero_w/mpconfigboard.h index 389868f882..4dc1372ae5 100644 --- a/ports/broadcom/boards/raspberrypi_zero_w/mpconfigboard.h +++ b/ports/broadcom/boards/raspberrypi_zero_w/mpconfigboard.h @@ -4,3 +4,6 @@ #define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) #define MICROPY_HW_LED_STATUS (&pin_GPIO47) + +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO14) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO15) diff --git a/ports/broadcom/boards/raspberrypi_zero_w/mpconfigboard.mk b/ports/broadcom/boards/raspberrypi_zero_w/mpconfigboard.mk index 24d09e0530..cd55f73ee8 100644 --- a/ports/broadcom/boards/raspberrypi_zero_w/mpconfigboard.mk +++ b/ports/broadcom/boards/raspberrypi_zero_w/mpconfigboard.mk @@ -4,3 +4,5 @@ USB_PRODUCT = "Zero W" USB_MANUFACTURER = "Raspberry Pi" CHIP_VARIANT = "bcm2835" + +CIRCUITPY_BUILD_EXTENSIONS = disk.img.zip,kernel.img diff --git a/ports/broadcom/common-hal/busio/I2C.c b/ports/broadcom/common-hal/busio/I2C.c index 3142fda145..64187f434b 100644 --- a/ports/broadcom/common-hal/busio/I2C.c +++ b/ports/broadcom/common-hal/busio/I2C.c @@ -98,7 +98,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, self->sda_pin = sda; self->scl_pin = scl; - uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); + uint32_t source_clock = vcmailbox_get_clock_rate(VCMAILBOX_CLOCK_CORE); uint16_t clock_divider = source_clock / frequency; self->peripheral->DIV_b.CDIV = clock_divider; diff --git a/ports/broadcom/common-hal/busio/SPI.c b/ports/broadcom/common-hal/busio/SPI.c index 017674dfc0..5780ebe801 100644 --- a/ports/broadcom/common-hal/busio/SPI.c +++ b/ports/broadcom/common-hal/busio/SPI.c @@ -87,6 +87,8 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_NotImplementedError(translate("Half duplex SPI is not implemented")); } + // BCM_VERSION != 2711 have 3 SPI but as listed in peripherals/gen/pins.c two are on + // index 0, once one index 0 SPI is found the other will throw an invalid_pins error. for (size_t i = 0; i < NUM_SPI; i++) { if (spi_in_use[i]) { continue; @@ -157,6 +159,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { common_hal_reset_pin(self->MOSI); common_hal_reset_pin(self->MISO); self->clock = NULL; + spi_in_use[self->index] = false; if (self->index == 1 || self->index == 2) { @@ -180,7 +183,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, if (self->index == 1 || self->index == 2) { SPI1_Type *p = aux_spi[self->index]; - uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); + uint32_t source_clock = vcmailbox_get_clock_rate(VCMAILBOX_CLOCK_CORE); uint16_t clock_divider = source_clock / baudrate; if (source_clock % baudrate > 0) { clock_divider += 2; @@ -198,7 +201,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, SPI0_Type *p = spi[self->index]; p->CS = polarity << SPI0_CS_CPOL_Pos | phase << SPI0_CS_CPHA_Pos; - uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); + uint32_t source_clock = vcmailbox_get_clock_rate(VCMAILBOX_CLOCK_CORE); uint16_t clock_divider = source_clock / baudrate; if (source_clock % baudrate > 0) { clock_divider += 2; diff --git a/ports/broadcom/common-hal/busio/UART.c b/ports/broadcom/common-hal/busio/UART.c index 52d1b7a418..5be098cf03 100644 --- a/ports/broadcom/common-hal/busio/UART.c +++ b/ports/broadcom/common-hal/busio/UART.c @@ -124,7 +124,7 @@ void pl011_IRQHandler(uint8_t index) { // Clear the interrupt in case we weren't able to clear it by emptying the // FIFO. (This won't clear the FIFO.) ARM_UART_PL011_Type *pl011 = uart[index]; - pl011->ICR = UART0_ICR_RXIC_Msk; + pl011->ICR = ARM_UART_PL011_ICR_RXIC_Msk; } void UART0_IRQHandler(void) { @@ -208,8 +208,9 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->sigint_enabled = sigint_enabled; if (rx != NULL) { + // Use the provided buffer when given. if (receiver_buffer != NULL) { - self->ringbuf = (ringbuf_t) { receiver_buffer, receiver_buffer_size }; + ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); } else { // Initially allocate the UART's buffer in the long-lived part of the // heap. UARTs are generally long-lived objects, but the "make long- @@ -217,7 +218,6 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // self->buffer, so do it manually. (However, as long as internal // pointers like this are NOT moved, allocating the buffer // in the long-lived pool is not strictly necessary) - // (This is a macro.) if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { m_malloc_fail(receiver_buffer_size); } @@ -258,31 +258,31 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, common_hal_busio_uart_set_baudrate(self, baudrate); - uint32_t line_control = UART0_LCR_H_FEN_Msk; - line_control |= (bits - 5) << UART0_LCR_H_WLEN_Pos; + uint32_t line_control = ARM_UART_PL011_LCR_H_FEN_Msk; + line_control |= (bits - 5) << ARM_UART_PL011_LCR_H_WLEN_Pos; if (stop == 2) { - line_control |= UART0_LCR_H_STP2_Msk; + line_control |= ARM_UART_PL011_LCR_H_STP2_Msk; } if (parity != BUSIO_UART_PARITY_NONE) { - line_control |= UART0_LCR_H_PEN_Msk; + line_control |= ARM_UART_PL011_LCR_H_PEN_Msk; } if (parity == BUSIO_UART_PARITY_EVEN) { - line_control |= UART0_LCR_H_EPS_Msk; + line_control |= ARM_UART_PL011_LCR_H_EPS_Msk; } pl011->LCR_H = line_control; - uint32_t control = UART0_CR_UARTEN_Msk; + uint32_t control = ARM_UART_PL011_CR_UARTEN_Msk; if (tx != NULL) { - control |= UART0_CR_TXE_Msk; + control |= ARM_UART_PL011_CR_TXE_Msk; } if (rx != NULL) { - control |= UART0_CR_RXE_Msk; + control |= ARM_UART_PL011_CR_RXE_Msk; } if (cts != NULL) { - control |= UART0_CR_CTSEN_Msk; + control |= ARM_UART_PL011_CR_CTSEN_Msk; } if (rts != NULL) { - control |= UART0_CR_RTSEN_Msk; + control |= ARM_UART_PL011_CR_RTSEN_Msk; } pl011->CR = control; } @@ -337,7 +337,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { pl011->CR = 0; } active_uart[self->uart_id] = NULL; - ringbuf_free(&self->ringbuf); + ringbuf_deinit(&self->ringbuf); uart_status[self->uart_id] = STATUS_FREE; common_hal_reset_pin(self->tx_pin); common_hal_reset_pin(self->rx_pin); @@ -460,7 +460,7 @@ uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { if (self->uart_id == 1) { - uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); + uint32_t source_clock = vcmailbox_get_clock_rate(VCMAILBOX_CLOCK_CORE); UART1->BAUD = ((source_clock / (baudrate * 8)) - 1); } else { ARM_UART_PL011_Type *pl011 = uart[self->uart_id]; diff --git a/ports/broadcom/common-hal/busio/UART.h b/ports/broadcom/common-hal/busio/UART.h index 0590bc28b6..57926ca58b 100644 --- a/ports/broadcom/common-hal/busio/UART.h +++ b/ports/broadcom/common-hal/busio/UART.h @@ -36,11 +36,11 @@ typedef struct { const mcu_pin_obj_t *rx_pin; const mcu_pin_obj_t *cts_pin; const mcu_pin_obj_t *rts_pin; - uint8_t uart_id; uint32_t baudrate; uint32_t timeout_ms; - bool sigint_enabled; ringbuf_t ringbuf; + bool sigint_enabled; + uint8_t uart_id; } busio_uart_obj_t; extern void reset_uart(void); diff --git a/ports/broadcom/common-hal/digitalio/DigitalInOut.c b/ports/broadcom/common-hal/digitalio/DigitalInOut.c index d8ac3472de..0dd74a8412 100644 --- a/ports/broadcom/common-hal/digitalio/DigitalInOut.c +++ b/ports/broadcom/common-hal/digitalio/DigitalInOut.c @@ -63,11 +63,12 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self self->pin = NULL; } -void common_hal_digitalio_digitalinout_switch_to_input( +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { self->output = false; // This also sets direction to input. common_hal_digitalio_digitalinout_set_pull(self, pull); + return DIGITALINOUT_OK; } digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( @@ -134,7 +135,7 @@ digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( } } -void common_hal_digitalio_digitalinout_set_pull( +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { const uint8_t pin = self->pin->number; BP_PULL_Enum bp_pull = BP_PULL_NONE; @@ -144,6 +145,7 @@ void common_hal_digitalio_digitalinout_set_pull( bp_pull = BP_PULL_DOWN; } gpio_set_pull(pin, bp_pull); + return DIGITALINOUT_OK; } digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( diff --git a/ports/broadcom/common-hal/microcontroller/__init__.c b/ports/broadcom/common-hal/microcontroller/__init__.c index a1491d9668..53f04ebec3 100644 --- a/ports/broadcom/common-hal/microcontroller/__init__.c +++ b/ports/broadcom/common-hal/microcontroller/__init__.c @@ -46,7 +46,7 @@ void common_hal_mcu_disable_interrupts(void) { void common_hal_mcu_enable_interrupts(void) { if (nesting_count == 0) { - // reset_into_safe_mode(LOCKING_ERROR); + // reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); } nesting_count--; if (nesting_count > 0) { diff --git a/ports/broadcom/common-hal/neopixel_write/__init__.c b/ports/broadcom/common-hal/neopixel_write/__init__.c index 0cd76ebca9..245244614f 100644 --- a/ports/broadcom/common-hal/neopixel_write/__init__.c +++ b/ports/broadcom/common-hal/neopixel_write/__init__.c @@ -45,7 +45,10 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, uint8_t *pixels, uint32_t num_bytes) { // Wait to make sure we don't append onto the last transmission. This should only be a tick or // two. - while (port_get_raw_ticks(NULL) < next_start_raw_ticks) { + int icnt; + while ((port_get_raw_ticks(NULL) < next_start_raw_ticks) && + (next_start_raw_ticks - port_get_raw_ticks(NULL) < 100)) { + RUN_BACKGROUND_TASKS; } BP_Function_Enum alt_function = GPIO_FUNCTION_OUTPUT; @@ -92,7 +95,8 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, // Wait for the clock to start up. COMPLETE_MEMORY_READS; - while (CM_PWM->CS_b.BUSY == 0) { + icnt = 0; + while ((CM_PWM->CS_b.BUSY == 0) && (icnt++ < 1000)) { } } @@ -134,24 +138,45 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, expanded |= 0x80000000; } } - while (pwm->STA_b.FULL1 == 1) { - RUN_BACKGROUND_TASKS; - } if (channel == 1) { + icnt = 0; + while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) { + RUN_BACKGROUND_TASKS; + } // Dummy value for the first channel. pwm->FIF1 = 0x000000; } + icnt = 0; + while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) { + RUN_BACKGROUND_TASKS; + } pwm->FIF1 = expanded; if (channel == 0) { + icnt = 0; + while ((pwm->STA_b.FULL1 == 1) && (icnt++ < 150)) { + RUN_BACKGROUND_TASKS; + } // Dummy value for the second channel. pwm->FIF1 = 0x000000; } } - // Wait just a little bit so that transmission can start. - common_hal_mcu_delay_us(2); - while (pwm->STA_b.STA1 == 1) { + + icnt = 0; + while ((pwm->STA_b.EMPT1 == 0) && (icnt++ < 2500)) { RUN_BACKGROUND_TASKS; } + // Wait for transmission to start. + icnt = 0; + while (((pwm->STA_b.STA1 == 0) && (pwm->STA_b.STA2 == 0)) && (icnt++ < 150)) { + RUN_BACKGROUND_TASKS; + } + // Wait for transmission to complete. + icnt = 0; + while (((pwm->STA_b.STA1 == 1) || (pwm->STA_b.STA2 == 1)) && (icnt++ < 150)) { + RUN_BACKGROUND_TASKS; + } + // Shouldn't be anything left in queue but clear it so the clock doesn't crash if there is + pwm->CTL = PWM0_CTL_CLRF1_Msk; gpio_set_function(digitalinout->pin->number, GPIO_FUNCTION_OUTPUT); diff --git a/ports/espressif/fatfs_port.c b/ports/broadcom/common-hal/rtc/RTC.c similarity index 55% rename from ports/espressif/fatfs_port.c rename to ports/broadcom/common-hal/rtc/RTC.c index 38c2d923b8..8f6743cb05 100644 --- a/ports/espressif/fatfs_port.c +++ b/ports/broadcom/common-hal/rtc/RTC.c @@ -3,7 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * Copyright (c) 2019 Artur Pacholec * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,28 +25,34 @@ * THE SOFTWARE. */ +#include + +#include "py/obj.h" #include "py/runtime.h" -#include "lib/oofatfs/ff.h" #include "shared/timeutils/timeutils.h" -#include "shared-bindings/rtc/RTC.h" -#include "shared-bindings/time/__init__.h" -#include "supervisor/fatfs_port.h" +#include "supervisor/port.h" -DWORD _time_override = 0; -DWORD get_fattime(void) { - if (_time_override > 0) { - return _time_override; - } - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif +// This is the time in seconds since 2000 that the RTC was started. +// TODO: Change the offset to ticks so that it can be a subsecond adjustment. +static uint32_t rtc_offset = 0; + +void common_hal_rtc_get_time(timeutils_struct_time_t *tm) { + uint64_t ticks_s = port_get_raw_ticks(NULL) / 1024; + timeutils_seconds_since_2000_to_struct_time(rtc_offset + ticks_s, tm); } -void override_fattime(DWORD time) { - _time_override = time; +void common_hal_rtc_set_time(timeutils_struct_time_t *tm) { + uint64_t ticks_s = port_get_raw_ticks(NULL) / 1024; + uint32_t epoch_s = timeutils_seconds_since_2000( + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec + ); + rtc_offset = epoch_s - ticks_s; +} + +int common_hal_rtc_get_calibration(void) { + return 0; +} + +void common_hal_rtc_set_calibration(int calibration) { + mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_calibration); } diff --git a/ports/broadcom/common-hal/rtc/RTC.h b/ports/broadcom/common-hal/rtc/RTC.h new file mode 100644 index 0000000000..09ae4ea86f --- /dev/null +++ b/ports/broadcom/common-hal/rtc/RTC.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * Copyright (c) 2019 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_BROADCOM_COMMON_HAL_RTC_RTC_H +#define MICROPY_INCLUDED_BROADCOM_COMMON_HAL_RTC_RTC_H + +extern void rtc_reset(void); + +#endif // MICROPY_INCLUDED_BROADCOM_COMMON_HAL_RTC_RTC_H diff --git a/ports/broadcom/common-hal/rtc/__init__.c b/ports/broadcom/common-hal/rtc/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ports/broadcom/common-hal/sdioio/SDCard.c b/ports/broadcom/common-hal/sdioio/SDCard.c index 27b36041de..cf8bfb1faa 100644 --- a/ports/broadcom/common-hal/sdioio/SDCard.c +++ b/ports/broadcom/common-hal/sdioio/SDCard.c @@ -122,27 +122,27 @@ STATIC sdmmc_err_t _do_transaction(int slot, sdmmc_command_t *cmdinfo) { if (EMMC->STATUS_b.DAT_INHIBIT) { return SDMMC_ERR_BUSY; } - cmd_flags = EMMC_CMDTM_TM_BLKCNT_EN_Msk | EMMC_CMDTM_CMD_ISDATA_Msk; + cmd_flags = Arasan_EMMC_Distributor_CMDTM_TM_BLKCNT_EN_Msk | Arasan_EMMC_Distributor_CMDTM_CMD_ISDATA_Msk; if (cmdinfo->datalen > cmdinfo->blklen) { - cmd_flags |= EMMC_CMDTM_TM_MULTI_BLOCK_Msk; + cmd_flags |= Arasan_EMMC_Distributor_CMDTM_TM_MULTI_BLOCK_Msk; if ((cmdinfo->flags & SCF_AUTO_STOP) != 0) { - cmd_flags |= 1 << EMMC_CMDTM_TM_AUTO_CMD_EN_Pos; + cmd_flags |= 1 << Arasan_EMMC_Distributor_CMDTM_TM_AUTO_CMD_EN_Pos; } } if (read) { - cmd_flags |= EMMC_CMDTM_TM_DAT_DIR_Msk; + cmd_flags |= Arasan_EMMC_Distributor_CMDTM_TM_DAT_DIR_Msk; } - EMMC->BLKSIZECNT = (cmdinfo->datalen / cmdinfo->blklen) << EMMC_BLKSIZECNT_BLKCNT_Pos | - cmdinfo->blklen << EMMC_BLKSIZECNT_BLKSIZE_Pos; + EMMC->BLKSIZECNT = (cmdinfo->datalen / cmdinfo->blklen) << Arasan_EMMC_Distributor_BLKSIZECNT_BLKCNT_Pos | + cmdinfo->blklen << Arasan_EMMC_Distributor_BLKSIZECNT_BLKSIZE_Pos; } uint32_t response_type = EMMC_CMDTM_CMD_RSPNS_TYPE_RESPONSE_48BITS; uint32_t crc = 0; if ((cmdinfo->flags & SCF_RSP_CRC) != 0) { - crc |= EMMC_CMDTM_CMD_CRCCHK_EN_Msk; + crc |= Arasan_EMMC_Distributor_CMDTM_CMD_CRCCHK_EN_Msk; } if ((cmdinfo->flags & SCF_RSP_IDX) != 0) { - crc |= EMMC_CMDTM_CMD_IXCHK_EN_Msk; + crc |= Arasan_EMMC_Distributor_CMDTM_CMD_IXCHK_EN_Msk; } if ((cmdinfo->flags & SCF_RSP_136) != 0) { response_type = EMMC_CMDTM_CMD_RSPNS_TYPE_RESPONSE_136BITS; @@ -152,8 +152,8 @@ STATIC sdmmc_err_t _do_transaction(int slot, sdmmc_command_t *cmdinfo) { response_type = EMMC_CMDTM_CMD_RSPNS_TYPE_RESPONSE_NONE; } uint32_t full_cmd = cmd_flags | crc | - cmdinfo->opcode << EMMC_CMDTM_CMD_INDEX_Pos | - response_type << EMMC_CMDTM_CMD_RSPNS_TYPE_Pos; + cmdinfo->opcode << Arasan_EMMC_Distributor_CMDTM_CMD_INDEX_Pos | + response_type << Arasan_EMMC_Distributor_CMDTM_CMD_RSPNS_TYPE_Pos; EMMC->CMDTM = full_cmd; // Wait for an interrupt to indicate completion of the command. @@ -170,7 +170,7 @@ STATIC sdmmc_err_t _do_transaction(int slot, sdmmc_command_t *cmdinfo) { } return SDMMC_ERR_TIMEOUT; } else { - EMMC->INTERRUPT = EMMC_INTERRUPT_CMD_DONE_Msk; + EMMC->INTERRUPT = Arasan_EMMC_Distributor_INTERRUPT_CMD_DONE_Msk; } // Transfer the data. @@ -197,7 +197,7 @@ STATIC sdmmc_err_t _do_transaction(int slot, sdmmc_command_t *cmdinfo) { EMMC->DATA = ((uint32_t *)cmdinfo->data)[i]; } } - uint32_t data_done_mask = EMMC_INTERRUPT_ERR_Msk | EMMC_INTERRUPT_DATA_DONE_Msk; + uint32_t data_done_mask = Arasan_EMMC_Distributor_INTERRUPT_ERR_Msk | Arasan_EMMC_Distributor_INTERRUPT_DATA_DONE_Msk; start_ticks = port_get_raw_ticks(NULL); while ((EMMC->INTERRUPT & data_done_mask) == 0 && (port_get_raw_ticks(NULL) - start_ticks) < (size_t)cmdinfo->timeout_ms) { } @@ -282,7 +282,7 @@ void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self, } // Set max timeout - EMMC->CONTROL1 |= EMMC_CONTROL1_CLK_INTLEN_Msk | (0xe << EMMC_CONTROL1_DATA_TOUNIT_Pos); + EMMC->CONTROL1 |= Arasan_EMMC_Distributor_CONTROL1_CLK_INTLEN_Msk | (0xe << Arasan_EMMC_Distributor_CONTROL1_DATA_TOUNIT_Pos); EMMC->IRPT_MASK = 0xffffffff; diff --git a/ports/broadcom/mpconfigport.h b/ports/broadcom/mpconfigport.h index fc3966fc71..e77725cca3 100644 --- a/ports/broadcom/mpconfigport.h +++ b/ports/broadcom/mpconfigport.h @@ -60,7 +60,4 @@ #define MICROPY_PORT_ROOT_POINTERS \ CIRCUITPY_COMMON_ROOT_POINTERS -#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO14) -#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO15) - #endif // __INCLUDED_MPCONFIGPORT_H diff --git a/ports/broadcom/mpconfigport.mk b/ports/broadcom/mpconfigport.mk index 7296461d1f..b992d24f0e 100644 --- a/ports/broadcom/mpconfigport.mk +++ b/ports/broadcom/mpconfigport.mk @@ -9,13 +9,12 @@ CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOIO = 0 CIRCUITPY_COUNTIO = 0 CIRCUITPY_FREQUENCYIO = 0 -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_NVM = 0 CIRCUITPY_PARALLELDISPLAY = 0 CIRCUITPY_PULSEIO = 0 CIRCUITPY_PWMIO = 0 CIRCUITPY_ROTARYIO = 0 -CIRCUITPY_RTC = 0 CIRCUITPY_SDIOIO = 1 CIRCUITPY_VIDEOCORE = 1 @@ -24,3 +23,5 @@ INTERNAL_FLASH_FILESYSTEM = 1 USB_NUM_ENDPOINT_PAIRS = 8 USB_HIGHSPEED = 1 + +CIRCUITPY_BUILD_EXTENSIONS ?= disk.img.zip,kernel8.img diff --git a/ports/broadcom/peripherals b/ports/broadcom/peripherals index 0837008608..d3a6b50a21 160000 --- a/ports/broadcom/peripherals +++ b/ports/broadcom/peripherals @@ -1 +1 @@ -Subproject commit 08370086080759ed54ac1136d62d2ad24c6fa267 +Subproject commit d3a6b50a21e7dd49ba4bfa0374da3407594caa50 diff --git a/ports/broadcom/supervisor/port.c b/ports/broadcom/supervisor/port.c index e036a76cef..ec6feb8703 100644 --- a/ports/broadcom/supervisor/port.c +++ b/ports/broadcom/supervisor/port.c @@ -32,7 +32,7 @@ #include "genhdr/mpversion.h" -// #include "common-hal/rtc/RTC.h" +#include "common-hal/rtc/RTC.h" #include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" #include "common-hal/busio/UART.h" @@ -78,10 +78,10 @@ safe_mode_t port_init(void) { // Check brownout. if (board_requests_safe_mode()) { - return USER_SAFE_MODE; + return SAFE_MODE_USER; } - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } void reset_port(void) { diff --git a/ports/cxd56/.gitignore b/ports/cxd56/.gitignore deleted file mode 100644 index 414487d53e..0000000000 --- a/ports/cxd56/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build-*/ diff --git a/ports/cxd56/Makefile b/ports/cxd56/Makefile index 073d2d59ce..f90b6dd460 100644 --- a/ports/cxd56/Makefile +++ b/ports/cxd56/Makefile @@ -22,39 +22,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Select the board to build for. -ifeq ($(BOARD),) - $(error You must provide a BOARD parameter) -else - ifeq ($(wildcard boards/$(BOARD)/.),) - $(error Invalid BOARD specified) - endif -endif - -# If the build directory is not given, make it reflect the board name. -BUILD ?= build-$(BOARD) - -include ../../py/mkenv.mk - -# Board-specific -include boards/$(BOARD)/mpconfigboard.mk - -# Port-specific -include mpconfigport.mk - -# CircuitPython-specific -include $(TOP)/py/circuitpy_mpconfig.mk - -# qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h - -# include py core make definitions -include $(TOP)/py/py.mk - -include $(TOP)/supervisor/supervisor.mk - -# Include make rules and variables common across CircuitPython builds. -include $(TOP)/py/circuitpy_defns.mk +include ../../py/circuitpy_mkenv.mk CROSS_COMPILE = arm-none-eabi- @@ -166,13 +134,13 @@ SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(addprefix common-hal/, $(SRC_COMMON_HAL)) SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) + $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) SRC_S = supervisor/cpu.s SRC_C += \ background.c \ - fatfs_port.c \ mphalport.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ diff --git a/ports/cxd56/README.md b/ports/cxd56/README.md index 0656ad1f1a..4266c61c0c 100644 --- a/ports/cxd56/README.md +++ b/ports/cxd56/README.md @@ -75,7 +75,7 @@ Bootloader information: * You have to accept the End User License Agreement to be able to download and use the Spresense bootloader binary. -Download the spresense binaries zip archive from: [Spresense firmware v2-3-000](https://developer.sony.com/file/download/download-spresense-firmware-v2-3-000) +Download the spresense binaries zip archive from: [Spresense firmware v2-4-000](https://developer.sony.com/file/download/download-spresense-firmware-v2-4-000) Extract spresense binaries in your PC to ports/spresense/spresense-exported-sdk/firmware/ diff --git a/ports/cxd56/background.c b/ports/cxd56/background.c index 644a5d7b0b..da172cf5d7 100644 --- a/ports/cxd56/background.c +++ b/ports/cxd56/background.c @@ -30,6 +30,8 @@ #include "supervisor/filesystem.h" #include "supervisor/shared/stack.h" +void port_background_tick(void) { +} void port_background_task(void) { } void port_start_background_task(void) { diff --git a/ports/cxd56/boards/spresense/board.c b/ports/cxd56/boards/spresense/board.c index fba263c569..b397789c3e 100644 --- a/ports/cxd56/boards/spresense/board.c +++ b/ports/cxd56/boards/spresense/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/cxd56/common-hal/camera/Camera.c b/ports/cxd56/common-hal/camera/Camera.c index f304ed8f74..606ad0f1e6 100644 --- a/ports/cxd56/common-hal/camera/Camera.c +++ b/ports/cxd56/common-hal/camera/Camera.c @@ -47,7 +47,7 @@ typedef struct { uint16_t height; } image_size_t; -STATIC const image_size_t image_size_table[] = { +STATIC const image_size_t isx012_image_size_table[] = { { VIDEO_HSIZE_QVGA, VIDEO_VSIZE_QVGA }, { VIDEO_HSIZE_VGA, VIDEO_VSIZE_VGA }, { VIDEO_HSIZE_HD, VIDEO_VSIZE_HD }, @@ -57,12 +57,40 @@ STATIC const image_size_t image_size_table[] = { { VIDEO_HSIZE_5M, VIDEO_VSIZE_5M }, }; +STATIC const image_size_t isx019_image_size_table[] = { + { VIDEO_HSIZE_QVGA, VIDEO_VSIZE_QVGA }, + { VIDEO_HSIZE_VGA, VIDEO_VSIZE_VGA }, + { VIDEO_HSIZE_HD, VIDEO_VSIZE_HD }, + { VIDEO_HSIZE_QUADVGA, VIDEO_VSIZE_QUADVGA }, +}; + +static const char *get_imgsensor_name() { + static struct v4l2_capability cap; + + ioctl(camera_dev.fd, VIDIOC_QUERYCAP, (unsigned long)&cap); + + return (const char *)cap.driver; +} + static bool camera_check_width_and_height(uint16_t width, uint16_t height) { - for (int i = 0; i < MP_ARRAY_SIZE(image_size_table); i++) { - if (image_size_table[i].width == width && image_size_table[i].height == height) { - return true; + const char *sensor; + + sensor = get_imgsensor_name(); + + if (strncmp(sensor, "ISX012", strlen("ISX012")) == 0) { + for (int i = 0; i < MP_ARRAY_SIZE(isx012_image_size_table); i++) { + if (isx012_image_size_table[i].width == width && isx012_image_size_table[i].height == height) { + return true; + } + } + } else if (strncmp(sensor, "ISX019", strlen("ISX019"))) { + for (int i = 0; i < MP_ARRAY_SIZE(isx019_image_size_table); i++) { + if (isx019_image_size_table[i].width == width && isx019_image_size_table[i].height == height) { + return true; + } } } + return false; } diff --git a/ports/cxd56/common-hal/digitalio/DigitalInOut.c b/ports/cxd56/common-hal/digitalio/DigitalInOut.c index cfb39301df..c1f247d0a9 100644 --- a/ports/cxd56/common-hal/digitalio/DigitalInOut.c +++ b/ports/cxd56/common-hal/digitalio/DigitalInOut.c @@ -64,11 +64,12 @@ bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *se return self->pin == NULL; } -void common_hal_digitalio_digitalinout_switch_to_input(digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input(digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { self->input = true; self->pull = pull; board_gpio_write(self->pin->number, -1); board_gpio_config(self->pin->number, 0, true, true, pull); + return DIGITALINOUT_OK; } digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output(digitalio_digitalinout_obj_t *self, bool value, digitalio_drive_mode_t drive_mode) { @@ -124,10 +125,11 @@ digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode(digitali return self->open_drain ? DRIVE_MODE_OPEN_DRAIN : DRIVE_MODE_PUSH_PULL; } -void common_hal_digitalio_digitalinout_set_pull(digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull(digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { self->pull = pull; board_gpio_write(self->pin->number, -1); board_gpio_config(self->pin->number, 0, true, true, pull); + return DIGITALINOUT_OK; } digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(digitalio_digitalinout_obj_t *self) { diff --git a/ports/cxd56/common-hal/microcontroller/__init__.c b/ports/cxd56/common-hal/microcontroller/__init__.c index dd9a54063f..c77a8829f2 100644 --- a/ports/cxd56/common-hal/microcontroller/__init__.c +++ b/ports/cxd56/common-hal/microcontroller/__init__.c @@ -74,7 +74,7 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { if (runmode == RUNMODE_BOOTLOADER) { mp_raise_ValueError(translate("Cannot reset into bootloader because no bootloader is present")); } else if (runmode == RUNMODE_SAFE_MODE) { - safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE); + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); } } diff --git a/ports/cxd56/common-hal/pwmio/PWMOut.c b/ports/cxd56/common-hal/pwmio/PWMOut.c index 7e27817aab..10689dc55a 100644 --- a/ports/cxd56/common-hal/pwmio/PWMOut.c +++ b/ports/cxd56/common-hal/pwmio/PWMOut.c @@ -90,6 +90,8 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { return; } + pwmout_dev[self->number].reset = true; + ioctl(pwmout_dev[self->number].fd, PWMIOC_STOP, 0); close(pwmout_dev[self->number].fd); pwmout_dev[self->number].fd = -1; @@ -134,10 +136,6 @@ void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { pwmout_dev[self->number].reset = false; } -void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { - pwmout_dev[self->number].reset = true; -} - void pwmout_reset(void) { for (int i = 0; i < MP_ARRAY_SIZE(pwmout_dev); i++) { if (pwmout_dev[i].fd >= 0 && pwmout_dev[i].reset) { diff --git a/ports/cxd56/configs/circuitpython/defconfig b/ports/cxd56/configs/circuitpython/defconfig index 6a7c39cba8..92e282649b 100644 --- a/ports/cxd56/configs/circuitpython/defconfig +++ b/ports/cxd56/configs/circuitpython/defconfig @@ -113,4 +113,5 @@ CONFIG_USEC_PER_TICK=1000 CONFIG_USERMAIN_STACKSIZE=8192 CONFIG_USER_ENTRYPOINT="spresense_main" CONFIG_VIDEO_ISX012=y +CONFIG_VIDEO_ISX019=y CONFIG_VIDEO_STREAM=y diff --git a/ports/cxd56/mpconfigport.mk b/ports/cxd56/mpconfigport.mk index 813d85d4a7..cb54233a07 100644 --- a/ports/cxd56/mpconfigport.mk +++ b/ports/cxd56/mpconfigport.mk @@ -15,7 +15,7 @@ CIRCUITPY_COUNTIO = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_GNSS = 1 -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_NVM = 0 @@ -25,3 +25,5 @@ CIRCUITPY_TOUCHIO = 0 CIRCUITPY_USB_HID = 0 CIRCUITPY_USB_MIDI = 0 INTERNAL_LIBM = 1 + +CIRCUITPY_BUILD_EXTENSIONS ?= spk diff --git a/ports/cxd56/spresense-exported-sdk b/ports/cxd56/spresense-exported-sdk index 6a148be849..4f902ca3ff 160000 --- a/ports/cxd56/spresense-exported-sdk +++ b/ports/cxd56/spresense-exported-sdk @@ -1 +1 @@ -Subproject commit 6a148be8497704d4afb5d14c175a12a592813fac +Subproject commit 4f902ca3ffeb327e6c325940ef5133eda588c2e4 diff --git a/ports/cxd56/supervisor/port.c b/ports/cxd56/supervisor/port.c index 10fa4112e8..36d46dbad8 100644 --- a/ports/cxd56/supervisor/port.c +++ b/ports/cxd56/supervisor/port.c @@ -66,10 +66,10 @@ safe_mode_t port_init(void) { heap_size = size / sizeof(uint32_t); if (board_requests_safe_mode()) { - return USER_SAFE_MODE; + return SAFE_MODE_USER; } - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } void reset_cpu(void) { @@ -111,13 +111,13 @@ bool port_has_fixed_stack(void) { uint32_t *port_stack_get_limit(void) { struct tcb_s *rtcb = this_task(); - return rtcb->adj_stack_ptr - (uint32_t)rtcb->adj_stack_size; + return rtcb->stack_base_ptr; } uint32_t *port_stack_get_top(void) { struct tcb_s *rtcb = this_task(); - return rtcb->adj_stack_ptr; + return rtcb->stack_base_ptr + (uint32_t)rtcb->adj_stack_size; } uint32_t *port_heap_get_bottom(void) { diff --git a/ports/espressif/.gitignore b/ports/espressif/.gitignore index 2e3080a40d..63e4a35878 100644 --- a/ports/espressif/.gitignore +++ b/ports/espressif/.gitignore @@ -1,2 +1,5 @@ -build*/ -sdkconfig.old +# idf.py menuconfig +/sdkconfig* + +# lock files for examples and components +dependencies.lock diff --git a/ports/espressif/CMakeLists.txt b/ports/espressif/CMakeLists.txt index 4c834397b9..ce2935a502 100644 --- a/ports/espressif/CMakeLists.txt +++ b/ports/espressif/CMakeLists.txt @@ -6,7 +6,14 @@ set(ENV{IDF_PATH} ${CMAKE_SOURCE_DIR}/esp-idf) # The component list here determines what options we get in menuconfig and what the ninja file # can build. -set(COMPONENTS esptool_py soc driver log main esp-tls mbedtls mdns esp_event esp_adc_cal esp_netif esp_wifi lwip wpa_supplicant freertos bt) +set(COMPONENTS esptool_py soc driver log main esp-tls mbedtls mdns esp_event esp_adc_cal esp_netif esp_wifi lwip ulp wpa_supplicant freertos bt usb) + +if("${CIRCUITPY_ESPCAMERA}") +message("Including esp32-camera") +set(EXTRA_COMPONENT_DIRS "esp32-camera") +list(APPEND COMPONENTS "esp32-camera") +message("COMPONENTS = ${COMPONENTS}") +endif() include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(circuitpython) diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index 204802cb16..ea70f320cb 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -22,42 +22,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Select the board to build for. -ifeq ($(BOARD),) - $(error You must provide a BOARD parameter) -else - ifeq ($(wildcard boards/$(BOARD)/.),) - $(error Invalid BOARD specified) - endif -endif - -# If the flash PORT is not given, use the default /dev/tty.SLAB_USBtoUART. -PORT ?= /dev/tty.SLAB_USBtoUART - -# If the build directory is not given, make it reflect the board name. -BUILD ?= build-$(BOARD) - -include ../../py/mkenv.mk - -# Board-specific -include boards/$(BOARD)/mpconfigboard.mk - -# Port-specific -include mpconfigport.mk - -# CircuitPython-specific -include $(TOP)/py/circuitpy_mpconfig.mk - -# qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h - -# include py core make definitions -include $(TOP)/py/py.mk - -include $(TOP)/supervisor/supervisor.mk - -# Include make rules and variables common across CircuitPython builds. -include $(TOP)/py/circuitpy_defns.mk +include ../../py/circuitpy_mkenv.mk ifeq ($(IDF_TARGET),esp32c3) IDF_TARGET_ARCH = riscv @@ -98,6 +63,8 @@ INC += \ -isystem esp-idf/components/bt/host/nimble/port/include \ -isystem esp-idf/components/driver/include \ -isystem esp-idf/components/driver/$(IDF_TARGET)/include \ + -isystem esp-idf/components/efuse/include \ + -isystem esp-idf/components/efuse/$(IDF_TARGET)/include \ -isystem esp-idf/components/$(IDF_TARGET)/include \ -isystem esp-idf/components/esp_adc_cal/include \ -isystem esp-idf/components/esp_common/include \ @@ -159,12 +126,9 @@ ifeq ($(DEBUG), 1) # CFLAGS += -fno-inline -fno-ipa-sra else CFLAGS += -DNDEBUG -ggdb3 - ifeq ($(IDF_TARGET_ARCH),xtensa) - OPTIMIZATION_FLAGS ?= -O2 - else - # RISC-V is larger than xtensa so do -Os for it - OPTIMIZATION_FLAGS ?= -Os - endif + OPTIMIZATION_FLAGS ?= -O2 + # RISC-V is larger than xtensa + # Use -Os for RISC-V when it overflows endif # option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk @@ -174,6 +138,8 @@ CFLAGS += $(INC) -Werror -Wall -std=gnu11 -Wl,--gc-sections $(BASE_CFLAGS) $(C_D ifeq ($(IDF_TARGET_ARCH),xtensa) CFLAGS += -mlongcalls +else ifeq ($(IDF_TARGET_ARCH),riscv) +CFLAGS += -march=rv32imc endif LDFLAGS = $(CFLAGS) -Wl,-nostdlib -Wl,-Map=$@.map -Wl,-cref -Wl,--undefined=uxTopUsedPriority @@ -224,8 +190,12 @@ endif # TinyUSB defines ifeq ($(CIRCUITPY_USB),1) +ifeq ($(IDF_TARGET),esp32s2) +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32S2 +else ifeq ($(IDF_TARGET),esp32s3) +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32S3 +endif CFLAGS += \ - -DCFG_TUSB_MCU=OPT_MCU_ESP32S2 \ -DCFG_TUSB_OS=OPT_OS_FREERTOS \ -DCFG_TUD_CDC_RX_BUFSIZE=1024 \ -DCFG_TUD_CDC_TX_BUFSIZE=1024 \ @@ -233,7 +203,8 @@ CFLAGS += \ -DCFG_TUD_MIDI_RX_BUFSIZE=128 \ -DCFG_TUD_MIDI_TX_BUFSIZE=128 \ -DCFG_TUD_VENDOR_RX_BUFSIZE=128 \ - -DCFG_TUD_VENDOR_TX_BUFSIZE=128 + -DCFG_TUD_VENDOR_TX_BUFSIZE=128 \ + -DCFG_TUD_TASK_QUEUE_SZ=32 endif ###################################### @@ -242,7 +213,6 @@ endif SRC_C += \ background.c \ - fatfs_port.c \ mphalport.c \ bindings/espidf/__init__.c \ boards/$(BOARD)/board.c \ @@ -259,7 +229,6 @@ SRC_C += \ peripherals/touch.c ifeq ($(IDF_TARGET),esp32s2) SRC_C += \ - cam.c \ i2s_lcd_esp32s2_driver.c endif endif @@ -279,6 +248,26 @@ ifneq ($(CIRCUITPY_BLEIO),0) SRC_C += common-hal/_bleio/ble_events.c endif +SRC_C += $(wildcard common-hal/espidf/*.c) + +ifneq ($(CIRCUITPY_ESPCAMERA),0) +SRC_CAMERA := \ + $(wildcard common-hal/espcamera/*.c) \ + $(wildcard bindings/espcamera/*.c) +SRC_C += $(SRC_CAMERA) +CFLAGS += -isystem esp32-camera/driver/include +CFLAGS += -isystem esp32-camera/conversions/include +endif + +ifneq ($(CIRCUITPY_ESPULP),0) +SRC_ULP := \ + $(wildcard common-hal/espulp/*.c) \ + $(wildcard bindings/espulp/*.c) +SRC_C += $(SRC_ULP) +CFLAGS += -isystem esp-idf/components/ulp/include +CFLAGS += -isystem esp-idf/components/ulp/ulp_riscv/include +endif + SRC_COMMON_HAL_EXPANDED = \ $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ @@ -319,12 +308,16 @@ $(BUILD)/esp-idf: TARGET_SDKCONFIG = esp-idf-config/sdkconfig-$(IDF_TARGET).defaults -UF2_BOOTLOADER ?= $(if $(filter $(IDF_TARGET),esp32s2 esp32s3),1) +ifeq ($(CIRCUITPY_ESP_FLASH_SIZE), 2MB) + FLASH_SDKCONFIG = esp-idf-config/sdkconfig-$(CIRCUITPY_ESP_FLASH_SIZE)-no-ota-no-uf2.defaults +else +UF2_BOOTLOADER ?= $(CIRCUITPY_USB) ifeq ($(UF2_BOOTLOADER), 1) FLASH_SDKCONFIG = esp-idf-config/sdkconfig-$(CIRCUITPY_ESP_FLASH_SIZE).defaults else FLASH_SDKCONFIG = esp-idf-config/sdkconfig-$(CIRCUITPY_ESP_FLASH_SIZE)-no-uf2.defaults endif +endif ifeq ($(DEBUG), 1) DEBUG_SDKCONFIG = esp-idf-config/sdkconfig-debug.defaults @@ -337,8 +330,10 @@ ifneq ($(CIRCUITPY_BLEIO),0) SDKCONFIGS := esp-idf-config/sdkconfig-ble.defaults;$(SDKCONFIGS) endif # create the config headers -$(BUILD)/esp-idf/config/sdkconfig.h: boards/$(BOARD)/sdkconfig | $(BUILD)/esp-idf - IDF_PATH=$(IDF_PATH) cmake -S . -B $(BUILD)/esp-idf -DSDKCONFIG=$(BUILD)/esp-idf/sdkconfig -DSDKCONFIG_DEFAULTS="$(SDKCONFIGS)" -DCMAKE_TOOLCHAIN_FILE=$(IDF_PATH)/tools/cmake/toolchain-$(IDF_TARGET).cmake -DIDF_TARGET=$(IDF_TARGET) -GNinja +.PHONY: do-sdkconfig +do-sdkconfig: $(BUILD)/esp-idf/config/sdkconfig.h +$(BUILD)/esp-idf/config/sdkconfig.h: boards/$(BOARD)/sdkconfig CMakeLists.txt | $(BUILD)/esp-idf + IDF_PATH=$(IDF_PATH) cmake -S . -B $(BUILD)/esp-idf -DSDKCONFIG=$(BUILD)/esp-idf/sdkconfig -DSDKCONFIG_DEFAULTS="$(SDKCONFIGS)" -DCMAKE_TOOLCHAIN_FILE=$(IDF_PATH)/tools/cmake/toolchain-$(IDF_TARGET).cmake -DIDF_TARGET=$(IDF_TARGET) -GNinja -DCIRCUITPY_ESPCAMERA=$(CIRCUITPY_ESPCAMERA) # build a lib # Adding -d explain -j 1 -v to the ninja line will output debug info @@ -376,6 +371,9 @@ ifneq ($(CIRCUITPY_BLEIO),0) BINARY_BLOBS += esp-idf/components/esp_phy/lib/$(IDF_TARGET)/libbtbb.a \ esp-idf/components/bt/controller/lib_esp32c3_family/$(IDF_TARGET)/libbtdm_app.a endif +ifneq ($(CIRCUITPY_ESPULP),0) + ESP_IDF_COMPONENTS_LINK += ulp +endif ESP_IDF_COMPONENTS_EXPANDED = $(foreach component, $(ESP_IDF_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/$(component)/lib$(component).a) @@ -387,6 +385,11 @@ BINARY_BLOBS += esp-idf/components/xtensa/$(IDF_TARGET)/libxt_hal.a ESP_IDF_COMPONENTS_EXPANDED += esp-idf/components/xtensa/$(IDF_TARGET)/libxt_hal.a endif +ifneq ($(CIRCUITPY_ESPCAMERA),0) +ESP_IDF_COMPONENTS_EXPANDED += $(BUILD)/esp-idf/esp-idf/esp32-camera/libesp32-camera.a +#$(error $(ESP_IDF_COMPONENTS_EXPANDED)) +endif + # BOOTLOADER_OFFSET is determined by chip type, based on the ROM bootloader, and is not changeable. ifeq ($(IDF_TARGET),esp32) BOOTLOADER_OFFSET = 0x1000 @@ -426,12 +429,12 @@ esp-idf-stamp: $(BUILD)/esp-idf/config/sdkconfig.h $(BUILD)/firmware.elf: $(OBJ) | esp-idf-stamp $(STEPECHO) "LINK $@" - $(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(ESP_IDF_COMPONENTS_EXPANDED) $(BINARY_BLOBS) $(MBEDTLS_COMPONENTS_LINK_EXPANDED) $(BUILD)/esp-idf/esp-idf/newlib/libnewlib.a -Wl,--end-group -u newlib_include_pthread_impl -Wl,--start-group $(LIBS) -Wl,--end-group $(BUILD)/esp-idf/esp-idf/pthread/libpthread.a -u __cxx_fatal_exception + $(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(ESP_IDF_COMPONENTS_EXPANDED) $(BINARY_BLOBS) $(MBEDTLS_COMPONENTS_LINK_EXPANDED) $(BUILD)/esp-idf/esp-idf/newlib/libnewlib.a -Wl,--end-group -u newlib_include_pthread_impl -u ld_include_highint_hdl -Wl,--start-group $(LIBS) -Wl,--end-group $(BUILD)/esp-idf/esp-idf/pthread/libpthread.a -u __cxx_fatal_exception $(BUILD)/circuitpython-firmware.bin: $(BUILD)/firmware.elf | tools/build_memory_info.py $(STEPECHO) "Create $@" $(Q)esptool.py --chip $(IDF_TARGET) elf2image $(FLASH_FLAGS) --elf-sha256-offset 0xb0 -o $@ $^ - $(Q)$(PYTHON) tools/build_memory_info.py $< $(BUILD)/esp-idf/sdkconfig $@ + $(Q)$(PYTHON) tools/build_memory_info.py $< $(BUILD)/esp-idf/sdkconfig $@ $(BUILD) $(BUILD)/firmware.bin: $(BUILD)/circuitpython-firmware.bin | esp-idf-stamp $(Q)$(PYTHON) ../../tools/join_bins.py $@ $(BOOTLOADER_OFFSET) $(BUILD)/esp-idf/bootloader/bootloader.bin $(PARTITION_TABLE_OFFSET) $(BUILD)/esp-idf/partition_table/partition-table.bin $(FIRMWARE_OFFSET) $(BUILD)/circuitpython-firmware.bin diff --git a/ports/espressif/background.c b/ports/espressif/background.c index 0b5bb96a3b..3fac768f3f 100644 --- a/ports/espressif/background.c +++ b/ports/espressif/background.c @@ -40,7 +40,7 @@ #include "common-hal/pulseio/PulseIn.h" #endif -void port_background_task(void) { +void port_background_tick(void) { // Zero delay in case FreeRTOS wants to switch to something else. vTaskDelay(0); #if CIRCUITPY_PULSEIO @@ -48,6 +48,9 @@ void port_background_task(void) { #endif } +void port_background_task(void) { +} + void port_start_background_task(void) { } diff --git a/ports/espressif/bindings/espcamera/Camera.c b/ports/espressif/bindings/espcamera/Camera.c new file mode 100644 index 0000000000..824bc7d3dc --- /dev/null +++ b/ports/espressif/bindings/espcamera/Camera.c @@ -0,0 +1,1001 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/mphal.h" +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "bindings/espcamera/__init__.h" +#include "bindings/espcamera/Camera.h" +#include "common-hal/espcamera/Camera.h" + +#include "shared-bindings/displayio/Bitmap.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "esp_camera.h" +#include "sensor.h" + +//| class Camera: +//| def __init__( +//| self, +//| *, +//| data_pins: List[microcontroller.Pin], +//| pixel_clock_pin: microcontroller.Pin, +//| vsync_pin: microcontroller.Pin, +//| href_pin: microcontroller.Pin, +//| i2c: busio.I2C, +//| external_clock_pin: Optional[microcontroller.Pin] = None, +//| external_clock_frequency: int = 20_000_000, +//| powerdown_pin: Optional[microcontroller.Pin] = None, +//| reset_pin: Optional[microcontroller.Pin] = None, +//| pixel_format: PixelFormat = PixelFormat.RGB565, +//| frame_size: FrameSize = FrameSize.QQVGA, +//| jpeg_quality: int = 15, +//| framebuffer_count: int = 1, +//| grab_mode: GrabMode = GrabMode.WHEN_EMPTY, +//| ) -> None: +//| """ +//| Configure and initialize a camera with the given properties +//| +//| This driver requires that the ``CIRCUITPY_RESERVED_PSRAM`` in ``settings.toml`` be large enough to hold the camera frambuffer(s). Generally, boards with built-in cameras will have a default setting that is large enough. If the constructor raises a MemoryError or an IDFError, this probably indicates the setting is too small and should be increased. +//| +//| +//| .. important:: +//| +//| Not all supported sensors have all +//| of the properties listed below. For instance, the +//| OV5640 supports `denoise`, but the +//| OV2640 does not. The underlying esp32-camera +//| library does not provide a reliable API to check +//| which settings are supported. CircuitPython makes +//| a best effort to determine when an unsupported +//| property is set and will raise an exception in +//| that case. +//| +//| :param data_pins: The 8 data data_pins used for image data transfer from the camera module, least significant bit first +//| :param pixel_clock_pin: The pixel clock output from the camera module +//| :param vsync_pin: The vertical sync pulse output from the camera module +//| :param href_pin: The horizontal reference output from the camera module +//| :param i2c: The I2C bus connected to the camera module +//| :param external_clock_pin: The pin on which to generate the external clock +//| :param external_clock_frequency: The frequency generated on the external clock pin +//| :param powerdown_pin: The powerdown input to the camera module +//| :param reset_pin: The reset input to the camera module +//| :param pixel_format: The pixel format of the captured image +//| :param frame_size: The size of captured image +//| :param jpeg_quality: For `PixelFormat.JPEG`, the quality. Higher numbers increase quality. If the quality is too high, the JPEG data will be larger than the availalble buffer size and the image will be unusable or truncated. The exact range of appropriate values depends on the sensor and must be determined empirically. +//| :param framebuffer_count: The number of framebuffers (1 for single-buffered and 2 for double-buffered) +//| :param grab_mode: When to grab a new frame +//| """ +STATIC mp_obj_t espcamera_camera_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_data_pins, ARG_pixel_clock_pin, ARG_vsync_pin, ARG_href_pin, ARG_i2c, ARG_external_clock_pin, ARG_external_clock_frequency, ARG_powerdown_pin, ARG_reset_pin, ARG_pixel_format, ARG_frame_size, ARG_jpeg_quality, ARG_framebuffer_count, ARG_grab_mode, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_data_pins, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_pixel_clock_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_vsync_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_href_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_i2c, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_external_clock_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = MP_ROM_NONE } }, + { MP_QSTR_external_clock_frequency, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 20000000L } }, + { MP_QSTR_powerdown_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = MP_ROM_NONE } }, + { MP_QSTR_reset_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = MP_ROM_NONE } }, + { MP_QSTR_pixel_format, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = MP_ROM_PTR((void *)&pixel_format_RGB565_obj) } }, + { MP_QSTR_frame_size, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = MP_ROM_PTR((void *)&frame_size_QQVGA_obj) } }, + { MP_QSTR_jpeg_quality, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 15 } }, + { MP_QSTR_framebuffer_count, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 1 } }, + { MP_QSTR_grab_mode, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = MP_ROM_PTR((void *)&grab_mode_WHEN_EMPTY_obj) } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + MP_STATIC_ASSERT(MP_ARRAY_SIZE(allowed_args) == NUM_ARGS); + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + uint8_t data_pins[8]; + uint8_t data_pin_count; + validate_pins(MP_QSTR_data_pins, data_pins, MP_ARRAY_SIZE(data_pins), args[ARG_data_pins].u_obj, &data_pin_count); + mp_arg_validate_length(data_pin_count, 8, MP_QSTR_data_pins); + + const mcu_pin_obj_t *pixel_clock_pin = + validate_obj_is_free_pin(args[ARG_pixel_clock_pin].u_obj, MP_QSTR_pixel_clock_pin); + const mcu_pin_obj_t *vsync_pin = + validate_obj_is_free_pin(args[ARG_vsync_pin].u_obj, MP_QSTR_vsync_pin); + const mcu_pin_obj_t *href_pin = + validate_obj_is_free_pin(args[ARG_href_pin].u_obj, MP_QSTR_href_pin); + busio_i2c_obj_t *i2c = MP_OBJ_TO_PTR(mp_arg_validate_type(args[ARG_i2c].u_obj, &busio_i2c_type, MP_QSTR_i2c)); + const mcu_pin_obj_t *external_clock_pin = + validate_obj_is_free_pin_or_none(args[ARG_external_clock_pin].u_obj, MP_QSTR_external_clock_pin); + const mcu_pin_obj_t *powerdown_pin = + validate_obj_is_free_pin_or_none(args[ARG_powerdown_pin].u_obj, MP_QSTR_powerdown_pin); + const mcu_pin_obj_t *reset_pin = + validate_obj_is_free_pin_or_none(args[ARG_reset_pin].u_obj, MP_QSTR_reset_pin); + const mp_int_t external_clock_frequency = + mp_arg_validate_int_range(args[ARG_external_clock_frequency].u_int, 0, 40000000, MP_QSTR_external_clock_frequency); + + camera_grab_mode_t grab_mode = validate_grab_mode(args[ARG_grab_mode].u_obj, MP_QSTR_grab_mode); + framesize_t frame_size = validate_frame_size(args[ARG_frame_size].u_obj, MP_QSTR_frame_size); + pixformat_t pixel_format = validate_pixel_format(args[ARG_pixel_format].u_obj, MP_QSTR_pixel_format); + mp_int_t jpeg_quality = mp_arg_validate_int_range(args[ARG_jpeg_quality].u_int, 2, 55, MP_QSTR_jpeg_quality); + mp_int_t framebuffer_count = mp_arg_validate_int_range(args[ARG_framebuffer_count].u_int, 1, 2, MP_QSTR_framebuffer_count); + + espcamera_camera_obj_t *self = m_new_obj(espcamera_camera_obj_t); + self->base.type = &espcamera_camera_type; + common_hal_espcamera_camera_construct( + self, + data_pins, + external_clock_pin, + pixel_clock_pin, + vsync_pin, + href_pin, + powerdown_pin, + reset_pin, + i2c, + external_clock_frequency, + pixel_format, + frame_size, + jpeg_quality, + framebuffer_count, + grab_mode); + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the camera and releases all memory resources for reuse.""" +//| ... +STATIC mp_obj_t espcamera_camera_deinit(mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_espcamera_camera_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_deinit_obj, espcamera_camera_deinit); + +STATIC void check_for_deinit(espcamera_camera_obj_t *self) { + if (common_hal_espcamera_camera_deinited(self)) { + raise_deinited_error(); + } +} + +//| def __enter__(self) -> Camera: +//| """No-op used by Context Managers.""" +//| ... +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +STATIC mp_obj_t espcamera_camera_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + return espcamera_camera_deinit(args[0]); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espcamera_camera___exit___obj, 4, 4, espcamera_camera_obj___exit__); + +//| frame_available: bool +//| """True if a frame is available, False otherwise""" + +STATIC mp_obj_t espcamera_camera_frame_available_get(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(esp_camera_fb_available()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_frame_available_get_obj, espcamera_camera_frame_available_get); + +MP_PROPERTY_GETTER(espcamera_camera_frame_available_obj, + (mp_obj_t)&espcamera_camera_frame_available_get_obj); + +//| def take( +//| self, timeout: Optional[float] = 0.25 +//| ) -> Optional[displayio.Bitmap | ReadableBuffer]: +//| """Record a frame. Wait up to 'timeout' seconds for a frame to be captured. +//| +//| In the case of timeout, `None` is returned. +//| If `pixel_format` is `PixelFormat.JPEG`, the returned value is a read-only `memoryview`. +//| Otherwise, the returned value is a read-only `displayio.Bitmap`. +//| """ +STATIC mp_obj_t espcamera_camera_take(size_t n_args, const mp_obj_t *args) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(args[0]); + mp_float_t timeout = n_args < 2 ? MICROPY_FLOAT_CONST(0.25) : mp_obj_get_float(args[1]); + check_for_deinit(self); + camera_fb_t *result = common_hal_espcamera_camera_take(self, (int)MICROPY_FLOAT_C_FUN(round)(timeout * 1000)); + if (!result) { + return mp_const_none; + } + pixformat_t format = common_hal_espcamera_camera_get_pixel_format(self); + if (format == PIXFORMAT_JPEG) { + return mp_obj_new_memoryview('b', result->len, result->buf); + } else { + int width = common_hal_espcamera_camera_get_width(self); + int height = common_hal_espcamera_camera_get_height(self); + displayio_bitmap_t *bitmap = m_new_obj(displayio_bitmap_t); + bitmap->base.type = &displayio_bitmap_type; + common_hal_displayio_bitmap_construct_from_buffer(bitmap, width, height, (format == PIXFORMAT_RGB565) ? 16 : 8, (uint32_t *)(void *)result->buf, true); + return bitmap; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espcamera_camera_take_obj, 1, 2, espcamera_camera_take); + + +//| def reconfigure( +//| self, +//| frame_size: Optional[FrameSize] = None, +//| pixel_format: Optional[PixelFormat] = None, +//| grab_mode: Optional[GrabMode] = None, +//| framebuffer_count: Optional[int] = None, +//| ) -> None: +//| """Change multiple related camera settings simultaneously +//| +//| Because these settings interact in complex ways, and take longer than +//| the other properties to set, they are set together in a single function call. +//| +//| If an argument is unspecified or None, then the setting is unchanged.""" + +STATIC mp_obj_t espcamera_camera_reconfigure(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + + enum { ARG_frame_size, ARG_pixel_format, ARG_grab_mode, ARG_framebuffer_count }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_frame_size, MP_ARG_OBJ, {.u_obj = MP_ROM_NONE} }, + { MP_QSTR_pixel_format, MP_ARG_OBJ, {.u_obj = MP_ROM_NONE} }, + { MP_QSTR_grab_mode, MP_ARG_OBJ, {.u_obj = MP_ROM_NONE} }, + { MP_QSTR_framebuffer_count, MP_ARG_OBJ, {.u_obj = MP_ROM_NONE} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + framesize_t frame_size = + args[ARG_frame_size].u_obj != MP_ROM_NONE + ? validate_frame_size(args[ARG_frame_size].u_obj, MP_QSTR_frame_size) + : common_hal_espcamera_camera_get_frame_size(self); + pixformat_t pixel_format = + args[ARG_pixel_format].u_obj != MP_ROM_NONE + ? validate_pixel_format(args[ARG_pixel_format].u_obj, MP_QSTR_pixel_format) + : common_hal_espcamera_camera_get_pixel_format(self); + camera_grab_mode_t grab_mode = + args[ARG_grab_mode].u_obj != MP_ROM_NONE + ? validate_grab_mode(args[ARG_grab_mode].u_obj, MP_QSTR_grab_mode) + : common_hal_espcamera_camera_get_grab_mode(self); + bool framebuffer_count = + args[ARG_framebuffer_count].u_obj != MP_ROM_NONE + ? mp_obj_get_int(args[ARG_framebuffer_count].u_obj) + : common_hal_espcamera_camera_get_framebuffer_count(self); + + common_hal_espcamera_camera_reconfigure(self, frame_size, pixel_format, grab_mode, framebuffer_count); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(espcamera_camera_reconfigure_obj, 1, espcamera_camera_reconfigure); + +//| pixel_format: PixelFormat +//| """The pixel format of captured frames""" + +STATIC mp_obj_t espcamera_camera_get_pixel_format(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return cp_enum_find(&espcamera_pixel_format_type, common_hal_espcamera_camera_get_pixel_format(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_pixel_format_obj, espcamera_camera_get_pixel_format); + +MP_PROPERTY_GETTER(espcamera_camera_pixel_format_obj, + (mp_obj_t)&espcamera_camera_get_pixel_format_obj); + + +//| frame_size: FrameSize +//| """The size of captured frames""" + +STATIC mp_obj_t espcamera_camera_get_frame_size(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return cp_enum_find(&espcamera_frame_size_type, common_hal_espcamera_camera_get_frame_size(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_frame_size_obj, espcamera_camera_get_frame_size); + +MP_PROPERTY_GETTER(espcamera_camera_frame_size_obj, + (mp_obj_t)&espcamera_camera_get_frame_size_obj); + +//| contrast: int +//| """The sensor contrast. Positive values increase contrast, negative values lower it. The total range is device-specific but is often from -2 to +2 inclusive.""" + +STATIC mp_obj_t espcamera_camera_get_contrast(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_contrast(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_contrast_obj, espcamera_camera_get_contrast); + +STATIC mp_obj_t espcamera_camera_set_contrast(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_contrast(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_contrast_obj, espcamera_camera_set_contrast); +MP_PROPERTY_GETSET(espcamera_camera_contrast_obj, + (mp_obj_t)&espcamera_camera_get_contrast_obj, + (mp_obj_t)&espcamera_camera_set_contrast_obj); + +//| brightness: int +//| """The sensor brightness. Positive values increase brightness, negative values lower it. The total range is device-specific but is often from -2 to +2 inclusive.""" + +STATIC mp_obj_t espcamera_camera_get_brightness(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_brightness(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_brightness_obj, espcamera_camera_get_brightness); + +STATIC mp_obj_t espcamera_camera_set_brightness(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_brightness(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_brightness_obj, espcamera_camera_set_brightness); +MP_PROPERTY_GETSET(espcamera_camera_brightness_obj, + (mp_obj_t)&espcamera_camera_get_brightness_obj, + (mp_obj_t)&espcamera_camera_set_brightness_obj); + +//| saturation: int +//| """The sensor saturation. Positive values increase saturation (more vibrant colors), negative values lower it (more muted colors). The total range is device-specific but the value is often from -2 to +2 inclusive.""" + +STATIC mp_obj_t espcamera_camera_get_saturation(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_saturation(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_saturation_obj, espcamera_camera_get_saturation); + +STATIC mp_obj_t espcamera_camera_set_saturation(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_saturation(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_saturation_obj, espcamera_camera_set_saturation); +MP_PROPERTY_GETSET(espcamera_camera_saturation_obj, + (mp_obj_t)&espcamera_camera_get_saturation_obj, + (mp_obj_t)&espcamera_camera_set_saturation_obj); + +//| sharpness: int +//| """The sensor sharpness. Positive values increase sharpness (more defined edges), negative values lower it (softer edges). The total range is device-specific but the value is often from -2 to +2 inclusive.""" + +STATIC mp_obj_t espcamera_camera_get_sharpness(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_sharpness(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_sharpness_obj, espcamera_camera_get_sharpness); + +STATIC mp_obj_t espcamera_camera_set_sharpness(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_sharpness(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_sharpness_obj, espcamera_camera_set_sharpness); +MP_PROPERTY_GETSET(espcamera_camera_sharpness_obj, + (mp_obj_t)&espcamera_camera_get_sharpness_obj, + (mp_obj_t)&espcamera_camera_set_sharpness_obj); + +//| denoise: int +//| """The sensor 'denoise' setting. Any camera sensor has inherent 'noise', especially in low brightness environments. Software algorithms can decrease noise at the expense of fine detail. A larger value increases the amount of software noise removal. The total range is device-specific but the value is often from 0 to 10.""" + +STATIC mp_obj_t espcamera_camera_get_denoise(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_denoise(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_denoise_obj, espcamera_camera_get_denoise); + +STATIC mp_obj_t espcamera_camera_set_denoise(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_denoise(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_denoise_obj, espcamera_camera_set_denoise); +MP_PROPERTY_GETSET(espcamera_camera_denoise_obj, + (mp_obj_t)&espcamera_camera_get_denoise_obj, + (mp_obj_t)&espcamera_camera_set_denoise_obj); + +//| gain_ceiling: GainCeiling +//| """The sensor 'gain ceiling' setting. "Gain" is an analog multiplier applied to the raw sensor data. The 'ceiling' is the maximum gain value that the sensor will use. A higher gain means that the sensor has a greater response to light, but also makes sensor noise more visible.""" + +STATIC mp_obj_t espcamera_camera_get_gain_ceiling(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return cp_enum_find(&espcamera_gain_ceiling_type, common_hal_espcamera_camera_get_gainceiling(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_gain_ceiling_obj, espcamera_camera_get_gain_ceiling); + +STATIC mp_obj_t espcamera_camera_set_gain_ceiling(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_gainceiling(self, validate_gain_ceiling(arg, MP_QSTR_gain_ceiling)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_gain_ceiling_obj, espcamera_camera_set_gain_ceiling); +MP_PROPERTY_GETSET(espcamera_camera_gain_ceiling_obj, + (mp_obj_t)&espcamera_camera_get_gain_ceiling_obj, + (mp_obj_t)&espcamera_camera_set_gain_ceiling_obj); + +//| quality: int +//| """The 'quality' setting when capturing JPEG images. This is similar to the quality setting when exporting a jpeg image from photo editing software. Typical values range from 5 to 40, with higher numbers leading to larger image sizes and better overall image quality. However, when the quality is set to a high number, the total size of the JPEG data can exceed the size of an internal buffer, causing image capture to fail.""" + +STATIC mp_obj_t espcamera_camera_get_quality(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_quality(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_quality_obj, espcamera_camera_get_quality); + +STATIC mp_obj_t espcamera_camera_set_quality(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_quality(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_quality_obj, espcamera_camera_set_quality); +MP_PROPERTY_GETSET(espcamera_camera_quality_obj, + (mp_obj_t)&espcamera_camera_get_quality_obj, + (mp_obj_t)&espcamera_camera_set_quality_obj); + +//| colorbar: bool +//| """When `True`, a test pattern image is captured and the real sensor data is not used.""" + +STATIC mp_obj_t espcamera_camera_get_colorbar(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_colorbar(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_colorbar_obj, espcamera_camera_get_colorbar); + +STATIC mp_obj_t espcamera_camera_set_colorbar(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_colorbar(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_colorbar_obj, espcamera_camera_set_colorbar); +MP_PROPERTY_GETSET(espcamera_camera_colorbar_obj, + (mp_obj_t)&espcamera_camera_get_colorbar_obj, + (mp_obj_t)&espcamera_camera_set_colorbar_obj); + +//| whitebal: bool +//| """When `True`, the camera attempts to automatically control white balance. When `False`, the `wb_mode` setting is used instead.""" + +STATIC mp_obj_t espcamera_camera_get_whitebal(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_whitebal(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_whitebal_obj, espcamera_camera_get_whitebal); + +STATIC mp_obj_t espcamera_camera_set_whitebal(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_whitebal(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_whitebal_obj, espcamera_camera_set_whitebal); +MP_PROPERTY_GETSET(espcamera_camera_whitebal_obj, + (mp_obj_t)&espcamera_camera_get_whitebal_obj, + (mp_obj_t)&espcamera_camera_set_whitebal_obj); + +//| gain_ctrl: bool +//| """When `True`, the camera attempts to automatically control the sensor gain, up to the value in the `gain_ceiling` property. When `False`, the `agc_gain` setting is used instead.""" + +STATIC mp_obj_t espcamera_camera_get_gain_ctrl(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_gain_ctrl(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_gain_ctrl_obj, espcamera_camera_get_gain_ctrl); + +STATIC mp_obj_t espcamera_camera_set_gain_ctrl(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_gain_ctrl(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_gain_ctrl_obj, espcamera_camera_set_gain_ctrl); +MP_PROPERTY_GETSET(espcamera_camera_gain_ctrl_obj, + (mp_obj_t)&espcamera_camera_get_gain_ctrl_obj, + (mp_obj_t)&espcamera_camera_set_gain_ctrl_obj); + +//| exposure_ctrl: bool +//| """When `True` the camera attempts to automatically control the exposure. When `False`, the `aec_value` setting is used instead.""" + +STATIC mp_obj_t espcamera_camera_get_exposure_ctrl(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_exposure_ctrl(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_exposure_ctrl_obj, espcamera_camera_get_exposure_ctrl); + +STATIC mp_obj_t espcamera_camera_set_exposure_ctrl(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_exposure_ctrl(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_exposure_ctrl_obj, espcamera_camera_set_exposure_ctrl); +MP_PROPERTY_GETSET(espcamera_camera_exposure_ctrl_obj, + (mp_obj_t)&espcamera_camera_get_exposure_ctrl_obj, + (mp_obj_t)&espcamera_camera_set_exposure_ctrl_obj); + +//| hmirror: bool +//| """When `True` the camera image is mirrored left-to-right""" + +STATIC mp_obj_t espcamera_camera_get_hmirror(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_hmirror(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_hmirror_obj, espcamera_camera_get_hmirror); + +STATIC mp_obj_t espcamera_camera_set_hmirror(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_hmirror(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_hmirror_obj, espcamera_camera_set_hmirror); +MP_PROPERTY_GETSET(espcamera_camera_hmirror_obj, + (mp_obj_t)&espcamera_camera_get_hmirror_obj, + (mp_obj_t)&espcamera_camera_set_hmirror_obj); + +//| vflip: bool +//| """When `True` the camera image is flipped top-to-bottom""" + +STATIC mp_obj_t espcamera_camera_get_vflip(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_vflip(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_vflip_obj, espcamera_camera_get_vflip); + +STATIC mp_obj_t espcamera_camera_set_vflip(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_vflip(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_vflip_obj, espcamera_camera_set_vflip); +MP_PROPERTY_GETSET(espcamera_camera_vflip_obj, + (mp_obj_t)&espcamera_camera_get_vflip_obj, + (mp_obj_t)&espcamera_camera_set_vflip_obj); + +//| aec2: bool +//| """When `True` the sensor's "night mode" is enabled, extending the range of automatic gain control.""" + +STATIC mp_obj_t espcamera_camera_get_aec2(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_aec2(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_aec2_obj, espcamera_camera_get_aec2); + +STATIC mp_obj_t espcamera_camera_set_aec2(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_aec2(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_aec2_obj, espcamera_camera_set_aec2); +MP_PROPERTY_GETSET(espcamera_camera_aec2_obj, + (mp_obj_t)&espcamera_camera_get_aec2_obj, + (mp_obj_t)&espcamera_camera_set_aec2_obj); + +//| awb_gain: bool +//| """Access the awb_gain property of the camera sensor""" + +STATIC mp_obj_t espcamera_camera_get_awb_gain(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_awb_gain(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_awb_gain_obj, espcamera_camera_get_awb_gain); + +STATIC mp_obj_t espcamera_camera_set_awb_gain(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_awb_gain(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_awb_gain_obj, espcamera_camera_set_awb_gain); +MP_PROPERTY_GETSET(espcamera_camera_awb_gain_obj, + (mp_obj_t)&espcamera_camera_get_awb_gain_obj, + (mp_obj_t)&espcamera_camera_set_awb_gain_obj); + +//| agc_gain: int +//| """Access the gain level of the sensor. Higher values produce brighter images. Typical settings range from 0 to 30. """ + +STATIC mp_obj_t espcamera_camera_get_agc_gain(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_agc_gain(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_agc_gain_obj, espcamera_camera_get_agc_gain); + +STATIC mp_obj_t espcamera_camera_set_agc_gain(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_agc_gain(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_agc_gain_obj, espcamera_camera_set_agc_gain); +MP_PROPERTY_GETSET(espcamera_camera_agc_gain_obj, + (mp_obj_t)&espcamera_camera_get_agc_gain_obj, + (mp_obj_t)&espcamera_camera_set_agc_gain_obj); + +//| aec_value: int +//| """Access the exposure value of the camera. Higher values produce brighter images. Typical settings range from 0 to 1200.""" + +STATIC mp_obj_t espcamera_camera_get_aec_value(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_aec_value(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_aec_value_obj, espcamera_camera_get_aec_value); + +STATIC mp_obj_t espcamera_camera_set_aec_value(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_aec_value(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_aec_value_obj, espcamera_camera_set_aec_value); +MP_PROPERTY_GETSET(espcamera_camera_aec_value_obj, + (mp_obj_t)&espcamera_camera_get_aec_value_obj, + (mp_obj_t)&espcamera_camera_set_aec_value_obj); + +//| special_effect: int +//| """Enable a "special effect". Zero is no special effect. On OV5640, special effects range from 0 to 6 inclusive and select various color modes.""" + +STATIC mp_obj_t espcamera_camera_get_special_effect(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_special_effect(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_special_effect_obj, espcamera_camera_get_special_effect); + +STATIC mp_obj_t espcamera_camera_set_special_effect(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_special_effect(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_special_effect_obj, espcamera_camera_set_special_effect); +MP_PROPERTY_GETSET(espcamera_camera_special_effect_obj, + (mp_obj_t)&espcamera_camera_get_special_effect_obj, + (mp_obj_t)&espcamera_camera_set_special_effect_obj); + +//| wb_mode: int +//| """The white balance mode. 0 is automatic white balance. Typical values range from 0 to 4 inclusive.""" + +STATIC mp_obj_t espcamera_camera_get_wb_mode(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_wb_mode(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_wb_mode_obj, espcamera_camera_get_wb_mode); + +STATIC mp_obj_t espcamera_camera_set_wb_mode(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_wb_mode(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_wb_mode_obj, espcamera_camera_set_wb_mode); +MP_PROPERTY_GETSET(espcamera_camera_wb_mode_obj, + (mp_obj_t)&espcamera_camera_get_wb_mode_obj, + (mp_obj_t)&espcamera_camera_set_wb_mode_obj); + +//| ae_level: int +//| """The exposure offset for automatic exposure. Typical values range from -2 to +2.""" + +STATIC mp_obj_t espcamera_camera_get_ae_level(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_ae_level(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_ae_level_obj, espcamera_camera_get_ae_level); + +STATIC mp_obj_t espcamera_camera_set_ae_level(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_ae_level(self, mp_obj_get_int(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_ae_level_obj, espcamera_camera_set_ae_level); +MP_PROPERTY_GETSET(espcamera_camera_ae_level_obj, + (mp_obj_t)&espcamera_camera_get_ae_level_obj, + (mp_obj_t)&espcamera_camera_set_ae_level_obj); + +//| dcw: bool +//| """When `True` an advanced white balance mode is selected.""" + +STATIC mp_obj_t espcamera_camera_get_dcw(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_dcw(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_dcw_obj, espcamera_camera_get_dcw); + +STATIC mp_obj_t espcamera_camera_set_dcw(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_dcw(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_dcw_obj, espcamera_camera_set_dcw); +MP_PROPERTY_GETSET(espcamera_camera_dcw_obj, + (mp_obj_t)&espcamera_camera_get_dcw_obj, + (mp_obj_t)&espcamera_camera_set_dcw_obj); + +//| bpc: bool +//| """When `True`, "black point compensation" is enabled. This can make black parts of the image darker.""" + +STATIC mp_obj_t espcamera_camera_get_bpc(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_bpc(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_bpc_obj, espcamera_camera_get_bpc); + +STATIC mp_obj_t espcamera_camera_set_bpc(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_bpc(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_bpc_obj, espcamera_camera_set_bpc); +MP_PROPERTY_GETSET(espcamera_camera_bpc_obj, + (mp_obj_t)&espcamera_camera_get_bpc_obj, + (mp_obj_t)&espcamera_camera_set_bpc_obj); + +//| wpc: bool +//| """When `True`, "white point compensation" is enabled. This can make white parts of the image whiter.""" + +STATIC mp_obj_t espcamera_camera_get_wpc(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_wpc(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_wpc_obj, espcamera_camera_get_wpc); + +STATIC mp_obj_t espcamera_camera_set_wpc(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_wpc(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_wpc_obj, espcamera_camera_set_wpc); +MP_PROPERTY_GETSET(espcamera_camera_wpc_obj, + (mp_obj_t)&espcamera_camera_get_wpc_obj, + (mp_obj_t)&espcamera_camera_set_wpc_obj); + +//| raw_gma: bool +//| """When `True`, raw gamma mode is enabled.""" + +STATIC mp_obj_t espcamera_camera_get_raw_gma(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_raw_gma(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_raw_gma_obj, espcamera_camera_get_raw_gma); + +STATIC mp_obj_t espcamera_camera_set_raw_gma(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_raw_gma(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_raw_gma_obj, espcamera_camera_set_raw_gma); +MP_PROPERTY_GETSET(espcamera_camera_raw_gma_obj, + (mp_obj_t)&espcamera_camera_get_raw_gma_obj, + (mp_obj_t)&espcamera_camera_set_raw_gma_obj); + +//| lenc: bool +//| """Enable "lens correction". This can help compensate for light fall-off at the edge of the sensor area.""" + +STATIC mp_obj_t espcamera_camera_get_lenc(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_lenc(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_lenc_obj, espcamera_camera_get_lenc); + +STATIC mp_obj_t espcamera_camera_set_lenc(const mp_obj_t self_in, const mp_obj_t arg) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_espcamera_camera_set_lenc(self, mp_obj_is_true(arg)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espcamera_camera_set_lenc_obj, espcamera_camera_set_lenc); +MP_PROPERTY_GETSET(espcamera_camera_lenc_obj, + (mp_obj_t)&espcamera_camera_get_lenc_obj, + (mp_obj_t)&espcamera_camera_set_lenc_obj); + +//| max_frame_size: FrameSize +//| """The maximum frame size that can be captured""" +STATIC mp_obj_t espcamera_camera_get_max_frame_size(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return cp_enum_find(&espcamera_frame_size_type, common_hal_espcamera_camera_get_max_frame_size(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_max_frame_size_obj, espcamera_camera_get_max_frame_size); + +MP_PROPERTY_GETTER(espcamera_camera_max_frame_size_obj, + (mp_obj_t)&espcamera_camera_get_max_frame_size_obj); + + +//| address: int +//| """The I2C (SCCB) address of the sensor""" +STATIC mp_obj_t espcamera_camera_get_address(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_address(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_address_obj, espcamera_camera_get_address); + +MP_PROPERTY_GETTER(espcamera_camera_address_obj, + (mp_obj_t)&espcamera_camera_get_address_obj); + + +//| sensor_name: str +//| """The name of the sensor""" +STATIC mp_obj_t espcamera_camera_get_sensor_name(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + const char *sensor_name = common_hal_espcamera_camera_get_sensor_name(self); + return mp_obj_new_str(sensor_name, strlen(sensor_name)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_sensor_name_obj, espcamera_camera_get_sensor_name); + +MP_PROPERTY_GETTER(espcamera_camera_sensor_name_obj, + (mp_obj_t)&espcamera_camera_get_sensor_name_obj); + + +//| supports_jpeg: bool +//| """True if the sensor can capture images in JPEG format""" +STATIC mp_obj_t espcamera_camera_get_supports_jpeg(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_espcamera_camera_get_supports_jpeg(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_supports_jpeg_obj, espcamera_camera_get_supports_jpeg); + +MP_PROPERTY_GETTER(espcamera_camera_supports_jpeg_obj, + (mp_obj_t)&espcamera_camera_get_supports_jpeg_obj); + +//| height: int +//| """The height of the image being captured""" +STATIC mp_obj_t espcamera_camera_get_height(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_height(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_height_obj, espcamera_camera_get_height); + +MP_PROPERTY_GETTER(espcamera_camera_height_obj, + (mp_obj_t)&espcamera_camera_get_height_obj); + +//| width: int +//| """The width of the image being captured""" +STATIC mp_obj_t espcamera_camera_get_width(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_width(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_width_obj, espcamera_camera_get_width); + +MP_PROPERTY_GETTER(espcamera_camera_width_obj, + (mp_obj_t)&espcamera_camera_get_width_obj); + +//| grab_mode: GrabMode +//| """The grab mode of the camera""" +STATIC mp_obj_t espcamera_camera_get_grab_mode(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return cp_enum_find(&espcamera_grab_mode_type, common_hal_espcamera_camera_get_grab_mode(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_grab_mode_obj, espcamera_camera_get_grab_mode); + +MP_PROPERTY_GETTER(espcamera_camera_grab_mode_obj, + (mp_obj_t)&espcamera_camera_get_grab_mode_obj); + + +//| framebuffer_count: int +//| """True if double buffering is used""" +//| +STATIC mp_obj_t espcamera_camera_get_framebuffer_count(const mp_obj_t self_in) { + espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_espcamera_camera_get_framebuffer_count(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_get_framebuffer_count_obj, espcamera_camera_get_framebuffer_count); + +MP_PROPERTY_GETTER(espcamera_camera_framebuffer_count_obj, + (mp_obj_t)&espcamera_camera_get_framebuffer_count_obj); + + +STATIC const mp_rom_map_elem_t espcamera_camera_locals_table[] = { + { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&espcamera_camera_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_aec2), MP_ROM_PTR(&espcamera_camera_aec2_obj) }, + { MP_ROM_QSTR(MP_QSTR_aec_value), MP_ROM_PTR(&espcamera_camera_aec_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_ae_level), MP_ROM_PTR(&espcamera_camera_ae_level_obj) }, + { MP_ROM_QSTR(MP_QSTR_agc_gain), MP_ROM_PTR(&espcamera_camera_agc_gain_obj) }, + { MP_ROM_QSTR(MP_QSTR_awb_gain), MP_ROM_PTR(&espcamera_camera_awb_gain_obj) }, + { MP_ROM_QSTR(MP_QSTR_bpc), MP_ROM_PTR(&espcamera_camera_bpc_obj) }, + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&espcamera_camera_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_colorbar), MP_ROM_PTR(&espcamera_camera_colorbar_obj) }, + { MP_ROM_QSTR(MP_QSTR_contrast), MP_ROM_PTR(&espcamera_camera_contrast_obj) }, + { MP_ROM_QSTR(MP_QSTR_dcw), MP_ROM_PTR(&espcamera_camera_dcw_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espcamera_camera_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_denoise), MP_ROM_PTR(&espcamera_camera_denoise_obj) }, + { MP_ROM_QSTR(MP_QSTR_framebuffer_count), MP_ROM_PTR(&espcamera_camera_framebuffer_count_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&espcamera_camera___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_exposure_ctrl), MP_ROM_PTR(&espcamera_camera_exposure_ctrl_obj) }, + { MP_ROM_QSTR(MP_QSTR_frame_available), MP_ROM_PTR(&espcamera_camera_frame_available_obj) }, + { MP_ROM_QSTR(MP_QSTR_frame_size), MP_ROM_PTR(&espcamera_camera_frame_size_obj) }, + { MP_ROM_QSTR(MP_QSTR_gain_ceiling), MP_ROM_PTR(&espcamera_camera_gain_ceiling_obj) }, + { MP_ROM_QSTR(MP_QSTR_gain_ctrl), MP_ROM_PTR(&espcamera_camera_gain_ctrl_obj) }, + { MP_ROM_QSTR(MP_QSTR_grab_mode), MP_ROM_PTR(&espcamera_camera_grab_mode_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&espcamera_camera_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_hmirror), MP_ROM_PTR(&espcamera_camera_hmirror_obj) }, + { MP_ROM_QSTR(MP_QSTR_lenc), MP_ROM_PTR(&espcamera_camera_lenc_obj) }, + { MP_ROM_QSTR(MP_QSTR_max_frame_size), MP_ROM_PTR(&espcamera_camera_max_frame_size_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_format), MP_ROM_PTR(&espcamera_camera_pixel_format_obj) }, + { MP_ROM_QSTR(MP_QSTR_quality), MP_ROM_PTR(&espcamera_camera_quality_obj) }, + { MP_ROM_QSTR(MP_QSTR_raw_gma), MP_ROM_PTR(&espcamera_camera_raw_gma_obj) }, + { MP_ROM_QSTR(MP_QSTR_reconfigure), MP_ROM_PTR(&espcamera_camera_reconfigure_obj) }, + { MP_ROM_QSTR(MP_QSTR_saturation), MP_ROM_PTR(&espcamera_camera_saturation_obj) }, + { MP_ROM_QSTR(MP_QSTR_sensor_name), MP_ROM_PTR(&espcamera_camera_sensor_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_sharpness), MP_ROM_PTR(&espcamera_camera_sharpness_obj) }, + { MP_ROM_QSTR(MP_QSTR_special_effect), MP_ROM_PTR(&espcamera_camera_special_effect_obj) }, + { MP_ROM_QSTR(MP_QSTR_supports_jpeg), MP_ROM_PTR(&espcamera_camera_supports_jpeg_obj) }, + { MP_ROM_QSTR(MP_QSTR_take), MP_ROM_PTR(&espcamera_camera_take_obj) }, + { MP_ROM_QSTR(MP_QSTR_vflip), MP_ROM_PTR(&espcamera_camera_vflip_obj) }, + { MP_ROM_QSTR(MP_QSTR_wb_mode), MP_ROM_PTR(&espcamera_camera_wb_mode_obj) }, + { MP_ROM_QSTR(MP_QSTR_whitebal), MP_ROM_PTR(&espcamera_camera_whitebal_obj) }, + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&espcamera_camera_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_wpc), MP_ROM_PTR(&espcamera_camera_wpc_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(espcamera_camera_locals_dict, espcamera_camera_locals_table); + +const mp_obj_type_t espcamera_camera_type = { + .base = { &mp_type_type }, + .name = MP_QSTR_Camera, + .make_new = espcamera_camera_make_new, + .locals_dict = (mp_obj_t)&espcamera_camera_locals_dict, +}; diff --git a/ports/espressif/bindings/espcamera/Camera.h b/ports/espressif/bindings/espcamera/Camera.h new file mode 100644 index 0000000000..c6d8182090 --- /dev/null +++ b/ports/espressif/bindings/espcamera/Camera.h @@ -0,0 +1,116 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/enum.h" +#include "py/obj.h" + +#include "esp_camera.h" + +#include "shared-bindings/busio/I2C.h" + +extern const mp_obj_type_t espcamera_camera_type; +typedef struct espcamera_camera_obj espcamera_camera_obj_t; + +extern void common_hal_espcamera_camera_construct( + espcamera_camera_obj_t *self, + uint8_t data_pins[8], + const mcu_pin_obj_t *external_clock_pin, + const mcu_pin_obj_t *pixel_clock_pin, + const mcu_pin_obj_t *vsync_pin, + const mcu_pin_obj_t *href_pin, + const mcu_pin_obj_t *powerdown_pin, + const mcu_pin_obj_t *reset_pin, + busio_i2c_obj_t *i2c, + mp_int_t external_clock_frequency, + pixformat_t pixel_format, + framesize_t frame_size, + mp_int_t jpeg_quality, + mp_int_t framebuffer_count, + camera_grab_mode_t grab_mode); + +extern void common_hal_espcamera_camera_deinit(espcamera_camera_obj_t *self); +extern bool common_hal_espcamera_camera_deinited(espcamera_camera_obj_t *self); +extern bool common_hal_espcamera_camera_available(espcamera_camera_obj_t *self); +extern camera_fb_t *common_hal_espcamera_camera_take(espcamera_camera_obj_t *self, int timeout_ms); +extern void common_hal_espcamera_camera_reconfigure(espcamera_camera_obj_t *self, framesize_t frame_size, pixformat_t pixel_format, camera_grab_mode_t grab_mode, mp_int_t framebuffer_count); + +#define DECLARE_SENSOR_GETSET(type, name, field_name, setter_function_name) \ + DECLARE_SENSOR_GET(type, name, field_name, setter_function_name) \ + DECLARE_SENSOR_SET(type, name, setter_function_name) + +#define DECLARE_SENSOR_STATUS_GETSET(type, name, status_field_name, setter_function_name) \ + DECLARE_SENSOR_GETSET(type, name, status.status_field_name, setter_function_name) + +#define DECLARE_SENSOR_STATUS_GET(type, name, status_field_name, setter_function_name) \ + DECLARE_SENSOR_GET(type, name, status.status_field_name, setter_function_name) + +#define DECLARE_SENSOR_GET(type, name, status_field_name, setter_function_name) \ + extern type common_hal_espcamera_camera_get_##name(espcamera_camera_obj_t * self); + +#define DECLARE_SENSOR_SET(type, name, setter_function_name) \ + extern void common_hal_espcamera_camera_set_##name(espcamera_camera_obj_t * self, type value); + +DECLARE_SENSOR_GET(pixformat_t, pixel_format, pixformat, set_pixformat) +DECLARE_SENSOR_STATUS_GET(framesize_t, frame_size, framesize, set_framesize) +DECLARE_SENSOR_STATUS_GETSET(int, contrast, contrast, set_contrast); +DECLARE_SENSOR_STATUS_GETSET(int, brightness, brightness, set_brightness); +DECLARE_SENSOR_STATUS_GETSET(int, saturation, saturation, set_saturation); +DECLARE_SENSOR_STATUS_GETSET(int, sharpness, sharpness, set_sharpness); +DECLARE_SENSOR_STATUS_GETSET(int, denoise, denoise, set_denoise); +DECLARE_SENSOR_STATUS_GETSET(gainceiling_t, gainceiling, gainceiling, set_gainceiling); +DECLARE_SENSOR_STATUS_GETSET(int, quality, quality, set_quality); +DECLARE_SENSOR_STATUS_GETSET(bool, colorbar, colorbar, set_colorbar); +DECLARE_SENSOR_STATUS_GETSET(bool, whitebal, whitebal, set_whitebal); +DECLARE_SENSOR_STATUS_GETSET(bool, gain_ctrl, gain_ctrl, set_gain_ctrl); +DECLARE_SENSOR_STATUS_GETSET(bool, exposure_ctrl, exposure_ctrl, set_exposure_ctrl); +DECLARE_SENSOR_STATUS_GETSET(bool, hmirror, hmirror, set_hmirror); +DECLARE_SENSOR_STATUS_GETSET(bool, vflip, vflip, set_vflip); +DECLARE_SENSOR_STATUS_GETSET(bool, aec2, aec2, set_aec2); +DECLARE_SENSOR_STATUS_GETSET(bool, awb_gain, awb_gain, set_awb_gain); +DECLARE_SENSOR_STATUS_GETSET(int, agc_gain, agc_gain, set_agc_gain); +DECLARE_SENSOR_STATUS_GETSET(int, aec_value, aec_value, set_aec_value); +DECLARE_SENSOR_STATUS_GETSET(int, special_effect, special_effect, set_special_effect); +DECLARE_SENSOR_STATUS_GETSET(int, wb_mode, wb_mode, set_wb_mode); +DECLARE_SENSOR_STATUS_GETSET(int, ae_level, ae_level, set_ae_level); +DECLARE_SENSOR_STATUS_GETSET(bool, dcw, dcw, set_dcw); +DECLARE_SENSOR_STATUS_GETSET(bool, bpc, bpc, set_bpc); +DECLARE_SENSOR_STATUS_GETSET(bool, wpc, wpc, set_wpc); +DECLARE_SENSOR_STATUS_GETSET(bool, raw_gma, raw_gma, set_raw_gma); +DECLARE_SENSOR_STATUS_GETSET(bool, lenc, lenc, set_lenc); + +// From settings +extern camera_grab_mode_t common_hal_espcamera_camera_get_grab_mode(espcamera_camera_obj_t *self); +extern int common_hal_espcamera_camera_get_framebuffer_count(espcamera_camera_obj_t *self); + +// From camera_sensor_info_t +extern int common_hal_espcamera_camera_get_address(espcamera_camera_obj_t *self); +extern const char *common_hal_espcamera_camera_get_sensor_name(espcamera_camera_obj_t *self); +extern const bool common_hal_espcamera_camera_get_supports_jpeg(espcamera_camera_obj_t *self); +extern framesize_t common_hal_espcamera_camera_get_max_frame_size(espcamera_camera_obj_t *self); +extern int common_hal_espcamera_camera_get_width(espcamera_camera_obj_t *self); +extern int common_hal_espcamera_camera_get_height(espcamera_camera_obj_t *self); diff --git a/ports/espressif/bindings/espcamera/__init__.c b/ports/espressif/bindings/espcamera/__init__.c new file mode 100644 index 0000000000..633f547fe9 --- /dev/null +++ b/ports/espressif/bindings/espcamera/__init__.c @@ -0,0 +1,288 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "bindings/espidf/__init__.h" +#include "bindings/espcamera/__init__.h" +#include "bindings/espcamera/Camera.h" + +#include "esp_camera.h" +#include "sensor.h" + +//| """Wrapper for the espcamera library +//| +//| This library enables access to any camera sensor supported by the library, +//| including OV5640 and OV2640. +//| +//| .. seealso:: +//| +//| Non-Espressif microcontrollers use the `imagecapture` module together with wrapper libraries such as `adafruit_ov5640 `_. +//| +//| """ +//| + +//| class GrabMode: +//| """Controls when a new frame is grabbed.""" +//| +//| WHEN_EMPTY: GrabMode +//| """Fills buffers when they are empty. Less resources but first ``fb_count`` frames might be old""" +//| +//| LATEST: GrabMode +//| """Except when 1 frame buffer is used, queue will always contain the last ``fb_count`` frames""" +//| + +MAKE_ENUM_VALUE(espcamera_grab_mode_type, grab_mode, WHEN_EMPTY, CAMERA_GRAB_WHEN_EMPTY); +MAKE_ENUM_VALUE(espcamera_grab_mode_type, grab_mode, LATEST, CAMERA_GRAB_LATEST); + +MAKE_ENUM_MAP(espcamera_grab_mode) { + MAKE_ENUM_MAP_ENTRY(grab_mode, WHEN_EMPTY), + MAKE_ENUM_MAP_ENTRY(grab_mode, LATEST), +}; + +STATIC MP_DEFINE_CONST_DICT(espcamera_grab_mode_locals_dict, espcamera_grab_mode_locals_table); +MAKE_PRINTER(espcamera, espcamera_grab_mode); +MAKE_ENUM_TYPE(espcamera, GrabMode, espcamera_grab_mode); + +camera_grab_mode_t validate_grab_mode(mp_obj_t obj, qstr arg_name) { + return cp_enum_value(&espcamera_grab_mode_type, obj, arg_name); +} + +//| class PixelFormat: +//| """Format of data in the captured frames""" +//| +//| RGB565: PixelFormat +//| """A 16-bit format with 5 bits of Red and Blue and 6 bits of Green""" +//| +//| GRAYSCALE: PixelFormat +//| """An 8-bit format with 8-bits of luminance""" +//| +//| JPEG: PixelFormat +//| """A compressed format""" +//| + +MAKE_ENUM_VALUE(espcamera_pixel_format_type, pixel_format, RGB565, PIXFORMAT_RGB565); +MAKE_ENUM_VALUE(espcamera_pixel_format_type, pixel_format, GRAYSCALE, PIXFORMAT_GRAYSCALE); +MAKE_ENUM_VALUE(espcamera_pixel_format_type, pixel_format, JPEG, PIXFORMAT_JPEG); + +MAKE_ENUM_MAP(espcamera_pixel_format) { + MAKE_ENUM_MAP_ENTRY(pixel_format, RGB565), + MAKE_ENUM_MAP_ENTRY(pixel_format, GRAYSCALE), + MAKE_ENUM_MAP_ENTRY(pixel_format, JPEG), +}; + +STATIC MP_DEFINE_CONST_DICT(espcamera_pixel_format_locals_dict, espcamera_pixel_format_locals_table); +MAKE_PRINTER(espcamera, espcamera_pixel_format); +MAKE_ENUM_TYPE(espcamera, PixelFormat, espcamera_pixel_format); + +pixformat_t validate_pixel_format(mp_obj_t obj, qstr arg_name) { + return cp_enum_value(&espcamera_pixel_format_type, obj, arg_name); +} + +//| class FrameSize: +//| """The pixel size of the captured frames""" +//| +//| R96X96: FrameSize +//| """96x96""" +//| +//| QQVGA: FrameSize +//| """160x120""" +//| +//| QCIF: FrameSize +//| """176x144""" +//| +//| HQVGA: FrameSize +//| """240x176""" +//| +//| R240X240: FrameSize +//| """240x240""" +//| +//| QVGA: FrameSize +//| """320x240 """ +//| +//| CIF: FrameSize +//| """400x296""" +//| +//| HVGA: FrameSize +//| """480x320""" +//| +//| VGA: FrameSize +//| """640x480""" +//| +//| SVGA: FrameSize +//| """800x600""" +//| +//| XGA: FrameSize +//| """1024x768""" +//| +//| HD: FrameSize +//| """1280x720""" +//| +//| SXGA: FrameSize +//| """1280x1024""" +//| +//| UXGA: FrameSize +//| """1600x1200""" +//| +//| FHD: FrameSize +//| """1920x1080""" +//| +//| P_HD: FrameSize +//| """ 720x1280""" +//| +//| P_3MP: FrameSize +//| """ 864x1536""" +//| +//| QXGA: FrameSize +//| """2048x1536""" +//| +//| QHD: FrameSize +//| """2560x1440""" +//| +//| WQXGA: FrameSize +//| """2560x1600""" +//| +//| P_FHD: FrameSize +//| """1080x1920""" +//| +//| QSXGA: FrameSize +//| """2560x1920""" +//| + +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, R96X96, FRAMESIZE_96X96); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, R240X240, FRAMESIZE_240X240); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, QQVGA, FRAMESIZE_QQVGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, QCIF, FRAMESIZE_QCIF); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, HQVGA, FRAMESIZE_HQVGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, QVGA, FRAMESIZE_QVGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, CIF, FRAMESIZE_CIF); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, HVGA, FRAMESIZE_HVGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, VGA, FRAMESIZE_VGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, SVGA, FRAMESIZE_SVGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, XGA, FRAMESIZE_XGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, HD, FRAMESIZE_HD); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, SXGA, FRAMESIZE_SXGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, UXGA, FRAMESIZE_UXGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, FHD, FRAMESIZE_FHD); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, P_HD, FRAMESIZE_P_HD); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, P_3MP, FRAMESIZE_P_3MP); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, QXGA, FRAMESIZE_QXGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, QHD, FRAMESIZE_QHD); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, WQXGA, FRAMESIZE_WQXGA); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, P_FHD, FRAMESIZE_P_FHD); +MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, QSXGA, FRAMESIZE_QSXGA); +MAKE_ENUM_MAP(espcamera_frame_size) { + MAKE_ENUM_MAP_ENTRY(frame_size, R96X96), + MAKE_ENUM_MAP_ENTRY(frame_size, R240X240), + MAKE_ENUM_MAP_ENTRY(frame_size, QQVGA), + MAKE_ENUM_MAP_ENTRY(frame_size, QCIF), + MAKE_ENUM_MAP_ENTRY(frame_size, HQVGA), + MAKE_ENUM_MAP_ENTRY(frame_size, QVGA), + MAKE_ENUM_MAP_ENTRY(frame_size, CIF), + MAKE_ENUM_MAP_ENTRY(frame_size, HVGA), + MAKE_ENUM_MAP_ENTRY(frame_size, VGA), + MAKE_ENUM_MAP_ENTRY(frame_size, SVGA), + MAKE_ENUM_MAP_ENTRY(frame_size, XGA), + MAKE_ENUM_MAP_ENTRY(frame_size, HD), + MAKE_ENUM_MAP_ENTRY(frame_size, SXGA), + MAKE_ENUM_MAP_ENTRY(frame_size, UXGA), + MAKE_ENUM_MAP_ENTRY(frame_size, FHD), + MAKE_ENUM_MAP_ENTRY(frame_size, P_HD), + MAKE_ENUM_MAP_ENTRY(frame_size, P_3MP), + MAKE_ENUM_MAP_ENTRY(frame_size, QXGA), + MAKE_ENUM_MAP_ENTRY(frame_size, QHD), + MAKE_ENUM_MAP_ENTRY(frame_size, WQXGA), + MAKE_ENUM_MAP_ENTRY(frame_size, P_FHD), + MAKE_ENUM_MAP_ENTRY(frame_size, QSXGA), +}; + +STATIC MP_DEFINE_CONST_DICT(espcamera_frame_size_locals_dict, espcamera_frame_size_locals_table); +MAKE_PRINTER(espcamera, espcamera_frame_size); +MAKE_ENUM_TYPE(espcamera, FrameSize, espcamera_frame_size); + +framesize_t validate_frame_size(mp_obj_t obj, qstr arg_name) { + return cp_enum_value(&espcamera_frame_size_type, obj, arg_name); +} + +//| class GainCeiling: +//| """The maximum amount of gain applied to raw sensor data. +//| +//| Higher values are useful in darker conditions, but increase image noise.""" +//| +//| GAIN_2X: GainCeiling +//| GAIN_4X: GainCeiling +//| GAIN_8X: GainCeiling +//| GAIN_16X: GainCeiling +//| GAIN_32X: GainCeiling +//| GAIN_64X: GainCeiling +//| GAIN_128X: GainCeiling +//| + +MAKE_ENUM_VALUE(espcamera_gain_ceiling_type, gain_ceiling, GAIN_2X, GAINCEILING_2X); +MAKE_ENUM_VALUE(espcamera_gain_ceiling_type, gain_ceiling, GAIN_4X, GAINCEILING_4X); +MAKE_ENUM_VALUE(espcamera_gain_ceiling_type, gain_ceiling, GAIN_8X, GAINCEILING_8X); +MAKE_ENUM_VALUE(espcamera_gain_ceiling_type, gain_ceiling, GAIN_16X, GAINCEILING_16X); +MAKE_ENUM_VALUE(espcamera_gain_ceiling_type, gain_ceiling, GAIN_32X, GAINCEILING_32X); +MAKE_ENUM_VALUE(espcamera_gain_ceiling_type, gain_ceiling, GAIN_64X, GAINCEILING_64X); +MAKE_ENUM_VALUE(espcamera_gain_ceiling_type, gain_ceiling, GAIN_128X, GAINCEILING_128X); + +MAKE_ENUM_MAP(espcamera_gain_ceiling) { + MAKE_ENUM_MAP_ENTRY(gain_ceiling, GAIN_2X), + MAKE_ENUM_MAP_ENTRY(gain_ceiling, GAIN_4X), + MAKE_ENUM_MAP_ENTRY(gain_ceiling, GAIN_8X), + MAKE_ENUM_MAP_ENTRY(gain_ceiling, GAIN_16X), + MAKE_ENUM_MAP_ENTRY(gain_ceiling, GAIN_32X), + MAKE_ENUM_MAP_ENTRY(gain_ceiling, GAIN_64X), + MAKE_ENUM_MAP_ENTRY(gain_ceiling, GAIN_128X) +}; + +STATIC MP_DEFINE_CONST_DICT(espcamera_gain_ceiling_locals_dict, espcamera_gain_ceiling_locals_table); +MAKE_PRINTER(espcamera, espcamera_gain_ceiling); +MAKE_ENUM_TYPE(espcamera, GainCeiling, espcamera_gain_ceiling); + +gainceiling_t validate_gain_ceiling(mp_obj_t obj, qstr arg_name) { + return cp_enum_value(&espcamera_gain_ceiling_type, obj, arg_name); +} + +STATIC const mp_rom_map_elem_t espcamera_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_espcamera) }, + { MP_ROM_QSTR(MP_QSTR_Camera), MP_ROM_PTR(&espcamera_camera_type), }, + { MP_ROM_QSTR(MP_QSTR_FrameSize), &espcamera_frame_size_type }, + { MP_ROM_QSTR(MP_QSTR_GainCeiling), &espcamera_gain_ceiling_type }, + { MP_ROM_QSTR(MP_QSTR_GrabMode), &espcamera_grab_mode_type }, + { MP_ROM_QSTR(MP_QSTR_PixelFormat), &espcamera_pixel_format_type }, +}; + +STATIC MP_DEFINE_CONST_DICT(espcamera_module_globals, espcamera_module_globals_table); + +const mp_obj_module_t espcamera_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&espcamera_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_espcamera, espcamera_module, CIRCUITPY_ESPCAMERA); diff --git a/ports/espressif/bindings/espcamera/__init__.h b/ports/espressif/bindings/espcamera/__init__.h new file mode 100644 index 0000000000..6e55ac3870 --- /dev/null +++ b/ports/espressif/bindings/espcamera/__init__.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/enum.h" +#include "py/obj.h" + +#include "esp_camera.h" + +extern const mp_obj_type_t espcamera_grab_mode_type; +extern const cp_enum_obj_t grab_mode_WHEN_EMPTY_obj; +extern const mp_obj_type_t espcamera_pixel_format_type; +extern const cp_enum_obj_t pixel_format_RGB565_obj; +extern const mp_obj_type_t espcamera_frame_size_type; +extern const cp_enum_obj_t frame_size_QQVGA_obj; +extern const mp_obj_type_t espcamera_gain_ceiling_type; + +extern camera_grab_mode_t validate_grab_mode(mp_obj_t obj, qstr arg_name); +extern pixformat_t validate_pixel_format(mp_obj_t obj, qstr arg_name); +extern framesize_t validate_frame_size(mp_obj_t obj, qstr arg_name); +extern gainceiling_t validate_gain_ceiling(mp_obj_t obj, qstr arg_name); diff --git a/ports/espressif/bindings/espidf/__init__.c b/ports/espressif/bindings/espidf/__init__.c index 4f7da39540..c1ef9da1e0 100644 --- a/ports/espressif/bindings/espidf/__init__.c +++ b/ports/espressif/bindings/espidf/__init__.c @@ -37,6 +37,7 @@ //| """Direct access to a few ESP-IDF details. This module *should not* include any functionality //| that could be implemented by other frameworks. It should only include ESP-IDF specific //| things.""" +//| //| def heap_caps_get_total_size() -> int: //| """Return the total size of the ESP-IDF, which includes the CircuitPython heap.""" @@ -72,7 +73,9 @@ MP_DEFINE_CONST_FUN_OBJ_0(espidf_heap_caps_get_largest_free_block_obj, espidf_he //| """Erase all data in the non-volatile storage (nvs), including data stored by with `microcontroller.nvm` //| //| This is necessary when upgrading from CircuitPython 6.3.0 or earlier to CircuitPython 7.0.0, because the -//| layout of data in nvs has changed. The old data will be lost when you perform this operation.""" +//| layout of data in nvs has changed. The old data will be lost when you perform this operation. +//| """ +//| STATIC mp_obj_t espidf_erase_nvs(void) { ESP_ERROR_CHECK(nvs_flash_deinit()); ESP_ERROR_CHECK(nvs_flash_erase()); @@ -103,8 +106,10 @@ const mp_obj_type_t mp_type_espidf_IDFError = { //| import builtins +//| //| class MemoryError(builtins.MemoryError): //| """Raised when an ESP IDF memory allocation fails.""" +//| //| ... //| NORETURN void mp_raise_espidf_MemoryError(void) { @@ -120,6 +125,22 @@ const mp_obj_type_t mp_type_espidf_MemoryError = { .parent = &mp_type_MemoryError, }; +//| def get_total_psram() -> int: +//| """Returns the number of bytes of psram detected, or 0 if psram is not present or not configured""" +//| +STATIC mp_obj_t espidf_get_total_psram(void) { + return MP_OBJ_NEW_SMALL_INT(common_hal_espidf_get_total_psram()); +} +MP_DEFINE_CONST_FUN_OBJ_0(espidf_get_total_psram_obj, espidf_get_total_psram); + +//| def get_reserved_psram() -> int: +//| """Returns number of bytes of psram reserved for use by esp-idf, either a board-specific default value or the value defined in ``settings.toml``.""" +//| +STATIC mp_obj_t espidf_get_reserved_psram(void) { + return MP_OBJ_NEW_SMALL_INT(common_hal_espidf_get_reserved_psram()); +} +MP_DEFINE_CONST_FUN_OBJ_0(espidf_get_reserved_psram_obj, espidf_get_reserved_psram); + STATIC const mp_rom_map_elem_t espidf_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_espidf) }, @@ -129,6 +150,8 @@ STATIC const mp_rom_map_elem_t espidf_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_erase_nvs), MP_ROM_PTR(&espidf_erase_nvs_obj)}, + { MP_ROM_QSTR(MP_QSTR_get_total_psram), MP_ROM_PTR(&espidf_get_total_psram_obj)}, + { MP_ROM_QSTR(MP_QSTR_get_reserved_psram), MP_ROM_PTR(&espidf_get_reserved_psram_obj)}, { MP_ROM_QSTR(MP_QSTR_IDFError), MP_ROM_PTR(&mp_type_espidf_IDFError) }, { MP_ROM_QSTR(MP_QSTR_MemoryError), MP_ROM_PTR(&mp_type_espidf_MemoryError) }, }; @@ -139,66 +162,3 @@ const mp_obj_module_t espidf_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&espidf_module_globals, }; - -void raise_esp_error(esp_err_t err) { - const compressed_string_t *msg = NULL; - const mp_obj_type_t *exception_type = &mp_type_espidf_IDFError; - switch (err) { - case ESP_FAIL: - msg = translate("Generic Failure"); - break; - case ESP_ERR_NO_MEM: - exception_type = &mp_type_espidf_MemoryError; - msg = translate("Out of memory"); - break; - case ESP_ERR_INVALID_ARG: - msg = translate("Invalid argument"); - break; - case ESP_ERR_INVALID_STATE: - msg = translate("Invalid state"); - break; - case ESP_ERR_INVALID_SIZE: - msg = translate("Invalid size"); - break; - case ESP_ERR_NOT_FOUND: - msg = translate("Requested resource not found"); - break; - case ESP_ERR_NOT_SUPPORTED: - msg = translate("Operation or feature not supported"); - break; - case ESP_ERR_TIMEOUT: - msg = translate("Operation timed out"); - break; - case ESP_ERR_INVALID_RESPONSE: - msg = translate("Received response was invalid"); - break; - case ESP_ERR_INVALID_CRC: - msg = translate("CRC or checksum was invalid"); - break; - case ESP_ERR_INVALID_VERSION: - msg = translate("Version was invalid"); - break; - case ESP_ERR_INVALID_MAC: - msg = translate("MAC address was invalid"); - break; - } - if (msg) { - mp_raise_msg(exception_type, msg); - } - - const char *group = "ESP-IDF"; - - // tests must be in descending order - MP_STATIC_ASSERT(ESP_ERR_FLASH_BASE > ESP_ERR_MESH_BASE); - MP_STATIC_ASSERT(ESP_ERR_MESH_BASE > ESP_ERR_WIFI_BASE); - if (err >= ESP_ERR_FLASH_BASE) { - group = "Flash"; - } else if (err >= ESP_ERR_MESH_BASE) { - group = "Mesh"; - } else if (err >= ESP_ERR_WIFI_BASE) { - group = "WiFi"; - } - mp_raise_msg_varg(exception_type, translate("%s error 0x%x"), group, err); -} - -MP_REGISTER_MODULE(MP_QSTR_espidf, espidf_module, CIRCUITPY_ESPIDF); diff --git a/ports/espressif/bindings/espidf/__init__.h b/ports/espressif/bindings/espidf/__init__.h index 5891d2c5c0..e091a5c477 100644 --- a/ports/espressif/bindings/espidf/__init__.h +++ b/ports/espressif/bindings/espidf/__init__.h @@ -39,4 +39,11 @@ NORETURN void mp_raise_espidf_MemoryError(void); void raise_esp_error(esp_err_t err) NORETURN; #define CHECK_ESP_RESULT(x) do { int res = (x); if (res != ESP_OK) raise_esp_error(res); } while (0) +void common_hal_espidf_reserve_psram(void); +bool common_hal_espidf_set_reserved_psram(size_t amount); +size_t common_hal_espidf_get_reserved_psram(void); +size_t common_hal_espidf_get_total_psram(void); +intptr_t common_hal_espidf_get_psram_start(void); +intptr_t common_hal_espidf_get_psram_end(void); + #endif // MICROPY_INCLUDED_ESPRESSIF_BINDINGS_ESPIDF___INIT___H diff --git a/ports/espressif/bindings/espulp/Architecture.c b/ports/espressif/bindings/espulp/Architecture.c new file mode 100644 index 0000000000..d87691716c --- /dev/null +++ b/ports/espressif/bindings/espulp/Architecture.c @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 MicroDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/enum.h" + +#include "bindings/espulp/Architecture.h" + +MAKE_ENUM_VALUE(espulp_architecture_type, architecture, FSM, FSM); +MAKE_ENUM_VALUE(espulp_architecture_type, architecture, RISCV, RISCV); + +//| class Architecture: +//| """The ULP architectures available.""" +//| +//| FSM: Architecture +//| """The ULP Finite State Machine.""" +//| +//| RISCV: Architecture +//| """The ULP RISC-V Coprocessor.""" +//| +MAKE_ENUM_MAP(espulp_architecture) { + MAKE_ENUM_MAP_ENTRY(architecture, FSM), + MAKE_ENUM_MAP_ENTRY(architecture, RISCV), +}; +STATIC MP_DEFINE_CONST_DICT(espulp_architecture_locals_dict, espulp_architecture_locals_table); + +MAKE_PRINTER(espulp, espulp_architecture); + +MAKE_ENUM_TYPE(espulp, Architecture, espulp_architecture); diff --git a/ports/espressif/bindings/espulp/Architecture.h b/ports/espressif/bindings/espulp/Architecture.h new file mode 100644 index 0000000000..54c0677f05 --- /dev/null +++ b/ports/espressif/bindings/espulp/Architecture.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 MicroDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_BINDINGS_ESPULP_ARCHITECTURE_H +#define MICROPY_INCLUDED_BINDINGS_ESPULP_ARCHITECTURE_H + +#include "py/enum.h" + +typedef enum { + FSM, + RISCV +} espulp_architecture_t; + +extern const mp_obj_type_t espulp_architecture_type; +extern const cp_enum_obj_t architecture_FSM_obj; + +#endif // MICROPY_INCLUDED_BINDINGS_ESPULP_ARCHITECTURE_H diff --git a/ports/espressif/bindings/espulp/ULP.c b/ports/espressif/bindings/espulp/ULP.c new file mode 100644 index 0000000000..c9666fb143 --- /dev/null +++ b/ports/espressif/bindings/espulp/ULP.c @@ -0,0 +1,181 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "bindings/espulp/ULP.h" + +#include "py/enum.h" +#include "py/runtime.h" +#include "py/objproperty.h" + +//| class ULP: +//| def __init__(self, arch: Architecture = Architecture.FSM): +//| """The ultra-low-power processor. +//| +//| Raises an exception if another ULP has been instantiated. This +//| ensures that is is only used by one piece of code at a time. +//| +//| :param Architecture arch: The ulp arch""" +//| ... +STATIC mp_obj_t espulp_ulp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_arch }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_arch, MP_ARG_OBJ, {.u_obj = (void *)&architecture_FSM_obj} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const espulp_architecture_t arch = cp_enum_value(&espulp_architecture_type, args[ARG_arch].u_obj, MP_QSTR_arch); + + espulp_ulp_obj_t *self = m_new_obj(espulp_ulp_obj_t); + self->base.type = &espulp_ulp_type; + + common_hal_espulp_ulp_construct(self, arch); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void check_for_deinit(espulp_ulp_obj_t *self) { + if (common_hal_espulp_ulp_deinited(self)) { + raise_deinited_error(); + } +} + +//| def deinit(self) -> None: +//| """Deinitialises the ULP and releases it for another program.""" +//| ... +STATIC mp_obj_t espulp_ulp_deinit(mp_obj_t self_in) { + espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_espulp_ulp_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espulp_ulp_deinit_obj, espulp_ulp_deinit); + +//| def __enter__(self) -> ULP: +//| """No-op used by Context Managers.""" +//| ... +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +STATIC mp_obj_t espulp_ulp_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + return espulp_ulp_deinit(args[0]); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espulp_ulp___exit___obj, 4, 4, espulp_ulp_obj___exit__); + +//| def run( +//| self, program: ReadableBuffer, *, pins: Sequence[microcontroller.Pin] = () +//| ) -> None: +//| """Loads the program into ULP memory and then runs the program. The given pins are +//| claimed and not reset until `halt()` is called. +//| +//| The program will continue to run even when the running Python is halted.""" +//| ... +STATIC mp_obj_t espulp_ulp_run(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + + enum { ARG_program, ARG_pins }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_program, MP_ARG_REQUIRED | MP_ARG_OBJ}, + { MP_QSTR_pins, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_tuple} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_program].u_obj, &bufinfo, MP_BUFFER_READ); + + mp_obj_t pins_in = args[ARG_pins].u_obj; + const size_t num_pins = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(pins_in)); + + // The ULP only supports 21 pins on the ESP32-S2 and S3. So we can store it + // as a bitmask in a 32 bit number. The common-hal code does further checks. + uint32_t pin_mask = 0; + + for (mp_uint_t i = 0; i < num_pins; i++) { + mp_obj_t pin_obj = mp_obj_subscr(pins_in, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL); + validate_obj_is_free_pin(pin_obj, MP_QSTR_pin); + const mcu_pin_obj_t *pin = ((const mcu_pin_obj_t *)pin_obj); + if (pin->number >= 32) { + raise_ValueError_invalid_pin(); + } + pin_mask |= 1 << pin->number; + } + + common_hal_espulp_ulp_run(self, bufinfo.buf, bufinfo.len, pin_mask); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(espulp_ulp_run_obj, 2, espulp_ulp_run); + +//| def halt(self) -> None: +//| """Halts the running program and releases the pins given in `run()`.""" +//| ... +STATIC mp_obj_t espulp_ulp_halt(mp_obj_t self_in) { + espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + common_hal_espulp_ulp_halt(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espulp_ulp_halt_obj, espulp_ulp_halt); + +//| arch: Architecture +//| """The ulp architecture. (read-only)""" +//| +STATIC mp_obj_t espulp_ulp_get_arch(mp_obj_t self_in) { + espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return cp_enum_find(&espulp_architecture_type, self->arch); +} +MP_DEFINE_CONST_FUN_OBJ_1(espulp_ulp_get_arch_obj, espulp_ulp_get_arch); + +MP_PROPERTY_GETTER(espulp_ulp_arch_obj, + (mp_obj_t)&espulp_ulp_get_arch_obj); + +STATIC const mp_rom_map_elem_t espulp_ulp_locals_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espulp_ulp_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&espulp_ulp___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_run), MP_ROM_PTR(&espulp_ulp_run_obj) }, + { MP_ROM_QSTR(MP_QSTR_halt), MP_ROM_PTR(&espulp_ulp_halt_obj) }, + { MP_ROM_QSTR(MP_QSTR_arch), MP_ROM_PTR(&espulp_ulp_arch_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(espulp_ulp_locals_dict, espulp_ulp_locals_table); + +const mp_obj_type_t espulp_ulp_type = { + { &mp_type_type }, + .name = MP_QSTR_ULP, + .make_new = espulp_ulp_make_new, + .locals_dict = (mp_obj_t)&espulp_ulp_locals_dict, +}; diff --git a/py/ioctl.h b/ports/espressif/bindings/espulp/ULP.h similarity index 69% rename from py/ioctl.h rename to ports/espressif/bindings/espulp/ULP.h index 8c84835cc1..490cbef1ca 100644 --- a/py/ioctl.h +++ b/ports/espressif/bindings/espulp/ULP.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2015 Damien P. George + * Copyright (c) 2022 microDev * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,16 +23,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_PY_IOCTL_H -#define MICROPY_INCLUDED_PY_IOCTL_H -#define MP_IOCTL_POLL (0x100 | 1) +#pragma once -// These values are compatible with Linux, which are in turn -// compatible with iBCS2 spec. -#define MP_IOCTL_POLL_RD (0x0001) -#define MP_IOCTL_POLL_WR (0x0004) -#define MP_IOCTL_POLL_ERR (0x0008) -#define MP_IOCTL_POLL_HUP (0x0010) +#include "py/obj.h" +#include "common-hal/espulp/ULP.h" -#endif // MICROPY_INCLUDED_PY_IOCTL_H +extern const mp_obj_type_t espulp_ulp_type; + +void common_hal_espulp_ulp_construct(espulp_ulp_obj_t *self, espulp_architecture_t arch); +bool common_hal_espulp_ulp_deinited(espulp_ulp_obj_t *self); +void common_hal_espulp_ulp_deinit(espulp_ulp_obj_t *self); + +void common_hal_espulp_ulp_run(espulp_ulp_obj_t *self, uint32_t *program, size_t length, uint32_t pin_mask); +void common_hal_espulp_ulp_halt(espulp_ulp_obj_t *self); diff --git a/ports/espressif/bindings/espulp/ULPAlarm.c b/ports/espressif/bindings/espulp/ULPAlarm.c new file mode 100644 index 0000000000..6efd1c98ef --- /dev/null +++ b/ports/espressif/bindings/espulp/ULPAlarm.c @@ -0,0 +1,67 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "bindings/espulp/ULPAlarm.h" + +#include "py/runtime.h" +#include "py/objproperty.h" + +//| class ULPAlarm: +//| """Trigger an alarm when the ULP requests wake-up.""" +//| +//| def __init__(self, ulp: ULP) -> None: +//| """Create an alarm that will be triggered when the ULP requests wake-up. +//| +//| The alarm is not active until it is passed to an `alarm`-enabling function, such as +//| `alarm.light_sleep_until_alarms()` or `alarm.exit_and_deep_sleep_until_alarms()`. +//| +//| :param ULP ulp: The ulp instance""" +//| ... +//| +STATIC mp_obj_t espulp_ulpalarm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_ulp }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_ulp, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + espulp_ulpalarm_obj_t *self = m_new_obj(espulp_ulpalarm_obj_t); + self->base.type = &espulp_ulpalarm_type; + + espulp_ulp_obj_t *ulp = mp_arg_validate_type(args[ARG_ulp].u_obj, &espulp_ulp_type, MP_QSTR_ulp); + + common_hal_espulp_ulpalarm_construct(self, ulp); + + return MP_OBJ_FROM_PTR(self); +} + +const mp_obj_type_t espulp_ulpalarm_type = { + { &mp_type_type }, + .name = MP_QSTR_ULPAlarm, + .make_new = espulp_ulpalarm_make_new, +}; diff --git a/ports/espressif/bindings/espulp/ULPAlarm.h b/ports/espressif/bindings/espulp/ULPAlarm.h new file mode 100644 index 0000000000..f2b2e69bba --- /dev/null +++ b/ports/espressif/bindings/espulp/ULPAlarm.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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. + */ + +#pragma once + +#include "common-hal/espulp/ULPAlarm.h" + +extern const mp_obj_type_t espulp_ulpalarm_type; + +void common_hal_espulp_ulpalarm_construct(espulp_ulpalarm_obj_t *self, espulp_ulp_obj_t *ulp); diff --git a/ports/espressif/bindings/espulp/__init__.c b/ports/espressif/bindings/espulp/__init__.c new file mode 100644 index 0000000000..f2b688dda4 --- /dev/null +++ b/ports/espressif/bindings/espulp/__init__.c @@ -0,0 +1,94 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/util.h" + +#include "bindings/espulp/__init__.h" +#include "bindings/espulp/ULP.h" +#include "bindings/espulp/ULPAlarm.h" +#include "bindings/espulp/Architecture.h" + +#include "py/runtime.h" + +//| """ESP Ultra Low Power Processor Module +//| +//| The `espulp` module adds ability to load and run +//| programs on the ESP32-Sx's ultra-low-power RISC-V processor. +//| +//| .. code-block:: python +//| +//| import espulp +//| import memorymap +//| +//| shared_mem = memorymap.AddressRange(start=0x50000000, length=1024) +//| ulp = espulp.ULP() +//| +//| with open("program.bin", "rb") as f: +//| program = f.read() +//| +//| ulp.run(program) +//| print(shared_mem[0]) +//| # ulp.halt() +//| """ +//| ... +//| + +//| def get_rtc_gpio_number(pin: microcontroller.Pin) -> Optional[int]: +//| """Return the RTC GPIO number of the given pin or None if not connected +//| to RTC GPIO.""" +//| ... +//| + +STATIC mp_obj_t espulp_get_rtc_gpio_number(mp_obj_t pin_obj) { + const mcu_pin_obj_t *pin = validate_obj_is_pin(pin_obj, MP_QSTR_pin); + mp_int_t number = common_hal_espulp_get_rtc_gpio_number(pin); + if (number < 0) { + return mp_const_none; + } + return MP_OBJ_NEW_SMALL_INT(number); +} +MP_DEFINE_CONST_FUN_OBJ_1(espulp_get_rtc_gpio_number_obj, espulp_get_rtc_gpio_number); + +STATIC const mp_rom_map_elem_t espulp_module_globals_table[] = { + // module name + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_espulp) }, + + // module functions + { MP_ROM_QSTR(MP_QSTR_get_rtc_gpio_number), MP_OBJ_FROM_PTR(&espulp_get_rtc_gpio_number_obj) }, + + // module classes + { MP_ROM_QSTR(MP_QSTR_ULP), MP_OBJ_FROM_PTR(&espulp_ulp_type) }, + { MP_ROM_QSTR(MP_QSTR_ULPAlarm), MP_OBJ_FROM_PTR(&espulp_ulpalarm_type) }, + { MP_ROM_QSTR(MP_QSTR_Architecture), MP_ROM_PTR(&espulp_architecture_type) }, +}; +STATIC MP_DEFINE_CONST_DICT(espulp_module_globals, espulp_module_globals_table); + +const mp_obj_module_t espulp_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&espulp_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_espulp, espulp_module, CIRCUITPY_ESPULP); diff --git a/ports/espressif/bindings/espulp/__init__.h b/ports/espressif/bindings/espulp/__init__.h new file mode 100644 index 0000000000..70daf53183 --- /dev/null +++ b/ports/espressif/bindings/espulp/__init__.h @@ -0,0 +1,33 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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. + */ + +#pragma once + +#include "shared-bindings/microcontroller/Pin.h" + +void espulp_reset(void); + +mp_int_t common_hal_espulp_get_rtc_gpio_number(const mcu_pin_obj_t *pin); diff --git a/ports/espressif/boards/adafruit_esp32s2_camera/board.c b/ports/espressif/boards/adafruit_esp32s2_camera/board.c index 23a2eb7a34..280f2b14b8 100644 --- a/ports/espressif/boards/adafruit_esp32s2_camera/board.c +++ b/ports/espressif/boards/adafruit_esp32s2_camera/board.c @@ -56,16 +56,13 @@ void board_init(void) { bus->base.type = &displayio_fourwire_type; common_hal_displayio_fourwire_construct(bus, spi, - &pin_GPIO39, // TFT_DC Command or data - &pin_GPIO40, // TFT_CS Chip select - &pin_GPIO41, // TFT_RESET Reset + &pin_GPIO40, // TFT_DC Command or data + &pin_GPIO39, // TFT_CS Chip select + &pin_GPIO38, // TFT_RESET Reset 40000000, // Baudrate 0, // Polarity 0); // Phase - // workaround as board_init() is called before reset_port() in main.c - pwmout_reset(); - displayio_display_obj_t *display = &displays[0].display; display->base.type = &displayio_display_type; common_hal_displayio_display_construct( @@ -87,10 +84,9 @@ void board_init(void) { MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command display_init_sequence, sizeof(display_init_sequence), - &pin_GPIO38, // backlight pin + &pin_GPIO41, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -100,13 +96,8 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - void board_deinit(void) { common_hal_displayio_release_displays(); } + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_esp32s2_camera/mpconfigboard.h b/ports/espressif/boards/adafruit_esp32s2_camera/mpconfigboard.h index 793b675784..64ab1b966d 100644 --- a/ports/espressif/boards/adafruit_esp32s2_camera/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_esp32s2_camera/mpconfigboard.h @@ -30,7 +30,9 @@ #define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_NEOPIXEL (&pin_GPIO21) -#define MICROPY_HW_NEOPIXEL_COUNT (6) +#define MICROPY_HW_NEOPIXEL_COUNT (1) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO1) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO34) diff --git a/ports/espressif/boards/adafruit_esp32s2_camera/mpconfigboard.mk b/ports/espressif/boards/adafruit_esp32s2_camera/mpconfigboard.mk index 6b351c772b..1823c1dd88 100644 --- a/ports/espressif/boards/adafruit_esp32s2_camera/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_esp32s2_camera/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/adafruit_esp32s2_camera/pins.c b/ports/espressif/boards/adafruit_esp32s2_camera/pins.c index 688a555b02..5de2d800aa 100644 --- a/ports/espressif/boards/adafruit_esp32s2_camera/pins.c +++ b/ports/espressif/boards/adafruit_esp32s2_camera/pins.c @@ -24,13 +24,12 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, - { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO40) }, - { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_CARD_CS), MP_ROM_PTR(&pin_GPIO4) }, - { MP_ROM_QSTR(MP_QSTR_CARD_POWER), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_CARD_CS), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_IRQ), MP_ROM_PTR(&pin_GPIO3) }, @@ -39,7 +38,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO45) }, { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO1) }, { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO18) }, diff --git a/ports/espressif/boards/adafruit_feather_esp32_v2/board.c b/ports/espressif/boards/adafruit_feather_esp32_v2/board.c index 4c433a9da8..78341beb3b 100644 --- a/ports/espressif/boards/adafruit_feather_esp32_v2/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32_v2/board.c @@ -31,19 +31,15 @@ #include "components/hal/include/hal/gpio_hal.h" #include "common-hal/microcontroller/Pin.h" -void board_init(void) { - reset_board(); -} +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + if (pin_number == 2) { + // Turn on NeoPixel and I2C power by default. + gpio_set_direction(pin_number, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(pin_number, true); + return true; + } -bool board_requests_safe_mode(void) { return false; } -void reset_board(void) { - // Turn on NeoPixel and I2C power by default. - gpio_set_direction(2, GPIO_MODE_DEF_OUTPUT); - gpio_set_level(2, true); -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h index 104fbfc86d..4e9e679e5f 100644 --- a/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h @@ -32,6 +32,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO0) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO2) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define CIRCUITPY_BOARD_I2C (1) #define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO20, .sda = &pin_GPIO22}} @@ -45,7 +47,7 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO38) // Explanation of how a user got into safe mode -#define BOARD_USER_SAFE_MODE_ACTION translate("pressing SW38 button at start up.\n") +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed the SW38 button at start up.") // UART pins attached to the USB-serial converter chip #define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) diff --git a/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.mk index f25eda463f..38d689d08a 100644 --- a/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.mk @@ -3,16 +3,6 @@ CIRCUITPY_CREATION_ID = 0x00320001 IDF_TARGET = esp32 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - -CIRCUITPY_STATUS_BAR = 0 -CIRCUITPY_WEB_WORKFLOW = 0 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 8MB diff --git a/ports/espressif/boards/adafruit_feather_esp32_v2/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32_v2/sdkconfig index f2e8085d3e..c09d8c409a 100644 --- a/ports/espressif/boards/adafruit_feather_esp32_v2/sdkconfig +++ b/ports/espressif/boards/adafruit_feather_esp32_v2/sdkconfig @@ -1,11 +1,4 @@ -# -# Partition Table -# -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-8MB-no-uf2.csv" -CONFIG_PARTITION_TABLE_FILENAME="esp-idf-config/partitions-8MB-no-uf2.csv" -# end of Partition Table - -# +CONFIG_ESP32_SPIRAM_SUPPORT=y # SPI RAM config # # CONFIG_SPIRAM_TYPE_AUTO is not set @@ -25,15 +18,7 @@ CONFIG_SPIRAM_MEMTEST=y # CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set CONFIG_SPIRAM_CACHE_WORKAROUND=y -# -# SPI RAM config -# -CONFIG_ESP32_SPIRAM_SUPPORT=y -# CONFIG_SPIRAM_TYPE_AUTO is not set -# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set -# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set - -### # Uncomment to send log output to TX/RX pins on Feather ESP32V2 +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins ### # ### # ESP System Settings ### # diff --git a/ports/espressif/boards/adafruit_feather_esp32s2/board.c b/ports/espressif/boards/adafruit_feather_esp32s2/board.c index f9e88c097e..f701d18442 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s2/board.c @@ -35,10 +35,6 @@ void board_init(void) { reset_board(); } -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { // Turn on I2C power by default. @@ -53,5 +49,4 @@ void reset_board(void) { gpio_set_level(7, !restlevel); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_feather_esp32s2/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s2/mpconfigboard.h index 0be1357939..4e7da01b5a 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32s2/mpconfigboard.h @@ -32,6 +32,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO3) diff --git a/ports/espressif/boards/adafruit_feather_esp32s2/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s2/mpconfigboard.mk index 6af258b3d0..3ba91e62fd 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c new file mode 100644 index 0000000000..360c71804c --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c @@ -0,0 +1,136 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +// display init sequence according to LilyGO example app +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 150, + // sleep out + 0x11, 0 | DELAY, 255, + // normal display mode on + 0x13, 0, + // display and color format settings + 0x36, 1, 0x68, + 0xB6, 2, 0x0A, 0x82, + 0x3A, 1 | DELAY, 0x55, 10, + // ST7789V frame rate setting + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + // voltages: VGH / VGL + 0xB7, 1, 0x35, + // ST7789V power setting + 0xBB, 1, 0x28, + 0xC0, 1, 0x0C, + 0xC2, 2, 0x01, 0xFF, + 0xC3, 1, 0x10, + 0xC4, 1, 0x20, + 0xC6, 1, 0x0F, + 0xD0, 2, 0xA4, 0xA1, + // ST7789V gamma setting + 0xE0, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0E, 0x12, 0x14, 0x17, + 0xE1, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x31, 0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1B, 0x1E, + 0x21, 0, + // display on + 0x29, 0 | DELAY, 255, +}; + + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO40, // DC + &pin_GPIO42, // CS + &pin_GPIO41, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + + common_hal_displayio_display_construct( + display, + bus, + 240, // width (after rotation) + 135, // height (after rotation) + 40, // column start + 53, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO45, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Override the I2C/TFT power pin reset to prevent resetting the display. + if (pin_number == 21) { + // Turn on TFT and I2C + gpio_set_direction(21, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(21, true); + return true; + } + return false; +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. + +// TODO: Should we turn off the display when asleep, in board_deinit() ? diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h similarity index 86% rename from ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.h rename to ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h index 6cbe314f42..d170bba487 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h @@ -26,11 +26,13 @@ // Micropython setup -#define MICROPY_HW_BOARD_NAME "Feather ESP32S2 without PSRAM" +#define MICROPY_HW_BOARD_NAME "Adafruit Feather ESP32-S2 Reverse TFT" #define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) -#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21) +#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO34) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO3) @@ -39,4 +41,7 @@ #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) #define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) +#define DEFAULT_UART_BUS_RX (&pin_GPIO34) +#define DEFAULT_UART_BUS_TX (&pin_GPIO35) + #define DOUBLE_TAP_PIN (&pin_GPIO34) diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk new file mode 100644 index 0000000000..920b748e3d --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x239A +USB_PID = 0x80EE + +USB_PRODUCT = "Feather ESP32-S2 Reverse TFT" +USB_MANUFACTURER = "Adafruit" + +IDF_TARGET = esp32s2 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/pins.c b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/pins.c similarity index 83% rename from ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/pins.c rename to ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/pins.c index 54b9051d73..32718700b1 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/pins.c +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/pins.c @@ -5,22 +5,14 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO3) }, - - { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, - - { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO7) }, - - { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, @@ -30,46 +22,61 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, - { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, - { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, - { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, - { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_TFT_I2C_POWER), MP_ROM_PTR(&pin_GPIO7) }, - { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, - { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, - { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, - { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, - { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO42) }, { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO41) }, - { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, - // { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig new file mode 100644 index 0000000000..f19afafa3d --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig @@ -0,0 +1,37 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 +# end of SPI RAM config + +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +# +# PSRAM clock and cs IO for ESP32S2 +# +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM clock and cs IO for ESP32S2 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_80M is not set +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# end of LWIP diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c index aab7fbc608..c5b47a2f95 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c @@ -71,12 +71,6 @@ uint8_t display_init_sequence[] = { void board_init(void) { - // THIS SHOULD BE HANDLED BY espressif_board_reset_pin_number(), but it is not working. - // TEMPORARY FIX UNTIL IT'S DIAGNOSED. - common_hal_never_reset_pin(&pin_GPIO21); - gpio_set_direction(21, GPIO_MODE_DEF_OUTPUT); - gpio_set_level(21, true); - busio_spi_obj_t *spi = common_hal_board_create_spi(0); displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; bus->base.type = &displayio_fourwire_type; @@ -94,9 +88,6 @@ void board_init(void) { displayio_display_obj_t *display = &displays[0].display; display->base.type = &displayio_display_type; - // workaround as board_init() is called before reset_port() in main.c - pwmout_reset(); - common_hal_displayio_display_construct( display, bus, @@ -118,8 +109,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_GPIO45, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - false, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -128,28 +118,19 @@ void board_init(void) { false, // SH1107_addressing 50000 // backlight pwm frequency ); - - common_hal_never_reset_pin(&pin_GPIO45); // backlight pin -} - -bool board_requests_safe_mode(void) { - return false; } bool espressif_board_reset_pin_number(gpio_num_t pin_number) { // Override the I2C/TFT power pin reset to prevent resetting the display. if (pin_number == 21) { // Turn on TFT and I2C - gpio_set_direction(21, GPIO_MODE_DEF_OUTPUT); - gpio_set_level(21, true); + gpio_set_direction(pin_number, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(pin_number, true); return true; } return false; } -void reset_board(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. -void board_deinit(void) { - // TODO: Should we turn off the display when asleep? -} +// TODO: Should we turn off the display when asleep, in board_deinit()? diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tft/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s2_tft/mpconfigboard.h index bafb280014..e9eb3326ea 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tft/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32s2_tft/mpconfigboard.h @@ -32,6 +32,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO34) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO41) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO42) diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s2_tft/mpconfigboard.mk index 870c2aa3d0..4b559ff1ee 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tft/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s2_tft/mpconfigboard.mk @@ -6,13 +6,6 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.mk deleted file mode 100644 index 43c286ae3b..0000000000 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.mk +++ /dev/null @@ -1,21 +0,0 @@ -USB_VID = 0x239A -USB_PID = 0x80EE -USB_PRODUCT = "Feather ESP32S2 TFT no PSRAM" -USB_MANUFACTURER = "Adafruit" - -IDF_TARGET = esp32s2 - -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - -CIRCUITPY_ESP_FLASH_MODE = dio -CIRCUITPY_ESP_FLASH_FREQ = 40m -CIRCUITPY_ESP_FLASH_SIZE = 4MB - -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/sdkconfig deleted file mode 100644 index 5b9c86dcc3..0000000000 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/sdkconfig +++ /dev/null @@ -1,6 +0,0 @@ -# CONFIG_ESP32S2_SPIRAM_SUPPORT is not set -# -# LWIP -# -CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -# end of LWIP diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/board.c b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/board.c index d4d55c2e23..983d62a911 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/board.c @@ -35,10 +35,6 @@ void board_init(void) { reset_board(); } -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { // Turn on I2C power by default. @@ -46,5 +42,4 @@ void reset_board(void) { gpio_set_level(7, true); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.h index da623f73be..ecaa13a344 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.h @@ -32,6 +32,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO3) diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk index 39804bad26..a8d02f082c 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk @@ -5,15 +5,9 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_PS2IO = 0 +OPTIMIZATION_FLAGS = -Os +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/board.c b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/board.c index d4d55c2e23..983d62a911 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/board.c @@ -35,10 +35,6 @@ void board_init(void) { reset_board(); } -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { // Turn on I2C power by default. @@ -46,5 +42,4 @@ void reset_board(void) { gpio_set_level(7, true); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.h index b6477c766b..e089c5c251 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.h @@ -32,6 +32,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO3) diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk index 37979eed6f..582ed4409c 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c new file mode 100644 index 0000000000..360c71804c --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c @@ -0,0 +1,136 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +// display init sequence according to LilyGO example app +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 150, + // sleep out + 0x11, 0 | DELAY, 255, + // normal display mode on + 0x13, 0, + // display and color format settings + 0x36, 1, 0x68, + 0xB6, 2, 0x0A, 0x82, + 0x3A, 1 | DELAY, 0x55, 10, + // ST7789V frame rate setting + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + // voltages: VGH / VGL + 0xB7, 1, 0x35, + // ST7789V power setting + 0xBB, 1, 0x28, + 0xC0, 1, 0x0C, + 0xC2, 2, 0x01, 0xFF, + 0xC3, 1, 0x10, + 0xC4, 1, 0x20, + 0xC6, 1, 0x0F, + 0xD0, 2, 0xA4, 0xA1, + // ST7789V gamma setting + 0xE0, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0E, 0x12, 0x14, 0x17, + 0xE1, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x31, 0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1B, 0x1E, + 0x21, 0, + // display on + 0x29, 0 | DELAY, 255, +}; + + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO40, // DC + &pin_GPIO42, // CS + &pin_GPIO41, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + + common_hal_displayio_display_construct( + display, + bus, + 240, // width (after rotation) + 135, // height (after rotation) + 40, // column start + 53, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO45, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Override the I2C/TFT power pin reset to prevent resetting the display. + if (pin_number == 21) { + // Turn on TFT and I2C + gpio_set_direction(21, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(21, true); + return true; + } + return false; +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. + +// TODO: Should we turn off the display when asleep, in board_deinit() ? diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h new file mode 100644 index 0000000000..cb0237c3e5 --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Adafruit Feather ESP32-S3 Reverse TFT" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO33) +#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO34) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO3) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO34) +#define DEFAULT_UART_BUS_TX (&pin_GPIO35) + +#define DOUBLE_TAP_PIN (&pin_GPIO34) diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk new file mode 100644 index 0000000000..3fdb028f5e --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x239A +USB_PID = 0x8124 + +USB_PRODUCT = "Feather ESP32-S3 Reverse TFT" +USB_MANUFACTURER = "Adafruit" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/pins.c b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/pins.c new file mode 100644 index 0000000000..32718700b1 --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/pins.c @@ -0,0 +1,82 @@ +#include "shared-bindings/board/__init__.h" + +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_TFT_I2C_POWER), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/sdkconfig new file mode 100644 index 0000000000..9a05ab0205 --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/sdkconfig @@ -0,0 +1,47 @@ +# +# Component config +# +# +# ESP32S3-Specific +# +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +CONFIG_SPIRAM_MODE_QUAD=y +# CONFIG_SPIRAM_MODE_OCT is not set +CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 +# +# PSRAM Clock and CS IO for ESP32S3 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM Clock and CS IO for ESP32S3 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_120M is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# end of SPI RAM config + +# end of ESP32S3-Specific + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" +# end of LWIP + +# end of Component config diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c index aab7fbc608..7e28aafb8e 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c @@ -71,12 +71,6 @@ uint8_t display_init_sequence[] = { void board_init(void) { - // THIS SHOULD BE HANDLED BY espressif_board_reset_pin_number(), but it is not working. - // TEMPORARY FIX UNTIL IT'S DIAGNOSED. - common_hal_never_reset_pin(&pin_GPIO21); - gpio_set_direction(21, GPIO_MODE_DEF_OUTPUT); - gpio_set_level(21, true); - busio_spi_obj_t *spi = common_hal_board_create_spi(0); displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; bus->base.type = &displayio_fourwire_type; @@ -94,9 +88,6 @@ void board_init(void) { displayio_display_obj_t *display = &displays[0].display; display->base.type = &displayio_display_type; - // workaround as board_init() is called before reset_port() in main.c - pwmout_reset(); - common_hal_displayio_display_construct( display, bus, @@ -118,8 +109,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_GPIO45, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - false, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -128,12 +118,6 @@ void board_init(void) { false, // SH1107_addressing 50000 // backlight pwm frequency ); - - common_hal_never_reset_pin(&pin_GPIO45); // backlight pin -} - -bool board_requests_safe_mode(void) { - return false; } bool espressif_board_reset_pin_number(gpio_num_t pin_number) { @@ -147,9 +131,6 @@ bool espressif_board_reset_pin_number(gpio_num_t pin_number) { return false; } -void reset_board(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. -void board_deinit(void) { - // TODO: Should we turn off the display when asleep? -} +// TODO: Should we turn off the display when asleep, in board_deinit() ? diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.h index f2bf81d3d2..0bc80a884e 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.h @@ -32,6 +32,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO34) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO41) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO42) diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk index dcbd2f9c7a..858d0b1859 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk @@ -6,15 +6,9 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB OPTIMIZATION_FLAGS = -Os +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_feather_huzzah32/board.c b/ports/espressif/boards/adafruit_feather_huzzah32/board.c new file mode 100644 index 0000000000..164430c88c --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_huzzah32/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.h new file mode 100644 index 0000000000..0c481d6a4b --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Adafruit Feather HUZZAH32" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO23}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO5, .mosi = &pin_GPIO18, .miso = &pin_GPIO19}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk new file mode 100644 index 0000000000..8fafc18373 --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x0000239A +CIRCUITPY_CREATION_ID = 0x00320002 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_feather_huzzah32/pins.c b/ports/espressif/boards/adafruit_feather_huzzah32/pins.c new file mode 100644 index 0000000000..2d96457aad --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_huzzah32/pins.c @@ -0,0 +1,79 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/adafruit_feather_huzzah32/sdkconfig b/ports/espressif/boards/adafruit_feather_huzzah32/sdkconfig new file mode 100644 index 0000000000..6c0168c829 --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_huzzah32/sdkconfig @@ -0,0 +1,20 @@ +CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y +CONFIG_ESP32_SPIRAM_SUPPORT=n + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/adafruit_funhouse/board.c b/ports/espressif/boards/adafruit_funhouse/board.c index 8b4adc5fa9..d89a4db268 100644 --- a/ports/espressif/boards/adafruit_funhouse/board.c +++ b/ports/espressif/boards/adafruit_funhouse/board.c @@ -71,9 +71,6 @@ void board_init(void) { 0, // Polarity 0); // Phase - // workaround as board_init() is called before reset_port() in main.c - pwmout_reset(); - displayio_display_obj_t *display = &displays[0].display; display->base.type = &displayio_display_type; common_hal_displayio_display_construct( @@ -97,8 +94,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_GPIO21, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -108,13 +104,8 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - void board_deinit(void) { common_hal_displayio_release_displays(); } + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_funhouse/mpconfigboard.h b/ports/espressif/boards/adafruit_funhouse/mpconfigboard.h index a6f46af978..2b2438432e 100644 --- a/ports/espressif/boards/adafruit_funhouse/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_funhouse/mpconfigboard.h @@ -33,6 +33,8 @@ #define MICROPY_HW_APA102_SCK (&pin_GPIO15) #define MICROPY_HW_APA102_COUNT (5) +#define MICROPY_HW_LED_STATUS (&pin_GPIO37) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO33) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO34) diff --git a/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk b/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk index 531627d5a6..7d5c91f154 100644 --- a/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk @@ -5,17 +5,12 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 + # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_PortalBase FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_FakeRequests diff --git a/ports/espressif/boards/adafruit_huzzah32_breakout/board.c b/ports/espressif/boards/adafruit_huzzah32_breakout/board.c new file mode 100644 index 0000000000..164430c88c --- /dev/null +++ b/ports/espressif/boards/adafruit_huzzah32_breakout/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h b/ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h new file mode 100644 index 0000000000..0c6132c7ff --- /dev/null +++ b/ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Adafruit HUZZAH32 Breakout" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + +// For entering safe mode, use GPIO0 button +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed the GPIO0 button at start up.") + +// UART pins +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.mk b/ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.mk new file mode 100644 index 0000000000..ecf07e8e70 --- /dev/null +++ b/ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x0000239A +CIRCUITPY_CREATION_ID = 0x00320004 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_huzzah32_breakout/pins.c b/ports/espressif/boards/adafruit_huzzah32_breakout/pins.c new file mode 100644 index 0000000000..f0d6f3118a --- /dev/null +++ b/ports/espressif/boards/adafruit_huzzah32_breakout/pins.c @@ -0,0 +1,49 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/adafruit_huzzah32_breakout/sdkconfig b/ports/espressif/boards/adafruit_huzzah32_breakout/sdkconfig new file mode 100644 index 0000000000..6c0168c829 --- /dev/null +++ b/ports/espressif/boards/adafruit_huzzah32_breakout/sdkconfig @@ -0,0 +1,20 @@ +CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y +CONFIG_ESP32_SPIRAM_SUPPORT=n + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c index 3eee2f119b..681efc1cea 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c @@ -109,6 +109,10 @@ const uint8_t display_stop_sequence[] = { 0x02, 0x00 // Power off }; +const uint8_t refresh_sequence[] = { + 0x12, 0x00 +}; + void board_init(void) { // Debug UART #ifdef DEBUG @@ -137,6 +141,7 @@ void board_init(void) { display, bus, display_start_sequence, sizeof(display_start_sequence), + 0, // start up time display_stop_sequence, sizeof(display_stop_sequence), 296, // width 128, // height @@ -154,24 +159,17 @@ void board_init(void) { 0x13, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color - 0x12, // refresh_display_command + refresh_sequence, sizeof(refresh_sequence), 1.0, // refresh_time &pin_GPIO5, // busy_pin false, // busy_state 5.0, // seconds_per_frame false, // always_toggle_chip_select true, // grayscale + false, // acep false); // two_byte_sequence_length } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - bool espressif_board_reset_pin_number(gpio_num_t pin_number) { // Pin 16 is speaker enable and it's pulled down on the board. We don't want // to pull it high because then we'll compete with the external pull down. @@ -209,3 +207,5 @@ void board_deinit(void) { } common_hal_displayio_release_displays(); } + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h index 9f08ca330c..2892110f6e 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h @@ -34,6 +34,8 @@ #define CIRCUITPY_STATUS_LED_POWER_INVERTED (1) #define MICROPY_HW_NEOPIXEL_COUNT (4) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO34) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) diff --git a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.mk b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.mk index e1bd4997b7..d941039078 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.mk @@ -5,17 +5,12 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 + # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_PortalBase FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_FakeRequests diff --git a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/pins.c b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/pins.c index 2aa2b11b06..1df28f8e05 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/pins.c +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/pins.c @@ -37,6 +37,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_BUTTON_D), MP_ROM_PTR(&pin_GPIO11) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_GPIO3) }, { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, diff --git a/ports/espressif/boards/adafruit_metro_esp32s2/board.c b/ports/espressif/boards/adafruit_metro_esp32s2/board.c index 6772768da5..164430c88c 100644 --- a/ports/espressif/boards/adafruit_metro_esp32s2/board.c +++ b/ports/espressif/boards/adafruit_metro_esp32s2/board.c @@ -25,19 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_metro_esp32s2/mpconfigboard.h b/ports/espressif/boards/adafruit_metro_esp32s2/mpconfigboard.h index 3d9250bec1..698dc20764 100644 --- a/ports/espressif/boards/adafruit_metro_esp32s2/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_metro_esp32s2/mpconfigboard.h @@ -31,6 +31,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO45) +#define MICROPY_HW_LED_STATUS (&pin_GPIO42) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO34) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) diff --git a/ports/espressif/boards/adafruit_metro_esp32s2/mpconfigboard.mk b/ports/espressif/boards/adafruit_metro_esp32s2/mpconfigboard.mk index a0e7bfe6fc..8f139315c8 100644 --- a/ports/espressif/boards/adafruit_metro_esp32s2/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_metro_esp32s2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/adafruit_metro_esp32s2/pins.c b/ports/espressif/boards/adafruit_metro_esp32s2/pins.c index 0d2777b204..1f024f6e8e 100644 --- a/ports/espressif/boards/adafruit_metro_esp32s2/pins.c +++ b/ports/espressif/boards/adafruit_metro_esp32s2/pins.c @@ -60,8 +60,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO45) }, { MP_OBJ_NEW_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_DEBUG_RX), MP_ROM_PTR(&pin_GPIO38) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_GPIO37) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_DEBUG_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/espressif/boards/adafruit_qtpy_esp32_pico/board.c b/ports/espressif/boards/adafruit_qtpy_esp32_pico/board.c new file mode 100644 index 0000000000..b714fd41f0 --- /dev/null +++ b/ports/espressif/boards/adafruit_qtpy_esp32_pico/board.c @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "components/driver/include/driver/gpio.h" +#include "components/hal/include/hal/gpio_hal.h" +#include "common-hal/microcontroller/Pin.h" + +void board_init(void) { + reset_board(); +} + +void reset_board(void) { + // Turn on NeoPixel power by default. + gpio_set_direction(8, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(8, true); +} + +void board_deinit(void) { + // Turn off NeoPixel + gpio_set_direction(8, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(8, false); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.h b/ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.h new file mode 100644 index 0000000000..7f8288f17b --- /dev/null +++ b/ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#define MICROPY_HW_BOARD_NAME "Adafruit QT Py ESP32 PICO" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO5) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO33, .sda = &pin_GPIO4}, \ + {.scl = &pin_GPIO19, .sda = &pin_GPIO22}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO14, .mosi = &pin_GPIO13, .miso = &pin_GPIO12}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO32, .rx = &pin_GPIO7}} + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.mk b/ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.mk new file mode 100644 index 0000000000..de41053146 --- /dev/null +++ b/ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x0000239A +CIRCUITPY_CREATION_ID = 0x00320003 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 8MB diff --git a/ports/espressif/boards/adafruit_qtpy_esp32_pico/pins.c b/ports/espressif/boards/adafruit_qtpy_esp32_pico/pins.c new file mode 100644 index 0000000000..5d760603c1 --- /dev/null +++ b/ports/espressif/boards/adafruit_qtpy_esp32_pico/pins.c @@ -0,0 +1,63 @@ +#include "shared-bindings/board/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(stemma_i2c, i2c, 1) + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_stemma_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/adafruit_qtpy_esp32_pico/sdkconfig b/ports/espressif/boards/adafruit_qtpy_esp32_pico/sdkconfig new file mode 100644 index 0000000000..bec9e436b7 --- /dev/null +++ b/ports/espressif/boards/adafruit_qtpy_esp32_pico/sdkconfig @@ -0,0 +1,45 @@ +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 +CONFIG_SPIRAM_SPEED_40M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set +CONFIG_SPIRAM_CACHE_WORKAROUND=y + +# +# SPI RAM config +# +CONFIG_ESP32_SPIRAM_SUPPORT=y +# CONFIG_SPIRAM_TYPE_AUTO is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set + +### # Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### # CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=32 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=7 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/adafruit_qtpy_esp32c3/board.c b/ports/espressif/boards/adafruit_qtpy_esp32c3/board.c index 7a9ff98fcb..e29b6b93e7 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32c3/board.c +++ b/ports/espressif/boards/adafruit_qtpy_esp32c3/board.c @@ -25,25 +25,6 @@ * THE SOFTWARE. */ -#include "shared-bindings/microcontroller/Pin.h" #include "supervisor/board.h" -#include "components/driver/include/driver/gpio.h" -#include "soc/usb_serial_jtag_struct.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -bool espressif_board_reset_pin_number(gpio_num_t pin_number) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h b/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h index 0cc6509647..32b0940881 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h @@ -44,7 +44,4 @@ // For entering safe mode #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) -// Explanation of how a user got into safe mode -#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") - #define CIRCUITPY_ESP_USB_SERIAL_JTAG (1) diff --git a/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk b/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk index 6ca93a9fd4..e2ce1e438d 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk @@ -3,8 +3,6 @@ CIRCUITPY_CREATION_ID = 0x00c30001 IDF_TARGET = esp32c3 -INTERNAL_FLASH_FILESYSTEM = 1 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/adafruit_qtpy_esp32c3/sdkconfig b/ports/espressif/boards/adafruit_qtpy_esp32c3/sdkconfig index f9b0292400..b47420753c 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32c3/sdkconfig +++ b/ports/espressif/boards/adafruit_qtpy_esp32c3/sdkconfig @@ -1,62 +1,5 @@ -# Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) Project Configuration -# -# Bootloader config -# -CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y -# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set -CONFIG_BOOTLOADER_LOG_LEVEL=0 -# end of Bootloader config - -# -# Serial flasher config -# -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# end of Serial flasher config - -# -# Partition Table -# -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-4MB-no-uf2.csv" -CONFIG_PARTITION_TABLE_FILENAME="esp-idf-config/partitions-4MB-no-uf2.csv" -# end of Partition Table - -# -# Compiler options -# -# CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS is not set -# end of Compiler options - -# -# Component config -# -# -# ESP System Settings -# -# CONFIG_ESP_SYSTEM_USE_EH_FRAME is not set -CONFIG_ESP_CONSOLE_SECONDARY_NONE=y -# CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG is not set -# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set -# end of ESP System Settings - # # LWIP # CONFIG_LWIP_LOCAL_HOSTNAME="Adafruit-QTPy-ESP32C3" # end of LWIP - -# -# SPI Flash driver -# -# CONFIG_SPI_FLASH_AUTO_SUSPEND is not set -# end of SPI Flash driver - -# end of Component config - -# -# Deprecated options for backward compatibility -# -# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set -CONFIG_LOG_BOOTLOADER_LEVEL=0 -# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set -# end of Deprecated options for backward compatibility diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s2/board.c b/ports/espressif/boards/adafruit_qtpy_esp32s2/board.c index 6772768da5..164430c88c 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s2/board.c +++ b/ports/espressif/boards/adafruit_qtpy_esp32s2/board.c @@ -25,19 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s2/mpconfigboard.mk b/ports/espressif/boards/adafruit_qtpy_esp32s2/mpconfigboard.mk index 44c33310cc..f1bd7652fe 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s2/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_qtpy_esp32s2/mpconfigboard.mk @@ -6,13 +6,6 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/board.c b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/board.c index ff9418ec86..3b1f5efd87 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/board.c +++ b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk index 49ec368c49..e695bae635 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk @@ -6,13 +6,6 @@ USB_MANUFACTURER = "Adafruit" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB @@ -20,3 +13,4 @@ CIRCUITPY_ESP_FLASH_SIZE = 8MB FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/board.c b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/board.c index 7dd29fd6f6..2e09e7d9a4 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/board.c +++ b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/board.c @@ -43,10 +43,6 @@ void board_init(void) { USB_SERIAL_JTAG.conf0.dp_pullup = 0; } -bool board_requests_safe_mode(void) { - return false; -} - bool espressif_board_reset_pin_number(gpio_num_t pin_number) { // Pull LEDs down on reset rather than the default up if (pin_number == 3 || pin_number == 4 || pin_number == 5 || pin_number == 18 || pin_number == 19) { @@ -63,8 +59,4 @@ bool espressif_board_reset_pin_number(gpio_num_t pin_number) { return false; } -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.h b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.h index a42f8b0436..a9f0075a41 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.h +++ b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.h @@ -30,7 +30,9 @@ #define MICROPY_HW_MCU_NAME "ESP32-C3" // Status LED -#define MICROPY_HW_LED_STATUS (&pin_GPIO19) +#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO3) +#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO4) +#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO5) // Default bus pins #define DEFAULT_UART_BUS_RX (&pin_GPIO20) diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk index 125666b599..054810a088 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk +++ b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk @@ -1,10 +1,10 @@ -CIRCUITPY_CREATOR_ID = 0x70010001 -CIRCUITPY_CREATION_ID = 0x00100001 +CIRCUITPY_CREATOR_ID = 0x000C303B +CIRCUITPY_CREATION_ID = 0x00C30001 IDF_TARGET = esp32c3 -INTERNAL_FLASH_FILESYSTEM = 1 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 2MB + +CIRCUITPY_DUALBANK = 0 diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s/board.c b/ports/espressif/boards/ai_thinker_esp32-c3s/board.c index 7dd29fd6f6..2e09e7d9a4 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s/board.c +++ b/ports/espressif/boards/ai_thinker_esp32-c3s/board.c @@ -43,10 +43,6 @@ void board_init(void) { USB_SERIAL_JTAG.conf0.dp_pullup = 0; } -bool board_requests_safe_mode(void) { - return false; -} - bool espressif_board_reset_pin_number(gpio_num_t pin_number) { // Pull LEDs down on reset rather than the default up if (pin_number == 3 || pin_number == 4 || pin_number == 5 || pin_number == 18 || pin_number == 19) { @@ -63,8 +59,4 @@ bool espressif_board_reset_pin_number(gpio_num_t pin_number) { return false; } -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.h b/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.h index 20fb1ff022..f3f89d500b 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.h +++ b/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.h @@ -30,7 +30,9 @@ #define MICROPY_HW_MCU_NAME "ESP32-C3FN4" // Status LED -#define MICROPY_HW_LED_STATUS (&pin_GPIO19) +#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO3) +#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO4) +#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO5) // Default bus pins #define DEFAULT_UART_BUS_RX (&pin_GPIO20) diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk b/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk index eb88c5caab..3597166303 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk +++ b/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk @@ -1,10 +1,8 @@ -CIRCUITPY_CREATOR_ID = 0x70010001 -CIRCUITPY_CREATION_ID = 0x00100001 +CIRCUITPY_CREATOR_ID = 0x000C303B +CIRCUITPY_CREATION_ID = 0x00C30002 IDF_TARGET = esp32c3 -INTERNAL_FLASH_FILESYSTEM = 1 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/ai_thinker_esp_12k_nodemcu/board.c b/ports/espressif/boards/ai_thinker_esp_12k_nodemcu/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/ai_thinker_esp_12k_nodemcu/board.c +++ b/ports/espressif/boards/ai_thinker_esp_12k_nodemcu/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.mk b/ports/espressif/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.mk index de0fc66b9d..4ec2175eca 100644 --- a/ports/espressif/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.mk +++ b/ports/espressif/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Ai-Thinker" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/artisense_rd00/board.c b/ports/espressif/boards/artisense_rd00/board.c index ea363f6b54..fb3f6befc9 100644 --- a/ports/espressif/boards/artisense_rd00/board.c +++ b/ports/espressif/boards/artisense_rd00/board.c @@ -39,14 +39,3 @@ void board_init(void) { common_hal_never_reset_pin(&pin_GPIO15); common_hal_never_reset_pin(&pin_GPIO16); } - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} diff --git a/ports/espressif/boards/artisense_rd00/mpconfigboard.mk b/ports/espressif/boards/artisense_rd00/mpconfigboard.mk index b617b33fac..1011143972 100644 --- a/ports/espressif/boards/artisense_rd00/mpconfigboard.mk +++ b/ports/espressif/boards/artisense_rd00/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Artisense" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/atmegazero_esp32s2/board.c b/ports/espressif/boards/atmegazero_esp32s2/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/atmegazero_esp32s2/board.c +++ b/ports/espressif/boards/atmegazero_esp32s2/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/atmegazero_esp32s2/mpconfigboard.mk b/ports/espressif/boards/atmegazero_esp32s2/mpconfigboard.mk index 453591d3f8..53593be38b 100644 --- a/ports/espressif/boards/atmegazero_esp32s2/mpconfigboard.mk +++ b/ports/espressif/boards/atmegazero_esp32s2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "ATMegaZero" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 16MB diff --git a/ports/espressif/boards/beetle-esp32-c3/README.md b/ports/espressif/boards/beetle-esp32-c3/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ports/espressif/boards/beetle-esp32-c3/board.c b/ports/espressif/boards/beetle-esp32-c3/board.c new file mode 100644 index 0000000000..164430c88c --- /dev/null +++ b/ports/espressif/boards/beetle-esp32-c3/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.h b/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.h new file mode 100644 index 0000000000..2cdf48fad3 --- /dev/null +++ b/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Board setup + +#define MICROPY_HW_BOARD_NAME "DFRobot Beetle ESP32-C3" +#define MICROPY_HW_MCU_NAME "ESP32-C3FN4" + +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_GPIO10) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO9, .sda = &pin_GPIO8}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO4, .mosi = &pin_GPIO6, .miso = &pin_GPIO5}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO21, .rx = &pin_GPIO20}} + +#define CIRCUITPY_ESP_USB_SERIAL_JTAG (1) diff --git a/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk b/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk new file mode 100644 index 0000000000..b3fc9f5252 --- /dev/null +++ b/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk @@ -0,0 +1,9 @@ +# TODO +CIRCUITPY_CREATOR_ID = 0x10101010 +CIRCUITPY_CREATION_ID = 0x00C30001 + +IDF_TARGET = esp32c3 + +CIRCUITPY_ESP_FLASH_MODE=qio +CIRCUITPY_ESP_FLASH_FREQ=80m +CIRCUITPY_ESP_FLASH_SIZE=4MB diff --git a/ports/espressif/boards/beetle-esp32-c3/pins.c b/ports/espressif/boards/beetle-esp32-c3/pins.c new file mode 100644 index 0000000000..f9060cc306 --- /dev/null +++ b/ports/espressif/boards/beetle-esp32-c3/pins.c @@ -0,0 +1,66 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, // ADC1_0 + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, // ADC1_1 + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, // ADC1_2 + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + + // Pad on Board + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, // ADC1_3 + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, // ADC1_4, JTAG MTMS + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, // JTAG MTDI + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, // JTAG MTCK + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, // JTAG MTDO + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8) }, + + + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/beetle-esp32-c3/sdkconfig b/ports/espressif/boards/beetle-esp32-c3/sdkconfig new file mode 100644 index 0000000000..68be40df7a --- /dev/null +++ b/ports/espressif/boards/beetle-esp32-c3/sdkconfig @@ -0,0 +1,5 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="beetle-esp32-c3 +# end of LWIP diff --git a/ports/espressif/boards/bpi_bit_s2/board.c b/ports/espressif/boards/bpi_bit_s2/board.c new file mode 100644 index 0000000000..22cdb31898 --- /dev/null +++ b/ports/espressif/boards/bpi_bit_s2/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/bpi_bit_s2/mpconfigboard.h b/ports/espressif/boards/bpi_bit_s2/mpconfigboard.h new file mode 100644 index 0000000000..ddb51cdb6d --- /dev/null +++ b/ports/espressif/boards/bpi_bit_s2/mpconfigboard.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "BPI-Bit-S2" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +// #define MICROPY_HW_NEOPIXEL (&pin_GPIO18) +#define MICROPY_HW_LED_STATUS (&pin_GPIO0) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO16) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO15) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/bpi_bit_s2/mpconfigboard.mk b/ports/espressif/boards/bpi_bit_s2/mpconfigboard.mk new file mode 100644 index 0000000000..2c793ba5fb --- /dev/null +++ b/ports/espressif/boards/bpi_bit_s2/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x303A +USB_PID = 0x80E6 +USB_PRODUCT = "BPI-Bit-S2" +USB_MANUFACTURER = "BananaPi" + +IDF_TARGET = esp32s2 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=4MB + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/bpi_bit_s2/pins.c b/ports/espressif/boards/bpi_bit_s2/pins.c new file mode 100644 index 0000000000..4b14bbd79e --- /dev/null +++ b/ports/espressif/boards/bpi_bit_s2/pins.c @@ -0,0 +1,105 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_BUZZER), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_LUM1), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_LUM2), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_TEMPERATURE), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) } + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/bpi_bit_s2/sdkconfig b/ports/espressif/boards/bpi_bit_s2/sdkconfig new file mode 100644 index 0000000000..91758051d3 --- /dev/null +++ b/ports/espressif/boards/bpi_bit_s2/sdkconfig @@ -0,0 +1,37 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +CONFIG_SPIRAM_MODE_QUAD=y +# CONFIG_SPIRAM_MODE_OCT is not set +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 +# end of SPI RAM config + +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +# +# PSRAM Clock and CS IO for ESP32S3 +# +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM Clock and CS IO for ESP32S3 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_120M is not set +# CONFIG_SPIRAM_SPEED_80M is not set +CONFIG_SPIRAM_SPEED_40M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="BPI-BIT-S2" +# end of LWIP diff --git a/ports/espressif/boards/bpi_leaf_s3/board.c b/ports/espressif/boards/bpi_leaf_s3/board.c new file mode 100644 index 0000000000..3b1f5efd87 --- /dev/null +++ b/ports/espressif/boards/bpi_leaf_s3/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/bpi_leaf_s3/mpconfigboard.h b/ports/espressif/boards/bpi_leaf_s3/mpconfigboard.h new file mode 100644 index 0000000000..fd6aae04ea --- /dev/null +++ b/ports/espressif/boards/bpi_leaf_s3/mpconfigboard.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "BPI-Leaf-S3" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO48) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO16) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO15) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/bpi_leaf_s3/mpconfigboard.mk b/ports/espressif/boards/bpi_leaf_s3/mpconfigboard.mk new file mode 100644 index 0000000000..e2cd188059 --- /dev/null +++ b/ports/espressif/boards/bpi_leaf_s3/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x303A +USB_PID = 0x80E0 +USB_PRODUCT = "BPI-Leaf-S3" +USB_MANUFACTURER = "BananaPi" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=80m +CIRCUITPY_ESP_FLASH_SIZE=8MB + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/bpi_leaf_s3/pins.c b/ports/espressif/boards/bpi_leaf_s3/pins.c new file mode 100644 index 0000000000..bf193e88aa --- /dev/null +++ b/ports/espressif/boards/bpi_leaf_s3/pins.c @@ -0,0 +1,68 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + // { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_VBAT), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_VBAT_SENSE), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/bpi_leaf_s3/sdkconfig b/ports/espressif/boards/bpi_leaf_s3/sdkconfig new file mode 100644 index 0000000000..e9c767ea85 --- /dev/null +++ b/ports/espressif/boards/bpi_leaf_s3/sdkconfig @@ -0,0 +1,47 @@ +# +# Component config +# +# +# ESP32S3-Specific +# +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +CONFIG_SPIRAM_MODE_QUAD=y +# CONFIG_SPIRAM_MODE_OCT is not set +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 +# +# PSRAM Clock and CS IO for ESP32S3 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM Clock and CS IO for ESP32S3 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_120M is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# end of SPI RAM config + +# end of ESP32S3-Specific + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="BPI-Leaf-S3" +# end of LWIP + +# end of Component config diff --git a/ports/espressif/boards/bpi_picow_s3/board.c b/ports/espressif/boards/bpi_picow_s3/board.c new file mode 100644 index 0000000000..b3c8cb4191 --- /dev/null +++ b/ports/espressif/boards/bpi_picow_s3/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/bpi_picow_s3/mpconfigboard.h b/ports/espressif/boards/bpi_picow_s3/mpconfigboard.h new file mode 100644 index 0000000000..a261ed17fa --- /dev/null +++ b/ports/espressif/boards/bpi_picow_s3/mpconfigboard.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "BPI-PicoW-S3" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO48) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO46) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define DOUBLE_TAP_PIN (&pin_GPIO34) diff --git a/ports/espressif/boards/bpi_picow_s3/mpconfigboard.mk b/ports/espressif/boards/bpi_picow_s3/mpconfigboard.mk new file mode 100644 index 0000000000..6d77a94b08 --- /dev/null +++ b/ports/espressif/boards/bpi_picow_s3/mpconfigboard.mk @@ -0,0 +1,20 @@ +USB_VID = 0x303A +USB_PID = 0x812C +USB_PRODUCT = "BPI-PicoW-S3" +USB_MANUFACTURER = "BananaPi" + +IDF_TARGET = esp32s3 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/bpi_picow_s3/pins.c b/ports/espressif/boards/bpi_picow_s3/pins.c new file mode 100644 index 0000000000..5e88a96b49 --- /dev/null +++ b/ports/espressif/boards/bpi_picow_s3/pins.c @@ -0,0 +1,58 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO46) }, + + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/bpi_picow_s3/sdkconfig b/ports/espressif/boards/bpi_picow_s3/sdkconfig new file mode 100644 index 0000000000..04ab118924 --- /dev/null +++ b/ports/espressif/boards/bpi_picow_s3/sdkconfig @@ -0,0 +1,47 @@ +# +# Component config +# +# +# ESP32S3-Specific +# +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +CONFIG_SPIRAM_MODE_QUAD=y +# CONFIG_SPIRAM_MODE_OCT is not set +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 +# +# PSRAM Clock and CS IO for ESP32S3 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM Clock and CS IO for ESP32S3 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_120M is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# end of SPI RAM config + +# end of ESP32S3-Specific + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="BPI-PicoW-S3" +# end of LWIP + +# end of Component config diff --git a/ports/espressif/boards/brainboardz_neuron/board.c b/ports/espressif/boards/brainboardz_neuron/board.c new file mode 100755 index 0000000000..3b1f5efd87 --- /dev/null +++ b/ports/espressif/boards/brainboardz_neuron/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/brainboardz_neuron/mpconfigboard.h b/ports/espressif/boards/brainboardz_neuron/mpconfigboard.h new file mode 100755 index 0000000000..9507917ead --- /dev/null +++ b/ports/espressif/boards/brainboardz_neuron/mpconfigboard.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Neuron" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/brainboardz_neuron/mpconfigboard.mk b/ports/espressif/boards/brainboardz_neuron/mpconfigboard.mk new file mode 100755 index 0000000000..1083b18264 --- /dev/null +++ b/ports/espressif/boards/brainboardz_neuron/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x303A +USB_PID = 0x80C8 + +USB_PRODUCT = "Neuron" +USB_MANUFACTURER = "BrainBoardz" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=80m +CIRCUITPY_ESP_FLASH_SIZE=8MB diff --git a/ports/espressif/boards/brainboardz_neuron/pins.c b/ports/espressif/boards/brainboardz_neuron/pins.c new file mode 100755 index 0000000000..b0cbb91563 --- /dev/null +++ b/ports/espressif/boards/brainboardz_neuron/pins.c @@ -0,0 +1,68 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BT), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/brainboardz_neuron/sdkconfig b/ports/espressif/boards/brainboardz_neuron/sdkconfig new file mode 100755 index 0000000000..39bd2cdb4e --- /dev/null +++ b/ports/espressif/boards/brainboardz_neuron/sdkconfig @@ -0,0 +1,34 @@ +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +# CONFIG_SPIRAM_MODE_QUAD is not set +CONFIG_SPIRAM_MODE_OCT=y +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 +# end of SPI RAM config + +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +# +# PSRAM Clock and CS IO for ESP32S3 +# +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM Clock and CS IO for ESP32S3 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="BrainBoardzNeuron" +# end of LWIP diff --git a/ports/espressif/boards/crcibernetica-ideaboard/board.c b/ports/espressif/boards/crcibernetica-ideaboard/board.c new file mode 100644 index 0000000000..164430c88c --- /dev/null +++ b/ports/espressif/boards/crcibernetica-ideaboard/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.h b/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.h new file mode 100644 index 0000000000..2d20fff211 --- /dev/null +++ b/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "CRCibernetica IdeaBoard" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO23, .miso = &pin_GPIO19}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.mk b/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.mk new file mode 100644 index 0000000000..5862ee1192 --- /dev/null +++ b/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.mk @@ -0,0 +1,15 @@ +CIRCUITPY_CREATOR_ID = 0x0000303A +CIRCUITPY_CREATION_ID = 0x00320002 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 8MB +CIRCUITPY_ESPCAMERA = 0 + +# Include these Python libraries in firmware +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SimpleIO +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor diff --git a/ports/espressif/boards/crcibernetica-ideaboard/pins.c b/ports/espressif/boards/crcibernetica-ideaboard/pins.c new file mode 100644 index 0000000000..8f90bc90a0 --- /dev/null +++ b/ports/espressif/boards/crcibernetica-ideaboard/pins.c @@ -0,0 +1,52 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/crcibernetica-ideaboard/sdkconfig b/ports/espressif/boards/crcibernetica-ideaboard/sdkconfig new file mode 100644 index 0000000000..6c0168c829 --- /dev/null +++ b/ports/espressif/boards/crcibernetica-ideaboard/sdkconfig @@ -0,0 +1,20 @@ +CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y +CONFIG_ESP32_SPIRAM_SUPPORT=n + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/crumpspace_crumps2/board.c b/ports/espressif/boards/crumpspace_crumps2/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/crumpspace_crumps2/board.c +++ b/ports/espressif/boards/crumpspace_crumps2/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.h b/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.h index ca5d782036..ad0b899c1e 100644 --- a/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.h +++ b/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.h @@ -28,3 +28,7 @@ #define MICROPY_HW_BOARD_NAME "CrumpS2" #define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_APA102_MOSI (&pin_GPIO40) +#define MICROPY_HW_APA102_SCK (&pin_GPIO45) +#define MICROPY_HW_APA102_COUNT (1) diff --git a/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.mk b/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.mk index 5cd7682090..aca5950f9d 100644 --- a/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.mk +++ b/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "CrumpSpace" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/cytron_maker_feather_aiot_s3/board.c b/ports/espressif/boards/cytron_maker_feather_aiot_s3/board.c index 5c71b80fc0..1f9ef3c4e7 100644 --- a/ports/espressif/boards/cytron_maker_feather_aiot_s3/board.c +++ b/ports/espressif/boards/cytron_maker_feather_aiot_s3/board.c @@ -35,15 +35,51 @@ void board_init(void) { reset_board(); } -bool board_requests_safe_mode(void) { +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // For GPIOs used in Maker Feather AIoT S3, set the default state to pull down + // as most of them are connected to active high LED. + switch ((int8_t)pin_number) { + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 12: + case 14: + case 15: + case 16: + case 17: + case 18: + case 21: + case 38: + case 39: + case 40: + case 41: + case 42: + case 47: + case 48: + gpio_reset_pin(pin_number); + gpio_pullup_dis(pin_number); + gpio_pulldown_en(pin_number); + return true; + + // Do not pull up/down as this is the battery voltage monitoring pin. + case 13: + gpio_reset_pin(pin_number); + gpio_pullup_dis(pin_number); + gpio_pulldown_dis(pin_number); + return true; + } + return false; } void reset_board(void) { // Turn on VP by default. - gpio_set_direction(38, GPIO_MODE_DEF_OUTPUT); - gpio_set_level(38, true); + gpio_set_direction(11, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(11, true); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/cytron_maker_feather_aiot_s3/mpconfigboard.h b/ports/espressif/boards/cytron_maker_feather_aiot_s3/mpconfigboard.h index 478a06c70a..39c1edc5bd 100644 --- a/ports/espressif/boards/cytron_maker_feather_aiot_s3/mpconfigboard.h +++ b/ports/espressif/boards/cytron_maker_feather_aiot_s3/mpconfigboard.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2022 Wai Weng for Cytron Technologies * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,16 +30,18 @@ #define MICROPY_HW_MCU_NAME "ESP32S3" #define MICROPY_HW_NEOPIXEL (&pin_GPIO46) -#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO13) +#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO11) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO2) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO41) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO42) -#define DEFAULT_SPI_BUS_SCK (&pin_GPIO6) -#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO10) -#define DEFAULT_SPI_BUS_MISO (&pin_GPIO5) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO17) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO8) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO18) -#define DEFAULT_UART_BUS_RX (&pin_GPIO11) -#define DEFAULT_UART_BUS_TX (&pin_GPIO4) +#define DEFAULT_UART_BUS_RX (&pin_GPIO16) +#define DEFAULT_UART_BUS_TX (&pin_GPIO15) -#define DOUBLE_TAP_PIN (&pin_GPIO17) +#define DOUBLE_TAP_PIN (&pin_GPIO1) diff --git a/ports/espressif/boards/cytron_maker_feather_aiot_s3/mpconfigboard.mk b/ports/espressif/boards/cytron_maker_feather_aiot_s3/mpconfigboard.mk index 84ab3422e8..53e9750463 100644 --- a/ports/espressif/boards/cytron_maker_feather_aiot_s3/mpconfigboard.mk +++ b/ports/espressif/boards/cytron_maker_feather_aiot_s3/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Cytron" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB diff --git a/ports/espressif/boards/cytron_maker_feather_aiot_s3/pins.c b/ports/espressif/boards/cytron_maker_feather_aiot_s3/pins.c index 92e8e7cfc1..cca5f2617d 100644 --- a/ports/espressif/boards/cytron_maker_feather_aiot_s3/pins.c +++ b/ports/espressif/boards/cytron_maker_feather_aiot_s3/pins.c @@ -3,85 +3,99 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LED_BUILTIN), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO3) }, { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_T4), MP_ROM_PTR(&pin_GPIO4) }, { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_T5), MP_ROM_PTR(&pin_GPIO5) }, { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_T6), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_T7), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_T8), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_T9), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_T10), MP_ROM_PTR(&pin_GPIO10) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_VP_EN), MP_ROM_PTR(&pin_GPIO11) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, - { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_BUZZER), MP_ROM_PTR(&pin_GPIO12) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_VIN), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_VBATT), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_T14), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO15) }, { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, - { MP_ROM_QSTR(MP_QSTR_VIN), MP_ROM_PTR(&pin_GPIO18) }, - { MP_ROM_QSTR(MP_QSTR_VBATT), MP_ROM_PTR(&pin_GPIO18) }, - { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, - { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, - { MP_ROM_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO34) }, - { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, - { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, - { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, - - { MP_ROM_QSTR(MP_QSTR_VP_EN), MP_ROM_PTR(&pin_GPIO38) }, { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, - - { MP_ROM_QSTR(MP_QSTR_BUZZER), MP_ROM_PTR(&pin_GPIO39) }, { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_GPIO40) }, - { MP_ROM_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_GPIO41) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_GPIO41) }, - { MP_ROM_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_GPIO42) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO42) }, - - { MP_ROM_QSTR(MP_QSTR_D45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_GPIO42) }, { MP_ROM_QSTR(MP_QSTR_RGB), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_RGB_BUILTIN), MP_ROM_PTR(&pin_GPIO46) }, { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO46) }, { MP_ROM_QSTR(MP_QSTR_D46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_D47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_D48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, diff --git a/ports/espressif/boards/doit_esp32_devkit_v1/board.c b/ports/espressif/boards/doit_esp32_devkit_v1/board.c new file mode 100644 index 0000000000..164430c88c --- /dev/null +++ b/ports/espressif/boards/doit_esp32_devkit_v1/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/broadcom/fatfs_port.c b/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.h similarity index 61% rename from ports/broadcom/fatfs_port.c rename to ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.h index 58a0ef0d72..2a0dcd0104 100644 --- a/ports/broadcom/fatfs_port.c +++ b/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2022 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,25 +24,22 @@ * THE SOFTWARE. */ -#include "py/mphal.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ -#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ -#include "shared/timeutils/timeutils.h" +// Micropython setup -#if CIRCUITPY_RTC -#include "shared-bindings/rtc/RTC.h" -#endif +#define MICROPY_HW_BOARD_NAME "ESP32 Devkit V1" +#define MICROPY_HW_MCU_NAME "ESP32" -DWORD get_fattime(void) { - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif +#define MICROPY_HW_LED_STATUS (&pin_GPIO2) +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}} -} +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO23, .miso = &pin_GPIO19}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk b/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk new file mode 100644 index 0000000000..23f905dfdf --- /dev/null +++ b/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk @@ -0,0 +1,9 @@ +CIRCUITPY_CREATOR_ID = 0xB0D00000 +CIRCUITPY_CREATION_ID = 0x00320002 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/doit_esp32_devkit_v1/pins.c b/ports/espressif/boards/doit_esp32_devkit_v1/pins.c new file mode 100644 index 0000000000..78c37897ac --- /dev/null +++ b/ports/espressif/boards/doit_esp32_devkit_v1/pins.c @@ -0,0 +1,46 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + {MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15)}, + {MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2)}, + {MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_GPIO16)}, + {MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_GPIO17)}, + {MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5)}, + {MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18)}, + {MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19)}, + {MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21)}, + {MP_ROM_QSTR(MP_QSTR_RX0), MP_ROM_PTR(&pin_GPIO1)}, + {MP_ROM_QSTR(MP_QSTR_TX0), MP_ROM_PTR(&pin_GPIO3)}, + {MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22)}, + {MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23)}, + {MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13)}, + {MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12)}, + {MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14)}, + {MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27)}, + {MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26)}, + {MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25)}, + {MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33)}, + {MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32)}, + {MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35)}, + {MP_ROM_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO34)}, + + {MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2)}, + + {MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO21)}, + {MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO22)}, + + {MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18)}, + {MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23)}, + {MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19)}, + + {MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO17)}, + {MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO16)}, + + {MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj)}, + {MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj)}, + {MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/doit_esp32_devkit_v1/sdkconfig b/ports/espressif/boards/doit_esp32_devkit_v1/sdkconfig new file mode 100644 index 0000000000..6c0168c829 --- /dev/null +++ b/ports/espressif/boards/doit_esp32_devkit_v1/sdkconfig @@ -0,0 +1,20 @@ +CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y +CONFIG_ESP32_SPIRAM_SUPPORT=n + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/electroniccats_bastwifi/board.c b/ports/espressif/boards/electroniccats_bastwifi/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/electroniccats_bastwifi/board.c +++ b/ports/espressif/boards/electroniccats_bastwifi/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.h b/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.h index 229af1c865..bf8c1efa60 100644 --- a/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.h +++ b/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.h @@ -28,3 +28,5 @@ #define MICROPY_HW_BOARD_NAME "BastWiFi" #define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO14) diff --git a/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk b/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk index df377b2b6c..73acab519c 100644 --- a/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk +++ b/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk @@ -5,15 +5,9 @@ USB_MANUFACTURER = "ElectronicCats" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32_eye/board.c b/ports/espressif/boards/espressif_esp32_eye/board.c new file mode 100644 index 0000000000..1c09fb1316 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32_eye/board.c @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "components/driver/include/driver/gpio.h" +#include "components/hal/include/hal/gpio_hal.h" +#include "common-hal/microcontroller/Pin.h" + +void board_init(void) { + reset_board(); +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Pull LEDs down on reset rather than the default up + if (pin_number == 21 || pin_number == 22) { + gpio_config_t cfg = { + .pin_bit_mask = BIT64(pin_number), + .mode = GPIO_MODE_DISABLE, + .pull_up_en = false, + .pull_down_en = true, + .intr_type = GPIO_INTR_DISABLE, + }; + gpio_config(&cfg); + return true; + } + return false; +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.h b/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.h new file mode 100644 index 0000000000..accf539428 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Espressif ESP32-EYE" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO21) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO23, .sda = &pin_GPIO18}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) + +#define DEFAULT_RESERVED_PSRAM (1048576) diff --git a/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk new file mode 100644 index 0000000000..e29ca687c6 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x000C303A +CIRCUITPY_CREATION_ID = 0x00320001 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/espressif_esp32_eye/pins.c b/ports/espressif/boards/espressif_esp32_eye/pins.c new file mode 100644 index 0000000000..1824ba1cc0 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32_eye/pins.c @@ -0,0 +1,40 @@ +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_obj_tuple_t camera_data_tuple = { + {&mp_type_tuple}, + 8, + { + MP_ROM_PTR(&pin_GPIO34), + MP_ROM_PTR(&pin_GPIO13), + MP_ROM_PTR(&pin_GPIO14), + MP_ROM_PTR(&pin_GPIO35), + MP_ROM_PTR(&pin_GPIO39), // "S_VN" + MP_ROM_PTR(&pin_GPIO38), + MP_ROM_PTR(&pin_GPIO37), + MP_ROM_PTR(&pin_GPIO36), // "S_VP" + } +}; + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SDO), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_LED_WHITE), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA), MP_ROM_PTR(&camera_data_tuple) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_VSYNC), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_HREF), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_PCLK), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_XCLK), MP_ROM_PTR(&pin_GPIO4) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32_eye/sdkconfig b/ports/espressif/boards/espressif_esp32_eye/sdkconfig new file mode 100644 index 0000000000..a73d92e0a2 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32_eye/sdkconfig @@ -0,0 +1,72 @@ +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# +# +# Component config +# +# +# ESP32-specific +# +CONFIG_ESP32_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=-1 +CONFIG_SPIRAM_SPEED_40M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set +CONFIG_SPIRAM_CACHE_WORKAROUND=y +# CONFIG_SPIRAM_BANKSWITCH_ENABLE is not set +# end of SPI RAM config + +# end of ESP32-specific + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# end of NVS + +# +# Camera configuration +# +CONFIG_OV7670_SUPPORT=y +CONFIG_OV7725_SUPPORT=y +CONFIG_NT99141_SUPPORT=y +CONFIG_OV2640_SUPPORT=y +CONFIG_OV3660_SUPPORT=y +CONFIG_OV5640_SUPPORT=y +CONFIG_GC2145_SUPPORT=y +CONFIG_GC032A_SUPPORT=y +CONFIG_GC0308_SUPPORT=y +CONFIG_BF3005_SUPPORT=y +CONFIG_BF20A6_SUPPORT=y +# CONFIG_SC101IOT_SUPPORT is not set +CONFIG_SC030IOT_SUPPORT=y +# CONFIG_SCCB_HARDWARE_I2C_PORT0 is not set +CONFIG_SCCB_HARDWARE_I2C_PORT1=y +CONFIG_SCCB_CLK_FREQ=100000 +# CONFIG_GC_SENSOR_WINDOWING_MODE is not set +CONFIG_GC_SENSOR_SUBSAMPLE_MODE=y +CONFIG_CAMERA_CORE0=y +# CONFIG_CAMERA_CORE1 is not set +# CONFIG_CAMERA_NO_AFFINITY is not set +CONFIG_CAMERA_DMA_BUFFER_SIZE_MAX=32768 +# end of Camera configuration + +# end of Component config +# +CONFIG_ESP_CONSOLE_UART_TX_GPIO=1 +CONFIG_ESP_CONSOLE_UART_RX_GPIO=3 + diff --git a/ports/espressif/boards/espressif_esp32_lyrat/board.c b/ports/espressif/boards/espressif_esp32_lyrat/board.c new file mode 100644 index 0000000000..8c0c8b8b0b --- /dev/null +++ b/ports/espressif/boards/espressif_esp32_lyrat/board.c @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Radio Sound, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "components/driver/include/driver/gpio.h" +#include "components/hal/include/hal/gpio_hal.h" +#include "common-hal/microcontroller/Pin.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h b/ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h new file mode 100644 index 0000000000..7835e93f21 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Radio Sound, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Espressif ESP32-LyraT" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO22) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO23, .sda = &pin_GPIO18}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO14, .mosi = &pin_GPIO13, .miso = &pin_GPIO12}} + +#define CIRCUITPY_BOARD_UART (0) + +// For entering safe mode, use Rec button +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO36) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed the Rec button at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.mk new file mode 100644 index 0000000000..e9fcd24e61 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x000C303A +CIRCUITPY_CREATION_ID = 0x0032A000 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32_lyrat/pins.c b/ports/espressif/boards/espressif_esp32_lyrat/pins.c new file mode 100644 index 0000000000..afef90e480 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32_lyrat/pins.c @@ -0,0 +1,56 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + { MP_ROM_QSTR(MP_QSTR_CS0), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_REC), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_SW36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_MODE), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SW39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32_lyrat/sdkconfig b/ports/espressif/boards/espressif_esp32_lyrat/sdkconfig new file mode 100644 index 0000000000..4b2981ba62 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32_lyrat/sdkconfig @@ -0,0 +1,37 @@ +CONFIG_ESP32_SPIRAM_SUPPORT=y +# SPI RAM config +# +CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=4194304 +CONFIG_SPIRAM_SPEED_40M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set +CONFIG_SPIRAM_CACHE_WORKAROUND=y + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### # CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=8 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=7 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/board.c b/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/board.c index e3b71f4832..b155ed7a7b 100644 --- a/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/board.c +++ b/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/board.c @@ -35,14 +35,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -#if CIRCUITPY_ALARM -void board_deinit(void) { -} -#endif +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/mpconfigboard.mk index a652d71e8f..cd517e75b4 100644 --- a/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/mpconfigboard.mk @@ -3,8 +3,6 @@ CIRCUITPY_CREATION_ID = 0x00C30001 IDF_TARGET = esp32c3 -INTERNAL_FLASH_FILESYSTEM = 1 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/board.c b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/board.c +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk index 7d7ef438f6..d92eff48d0 100644 --- a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/board.c b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/board.c +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/mpconfigboard.mk index 06947b1275..aef3ce0dc7 100644 --- a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/board.c b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/board.c new file mode 100644 index 0000000000..b3c8cb4191 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/mpconfigboard.h b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/mpconfigboard.h new file mode 100644 index 0000000000..4875dcc745 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/mpconfigboard.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "ESP32-S2-DevKitC-1-N8R2" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/mpconfigboard.mk new file mode 100644 index 0000000000..883df304f4 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/mpconfigboard.mk @@ -0,0 +1,10 @@ +USB_VID = 0x303A +USB_PID = 0x7009 +USB_PRODUCT = "ESP32-S2-DevKitC-1-N8R2" +USB_MANUFACTURER = "Espressif" + +IDF_TARGET = esp32s2 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=8MB diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/pins.c b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/pins.c new file mode 100644 index 0000000000..435f251c80 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/pins.c @@ -0,0 +1,53 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/sdkconfig b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/sdkconfig new file mode 100644 index 0000000000..926a7813ba --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/sdkconfig @@ -0,0 +1,37 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +CONFIG_SPIRAM_MODE_QUAD=y +# CONFIG_SPIRAM_MODE_OCT is not set +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 +# end of SPI RAM config + +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +# +# PSRAM Clock and CS IO for ESP32S3 +# +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM Clock and CS IO for ESP32S3 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_120M is not set +# CONFIG_SPIRAM_SPEED_80M is not set +CONFIG_SPIRAM_SPEED_40M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s2" +# end of LWIP diff --git a/ports/espressif/boards/espressif_esp32s3_box/board.c b/ports/espressif/boards/espressif_esp32s3_box/board.c index 7eb4c6b20c..75c0ede92d 100644 --- a/ports/espressif/boards/espressif_esp32s3_box/board.c +++ b/ports/espressif/boards/espressif_esp32s3_box/board.c @@ -80,8 +80,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_GPIO45, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -97,13 +96,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk index a641450c93..5a2a4794bd 100644 --- a/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk @@ -5,13 +5,8 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_box/sdkconfig b/ports/espressif/boards/espressif_esp32s3_box/sdkconfig index 7fcf8ef297..ead0088da5 100644 --- a/ports/espressif/boards/espressif_esp32s3_box/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_box/sdkconfig @@ -1,35 +1,11 @@ -CONFIG_ESP32S3_SPIRAM_SUPPORT=y -# -# SPI RAM config -# -# CONFIG_SPIRAM_MODE_QUAD is not set -CONFIG_SPIRAM_MODE_OCT=y -CONFIG_SPIRAM_TYPE_AUTO=y -# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set -CONFIG_SPIRAM_SIZE=-1 -# end of SPI RAM config - -CONFIG_DEFAULT_PSRAM_CLK_IO=30 -# -# PSRAM Clock and CS IO for ESP32S3 -# -CONFIG_DEFAULT_PSRAM_CS_IO=26 -# end of PSRAM Clock and CS IO for ESP32S3 - -# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set -# CONFIG_SPIRAM_RODATA is not set -CONFIG_SPIRAM_SPEED_80M=y -# CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_TYPE_AUTO=y + CONFIG_SPIRAM_BOOT_INIT=y -# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set -# CONFIG_SPIRAM_USE_MEMMAP is not set -# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set -CONFIG_SPIRAM_USE_MALLOC=y -CONFIG_SPIRAM_MEMTEST=y -CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 -# CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP is not set -CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 +CONFIG_SPIRAM_USE_MEMMAP=y + # # LWIP # diff --git a/ports/espressif/boards/espressif_esp32s3_box_lite/board.c b/ports/espressif/boards/espressif_esp32s3_box_lite/board.c index 71659f4b0e..23c67d06b6 100644 --- a/ports/espressif/boards/espressif_esp32s3_box_lite/board.c +++ b/ports/espressif/boards/espressif_esp32s3_box_lite/board.c @@ -81,8 +81,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_GPIO45, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -98,13 +97,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk index de3d4cd0ed..a4bd29fa52 100644 --- a/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk @@ -5,13 +5,8 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 16MB -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - -CIRCUITPY_ESP_FLASH_MODE=dio -CIRCUITPY_ESP_FLASH_FREQ=40m -CIRCUITPY_ESP_FLASH_SIZE=16MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_box_lite/sdkconfig b/ports/espressif/boards/espressif_esp32s3_box_lite/sdkconfig index 7fcf8ef297..ead0088da5 100644 --- a/ports/espressif/boards/espressif_esp32s3_box_lite/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_box_lite/sdkconfig @@ -1,35 +1,11 @@ -CONFIG_ESP32S3_SPIRAM_SUPPORT=y -# -# SPI RAM config -# -# CONFIG_SPIRAM_MODE_QUAD is not set -CONFIG_SPIRAM_MODE_OCT=y -CONFIG_SPIRAM_TYPE_AUTO=y -# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set -CONFIG_SPIRAM_SIZE=-1 -# end of SPI RAM config - -CONFIG_DEFAULT_PSRAM_CLK_IO=30 -# -# PSRAM Clock and CS IO for ESP32S3 -# -CONFIG_DEFAULT_PSRAM_CS_IO=26 -# end of PSRAM Clock and CS IO for ESP32S3 - -# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set -# CONFIG_SPIRAM_RODATA is not set -CONFIG_SPIRAM_SPEED_80M=y -# CONFIG_SPIRAM_SPEED_40M is not set CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_TYPE_AUTO=y + CONFIG_SPIRAM_BOOT_INIT=y -# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set -# CONFIG_SPIRAM_USE_MEMMAP is not set -# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set -CONFIG_SPIRAM_USE_MALLOC=y -CONFIG_SPIRAM_MEMTEST=y -CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 -# CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP is not set -CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 +CONFIG_SPIRAM_USE_MEMMAP=y + # # LWIP # diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/board.c b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/board.c new file mode 100644 index 0000000000..ff9418ec86 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/board.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} + +void board_deinit(void) { +} diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/mpconfigboard.h b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/mpconfigboard.h new file mode 100644 index 0000000000..26410bb210 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/mpconfigboard.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "ESP32-S3-DevKitC-1-N32R8" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO48) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define AUTORESET_DELAY_MS 500 diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/mpconfigboard.mk new file mode 100644 index 0000000000..78423955bb --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/mpconfigboard.mk @@ -0,0 +1,10 @@ +USB_VID = 0x303A +USB_PID = 0x7003 +USB_PRODUCT = "ESP32-S3-DevKitC-1-N32R8" +USB_MANUFACTURER = "Espressif" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE=dout +CIRCUITPY_ESP_FLASH_FREQ=80m +CIRCUITPY_ESP_FLASH_SIZE=32MB diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/pins.c b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/pins.c new file mode 100644 index 0000000000..919deca8b4 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/pins.c @@ -0,0 +1,49 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/sdkconfig b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/sdkconfig new file mode 100644 index 0000000000..f915462e11 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/sdkconfig @@ -0,0 +1,77 @@ +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +# CONFIG_SPIRAM_MODE_QUAD is not set +CONFIG_SPIRAM_MODE_OCT=y +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 +# end of SPI RAM config + +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +# +# PSRAM Clock and CS IO for ESP32S3 +# +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM Clock and CS IO for ESP32S3 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +# CONFIG_ESPTOOLPY_NO_STUB is not set +CONFIG_ESPTOOLPY_OCT_FLASH=y +CONFIG_ESPTOOLPY_FLASHMODE_OPI=y +# CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR=y +CONFIG_ESPTOOLPY_FLASHMODE="dout" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_32MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="32MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" +# end of LWIP diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/board.c b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/board.c index ff9418ec86..3b1f5efd87 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/board.c +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk index 8e7b09dbc9..6f56013e09 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/board.c b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/board.c index ff9418ec86..3b1f5efd87 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/board.c +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/mpconfigboard.mk index 698c1fff88..7d5afe9a9f 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/board.c b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/board.c index ff9418ec86..3b1f5efd87 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/board.c +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/mpconfigboard.mk index f9c6cd9c44..95fa2d0324 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB diff --git a/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/board.c b/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/board.c index ff9418ec86..3b1f5efd87 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/board.c +++ b/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/mpconfigboard.mk index d6b401ac87..55ad754736 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_eye/board.c b/ports/espressif/boards/espressif_esp32s3_eye/board.c new file mode 100644 index 0000000000..be129c6a30 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_eye/board.c @@ -0,0 +1,122 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +// display init sequence according to LilyGO example app +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 150, + // sleep out + 0x11, 0 | DELAY, 255, + // normal display mode on + 0x13, 0, + // display and color format settings + 0x36, 1, 0x08, + 0xB6, 2, 0x0A, 0x82, + 0x3A, 1 | DELAY, 0x55, 10, + // ST7789V frame rate setting + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + // voltages: VGH / VGL + 0xB7, 1, 0x35, + // ST7789V power setting + 0xBB, 1, 0x28, + 0xC0, 1, 0x0C, + 0xC2, 2, 0x01, 0xFF, + 0xC3, 1, 0x10, + 0xC4, 1, 0x20, + 0xC6, 1, 0x0F, + 0xD0, 2, 0xA4, 0xA1, + // ST7789V gamma setting + 0xE0, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0E, 0x12, 0x14, 0x17, + 0xE1, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x31, 0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1B, 0x1E, + 0x21, 0, + // display on + 0x29, 0 | DELAY, 255, +}; + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO43, // DC + &pin_GPIO44, // CS + NULL, // no reset pin + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + + common_hal_displayio_display_construct( + display, + bus, + 240, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO48, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + false, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/fatfs_port.c b/ports/espressif/boards/espressif_esp32s3_eye/mpconfigboard.h similarity index 60% rename from ports/mimxrt10xx/fatfs_port.c rename to ports/espressif/boards/espressif_esp32s3_eye/mpconfigboard.h index 58a0ef0d72..43ade4f6c8 100644 --- a/ports/mimxrt10xx/fatfs_port.c +++ b/ports/espressif/boards/espressif_esp32s3_eye/mpconfigboard.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,25 +24,24 @@ * THE SOFTWARE. */ -#include "py/mphal.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ -#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ -#include "shared/timeutils/timeutils.h" +// Micropython setup -#if CIRCUITPY_RTC -#include "shared-bindings/rtc/RTC.h" -#endif +#define MICROPY_HW_BOARD_NAME "ESP32-S3-EYE" +#define MICROPY_HW_MCU_NAME "ESP32S3" -DWORD get_fattime(void) { - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif +// Shared by the camera and accelerometer +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) +// This is the SD card connection, not the LCD +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO39) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO40) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO38) +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN { \ + {.clock = &pin_GPIO21, .mosi = &pin_GPIO47, .miso = NULL}, \ + {.clock = &pin_GPIO39, .mosi = &pin_GPIO40, .miso = &pin_GPIO38}, \ } + +#define DEFAULT_RESERVED_PSRAM (1048576) diff --git a/ports/espressif/boards/espressif_esp32s3_eye/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_eye/mpconfigboard.mk new file mode 100644 index 0000000000..4711f28aaf --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_eye/mpconfigboard.mk @@ -0,0 +1,10 @@ +USB_VID = 0x303A +USB_PID = 0x700F +USB_PRODUCT = "ESP32-S3-EYE" +USB_MANUFACTURER = "Espressif" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB diff --git a/ports/espressif/boards/espressif_esp32s3_eye/pins.c b/ports/espressif/boards/espressif_esp32s3_eye/pins.c new file mode 100644 index 0000000000..4b4da0b199 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_eye/pins.c @@ -0,0 +1,55 @@ +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_obj_tuple_t camera_data_tuple = { + {&mp_type_tuple}, + 8, + { + MP_ROM_PTR(&pin_GPIO11), + MP_ROM_PTR(&pin_GPIO9), + MP_ROM_PTR(&pin_GPIO8), + MP_ROM_PTR(&pin_GPIO10), + MP_ROM_PTR(&pin_GPIO12), + MP_ROM_PTR(&pin_GPIO18), + MP_ROM_PTR(&pin_GPIO17), + MP_ROM_PTR(&pin_GPIO16), + } +}; + + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTONS), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_MIC_SDO), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, // LCD + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA), MP_ROM_PTR(&camera_data_tuple) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_VSYNC), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_HREF), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_PCLK), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_XCLK), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_MISO1), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_MOSI1), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_SCK1), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_MIC_SCK), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_MIC_WS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_BACKLIGHT), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32s3_eye/sdkconfig b/ports/espressif/boards/espressif_esp32s3_eye/sdkconfig new file mode 100644 index 0000000000..1a24832767 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_eye/sdkconfig @@ -0,0 +1,34 @@ +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +# CONFIG_SPIRAM_MODE_QUAD is not set +CONFIG_SPIRAM_MODE_OCT=y +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 +# end of SPI RAM config + +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +# +# PSRAM Clock and CS IO for ESP32S3 +# +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM Clock and CS IO for ESP32S3 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3-eye" +# end of LWIP diff --git a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c index f278c7ddbc..685e7cf156 100644 --- a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c +++ b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c @@ -108,8 +108,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_GPIO9, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -134,13 +133,4 @@ bool espressif_board_reset_pin_number(gpio_num_t pin_number) { return false; } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/mpconfigboard.mk index 3197d78a31..868e29bf60 100644 --- a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_hmi_devkit_1/board.c b/ports/espressif/boards/espressif_hmi_devkit_1/board.c index 93aa1c0436..b44ba7fad2 100644 --- a/ports/espressif/boards/espressif_hmi_devkit_1/board.c +++ b/ports/espressif/boards/espressif_hmi_devkit_1/board.c @@ -34,13 +34,4 @@ void board_init(void) { common_hal_never_reset_pin(&pin_GPIO44); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_hmi_devkit_1/mpconfigboard.mk b/ports/espressif/boards/espressif_hmi_devkit_1/mpconfigboard.mk index bd8e6c6e31..60ff9fd5a1 100644 --- a/ports/espressif/boards/espressif_hmi_devkit_1/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_hmi_devkit_1/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/espressif_kaluga_1.3/board.c b/ports/espressif/boards/espressif_kaluga_1.3/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/espressif_kaluga_1.3/board.c +++ b/ports/espressif/boards/espressif_kaluga_1.3/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_kaluga_1.3/mpconfigboard.h b/ports/espressif/boards/espressif_kaluga_1.3/mpconfigboard.h index 8f89bfcbc4..459a5b3289 100644 --- a/ports/espressif/boards/espressif_kaluga_1.3/mpconfigboard.h +++ b/ports/espressif/boards/espressif_kaluga_1.3/mpconfigboard.h @@ -30,3 +30,6 @@ #define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_NEOPIXEL (&pin_GPIO45) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO7) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) diff --git a/ports/espressif/boards/espressif_kaluga_1.3/mpconfigboard.mk b/ports/espressif/boards/espressif_kaluga_1.3/mpconfigboard.mk index 0ff4eab64f..23578067ac 100644 --- a/ports/espressif/boards/espressif_kaluga_1.3/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_kaluga_1.3/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/espressif_kaluga_1.3/pins.c b/ports/espressif/boards/espressif_kaluga_1.3/pins.c index dff98ceeb9..caa7ecd064 100644 --- a/ports/espressif/boards/espressif_kaluga_1.3/pins.c +++ b/ports/espressif/boards/espressif_kaluga_1.3/pins.c @@ -140,5 +140,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S1_LRCK_DAC1), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_AUDIO_I2S1_BCLK_DAC2), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_kaluga_1/board.c b/ports/espressif/boards/espressif_kaluga_1/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/espressif_kaluga_1/board.c +++ b/ports/espressif/boards/espressif_kaluga_1/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_kaluga_1/mpconfigboard.mk b/ports/espressif/boards/espressif_kaluga_1/mpconfigboard.mk index 0ff4eab64f..23578067ac 100644 --- a/ports/espressif/boards/espressif_kaluga_1/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_kaluga_1/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/espressif_saola_1_wroom/board.c b/ports/espressif/boards/espressif_saola_1_wroom/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/espressif_saola_1_wroom/board.c +++ b/ports/espressif/boards/espressif_saola_1_wroom/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk b/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk index 5e09be7b2e..03feef98ce 100644 --- a/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_saola_1_wrover/board.c b/ports/espressif/boards/espressif_saola_1_wrover/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/espressif_saola_1_wrover/board.c +++ b/ports/espressif/boards/espressif_saola_1_wrover/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_saola_1_wrover/mpconfigboard.mk b/ports/espressif/boards/espressif_saola_1_wrover/mpconfigboard.mk index 6185e40809..5156a5b6ce 100644 --- a/ports/espressif/boards/espressif_saola_1_wrover/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_saola_1_wrover/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/franzininho_wifi_wroom/board.c b/ports/espressif/boards/franzininho_wifi_wroom/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/franzininho_wifi_wroom/board.c +++ b/ports/espressif/boards/franzininho_wifi_wroom/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk b/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk index dc777ecd95..76661511e2 100644 --- a/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/franzininho_wifi_wrover/board.c b/ports/espressif/boards/franzininho_wifi_wrover/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/franzininho_wifi_wrover/board.c +++ b/ports/espressif/boards/franzininho_wifi_wrover/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/franzininho_wifi_wrover/mpconfigboard.mk b/ports/espressif/boards/franzininho_wifi_wrover/mpconfigboard.mk index 4d5081dd7f..2a09bc99eb 100644 --- a/ports/espressif/boards/franzininho_wifi_wrover/mpconfigboard.mk +++ b/ports/espressif/boards/franzininho_wifi_wrover/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/gravitech_cucumber_m/board.c b/ports/espressif/boards/gravitech_cucumber_m/board.c index 16a6af0742..b3c8cb4191 100644 --- a/ports/espressif/boards/gravitech_cucumber_m/board.c +++ b/ports/espressif/boards/gravitech_cucumber_m/board.c @@ -36,12 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.h b/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.h index a20ea362f2..fba644553f 100644 --- a/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.h +++ b/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.h @@ -31,5 +31,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO18) +#define MICROPY_HW_LED_STATUS (&pin_GPIO2) +#define MICROPY_HW_LED_STATUS_INVERTED (1) + #define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define DEFAULT_UART_BUS_RX (&pin_GPIO44) diff --git a/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk b/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk index 04f23bf4bb..801bd8b508 100644 --- a/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk +++ b/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Gravitech" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/gravitech_cucumber_ms/board.c b/ports/espressif/boards/gravitech_cucumber_ms/board.c index 16a6af0742..b3c8cb4191 100644 --- a/ports/espressif/boards/gravitech_cucumber_ms/board.c +++ b/ports/espressif/boards/gravitech_cucumber_ms/board.c @@ -36,12 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.h b/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.h index 17719c6f40..1fa96a84a6 100644 --- a/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.h +++ b/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.h @@ -31,6 +31,9 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO18) +#define MICROPY_HW_LED_STATUS (&pin_GPIO2) +#define MICROPY_HW_LED_STATUS_INVERTED (1) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO40) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO41) diff --git a/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk b/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk index 77861c0228..b57f74f23d 100644 --- a/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk +++ b/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Gravitech" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/gravitech_cucumber_r/board.c b/ports/espressif/boards/gravitech_cucumber_r/board.c index 16a6af0742..b3c8cb4191 100644 --- a/ports/espressif/boards/gravitech_cucumber_r/board.c +++ b/ports/espressif/boards/gravitech_cucumber_r/board.c @@ -36,12 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/gravitech_cucumber_r/mpconfigboard.h b/ports/espressif/boards/gravitech_cucumber_r/mpconfigboard.h index 53409cf263..07d65735a6 100644 --- a/ports/espressif/boards/gravitech_cucumber_r/mpconfigboard.h +++ b/ports/espressif/boards/gravitech_cucumber_r/mpconfigboard.h @@ -31,5 +31,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO18) +#define MICROPY_HW_LED_STATUS (&pin_GPIO2) +#define MICROPY_HW_LED_STATUS_INVERTED (1) + #define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define DEFAULT_UART_BUS_RX (&pin_GPIO44) diff --git a/ports/espressif/boards/gravitech_cucumber_r/mpconfigboard.mk b/ports/espressif/boards/gravitech_cucumber_r/mpconfigboard.mk index 5e4f6c4b98..d3e40f2df6 100644 --- a/ports/espressif/boards/gravitech_cucumber_r/mpconfigboard.mk +++ b/ports/espressif/boards/gravitech_cucumber_r/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Gravitech" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/gravitech_cucumber_rs/board.c b/ports/espressif/boards/gravitech_cucumber_rs/board.c index 16a6af0742..b3c8cb4191 100644 --- a/ports/espressif/boards/gravitech_cucumber_rs/board.c +++ b/ports/espressif/boards/gravitech_cucumber_rs/board.c @@ -36,12 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/gravitech_cucumber_rs/mpconfigboard.h b/ports/espressif/boards/gravitech_cucumber_rs/mpconfigboard.h index ee19f54ca5..1e91421574 100644 --- a/ports/espressif/boards/gravitech_cucumber_rs/mpconfigboard.h +++ b/ports/espressif/boards/gravitech_cucumber_rs/mpconfigboard.h @@ -31,6 +31,9 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO18) +#define MICROPY_HW_LED_STATUS (&pin_GPIO2) +#define MICROPY_HW_LED_STATUS_INVERTED (1) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO40) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO41) diff --git a/ports/espressif/boards/gravitech_cucumber_rs/mpconfigboard.mk b/ports/espressif/boards/gravitech_cucumber_rs/mpconfigboard.mk index 96b9dddf8b..e0b3f35d44 100644 --- a/ports/espressif/boards/gravitech_cucumber_rs/mpconfigboard.mk +++ b/ports/espressif/boards/gravitech_cucumber_rs/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Gravitech" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/hardkernel_odroid_go/board.c b/ports/espressif/boards/hardkernel_odroid_go/board.c new file mode 100644 index 0000000000..609572977e --- /dev/null +++ b/ports/espressif/boards/hardkernel_odroid_go/board.c @@ -0,0 +1,129 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#include "common-hal/microcontroller/Pin.h" + +#define DELAY 0x80 + +// ILI9341 init sequence from: +// https://github.com/hardkernel/ODROID-GO-MicroPython/blob/loboris/odroid_go/utils/lcd/lcd.py#L55 +uint8_t display_init_sequence[] = { + 0x0f, 3, 0x03, 0x80, 0x02, // RDDSDR + 0xcf, 3, 0x00, 0xcf, 0x30, // PWCRTLB + 0xed, 4, 0x64, 0x03, 0x12, 0x81, // PWRONCTRL + 0xe8, 3, 0x85, 0x00, 0x78, // DTCTRLA + 0xcb, 5, 0x39, 0x2c, 0x00, 0x34, 0x02, // PWCTRLA + 0xf7, 1, 0x20, // PRCTRL + 0xea, 2, 0x00, 0x00, // DTCTRLB + 0xc0, 1, 0x1b, // PWCTRL1 + 0xc1, 1, 0x12, // PWCTRL2 + 0xc5, 2, 0x3e, 0x3c, // VMCTRL1 + 0xc7, 1, 0x91, // VMCTRL2 + 0x36, 1, 0xa8, // MADCTL + 0x3a, 1, 0x55, // PIXSET + 0xb1, 2, 0x00, 0x1b, // FRMCTR1 + 0xb6, 3, 0x0a, 0xa2, 0x27, // DISCTRL + 0xf6, 2, 0x01, 0x30, // INTFACE + 0xf2, 1, 0x00, // ENA3G + 0x26, 1, 0x01, // GAMSET + 0xe0, 15, 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1, 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00, // PGAMCTRL + 0xe1, 15, 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1, 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f, // NGAMCTRL + 0x11, 0 | DELAY, 10, // SLPOUT + 0x29, 0 | DELAY, 100, // DISPON +}; + +void board_init(void) { + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO23, NULL, false); + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_GPIO21, // TFT_DC Command or data + &pin_GPIO5, // TFT_CS Chip select + NULL, // TFT_RST Reset + 40000000, // Baudrate + 0, // Polarity + 0); // Phase + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 320, // Width (after rotation) + 240, // Height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // Color depth + false, // grayscale + false, // pixels in byte share row. only used for depth < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO14, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000); // backlight pwm frequency +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Pull LED down on reset rather than the default up + if (pin_number == 2) { + gpio_config_t cfg = { + .pin_bit_mask = BIT64(pin_number), + .mode = GPIO_MODE_DISABLE, + .pull_up_en = false, + .pull_down_en = true, + .intr_type = GPIO_INTR_DISABLE, + }; + gpio_config(&cfg); + return true; + } + return false; +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h b/ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h new file mode 100644 index 0000000000..49d49f2427 --- /dev/null +++ b/ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#define MICROPY_HW_BOARD_NAME "Hardkernel Odroid Go" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO2) + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO23, .miso = &pin_GPIO19}} + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed the VOLUME button at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.mk b/ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.mk new file mode 100644 index 0000000000..ead48189fa --- /dev/null +++ b/ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x0D10D000 +CIRCUITPY_CREATION_ID = 0x00320060 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 16MB diff --git a/ports/espressif/boards/hardkernel_odroid_go/pins.c b/ports/espressif/boards/hardkernel_odroid_go/pins.c new file mode 100644 index 0000000000..40f4fcdc34 --- /dev/null +++ b/ports/espressif/boards/hardkernel_odroid_go/pins.c @@ -0,0 +1,60 @@ +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +// Pin names from: https://wiki.odroid.com/odroid_go/odroid_go + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Left side + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_BTN_START), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_BTN_AXIS_X), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_BTN_AXIS_Y), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_BTN_A), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_BTN_B), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_SPEAKER_IN_M), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_SPEAKER_IN_P), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_BTN_SELECT), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_BACKLIGHT_PWM), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_EXT3), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_BTN_MENU), MP_ROM_PTR(&pin_GPIO13) }, + + // Right side. + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_EXT8), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_EXT7), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_EXT2), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_EXT5), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_BTN_VOLUME), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_EXT4), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/hardkernel_odroid_go/sdkconfig b/ports/espressif/boards/hardkernel_odroid_go/sdkconfig new file mode 100644 index 0000000000..f4fea0c732 --- /dev/null +++ b/ports/espressif/boards/hardkernel_odroid_go/sdkconfig @@ -0,0 +1,37 @@ +CONFIG_ESP32_SPIRAM_SUPPORT=y +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM32=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=4194304 +CONFIG_SPIRAM_SPEED_40M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set +CONFIG_SPIRAM_CACHE_WORKAROUND=y + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### # CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### nCONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=12 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=15 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/hexky_s2/board.c b/ports/espressif/boards/hexky_s2/board.c index 584253488b..e4f8f48855 100644 --- a/ports/espressif/boards/hexky_s2/board.c +++ b/ports/espressif/boards/hexky_s2/board.c @@ -88,9 +88,6 @@ void board_init(void) { displayio_display_obj_t *display = &displays[0].display; display->base.type = &displayio_display_type; - // workaround as board_init() is called before reset_port() in main.c - pwmout_reset(); - common_hal_displayio_display_construct( display, bus, @@ -112,8 +109,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_GPIO45, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - false, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -122,12 +118,6 @@ void board_init(void) { false, // SH1107_addressing 50000 // backlight pwm frequency ); - - common_hal_never_reset_pin(&pin_GPIO45); // backlight pin -} - -bool board_requests_safe_mode(void) { - return false; } bool espressif_board_reset_pin_number(gpio_num_t pin_number) { @@ -141,9 +131,6 @@ bool espressif_board_reset_pin_number(gpio_num_t pin_number) { return false; } -void reset_board(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. -void board_deinit(void) { - // TODO: Should we turn off the display when asleep? -} +// TODO: Should we turn off the display when asleep, in board_deinit()? diff --git a/ports/espressif/boards/hexky_s2/mpconfigboard.h b/ports/espressif/boards/hexky_s2/mpconfigboard.h index 31dd096beb..f49901332f 100644 --- a/ports/espressif/boards/hexky_s2/mpconfigboard.h +++ b/ports/espressif/boards/hexky_s2/mpconfigboard.h @@ -30,7 +30,7 @@ #define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_NEOPIXEL (&pin_GPIO40) -#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO39) +#define MICROPY_HW_LED_STATUS (&pin_GPIO39) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) diff --git a/ports/espressif/boards/hexky_s2/mpconfigboard.mk b/ports/espressif/boards/hexky_s2/mpconfigboard.mk index dbde2f77e4..043dec5824 100644 --- a/ports/espressif/boards/hexky_s2/mpconfigboard.mk +++ b/ports/espressif/boards/hexky_s2/mpconfigboard.mk @@ -6,13 +6,6 @@ USB_MANUFACTURER = "FutureKeys" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/hiibot_iots2/board.c b/ports/espressif/boards/hiibot_iots2/board.c index e65401deda..c9cf7afb92 100644 --- a/ports/espressif/boards/hiibot_iots2/board.c +++ b/ports/espressif/boards/hiibot_iots2/board.c @@ -93,9 +93,6 @@ static void display_init(void) { displayio_display_obj_t *display = &displays[0].display; display->base.type = &displayio_display_type; - // workaround as board_init() is called before reset_port() in main.c - pwmout_reset(); - common_hal_displayio_display_construct( display, bus, @@ -117,8 +114,7 @@ static void display_init(void) { sizeof(display_init_sequence), &pin_GPIO38, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - false, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -127,8 +123,6 @@ static void display_init(void) { false, // SH1107_addressing 50000 // backlight pwm frequency ); - - common_hal_never_reset_pin(&pin_GPIO38); // backlight pin } void board_init(void) { @@ -155,12 +149,4 @@ void board_init(void) { display_init(); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/hiibot_iots2/mpconfigboard.mk b/ports/espressif/boards/hiibot_iots2/mpconfigboard.mk index b52c88cdc6..a60d894665 100644 --- a/ports/espressif/boards/hiibot_iots2/mpconfigboard.mk +++ b/ports/espressif/boards/hiibot_iots2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "HiiBot" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 8MB diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/board.c b/ports/espressif/boards/lilygo_tembed_esp32s3/board.c similarity index 67% rename from ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/board.c rename to ports/espressif/boards/lilygo_tembed_esp32s3/board.c index 04b6a46779..ed49eb504c 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/board.c +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/board.c @@ -26,64 +26,50 @@ #include "supervisor/board.h" #include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + #include "shared-bindings/busio/SPI.h" #include "shared-bindings/displayio/FourWire.h" -#include "shared-bindings/microcontroller/Pin.h" #include "shared-module/displayio/__init__.h" #include "shared-module/displayio/mipi_constants.h" -/* -displayio_fourwire_obj_t board_display_obj; - -#define DELAY 0x80 - uint8_t display_init_sequence[] = { - 0x01, 0 | DELAY, 150, // SWRESET - 0x11, 0 | DELAY, 255, // SLPOUT - 0x36, 1, 0x00, // _MADCTL bottom to top refresh in vsync aligned order. - 0x3a, 1, 0x55, // COLMOD - 16bit color - 0x21, 0 | DELAY, 10, // _INVON - 0x13, 0 | DELAY, 10, // _NORON - 0x29, 0 | DELAY, 255, // _DISPON + 0x01, 0x80, 0x96, // _SWRESET and Delay 150ms + 0x11, 0x80, 0xFF, // _SLPOUT and Delay 500ms + 0x3A, 0x81, 0x55, 0x0A, // _COLMOD and Delay 10ms + 0x13, 0x80, 0x0A, // _NORON and Delay 10ms + 0x36, 0x01, 0xC8, // _MADCTL + 0x29, 0x80, 0xFF, // _DISPON and Delay 500ms }; -*/ - void board_init(void) { - // Debug UART - #ifdef DEBUG - common_hal_never_reset_pin(&pin_GPIO43); - common_hal_never_reset_pin(&pin_GPIO44); - #endif /* DEBUG */ - - /* - busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO36, &pin_GPIO35, NULL); + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO12, &pin_GPIO11, NULL, false); common_hal_busio_spi_never_reset(spi); - displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; bus->base.type = &displayio_fourwire_type; common_hal_displayio_fourwire_construct(bus, spi, - &pin_GPIO40, // TFT_DC Command or data - &pin_GPIO42, // TFT_CS Chip select - &pin_GPIO41, // TFT_RST Reset - 4000000, // Baudrate + &pin_GPIO13, // TFT_DC Command or data + &pin_GPIO10, // TFT_CS Chip select + &pin_GPIO9, // TFT_RST Reset + 60000000, // Baudrate 0, // Polarity 0); // Phase - displayio_display_obj_t* display = &displays[0].display; + displayio_display_obj_t *display = &displays[0].display; display->base.type = &displayio_display_type; common_hal_displayio_display_construct(display, bus, - 240, // Width (after rotation) - 135, // Height (after rotation) - 0, // column start + 320, // Width + 170, // Height + 35, // column start 0, // row start - 0, // rotation + 90, // rotation 16, // Color depth false, // Grayscale - false, // Pixels in a byte share a row. Only used for depth < 8 + false, // pixels in a byte share a row. Only valid for depths < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 true, // reverse_pixels_in_word @@ -92,27 +78,22 @@ void board_init(void) { MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command display_init_sequence, sizeof(display_init_sequence), - &pin_GPIO7, // backlight pin + &pin_GPIO15, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh 60, // native_frames_per_second true, // backlight_on_high - false, // not SH1107 + false, // SH1107_addressing 50000); // backlight pwm frequency - */ + + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_tembed_esp32s3/mpconfigboard.h b/ports/espressif/boards/lilygo_tembed_esp32s3/mpconfigboard.h new file mode 100644 index 0000000000..307c103e33 --- /dev/null +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/mpconfigboard.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "LILYGO TEMBED ESP32S3" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO48) + +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO11) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO12) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/lilygo_tembed_esp32s3/mpconfigboard.mk b/ports/espressif/boards/lilygo_tembed_esp32s3/mpconfigboard.mk new file mode 100644 index 0000000000..2b8f67b560 --- /dev/null +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/mpconfigboard.mk @@ -0,0 +1,10 @@ +USB_VID = 0x303A +USB_PID = 0x8151 +USB_PRODUCT = "TEMBED ESP32S3" +USB_MANUFACTURER = "LILYGO" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB diff --git a/ports/espressif/boards/lilygo_tembed_esp32s3/pins.c b/ports/espressif/boards/lilygo_tembed_esp32s3/pins.c new file mode 100644 index 0000000000..94c57f162f --- /dev/null +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/pins.c @@ -0,0 +1,86 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + // TFT control pins + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_GPIO15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, + + // SD card control pins + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCLK), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO38) }, + + // Microphone control pins + { MP_ROM_QSTR(MP_QSTR_ES_BCLK), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_ES_LRCK), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_ES_DIN), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_ES_MCLK), MP_ROM_PTR(&pin_GPIO48) }, + + // Speaker control pins + { MP_ROM_QSTR(MP_QSTR_I2S_BCLK), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WCLK), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DOUT), MP_ROM_PTR(&pin_GPIO6) }, + + // Encoder control pins + { MP_ROM_QSTR(MP_QSTR_ENCODER_A), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_ENCODER_B), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_ENCODER_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + + // APA102 control pins (Leds) + { MP_ROM_QSTR(MP_QSTR_APA102_CLK), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_APA102_DI), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/lilygo_tembed_esp32s3/sdkconfig b/ports/espressif/boards/lilygo_tembed_esp32s3/sdkconfig new file mode 100644 index 0000000000..f508f4a67c --- /dev/null +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/sdkconfig @@ -0,0 +1,34 @@ +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +# CONFIG_SPIRAM_MODE_QUAD is not set +CONFIG_SPIRAM_MODE_OCT=y +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 +# end of SPI RAM config + +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +# +# PSRAM Clock and CS IO for ESP32S3 +# +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM Clock and CS IO for ESP32S3 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" +# end of LWIP diff --git a/ports/espressif/boards/lilygo_ttgo_t-01c3/board.c b/ports/espressif/boards/lilygo_ttgo_t-01c3/board.c index deeb8041ea..67b05e5cd2 100644 --- a/ports/espressif/boards/lilygo_ttgo_t-01c3/board.c +++ b/ports/espressif/boards/lilygo_ttgo_t-01c3/board.c @@ -11,28 +11,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -bool espressif_board_reset_pin_number(gpio_num_t pin_number) { - // Pull LED down on reset rather than the default up - if (pin_number == MICROPY_HW_LED_STATUS->number) { - gpio_config_t cfg = { - .pin_bit_mask = BIT64(pin_number), - .mode = GPIO_MODE_DISABLE, - .pull_up_en = false, - .pull_down_en = true, - .intr_type = GPIO_INTR_DISABLE, - }; - gpio_config(&cfg); - return true; - } - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_ttgo_t-01c3/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_t-01c3/mpconfigboard.mk index d40c9b6722..2ca19f332c 100644 --- a/ports/espressif/boards/lilygo_ttgo_t-01c3/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_ttgo_t-01c3/mpconfigboard.mk @@ -3,8 +3,6 @@ CIRCUITPY_CREATION_ID = 0x00C30001 IDF_TARGET = esp32c3 -INTERNAL_FLASH_FILESYSTEM = 1 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/lilygo_ttgo_t-oi-plus/board.c b/ports/espressif/boards/lilygo_ttgo_t-oi-plus/board.c index deeb8041ea..7bcdcdba25 100644 --- a/ports/espressif/boards/lilygo_ttgo_t-oi-plus/board.c +++ b/ports/espressif/boards/lilygo_ttgo_t-oi-plus/board.c @@ -1,3 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/board.h" @@ -11,28 +37,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -bool espressif_board_reset_pin_number(gpio_num_t pin_number) { - // Pull LED down on reset rather than the default up - if (pin_number == MICROPY_HW_LED_STATUS->number) { - gpio_config_t cfg = { - .pin_bit_mask = BIT64(pin_number), - .mode = GPIO_MODE_DISABLE, - .pull_up_en = false, - .pull_down_en = true, - .intr_type = GPIO_INTR_DISABLE, - }; - gpio_config(&cfg); - return true; - } - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.mk index 2f66e69415..7a80145217 100644 --- a/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.mk @@ -3,8 +3,6 @@ CIRCUITPY_CREATION_ID = 0x00C30002 IDF_TARGET = esp32c3 -INTERNAL_FLASH_FILESYSTEM = 1 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/board.c b/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/board.c index d522720629..6597b51c5f 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/board.c +++ b/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/board.c @@ -36,12 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/mpconfigboard.mk index 1d5e3ec719..3244d38869 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "LILYGO" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/lilygo_ttgo_t8_s2/board.c b/ports/espressif/boards/lilygo_ttgo_t8_s2/board.c index d522720629..6597b51c5f 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_s2/board.c +++ b/ports/espressif/boards/lilygo_ttgo_t8_s2/board.c @@ -36,12 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_ttgo_t8_s2/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_t8_s2/mpconfigboard.mk index 781818f53e..e7d70c671a 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_s2/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_ttgo_t8_s2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "LILYGO" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c index 8f0d01fe79..6c0a54c99c 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c +++ b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c @@ -93,9 +93,6 @@ static void display_init(void) { displayio_display_obj_t *display = &displays[0].display; display->base.type = &displayio_display_type; - // workaround as board_init() is called before reset_port() in main.c - pwmout_reset(); - common_hal_displayio_display_construct( display, bus, @@ -117,8 +114,7 @@ static void display_init(void) { sizeof(display_init_sequence), &pin_GPIO33, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - false, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -127,8 +123,6 @@ static void display_init(void) { false, // SH1107_addressing 50000 // backlight pwm frequency ); - - common_hal_never_reset_pin(&pin_GPIO33); // backlight pin } void board_init(void) { @@ -142,13 +136,4 @@ void board_init(void) { display_init(); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk index 4d6a586ff8..865dbe2661 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "LILYGO" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/lolin_c3_mini/board.c b/ports/espressif/boards/lolin_c3_mini/board.c index 8bca964dc7..164430c88c 100644 --- a/ports/espressif/boards/lolin_c3_mini/board.c +++ b/ports/espressif/boards/lolin_c3_mini/board.c @@ -24,24 +24,6 @@ * THE SOFTWARE. */ -#include "shared-bindings/microcontroller/Pin.h" #include "supervisor/board.h" -#include "components/driver/include/driver/gpio.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -bool espressif_board_reset_pin_number(gpio_num_t pin_number) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lolin_c3_mini/mpconfigboard.h b/ports/espressif/boards/lolin_c3_mini/mpconfigboard.h index 03e4d5d436..2a90d91845 100644 --- a/ports/espressif/boards/lolin_c3_mini/mpconfigboard.h +++ b/ports/espressif/boards/lolin_c3_mini/mpconfigboard.h @@ -45,7 +45,4 @@ #define CIRCUITPY_BOARD_UART (1) #define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO21, .rx = &pin_GPIO20}} -// Explanation of how a user got into safe mode -#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") - #define CIRCUITPY_ESP_USB_SERIAL_JTAG (1) diff --git a/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk b/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk index 28e4190adf..d1cd0129fd 100644 --- a/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk +++ b/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk @@ -3,8 +3,6 @@ CIRCUITPY_CREATION_ID = 0x00C30001 IDF_TARGET = esp32c3 -INTERNAL_FLASH_FILESYSTEM = 1 - CIRCUITPY_ESP_FLASH_MODE=qio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB diff --git a/ports/espressif/boards/lolin_c3_mini/pins.c b/ports/espressif/boards/lolin_c3_mini/pins.c index ccc70f6043..6b16020205 100644 --- a/ports/espressif/boards/lolin_c3_mini/pins.c +++ b/ports/espressif/boards/lolin_c3_mini/pins.c @@ -46,6 +46,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, diff --git a/ports/espressif/boards/lolin_c3_mini/sdkconfig b/ports/espressif/boards/lolin_c3_mini/sdkconfig index 2cb6b06589..833f8368fa 100644 --- a/ports/espressif/boards/lolin_c3_mini/sdkconfig +++ b/ports/espressif/boards/lolin_c3_mini/sdkconfig @@ -3,5 +3,3 @@ # CONFIG_LWIP_LOCAL_HOSTNAME="lolin-c3-mini" # end of LWIP - - diff --git a/ports/espressif/boards/lolin_s2_mini/board.c b/ports/espressif/boards/lolin_s2_mini/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/lolin_s2_mini/board.c +++ b/ports/espressif/boards/lolin_s2_mini/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lolin_s2_mini/mpconfigboard.h b/ports/espressif/boards/lolin_s2_mini/mpconfigboard.h index c490cd8ceb..e943e70184 100644 --- a/ports/espressif/boards/lolin_s2_mini/mpconfigboard.h +++ b/ports/espressif/boards/lolin_s2_mini/mpconfigboard.h @@ -29,6 +29,8 @@ #define MICROPY_HW_BOARD_NAME "S2Mini" #define MICROPY_HW_MCU_NAME "ESP32S2-S2FN4R2" // from Wemos MP +#define MICROPY_HW_LED_STATUS (&pin_GPIO15) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO35) // no I2C labels on S2 Mini, def from Wemos MP #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) // no I2C labels on S2 Mini, def from Wemos MP diff --git a/ports/espressif/boards/lolin_s2_mini/mpconfigboard.mk b/ports/espressif/boards/lolin_s2_mini/mpconfigboard.mk index acedc2ad51..24f88d9abf 100644 --- a/ports/espressif/boards/lolin_s2_mini/mpconfigboard.mk +++ b/ports/espressif/boards/lolin_s2_mini/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Lolin" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/lolin_s2_pico/board.c b/ports/espressif/boards/lolin_s2_pico/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/lolin_s2_pico/board.c +++ b/ports/espressif/boards/lolin_s2_pico/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lolin_s2_pico/mpconfigboard.h b/ports/espressif/boards/lolin_s2_pico/mpconfigboard.h index 19c41f84e4..a33e6ea4d0 100644 --- a/ports/espressif/boards/lolin_s2_pico/mpconfigboard.h +++ b/ports/espressif/boards/lolin_s2_pico/mpconfigboard.h @@ -29,6 +29,8 @@ #define MICROPY_HW_BOARD_NAME "S2Pico" #define MICROPY_HW_MCU_NAME "ESP32S2-S2FN4R2" // from Wemos MP +#define MICROPY_HW_LED_STATUS (&pin_GPIO10) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) // JST SH Connector Pin 3 NOT STEMMA QT / Feather pinout #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) // JST SH Connector Pin 2 NOT STEMMA QT / Feather pinout diff --git a/ports/espressif/boards/lolin_s2_pico/mpconfigboard.mk b/ports/espressif/boards/lolin_s2_pico/mpconfigboard.mk index bd4aca0337..bf946a483f 100644 --- a/ports/espressif/boards/lolin_s2_pico/mpconfigboard.mk +++ b/ports/espressif/boards/lolin_s2_pico/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Lolin" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/lolin_s3/board.c b/ports/espressif/boards/lolin_s3/board.c new file mode 100644 index 0000000000..164430c88c --- /dev/null +++ b/ports/espressif/boards/lolin_s3/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lolin_s3/mpconfigboard.h b/ports/espressif/boards/lolin_s3/mpconfigboard.h new file mode 100644 index 0000000000..9dc1b8f6a9 --- /dev/null +++ b/ports/espressif/boards/lolin_s3/mpconfigboard.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "LOLIN S3 16MB Flash 8MB PSRAM" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO38) + +// #define MICROPY_HW_LED_STATUS (&pin_GPIO13) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO41) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO42) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO12) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO11) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO13) diff --git a/ports/espressif/boards/lolin_s3/mpconfigboard.mk b/ports/espressif/boards/lolin_s3/mpconfigboard.mk new file mode 100644 index 0000000000..c81e3e6fb9 --- /dev/null +++ b/ports/espressif/boards/lolin_s3/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x303a +USB_PID = 0x8117 +USB_PRODUCT = "LOLIN S3 16MB Flash 8MB PSRAM" +USB_MANUFACTURER = "WEMOS" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +OPTIMIZATION_FLAGS = -Os +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/lolin_s3/pins.c b/ports/espressif/boards/lolin_s3/pins.c new file mode 100644 index 0000000000..4bde24788a --- /dev/null +++ b/ports/espressif/boards/lolin_s3/pins.c @@ -0,0 +1,127 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + + + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + + + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_A14), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_A16), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_A17), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/lolin_s3/sdkconfig b/ports/espressif/boards/lolin_s3/sdkconfig new file mode 100644 index 0000000000..23d005edd9 --- /dev/null +++ b/ports/espressif/boards/lolin_s3/sdkconfig @@ -0,0 +1,48 @@ +# +# Component config +# +# +# ESP32S3-Specific +# +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +CONFIG_SPIRAM_MODE_QUAD=y +# CONFIG_SPIRAM_MODE_OCT is not set +CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=8388608 +# +# PSRAM Clock and CS IO for ESP32S3 +# +# CONFIG_DEFAULT_PSRAM_CLK_IO=30 +# CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM Clock and CS IO for ESP32S3 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_120M is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +CONFIG_SPIRAM_MODE_OCT=y +# end of SPI RAM config + +# end of ESP32S3-Specific + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="LOLIN-S3" +# end of LWIP + +# end of Component config diff --git a/ports/espressif/boards/luatos_core_esp32c3/board.c b/ports/espressif/boards/luatos_core_esp32c3/board.c new file mode 100644 index 0000000000..164430c88c --- /dev/null +++ b/ports/espressif/boards/luatos_core_esp32c3/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/luatos_core_esp32c3/mpconfigboard.h b/ports/espressif/boards/luatos_core_esp32c3/mpconfigboard.h new file mode 100644 index 0000000000..23bb5ee9b2 --- /dev/null +++ b/ports/espressif/boards/luatos_core_esp32c3/mpconfigboard.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Board setup + +#define MICROPY_HW_BOARD_NAME "Luatos Core-ESP32C3" +#define MICROPY_HW_MCU_NAME "ESP32-C3" + +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_GPIO12) + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO21, .rx = &pin_GPIO20}} + +#define CIRCUITPY_ESP_USB_SERIAL_JTAG (1) diff --git a/ports/espressif/boards/luatos_core_esp32c3/mpconfigboard.mk b/ports/espressif/boards/luatos_core_esp32c3/mpconfigboard.mk new file mode 100644 index 0000000000..e0df58f756 --- /dev/null +++ b/ports/espressif/boards/luatos_core_esp32c3/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0xDEADBEEF +CIRCUITPY_CREATION_ID = 0x00C30001 + +IDF_TARGET = esp32c3 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=80m +CIRCUITPY_ESP_FLASH_SIZE=4MB diff --git a/ports/espressif/boards/luatos_core_esp32c3/pins.c b/ports/espressif/boards/luatos_core_esp32c3/pins.c new file mode 100644 index 0000000000..f45205b5c3 --- /dev/null +++ b/ports/espressif/boards/luatos_core_esp32c3/pins.c @@ -0,0 +1,36 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Luatos Core ESP32-C3 + // Documentation (Chinese only): + // https://wiki.luatos.com/chips/esp32c3/index.html + // Pinout: + // https://wiki.luatos.com/_images/20221023.png + // C3 Data Sheet + // https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + // IO11 used internally on this board version despite being broken out to a pin + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/luatos_core_esp32c3/sdkconfig b/ports/espressif/boards/luatos_core_esp32c3/sdkconfig new file mode 100644 index 0000000000..ccc70917b5 --- /dev/null +++ b/ports/espressif/boards/luatos_core_esp32c3/sdkconfig @@ -0,0 +1,5 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="luatos-core-esp32c3" +# end of LWIP diff --git a/ports/espressif/boards/m5stack_atom_echo/board.c b/ports/espressif/boards/m5stack_atom_echo/board.c new file mode 100644 index 0000000000..c0d9676d86 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_echo/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h b/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h new file mode 100644 index 0000000000..426d5c3bf7 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Atom Echo" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO27) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO32, .sda = &pin_GPIO26}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed the central button at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk new file mode 100644 index 0000000000..63ed093f0a --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x10151015 +CIRCUITPY_CREATION_ID = 0x00320005 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_echo/pins.c b/ports/espressif/boards/m5stack_atom_echo/pins.c new file mode 100644 index 0000000000..68b6389215 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_echo/pins.c @@ -0,0 +1,43 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + + { MP_ROM_QSTR(MP_QSTR_SPK_I2S_SDO), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SPK_I2S_SCK), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_SPK_I2S_LRC), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_PDM_MIC_CLK), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_PDM_MIC_DATA), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_A25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_A32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_BTN), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_IR_LED), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_atom_echo/sdkconfig b/ports/espressif/boards/m5stack_atom_echo/sdkconfig new file mode 100644 index 0000000000..3879222bab --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_echo/sdkconfig @@ -0,0 +1,26 @@ +CONFIG_ESP32_SPIRAM_SUPPORT=n + +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskAtomEcho" +# end of LWIP + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/m5stack_atom_lite/board.c b/ports/espressif/boards/m5stack_atom_lite/board.c new file mode 100644 index 0000000000..c0d9676d86 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_lite/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h b/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h new file mode 100644 index 0000000000..9ec15fa0f2 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Atom Lite" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO27) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO21, .sda = &pin_GPIO25}, \ + {.scl = &pin_GPIO32, .sda = &pin_GPIO26}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO23, .miso = &pin_GPIO19}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed the central button at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk new file mode 100644 index 0000000000..e1ba503b8c --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x10151015 +CIRCUITPY_CREATION_ID = 0x00320003 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_lite/pins.c b/ports/espressif/boards/m5stack_atom_lite/pins.c new file mode 100644 index 0000000000..495fb3a5a0 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_lite/pins.c @@ -0,0 +1,49 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(porta_i2c, i2c, 1) + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_A33), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_A25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_A32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_BTN), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_porta_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_atom_lite/sdkconfig b/ports/espressif/boards/m5stack_atom_lite/sdkconfig new file mode 100644 index 0000000000..8a9fb07019 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_lite/sdkconfig @@ -0,0 +1,27 @@ +CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y +CONFIG_ESP32_SPIRAM_SUPPORT=n + +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskAtomLite" +# end of LWIP + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/m5stack_atom_matrix/board.c b/ports/espressif/boards/m5stack_atom_matrix/board.c new file mode 100644 index 0000000000..c0d9676d86 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_matrix/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h b/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h new file mode 100644 index 0000000000..77eba4ab92 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Atom Matrix" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO27) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO21, .sda = &pin_GPIO25}, \ + {.scl = &pin_GPIO32, .sda = &pin_GPIO26}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO23, .mosi = &pin_GPIO19, .miso = &pin_GPIO33}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed the central button at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk new file mode 100644 index 0000000000..ecf9319584 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x10151015 +CIRCUITPY_CREATION_ID = 0x00320004 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_matrix/pins.c b/ports/espressif/boards/m5stack_atom_matrix/pins.c new file mode 100644 index 0000000000..9b18b954f0 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_matrix/pins.c @@ -0,0 +1,51 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(porta_i2c, i2c, 1) + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_A33), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_A25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_A32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_BTN), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_IR_LED), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_porta_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_atom_matrix/sdkconfig b/ports/espressif/boards/m5stack_atom_matrix/sdkconfig new file mode 100644 index 0000000000..474a760b56 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_matrix/sdkconfig @@ -0,0 +1,26 @@ +CONFIG_ESP32_SPIRAM_SUPPORT=n + +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskAtomMatrix" +# end of LWIP + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/m5stack_atom_u/board.c b/ports/espressif/boards/m5stack_atom_u/board.c new file mode 100644 index 0000000000..c0d9676d86 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_u/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/m5stack_atom_u/mpconfigboard.h b/ports/espressif/boards/m5stack_atom_u/mpconfigboard.h new file mode 100644 index 0000000000..b5b2101134 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_u/mpconfigboard.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Atom U" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO27) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO32, .sda = &pin_GPIO26}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO23, .mosi = &pin_GPIO19, .miso = &pin_GPIO33}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed the central button at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk new file mode 100644 index 0000000000..f271671113 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x10151015 +CIRCUITPY_CREATION_ID = 0x00320006 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_u/pins.c b/ports/espressif/boards/m5stack_atom_u/pins.c new file mode 100644 index 0000000000..4ba62ae2b7 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_u/pins.c @@ -0,0 +1,42 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + + { MP_ROM_QSTR(MP_QSTR_A25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_A33), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_A32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_BTN), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_IR_LED), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_PDM_MIC_CLK), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_PDM_MIC_DATA), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_atom_u/sdkconfig b/ports/espressif/boards/m5stack_atom_u/sdkconfig new file mode 100644 index 0000000000..90c99459a8 --- /dev/null +++ b/ports/espressif/boards/m5stack_atom_u/sdkconfig @@ -0,0 +1,26 @@ +CONFIG_ESP32_SPIRAM_SUPPORT=n + +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskAtomU" +# end of LWIP + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/m5stack_core_basic/board.c b/ports/espressif/boards/m5stack_core_basic/board.c new file mode 100644 index 0000000000..2736bc758b --- /dev/null +++ b/ports/espressif/boards/m5stack_core_basic/board.c @@ -0,0 +1,118 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +displayio_fourwire_obj_t board_display_obj; + + +// display init sequence according to M5Gfx +uint8_t display_init_sequence[] = { + 0x01,0x80,0x80, // Software reset then delay 0x80 (128ms) + 0xC8,0x03,0xFF,0x93,0x42, // Turn on the external command + 0xC0,0x02,0x12, 0x12, // Power Control 1 + 0xC1,0x01,0x03, // Power Control 2 + 0xC5,0x01,0xF2, // VCOM Control 1 + 0xB0,0x01,0xE0, // RGB Interface SYNC Mode + 0xF6,0x03,0x01, 0x00, 0x00, // Interface control + 0XE0,0x0F,0x00,0x0C,0x11,0x04,0x11,0x08,0x37,0x89,0x4C,0x06,0x0C,0x0A,0x2E,0x34,0x0F, // Positive Gamma Correction + 0xE1,0x0F,0x00,0x0B,0x11,0x05,0x13,0x09,0x33,0x67,0x48,0x07,0x0E,0x0B,0x2E,0x33,0x0F, // Negative Gamma Correction + 0xB6,0x04,0x08,0x82,0x1D,0x04, // Display Function Control + 0x3A,0x01,0x55, // COLMOD: Pixel Format Set 16 bit + 0x21,0x00, // Display inversion ON + 0x36,0x01,0x08, // Memory Access Control: RGB order + 0x11,0x80,0x78, // Exit Sleep then delay 0x78 (120ms) + 0x29,0x80,0x78, // Display on then delay 0x78 (120ms) +}; + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO27, // DC + &pin_GPIO14, // CS + &pin_GPIO33, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + + common_hal_displayio_display_construct( + display, + bus, + 320, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO32, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 61, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); + +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Set speaker gpio to ground to prevent noise from the speaker + if (pin_number == 25) { + gpio_set_direction(pin_number, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(pin_number, false); + return true; + } + return false; +} diff --git a/ports/espressif/boards/m5stack_core_basic/mpconfigboard.h b/ports/espressif/boards/m5stack_core_basic/mpconfigboard.h new file mode 100755 index 0000000000..0135b66661 --- /dev/null +++ b/ports/espressif/boards/m5stack_core_basic/mpconfigboard.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Core Basic" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO23, .miso = &pin_GPIO19}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed button A at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk b/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk new file mode 100644 index 0000000000..dedcde81e6 --- /dev/null +++ b/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk @@ -0,0 +1,9 @@ +CIRCUITPY_CREATOR_ID = 0x10151015 +CIRCUITPY_CREATION_ID = 0x00320002 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_core_basic/pins.c b/ports/espressif/boards/m5stack_core_basic/pins.c new file mode 100644 index 0000000000..b985231bea --- /dev/null +++ b/ports/espressif/boards/m5stack_core_basic/pins.c @@ -0,0 +1,93 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_PORTC_RX), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_A35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_A36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_PORTB_IN), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_A25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_PORTB_OUT), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_PORTC_TX), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_A34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO34) }, + + // buttons + { MP_ROM_QSTR(MP_QSTR_BTN_A), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_BTN_B), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_BTN_C), MP_ROM_PTR(&pin_GPIO37) }, + + // sd card + { MP_ROM_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_GPIO4) }, + + // tft + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_core_basic/sdkconfig b/ports/espressif/boards/m5stack_core_basic/sdkconfig new file mode 100644 index 0000000000..a4cedd8e81 --- /dev/null +++ b/ports/espressif/boards/m5stack_core_basic/sdkconfig @@ -0,0 +1,28 @@ +CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y +CONFIG_ESP32_SPIRAM_SUPPORT=n +CONFIG_ESP32_REV_MIN_3=y + +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskCoreBasic" +# end of LWIP + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/m5stack_core_fire/board.c b/ports/espressif/boards/m5stack_core_fire/board.c new file mode 100755 index 0000000000..2736bc758b --- /dev/null +++ b/ports/espressif/boards/m5stack_core_fire/board.c @@ -0,0 +1,118 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +displayio_fourwire_obj_t board_display_obj; + + +// display init sequence according to M5Gfx +uint8_t display_init_sequence[] = { + 0x01,0x80,0x80, // Software reset then delay 0x80 (128ms) + 0xC8,0x03,0xFF,0x93,0x42, // Turn on the external command + 0xC0,0x02,0x12, 0x12, // Power Control 1 + 0xC1,0x01,0x03, // Power Control 2 + 0xC5,0x01,0xF2, // VCOM Control 1 + 0xB0,0x01,0xE0, // RGB Interface SYNC Mode + 0xF6,0x03,0x01, 0x00, 0x00, // Interface control + 0XE0,0x0F,0x00,0x0C,0x11,0x04,0x11,0x08,0x37,0x89,0x4C,0x06,0x0C,0x0A,0x2E,0x34,0x0F, // Positive Gamma Correction + 0xE1,0x0F,0x00,0x0B,0x11,0x05,0x13,0x09,0x33,0x67,0x48,0x07,0x0E,0x0B,0x2E,0x33,0x0F, // Negative Gamma Correction + 0xB6,0x04,0x08,0x82,0x1D,0x04, // Display Function Control + 0x3A,0x01,0x55, // COLMOD: Pixel Format Set 16 bit + 0x21,0x00, // Display inversion ON + 0x36,0x01,0x08, // Memory Access Control: RGB order + 0x11,0x80,0x78, // Exit Sleep then delay 0x78 (120ms) + 0x29,0x80,0x78, // Display on then delay 0x78 (120ms) +}; + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO27, // DC + &pin_GPIO14, // CS + &pin_GPIO33, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + + common_hal_displayio_display_construct( + display, + bus, + 320, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO32, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 61, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); + +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Set speaker gpio to ground to prevent noise from the speaker + if (pin_number == 25) { + gpio_set_direction(pin_number, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(pin_number, false); + return true; + } + return false; +} diff --git a/ports/espressif/boards/m5stack_core_fire/mpconfigboard.h b/ports/espressif/boards/m5stack_core_fire/mpconfigboard.h new file mode 100755 index 0000000000..2073473e1a --- /dev/null +++ b/ports/espressif/boards/m5stack_core_fire/mpconfigboard.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Core Fire" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO23, .miso = &pin_GPIO19}} + +// GPIO16 & GPIO17 are used for PSRAM +// #define CIRCUITPY_BOARD_UART (1) +// #define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed button A at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk b/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk new file mode 100644 index 0000000000..82e462012c --- /dev/null +++ b/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk @@ -0,0 +1,9 @@ +CIRCUITPY_CREATOR_ID = 0x10151015 +CIRCUITPY_CREATION_ID = 0x00320001 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_core_fire/pins.c b/ports/espressif/boards/m5stack_core_fire/pins.c new file mode 100644 index 0000000000..f26f96ac8e --- /dev/null +++ b/ports/espressif/boards/m5stack_core_fire/pins.c @@ -0,0 +1,94 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + // GPIO16 & GPIO17 are used for PSRAM + // { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_GPIO16) }, + // { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_LED_BAR), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_A35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_A36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_PORTB_IN), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_A25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_PORTB_OUT), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + // GPIO16 & GPIO17 are used for PSRAM + // { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_GPIO17) }, + // { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_A34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_MIC), MP_ROM_PTR(&pin_GPIO34) }, + + // buttons + { MP_ROM_QSTR(MP_QSTR_BTN_A), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_BTN_B), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_BTN_C), MP_ROM_PTR(&pin_GPIO37) }, + + // sd card + { MP_ROM_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_GPIO4) }, + + // tft + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_core_fire/sdkconfig b/ports/espressif/boards/m5stack_core_fire/sdkconfig new file mode 100644 index 0000000000..d77fe64525 --- /dev/null +++ b/ports/espressif/boards/m5stack_core_fire/sdkconfig @@ -0,0 +1,58 @@ +CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y +CONFIG_ESP32_SPIRAM_SUPPORT=y +CONFIG_ESP32_REV_MIN_3=y + +# +# SPI RAM config +# +CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +#CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=8388608 +# end of SPI RAM config + +# +# PSRAM clock and cs IO for ESP32 +# +CONFIG_D0WD_PSRAM_CLK_IO=17 +CONFIG_D0WD_PSRAM_CS_IO=16 +# end of PSRAM clock and cs IO for ESP32 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskCoreFire" +# end of LWIP + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/espressif/boards/m5stack_stamp_c3/board.c b/ports/espressif/boards/m5stack_stamp_c3/board.c new file mode 100644 index 0000000000..164430c88c --- /dev/null +++ b/ports/espressif/boards/m5stack_stamp_c3/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/m5stack_stamp_c3/mpconfigboard.h b/ports/espressif/boards/m5stack_stamp_c3/mpconfigboard.h new file mode 100644 index 0000000000..3e8be96d7d --- /dev/null +++ b/ports/espressif/boards/m5stack_stamp_c3/mpconfigboard.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Board setup + +#define MICROPY_HW_BOARD_NAME "M5STACK STAMP-C3" +#define MICROPY_HW_MCU_NAME "ESP32-C3FN4" + +// Status LED +#define MICROPY_HW_NEOPIXEL (&pin_GPIO2) + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO21, .rx = &pin_GPIO20}} + +// #define CIRCUITPY_ESP_USB_SERIAL_JTAG (1) + +// Serial over UART +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO20) +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO21) diff --git a/ports/espressif/boards/m5stack_stamp_c3/mpconfigboard.mk b/ports/espressif/boards/m5stack_stamp_c3/mpconfigboard.mk new file mode 100644 index 0000000000..25a6f87428 --- /dev/null +++ b/ports/espressif/boards/m5stack_stamp_c3/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x10151015 +CIRCUITPY_CREATION_ID = 0x00C30001 + +IDF_TARGET = esp32c3 + +CIRCUITPY_ESP_FLASH_MODE=qio +CIRCUITPY_ESP_FLASH_FREQ=80m +CIRCUITPY_ESP_FLASH_SIZE=4MB diff --git a/ports/espressif/boards/m5stack_stamp_c3/pins.c b/ports/espressif/boards/m5stack_stamp_c3/pins.c new file mode 100644 index 0000000000..96bc0c60ed --- /dev/null +++ b/ports/espressif/boards/m5stack_stamp_c3/pins.c @@ -0,0 +1,63 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // port A + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + + // neopixel + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + + // button + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + + // GPIO + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + + // USB JTAG pins + { MP_ROM_QSTR(MP_QSTR_G18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_G19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_G20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_G21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_stamp_c3/sdkconfig b/ports/espressif/boards/m5stack_stamp_c3/sdkconfig new file mode 100644 index 0000000000..34260aa7f2 --- /dev/null +++ b/ports/espressif/boards/m5stack_stamp_c3/sdkconfig @@ -0,0 +1,5 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="m5stack-stamp-c3" +# end of LWIP diff --git a/ports/espressif/boards/m5stack_stick_c/axp192.h b/ports/espressif/boards/m5stack_stick_c/axp192.h new file mode 100644 index 0000000000..78c2d253e4 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c/axp192.h @@ -0,0 +1,256 @@ +/* + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Stephen Oliver + * Copyright (c) 2023 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef MICROPY_AXP192_H +#define MICROPY_AXP192_H + +#define AXP192_I2C_ADDRESS 0x34 + +#define AXP192_EXTEN_DCDC2_CTRL 0x10 +#define AXP192_EXTEN_DCDC2_CTRL_EXTEN 0b00000100 +#define AXP192_EXTEN_DCDC2_CTRL_DCDC2 0b00000001 + +#define AXP192_DCDC13_LDO23_CTRL 0x12 +#define AXP192_DCDC13_LDO23_CTRL_EXTEN 0b01000000 +#define AXP192_DCDC13_LDO23_CTRL_LDO3 0b00001000 +#define AXP192_DCDC13_LDO23_CTRL_LDO2 0b00000100 +#define AXP192_DCDC13_LDO23_CTRL_DCDC3 0b00000010 +#define AXP192_DCDC13_LDO23_CTRL_DCDC1 0b00000001 + +#define AXP192_DCDC2_OUT_VOLTAGE 0x25 + +#define AXP192_DCDC1_OUT_VOLTAGE 0x26 +#define AXP192_DCDC1_OUT_VOLTAGE_3_350V 0b01101010 + +#define AXP192_DCDC3_OUT_VOLTAGE 0x27 + + +#define AXP192_LDO23_OUT_VOLTAGE 0x28 +#define AXP192_LDO23_OUT_VOLTAGE_LDO2_3_0V 0b11000000 +#define AXP192_LDO23_OUT_VOLTAGE_LDO2_2_8V 0b10100000 +#define AXP192_LDO23_OUT_VOLTAGE_LDO2_MASK 0b11110000 +#define AXP192_LDO23_OUT_VOLTAGE_LDO3_3_0V 0b00001100 +#define AXP192_LDO23_OUT_VOLTAGE_LDO3_2_8V 0b00001010 +#define AXP192_LDO23_OUT_VOLTAGE_LDO3_MASK 0b00001111 + +#define AXP192_VBUS_IPSOUT 0x30 +#define AXP192_VBUS_IPSOUT_IGNORE_VBUSEN 0b10000000 +#define AXP192_VBUS_IPSOUT_VHOLD_LIMIT 0b01000000 +#define AXP192_VBUS_IPSOUT_VHOLD_VOLTAGE_4_4V 0b00100000 +#define AXP192_VBUS_IPSOUT_VHOLD_VOLTAGE_MASK 0b00111000 +#define AXP192_VBUS_IPSOUT_VBUS_LIMIT_CURRENT 0b00000010 +#define AXP192_VBUS_IPSOUT_VBUS_LIMIT_CURRENT_500mA 0b00000001 +#define AXP192_VBUS_IPSOUT_VBUS_LIMIT_CURRENT_100mA 0b00000000 + +#define AXP192_POWER_OFF_VOLTAGE 0x31 +#define AXP192_POWER_OFF_VOLTAGE_2_6V 0b0000 +#define AXP192_POWER_OFF_VOLTAGE_2_7V 0b0001 +#define AXP192_POWER_OFF_VOLTAGE_2_8V 0b0010 +#define AXP192_POWER_OFF_VOLTAGE_2_9V 0b0011 +#define AXP192_POWER_OFF_VOLTAGE_3_0V 0b0100 +#define AXP192_POWER_OFF_VOLTAGE_3_1V 0b0101 +#define AXP192_POWER_OFF_VOLTAGE_3_2V 0b0110 +#define AXP192_POWER_OFF_VOLTAGE_3_3V 0b0111 +#define AXP192_POWER_OFF_VOLTAGE_MASK 0b0111 + +#define AXP192_POWER_OFF_BATT_CHGLED_CTRL 0x32 +#define AXP192_POWER_OFF_BATT_CHGLED_CTRL_OFF 0b10000000 + +#define AXP192_CHARGING_CTRL1 0x33 +#define AXP192_CHARGING_CTRL1_ENABLE 0b10000000 +#define AXP192_CHARGING_CTRL1_VOLTAGE_4_36V 0b01100000 +#define AXP192_CHARGING_CTRL1_VOLTAGE_4_20V 0b01000000 +#define AXP192_CHARGING_CTRL1_VOLTAGE_4_15V 0b00100000 +#define AXP192_CHARGING_CTRL1_VOLTAGE_4_10V 0b00000000 +#define AXP192_CHARGING_CTRL1_VOLTAGE_MASK 0b01100000 +#define AXP192_CHARGING_CTRL1_CHARGING_THRESH_15PERC 0b00010000 +#define AXP192_CHARGING_CTRL1_CHARGING_THRESH_10PERC 0b00000000 +#define AXP192_CHARGING_CTRL1_CHARGING_THRESH_MASK 0b00010000 +#define AXP192_CHARGING_CTRL1_CURRENT_100mA 0b00000000 +#define AXP192_CHARGING_CTRL1_CURRENT_190mA 0b00000001 +#define AXP192_CHARGING_CTRL1_CURRENT_280mA 0b00000010 +#define AXP192_CHARGING_CTRL1_CURRENT_360mA 0b00000011 +#define AXP192_CHARGING_CTRL1_CURRENT_450mA 0b00000100 +#define AXP192_CHARGING_CTRL1_CURRENT_550mA 0b00000101 +#define AXP192_CHARGING_CTRL1_CURRENT_630mA 0b00000110 +#define AXP192_CHARGING_CTRL1_CURRENT_700mA 0b00000111 +#define AXP192_CHARGING_CTRL1_CURRENT_780mA 0b00001000 +#define AXP192_CHARGING_CTRL1_CURRENT_880mA 0b00001001 +#define AXP192_CHARGING_CTRL1_CURRENT_960mA 0b00001010 +#define AXP192_CHARGING_CTRL1_CURRENT_1000mA 0b00001011 + +#define AXP192_CHARGING_CTRL1_CURRENT_MASK 0b00001111 + +#define AXP192_CHARGING_CTRL2 0x34 + +#define AXP192_BACKUP_BATT 0x35 +#define AXP192_BACKUP_BATT_CHARGING_ENABLE 0b10000000 +#define AXP192_BACKUP_BATT_CHARGING_VOLTAGE_2_5V 0b01100000 +#define AXP192_BACKUP_BATT_CHARGING_VOLTAGE_3_0V 0b00100000 +#define AXP192_BACKUP_BATT_CHARGING_VOLTAGE_3_1V 0b00000000 +#define AXP192_BACKUP_BATT_CHARGING_VOLTAGE_MASK 0b01100000 +#define AXP192_BACKUP_BATT_CHARGING_CURRENT_400uA 0b00000011 +#define AXP192_BACKUP_BATT_CHARGING_CURRENT_200uA 0b00000010 +#define AXP192_BACKUP_BATT_CHARGING_CURRENT_100uA 0b00000001 +#define AXP192_BACKUP_BATT_CHARGING_CURRENT_50uA 0b00000000 +#define AXP192_BACKUP_BATT_CHARGING_CURRENT_MASK 0b00000011 + +#define AXP192_PEK 0x36 +#define AXP192_PEK_SHORT_PRESS_1S 0b11000000 +#define AXP192_PEK_SHORT_PRESS_512mS 0b10000000 +#define AXP192_PEK_SHORT_PRESS_256mS 0b01000000 +#define AXP192_PEK_SHORT_PRESS_128mS 0b00000000 +#define AXP192_PEK_SHORT_PRESS_MASK 0b11000000 +#define AXP192_PEK_LONG_PRESS_2_5S 0b00110000 +#define AXP192_PEK_LONG_PRESS_2_0S 0b00100000 +#define AXP192_PEK_LONG_PRESS_1_5S 0b00010000 +#define AXP192_PEK_LONG_PRESS_1_0S 0b00000000 +#define AXP192_PEK_LONG_PRESS_MASK 0b00110000 +#define AXP192_PEK_LONG_PRESS_POWER_OFF 0b00001000 +#define AXP192_PEK_PWROK_DELAY_64mS 0b00000100 +#define AXP192_PEK_PWROK_DELAY_32mS 0b00000000 +#define AXP192_PEK_PWROK_DELAY_MASK 0b00000100 +#define AXP192_PEK_POWER_OFF_TIME_12S 0b00000011 +#define AXP192_PEK_POWER_OFF_TIME_8S 0b00000010 +#define AXP192_PEK_POWER_OFF_TIME_6S 0b00000001 +#define AXP192_PEK_POWER_OFF_TIME_4S 0b00000000 +#define AXP192_PEK_POWER_OFF_TIME_MASK 0b00000011 + +#define AXP192_BATT_TEMP_LOW_THRESH 0x38 +#define AXP192_BATT_TEMP_HIGH_THRESH 0x39 +#define AXP192_BATT_TEMP_HIGH_THRESH_DEFAULT 0b11111100 + +#define AXP192_IRQ_1_ENABLE 0x40 +#define AXP192_IRQ_2_ENABLE 0x41 +#define AXP192_IRQ_3_ENABLE 0x42 +#define AXP192_IRQ_4_ENABLE 0x43 +#define AXP192_IRQ_5_ENABLE 0x4a + +#define AXP192_IRQ_1_STATUS 0x44 +#define AXP192_IRQ_2_STATUS 0x45 +#define AXP192_IRQ_3_STATUS 0x46 +#define AXP192_IRQ_4_STATUS 0x47 +#define AXP192_IRQ_5_STATUS 0x4d + +#define AXP192_IRQ_3_PEK_SHORT_PRESS 0b00000010 +#define AXP192_IRQ_3_PEK_LONG_PRESS 0b00000001 + +#define AXP192_ADC_ACIN_VOLTAGE_H 0x56 +#define AXP192_ADC_ACIN_VOLTAGE_L 0x57 +#define AXP192_ADC_ACIN_CURRENT_H 0x58 +#define AXP192_ADC_ACIN_CURRENT_L 0x59 +#define AXP192_ADC_VBUS_VOLTAGE_H 0x5a +#define AXP192_ADC_VBUS_VOLTAGE_L 0x5b +#define AXP192_ADC_VBUS_CURRENT_H 0x5c +#define AXP192_ADC_VBUS_CURRENT_L 0x5d +#define AXP192_ADC_INTERNAL_TEMP_H 0x5e +#define AXP192_ADC_INTERNAL_TEMP_L 0x5f + +#define AXP192_ADC_BATT_VOLTAGE_H 0x78 +#define AXP192_ADC_BATT_VOLTAGE_L 0x79 + +#define AXP192_ADC_BATT_POWER_H 0x70 +#define AXP192_ADC_BATT_POWER_M 0x71 +#define AXP192_ADC_BATT_POWER_L 0x72 + +#define AXP192_ADC_BATT_CHARGE_CURRENT_H 0x7a +#define AXP192_ADC_BATT_CHARGE_CURRENT_L 0x7b +#define AXP192_ADC_BATT_DISCHARGE_CURRENT_H 0x7c +#define AXP192_ADC_BATT_DISCHARGE_CURRENT_L 0x7d +#define AXP192_ADC_APS_VOLTAGE_H 0x7e +#define AXP192_ADC_APS_VOLTAGE_L 0x7f + +#define AXP192_ADC_ENABLE_1 0x82 +#define AXP192_ADC_ENABLE_1_BATT_VOL 0b10000000 +#define AXP192_ADC_ENABLE_1_BATT_CUR 0b01000000 +#define AXP192_ADC_ENABLE_1_ACIN_VOL 0b00100000 +#define AXP192_ADC_ENABLE_1_ACIN_CUR 0b00010000 +#define AXP192_ADC_ENABLE_1_VBUS_VOL 0b00001000 +#define AXP192_ADC_ENABLE_1_VBUS_CUR 0b00000100 +#define AXP192_ADC_ENABLE_1_APS_VOL 0b00000010 +#define AXP192_ADC_ENABLE_1_TS_PIN 0b00000001 + +#define AXP192_ADC_ENABLE_2 0x83 +#define AXP192_ADC_ENABLE_2_TEMP_MON 0b10000000 +#define AXP192_ADC_ENABLE_2_GPIO0 0b00001000 +#define AXP192_ADC_ENABLE_2_GPIO1 0b00000100 +#define AXP192_ADC_ENABLE_2_GPIO2 0b00000010 +#define AXP192_ADC_ENABLE_2_GPIO3 0b00000001 + +#define AXP192_ADC_TS 0x84 +#define AXP192_ADC_TS_SAMPLE_200HZ 0b11000000 +#define AXP192_ADC_TS_SAMPLE_100HZ 0b10000000 +#define AXP192_ADC_TS_SAMPLE_50HZ 0b01000000 +#define AXP192_ADC_TS_SAMPLE_25HZ 0b00000000 +#define AXP192_ADC_TS_SAMPLE_MASK 0b11000000 +#define AXP192_ADC_TS_OUT_CUR_80uA 0b00110000 +#define AXP192_ADC_TS_OUT_CUR_60uA 0b00100000 +#define AXP192_ADC_TS_OUT_CUR_40uA 0b00010000 +#define AXP192_ADC_TS_OUT_CUR_20uA 0b00000000 +#define AXP192_ADC_TS_OUT_CUR_MASK 0b00110000 +#define AXP192_ADC_TS_PIN_TEMP_MON 0b00000000 +#define AXP192_ADC_TS_PIN_EXTERN_ADC 0b00000100 +#define AXP192_ADC_TS_PIN_OUT_ALWAYS 0b00000011 +#define AXP192_ADC_TS_PIN_OUT_SAVE_ENG 0b00000010 +#define AXP192_ADC_TS_PIN_OUT_CHG 0b00000001 +#define AXP192_ADC_TS_PIN_OUT_DIS 0b00000000 +#define AXP192_ADC_TS_PIN_OUT_MASK 0b00000011 + +#define AXP192_GPIO0_FUNCTION 0x90 +#define AXP192_GPIO0_FUNCTION_FLOATING 0b00000111 +#define AXP192_GPIO0_FUNCTION_LOW_OUTPUT 0b00000101 +#define AXP192_GPIO0_FUNCTION_ADC_INPUT 0b00000100 +#define AXP192_GPIO0_FUNCTION_LDO_OUTPUT 0b00000010 +#define AXP192_GPIO0_FUNCTION_GENERAL_INPUT 0b00000001 +#define AXP192_GPIO0_FUNCTION_OPEN_DRAIN_OUTPUT 0b00000000 + +#define AXP192_GPIO0_LDO_VOLTAGE 0x91 +#define AXP192_GPIO0_LDO_VOLTAGE_3_3V 0b11110000 +#define AXP192_GPIO0_LDO_VOLTAGE_2_8V 0b10100000 +#define AXP192_GPIO0_LDO_VOLTAGE_1_8V 0b00000000 + + +#define AXP192_GPIO1_FUNCTION 0x92 +#define AXP192_GPIO1_FUNCTION_FLOATING 0b00000111 +#define AXP192_GPIO1_FUNCTION_LOW_OUTPUT 0b00000101 +#define AXP192_GPIO1_FUNCTION_ADC_INPUT 0b00000100 +#define AXP192_GPIO1_FUNCTION_PWM1_OUTPUT 0b00000010 +#define AXP192_GPIO1_FUNCTION_GENERAL_INPUT 0b00000001 +#define AXP192_GPIO1_FUNCTION_OPEN_DRAIN_OUTPUT 0b00000000 + + +#define AXP192_GPIO2_FUNCTION 0x93 +#define AXP192_GPIO2_FUNCTION_FLOATING 0b00000111 +#define AXP192_GPIO2_FUNCTION_LOW_OUTPUT 0b00000101 +#define AXP192_GPIO2_FUNCTION_ADC_INPUT 0b00000100 +#define AXP192_GPIO1_FUNCTION_PWM2_OUTPUT 0b00000010 +#define AXP192_GPIO2_FUNCTION_GENERAL_INPUT 0b00000001 +#define AXP192_GPIO2_FUNCTION_OPEN_DRAIN_OUTPUT 0b00000000 + +#define AXP192_PWM1_DUTY_RATIO 0x9A + +#endif diff --git a/ports/espressif/boards/m5stack_stick_c/board.c b/ports/espressif/boards/m5stack_stick_c/board.c new file mode 100644 index 0000000000..bbc0447056 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c/board.c @@ -0,0 +1,285 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +#include "axp192.h" + +// display init sequence according to adafruit_st7735r.py library +uint8_t display_init_sequence[] = { + 0x01,0x80,0x96, // SWRESET and Delay 150ms + 0x11,0x80,0xff, // SLPOUT and Delay + 0xb1,0x03,0x01,0x2C,0x2D, // _FRMCTR1 + 0xb2,0x03,0x01,0x2C,0x2D, // _FRMCTR2 + 0xb3,0x06,0x01,0x2C,0x2D,0x01,0x2C,0x2D, // _FRMCTR3 + 0xb4,0x01,0x07, // _INVCTR line inversion + 0xc0,0x03,0xa2,0x02,0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1,0x01,0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2,0x02,0x0a,0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3,0x02,0x8a,0x2a, + 0xc4,0x02,0x8a,0xee, + 0xc5,0x01,0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x36,0x01,0xc8, // MADCTL Rotate display + 0x21,0x00, // _INVON + 0x3a,0x01,0x05, // COLMOD - 16bit color + 0xe0,0x10,0x02,0x1c,0x07,0x12,0x37,0x32,0x29,0x2d,0x29,0x25,0x2B,0x39,0x00,0x01,0x03,0x10, // _GMCTRP1 Gamma + 0xe1,0x10,0x03,0x1d,0x07,0x06,0x2E,0x2C,0x29,0x2D,0x2E,0x2E,0x37,0x3F,0x00,0x00,0x02,0x10, // _GMCTRN1 + 0x13,0x80,0x0a, // _NORON + 0x29,0x80,0x64 // _DISPON +}; + +static bool pmic_init(void) { + int rc; + // uint8_t read_buf[1]; + uint8_t write_buf[2]; + + busio_i2c_obj_t *internal_i2c = common_hal_board_create_i2c(0); + + // Reg: 30h + // The VBUS-IPSOUT path can be selected to be opened regardless of the status of N_VBUSEN + // VBUS VHOLD pressure limit control disabled + // VBUS current limit control disabled + write_buf[0] = AXP192_VBUS_IPSOUT; + write_buf[1] = AXP192_VBUS_IPSOUT_IGNORE_VBUSEN; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 31h + // VOFF Shutdown voltage setting ( 3.0V ) + write_buf[0] = AXP192_POWER_OFF_VOLTAGE; + write_buf[1] = AXP192_POWER_OFF_VOLTAGE_3_0V; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 33h + // Charge function enable control bit, including internal and external channels + // Charging target voltage: 4.2V + // Charging end current: End charging when charging current is less than 10% setting + // Internal path charging current: 100mA + write_buf[0] = AXP192_CHARGING_CTRL1; + write_buf[1] = AXP192_CHARGING_CTRL1_ENABLE | + AXP192_CHARGING_CTRL1_VOLTAGE_4_20V | + AXP192_CHARGING_CTRL1_CURRENT_100mA; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 35h + // Enable RTC battery charge: 3.0V, 200uA + write_buf[0] = AXP192_BACKUP_BATT; + write_buf[1] = AXP192_BACKUP_BATT_CHARGING_ENABLE | + AXP192_BACKUP_BATT_CHARGING_VOLTAGE_3_0V | + AXP192_BACKUP_BATT_CHARGING_CURRENT_200uA; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 36h + // Power on: Short press 128ms + // Power off: Long press 1s + // Power OK delay 64ms + // Power off delay 4s + write_buf[0] = AXP192_PEK; + write_buf[1] = AXP192_PEK_SHORT_PRESS_128mS | + AXP192_PEK_LONG_PRESS_1_0S | + AXP192_PEK_LONG_PRESS_POWER_OFF | + AXP192_PEK_PWROK_DELAY_64mS | + AXP192_PEK_POWER_OFF_TIME_4S; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 82h + // ADC all on + write_buf[0] = AXP192_ADC_ENABLE_1; + write_buf[1] = AXP192_ADC_ENABLE_1_BATT_VOL | + AXP192_ADC_ENABLE_1_BATT_CUR | + AXP192_ADC_ENABLE_1_ACIN_VOL | + AXP192_ADC_ENABLE_1_ACIN_CUR | + AXP192_ADC_ENABLE_1_VBUS_VOL | + AXP192_ADC_ENABLE_1_VBUS_CUR | + AXP192_ADC_ENABLE_1_APS_VOL | + AXP192_ADC_ENABLE_1_TS_PIN; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 83h + // ADC temperature on + write_buf[0] = AXP192_ADC_ENABLE_2; + write_buf[1] = AXP192_ADC_ENABLE_2_TEMP_MON; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 84h + // ADC 25Hz + write_buf[0] = AXP192_ADC_TS; + write_buf[1] = AXP192_ADC_TS_SAMPLE_25HZ | + AXP192_ADC_TS_OUT_CUR_80uA | + AXP192_ADC_TS_PIN_OUT_SAVE_ENG; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 90h + // GPIO0(LDOio0) floating + write_buf[0] = AXP192_GPIO0_FUNCTION; + write_buf[1] = AXP192_GPIO0_FUNCTION_FLOATING; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 91h + // GPIO0(LDOio0) 2.8V + write_buf[0] = AXP192_GPIO0_LDO_VOLTAGE; + write_buf[1] = AXP192_GPIO0_LDO_VOLTAGE_2_8V; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 28h + // LDO2 (TFT backlight): 2.8V + // LDO3 (TFT logic): 3.0V + write_buf[0] = AXP192_LDO23_OUT_VOLTAGE; + write_buf[1] = AXP192_LDO23_OUT_VOLTAGE_LDO2_2_8V | + AXP192_LDO23_OUT_VOLTAGE_LDO3_3_0V; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 12h + // Enable EXTEN, DCDC1, LDO2 and LDO3 + write_buf[0] = AXP192_DCDC13_LDO23_CTRL; + write_buf[1] = AXP192_DCDC13_LDO23_CTRL_EXTEN | + AXP192_DCDC13_LDO23_CTRL_LDO3 | + AXP192_DCDC13_LDO23_CTRL_LDO2 | + AXP192_DCDC13_LDO23_CTRL_DCDC1; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 28h + // DCDC1 (ESP32 VDD): 3.350V + write_buf[0] = AXP192_DCDC1_OUT_VOLTAGE; + write_buf[1] = AXP192_DCDC1_OUT_VOLTAGE_3_350V; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + return true; +} + +static bool display_init(void) { + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO13, &pin_GPIO15, NULL, false); + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO23, // DC + &pin_GPIO5, // CS + &pin_GPIO18, // RST + 10000000, // baudrate + 0, // polarity + 0 // phase + ); + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + + common_hal_displayio_display_construct( + display, + bus, + 80, // width (after rotation) + 160, // height (after rotation) + 26, // column start + 1, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 80, // native_frames_per_second + false, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); + + return true; +} + +void board_init(void) { + if (!pmic_init()) { + mp_printf(&mp_plat_print, "could not initialize axp192 pmic\n"); + return; + } + + if (!display_init()) { + mp_printf(&mp_plat_print, "could not initialize ili9342c LCD"); + return; + } +} diff --git a/ports/espressif/boards/m5stack_stick_c/mpconfigboard.h b/ports/espressif/boards/m5stack_stick_c/mpconfigboard.h new file mode 100644 index 0000000000..c80dbc9ee2 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c/mpconfigboard.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 CDarius + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Stick C" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO10) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}, \ + {.scl = &pin_GPIO33, .sda = &pin_GPIO32}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO37) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed button A at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/m5stack_stick_c/mpconfigboard.mk b/ports/espressif/boards/m5stack_stick_c/mpconfigboard.mk new file mode 100644 index 0000000000..5910605915 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c/mpconfigboard.mk @@ -0,0 +1,9 @@ +CIRCUITPY_CREATOR_ID = 0x10151015 +CIRCUITPY_CREATION_ID = 0x00320007 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_stick_c/pins.c b/ports/espressif/boards/m5stack_stick_c/pins.c new file mode 100644 index 0000000000..65f0960382 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c/pins.c @@ -0,0 +1,56 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(porta_i2c, i2c, 1) + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_A36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IR_LED), MP_ROM_PTR(&pin_GPIO9) }, + + // buttons + { MP_ROM_QSTR(MP_QSTR_BTN_A), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_BTN_B), MP_ROM_PTR(&pin_GPIO39) }, + + // internal i2c bus + { MP_ROM_QSTR(MP_QSTR_SYS_SDA), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SYS_SCL), MP_ROM_PTR(&pin_GPIO22) }, + + // internal devices interrupt + { MP_ROM_QSTR(MP_QSTR_SYS_INT), MP_ROM_PTR(&pin_GPIO35) }, + + // pdm microphone + { MP_ROM_QSTR(MP_QSTR_PDM_MIC_CLK), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_PDM_MIC_DATA), MP_ROM_PTR(&pin_GPIO34) }, + + // lcd spi bus + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_SYS_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_porta_i2c_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_stick_c/sdkconfig b/ports/espressif/boards/m5stack_stick_c/sdkconfig new file mode 100644 index 0000000000..7ec6f90c15 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c/sdkconfig @@ -0,0 +1,26 @@ +CONFIG_ESP32_SPIRAM_SUPPORT=n + +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskStickC" +# end of LWIP + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings diff --git a/ports/atmel-samd/fatfs_port.c b/ports/espressif/boards/maker_badge/board.c similarity index 60% rename from ports/atmel-samd/fatfs_port.c rename to ports/espressif/boards/maker_badge/board.c index 58a0ef0d72..19dba31c57 100644 --- a/ports/atmel-samd/fatfs_port.c +++ b/ports/espressif/boards/maker_badge/board.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,25 +24,38 @@ * THE SOFTWARE. */ -#include "py/mphal.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ -#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ -#include "shared/timeutils/timeutils.h" +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/board.h" -#if CIRCUITPY_RTC -#include "shared-bindings/rtc/RTC.h" -#endif +#include "components/log/include/esp_log.h" -DWORD get_fattime(void) { - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif +#define DELAY 0x80 +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ } + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} + +void board_deinit(void) { +} diff --git a/ports/espressif/boards/maker_badge/mpconfigboard.h b/ports/espressif/boards/maker_badge/mpconfigboard.h new file mode 100644 index 0000000000..18f98a693b --- /dev/null +++ b/ports/espressif/boards/maker_badge/mpconfigboard.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Maker badge by Czech maker" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) +#define MICROPY_HW_NEOPIXEL_COUNT (4) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define AUTORESET_DELAY_MS 500 + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_GPIO18 1 +#define IGNORE_PIN_GPIO19 1 + +#define DOUBLE_TAP_PIN (&pin_GPIO38) diff --git a/ports/espressif/boards/maker_badge/mpconfigboard.mk b/ports/espressif/boards/maker_badge/mpconfigboard.mk new file mode 100644 index 0000000000..687f91ad60 --- /dev/null +++ b/ports/espressif/boards/maker_badge/mpconfigboard.mk @@ -0,0 +1,20 @@ +USB_VID = 0x239A +USB_PID = 0x2030 +USB_PRODUCT = "Maker badge" +USB_MANUFACTURER = "Czech maker" + +CIRCUITPY_ESPCAMERA = 0 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=4MB + +IDF_TARGET = esp32s2 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Text +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_UC8151D +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SSD1680 diff --git a/ports/espressif/boards/maker_badge/pins.c b/ports/espressif/boards/maker_badge/pins.c new file mode 100644 index 0000000000..f97eed60d5 --- /dev/null +++ b/ports/espressif/boards/maker_badge/pins.c @@ -0,0 +1,86 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_CAP5), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_CAP4), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_CAP3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_CAP2), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_CAP1), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER_INVERTED), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/maker_badge/sdkconfig b/ports/espressif/boards/maker_badge/sdkconfig new file mode 100644 index 0000000000..68689ed79e --- /dev/null +++ b/ports/espressif/boards/maker_badge/sdkconfig @@ -0,0 +1,6 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=n + +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="Maker_badge" +# end of LWIP diff --git a/ports/espressif/boards/microdev_micro_c3/board.c b/ports/espressif/boards/microdev_micro_c3/board.c index e3b71f4832..b155ed7a7b 100644 --- a/ports/espressif/boards/microdev_micro_c3/board.c +++ b/ports/espressif/boards/microdev_micro_c3/board.c @@ -35,14 +35,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -#if CIRCUITPY_ALARM -void board_deinit(void) { -} -#endif +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/microdev_micro_c3/mpconfigboard.h b/ports/espressif/boards/microdev_micro_c3/mpconfigboard.h index f5bc8faf0b..2153513306 100644 --- a/ports/espressif/boards/microdev_micro_c3/mpconfigboard.h +++ b/ports/espressif/boards/microdev_micro_c3/mpconfigboard.h @@ -25,24 +25,28 @@ */ // Board setup -#define MICROPY_HW_BOARD_NAME "MicroDev microC3" -#define MICROPY_HW_MCU_NAME "ESP32-C3FN4" +#define MICROPY_HW_BOARD_NAME "MicroDev microC3" +#define MICROPY_HW_MCU_NAME "ESP32-C3FN4" -// Status LED -#define MICROPY_HW_NEOPIXEL (&pin_GPIO7) -#define MICROPY_HW_NEOPIXEL_COUNT (2) +// Status LEDs +#define MICROPY_HW_NEOPIXEL (&pin_GPIO7) +#define MICROPY_HW_NEOPIXEL_COUNT (2) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO8) // Default bus pins -#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) -#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) -#define DEFAULT_SPI_BUS_SCK (&pin_GPIO1) -#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO2) -#define DEFAULT_SPI_BUS_MISO (&pin_GPIO3) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO1) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO2) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO3) -#define DEFAULT_UART_BUS_RX (&pin_GPIO20) -#define DEFAULT_UART_BUS_TX (&pin_GPIO21) +#define DEFAULT_UART_BUS_RX (&pin_GPIO20) +#define DEFAULT_UART_BUS_TX (&pin_GPIO21) -// Serial over UART -#define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX -#define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX +// For REPL over built-in USB Serial +#define CIRCUITPY_ESP_USB_SERIAL_JTAG (1) + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) diff --git a/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk b/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk index ce431624ae..94c64a8273 100644 --- a/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk +++ b/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk @@ -3,8 +3,6 @@ CIRCUITPY_CREATION_ID = 0x006d4333 IDF_TARGET = esp32c3 -INTERNAL_FLASH_FILESYSTEM = 1 - -CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/microdev_micro_c3/pins.c b/ports/espressif/boards/microdev_micro_c3/pins.c index 240966404f..ab3abdb39c 100644 --- a/ports/espressif/boards/microdev_micro_c3/pins.c +++ b/ports/espressif/boards/microdev_micro_c3/pins.c @@ -40,6 +40,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + + /* + Reserved for Flash: { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, @@ -47,6 +50,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + */ + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, diff --git a/ports/espressif/boards/microdev_micro_s2/board.c b/ports/espressif/boards/microdev_micro_s2/board.c index 0a2b17e001..65bb19aced 100644 --- a/ports/espressif/boards/microdev_micro_s2/board.c +++ b/ports/espressif/boards/microdev_micro_s2/board.c @@ -38,23 +38,4 @@ void board_init(void) { #endif } -bool board_requests_safe_mode(void) { - return false; -} - -bool espressif_board_reset_pin_number(gpio_num_t pin_number) { - // Pin 21 is a high side LED so pull it down to prevent lighting the LED. - if (pin_number == 21) { - gpio_reset_pin(21); - gpio_pullup_dis(21); - gpio_pulldown_en(21); - return true; - } - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/microdev_micro_s2/mpconfigboard.h b/ports/espressif/boards/microdev_micro_s2/mpconfigboard.h index c9354cabcc..c692c5e664 100644 --- a/ports/espressif/boards/microdev_micro_s2/mpconfigboard.h +++ b/ports/espressif/boards/microdev_micro_s2/mpconfigboard.h @@ -28,9 +28,11 @@ #define MICROPY_HW_BOARD_NAME "MicroDev microS2" #define MICROPY_HW_MCU_NAME "ESP32-S2" -// Status LED +// Status LEDs #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) +#define MICROPY_HW_LED_STATUS (&pin_GPIO21) + // Default bus pins #define DEFAULT_I2C_BUS_SCL (&pin_GPIO1) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) diff --git a/ports/espressif/boards/microdev_micro_s2/mpconfigboard.mk b/ports/espressif/boards/microdev_micro_s2/mpconfigboard.mk index d551a5601c..e5a7f05462 100644 --- a/ports/espressif/boards/microdev_micro_s2/mpconfigboard.mk +++ b/ports/espressif/boards/microdev_micro_s2/mpconfigboard.mk @@ -5,12 +5,6 @@ USB_MANUFACTURER = "MicroDev" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 16MB diff --git a/ports/espressif/boards/mixgo_ce_serial/board.c b/ports/espressif/boards/mixgo_ce_serial/board.c index e07fe5cfd7..e6ffb553b1 100644 --- a/ports/espressif/boards/mixgo_ce_serial/board.c +++ b/ports/espressif/boards/mixgo_ce_serial/board.c @@ -31,6 +31,7 @@ #include "lib/oofatfs/ff.h" #include "extmod/vfs_fat.h" #include "py/mpstate.h" +#include "supervisor/filesystem.h" void board_init(void) { // Debug UART @@ -41,7 +42,7 @@ void board_init(void) { mp_import_stat_t stat_b = mp_import_stat("boot.py"); if (stat_b != MP_IMPORT_STAT_FILE) { - FATFS *fatfs = &((fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj)->fatfs; + FATFS *fatfs = filesystem_circuitpy(); FIL fs; UINT char_written = 0; const byte buffer[] = "#Serial port upload mode\nimport storage\nstorage.remount(\"/\", False)\nstorage.disable_usb_drive()\n"; @@ -58,13 +59,4 @@ void board_init(void) { } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk b/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk index 31955af81f..1e4ed0b859 100644 --- a/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk +++ b/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk @@ -5,17 +5,13 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 + FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/mixgo_cp_lib/mixgoce_lib +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/mixgo_ce_udisk/board.c b/ports/espressif/boards/mixgo_ce_udisk/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/mixgo_ce_udisk/board.c +++ b/ports/espressif/boards/mixgo_ce_udisk/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk b/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk index 4b8fe6846c..e9cd0c6d4a 100644 --- a/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk +++ b/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk @@ -5,17 +5,13 @@ USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 + FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/mixgo_cp_lib/mixgoce_lib +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/morpheans_morphesp-240/board.c b/ports/espressif/boards/morpheans_morphesp-240/board.c index 54e83eaaab..30e0a04aad 100644 --- a/ports/espressif/boards/morpheans_morphesp-240/board.c +++ b/ports/espressif/boards/morpheans_morphesp-240/board.c @@ -172,9 +172,6 @@ void board_init(void) { 0 // phase ); - // workaround as board_init() is called before reset_port() in main.c - pwmout_reset(); - displayio_display_obj_t *display = &displays[0].display; display->base.type = &displayio_display_type; common_hal_displayio_display_construct( @@ -198,8 +195,7 @@ void board_init(void) { sizeof(display_init_sequence), NULL, // There is no backlight pin, defined for now. NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -210,14 +206,8 @@ void board_init(void) { ); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - void board_deinit(void) { common_hal_displayio_release_displays(); } + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk b/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk index 79dd73f58a..18dd435c53 100644 --- a/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk +++ b/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "MORPHEANS" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/muselab_nanoesp32_s2_wroom/board.c b/ports/espressif/boards/muselab_nanoesp32_s2_wroom/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/muselab_nanoesp32_s2_wroom/board.c +++ b/ports/espressif/boards/muselab_nanoesp32_s2_wroom/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk b/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk index d1b4b1b453..04fde1e562 100644 --- a/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Muselab" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/muselab_nanoesp32_s2_wrover/board.c b/ports/espressif/boards/muselab_nanoesp32_s2_wrover/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/muselab_nanoesp32_s2_wrover/board.c +++ b/ports/espressif/boards/muselab_nanoesp32_s2_wrover/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/muselab_nanoesp32_s2_wrover/mpconfigboard.mk b/ports/espressif/boards/muselab_nanoesp32_s2_wrover/mpconfigboard.mk index 80557e1575..f008241e19 100644 --- a/ports/espressif/boards/muselab_nanoesp32_s2_wrover/mpconfigboard.mk +++ b/ports/espressif/boards/muselab_nanoesp32_s2_wrover/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Muselab" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/odt_pixelwing_esp32_s2/board.c b/ports/espressif/boards/odt_pixelwing_esp32_s2/board.c index 6772768da5..164430c88c 100644 --- a/ports/espressif/boards/odt_pixelwing_esp32_s2/board.c +++ b/ports/espressif/boards/odt_pixelwing_esp32_s2/board.c @@ -25,19 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -#include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/odt_pixelwing_esp32_s2/mpconfigboard.h b/ports/espressif/boards/odt_pixelwing_esp32_s2/mpconfigboard.h index 9d7a480228..5d6ad95e1b 100644 --- a/ports/espressif/boards/odt_pixelwing_esp32_s2/mpconfigboard.h +++ b/ports/espressif/boards/odt_pixelwing_esp32_s2/mpconfigboard.h @@ -31,5 +31,7 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO45) +#define MICROPY_HW_LED_STATUS (&pin_GPIO21) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO34) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) diff --git a/ports/espressif/boards/odt_pixelwing_esp32_s2/mpconfigboard.mk b/ports/espressif/boards/odt_pixelwing_esp32_s2/mpconfigboard.mk index d02872f445..44546fc09f 100644 --- a/ports/espressif/boards/odt_pixelwing_esp32_s2/mpconfigboard.mk +++ b/ports/espressif/boards/odt_pixelwing_esp32_s2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Oak Dev Tech" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/seeed_xiao_esp32c3/board.c b/ports/espressif/boards/seeed_xiao_esp32c3/board.c new file mode 100644 index 0000000000..7bcdcdba25 --- /dev/null +++ b/ports/espressif/boards/seeed_xiao_esp32c3/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/board.h" + +#include "components/driver/include/driver/gpio.h" + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO20); + common_hal_never_reset_pin(&pin_GPIO21); + #endif +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.h b/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.h new file mode 100644 index 0000000000..638be9d197 --- /dev/null +++ b/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.h @@ -0,0 +1,14 @@ +#define MICROPY_HW_BOARD_NAME "Seeed Studio XIAO ESP32C3" +#define MICROPY_HW_MCU_NAME "ESP32-C3FN4" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO7) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO6) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO8) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO10) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO9) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO20) +#define DEFAULT_UART_BUS_TX (&pin_GPIO21) + +#define CIRCUITPY_ESP_USB_SERIAL_JTAG (1) diff --git a/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk b/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk new file mode 100644 index 0000000000..d7325cf44e --- /dev/null +++ b/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x000C2886 +CIRCUITPY_CREATION_ID = 0x00C30001 + +IDF_TARGET = esp32c3 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/seeed_xiao_esp32c3/pins.c b/ports/espressif/boards/seeed_xiao_esp32c3/pins.c new file mode 100644 index 0000000000..5fc475d564 --- /dev/null +++ b/ports/espressif/boards/seeed_xiao_esp32c3/pins.c @@ -0,0 +1,43 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/seeed_xiao_esp32c3/sdkconfig b/ports/espressif/boards/seeed_xiao_esp32c3/sdkconfig new file mode 100644 index 0000000000..b2c9bc0fe6 --- /dev/null +++ b/ports/espressif/boards/seeed_xiao_esp32c3/sdkconfig @@ -0,0 +1,5 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="seeed-xiao-esp32c3" +# end of LWIP diff --git a/ports/espressif/boards/smartbeedesigns_bee_motion_s3/board.c b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/board.c new file mode 100644 index 0000000000..b3c8cb4191 --- /dev/null +++ b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.h b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.h new file mode 100644 index 0000000000..11e2449e9b --- /dev/null +++ b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Bee-Motion-S3" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO48) +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO36) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO37) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO17) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO16) diff --git a/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.mk b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.mk new file mode 100644 index 0000000000..7e58f9979d --- /dev/null +++ b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x8114 +USB_PRODUCT = "Bee-Motion-S3" +USB_MANUFACTURER = "Smart Bee Designs" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/smartbeedesigns_bee_motion_s3/pins.c b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/pins.c new file mode 100644 index 0000000000..7696986472 --- /dev/null +++ b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/pins.c @@ -0,0 +1,102 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + + + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44)}, + { MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_BOOT_BTN), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_VBAT), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_VBAT_SENSE), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_LIGHT_SENSOR), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_PIR), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_PIR_SENSOR), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_LDO2), MP_ROM_PTR(&pin_GPIO34) }, + + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/smartbeedesigns_bee_motion_s3/sdkconfig b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/sdkconfig new file mode 100644 index 0000000000..84cf45aa83 --- /dev/null +++ b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/sdkconfig @@ -0,0 +1,6 @@ +# CONFIG_ESP32S3_SPIRAM_SUPPORT is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="smartbeedesigns_bee_motion_s3" +# end of LWIP diff --git a/ports/espressif/boards/smartbeedesigns_bee_s3/board.c b/ports/espressif/boards/smartbeedesigns_bee_s3/board.c new file mode 100644 index 0000000000..b3c8cb4191 --- /dev/null +++ b/ports/espressif/boards/smartbeedesigns_bee_s3/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.h b/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.h new file mode 100644 index 0000000000..1a17770fb7 --- /dev/null +++ b/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Bee-S3" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO48) +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO36) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO37) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO39) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO38) diff --git a/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk b/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk new file mode 100644 index 0000000000..9d0974517d --- /dev/null +++ b/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x8111 +USB_PRODUCT = "Bee-S3" +USB_MANUFACTURER = "Smart Bee Designs" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/smartbeedesigns_bee_s3/pins.c b/ports/espressif/boards/smartbeedesigns_bee_s3/pins.c new file mode 100644 index 0000000000..189899fa49 --- /dev/null +++ b/ports/espressif/boards/smartbeedesigns_bee_s3/pins.c @@ -0,0 +1,79 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44)}, + { MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_VBAT), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_VBAT_SENSE), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/smartbeedesigns_bee_s3/sdkconfig b/ports/espressif/boards/smartbeedesigns_bee_s3/sdkconfig new file mode 100644 index 0000000000..b7bb11fdd5 --- /dev/null +++ b/ports/espressif/boards/smartbeedesigns_bee_s3/sdkconfig @@ -0,0 +1,6 @@ +# CONFIG_ESP32S3_SPIRAM_SUPPORT is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="smartbeedesigns_bee_s3" +# end of LWIP diff --git a/ports/espressif/boards/targett_module_clip_wroom/board.c b/ports/espressif/boards/targett_module_clip_wroom/board.c index 66aea4bdd5..ce5a770920 100644 --- a/ports/espressif/boards/targett_module_clip_wroom/board.c +++ b/ports/espressif/boards/targett_module_clip_wroom/board.c @@ -40,13 +40,4 @@ void board_init(void) { common_hal_never_reset_pin(&pin_GPIO16); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk b/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk index 2345469304..e13c654aa6 100644 --- a/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk @@ -5,13 +5,7 @@ USB_MANUFACTURER = "Targett" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/targett_module_clip_wrover/board.c b/ports/espressif/boards/targett_module_clip_wrover/board.c index 66aea4bdd5..ce5a770920 100644 --- a/ports/espressif/boards/targett_module_clip_wrover/board.c +++ b/ports/espressif/boards/targett_module_clip_wrover/board.c @@ -40,13 +40,4 @@ void board_init(void) { common_hal_never_reset_pin(&pin_GPIO16); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/targett_module_clip_wrover/mpconfigboard.mk b/ports/espressif/boards/targett_module_clip_wrover/mpconfigboard.mk index 80014bdf98..6ef620ac50 100644 --- a/ports/espressif/boards/targett_module_clip_wrover/mpconfigboard.mk +++ b/ports/espressif/boards/targett_module_clip_wrover/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "Targett" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/unexpectedmaker_feathers2/board.c b/ports/espressif/boards/unexpectedmaker_feathers2/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2/board.c +++ b/ports/espressif/boards/unexpectedmaker_feathers2/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.h index d10ab94223..ebea0f447b 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.h @@ -32,6 +32,8 @@ // #define MICROPY_HW_APA102_MOSI (&pin_GPIO40) // #define MICROPY_HW_APA102_SCK (&pin_GPIO45) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) diff --git a/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.mk index 10ddea75f1..1d48ea1076 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.mk +++ b/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "UnexpectedMaker" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 16MB diff --git a/ports/espressif/boards/unexpectedmaker_feathers2_neo/board.c b/ports/espressif/boards/unexpectedmaker_feathers2_neo/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2_neo/board.c +++ b/ports/espressif/boards/unexpectedmaker_feathers2_neo/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.h index af61a67fbb..aeaf23d248 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.h @@ -32,6 +32,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO40) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO39) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) diff --git a/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.mk index f42f8ca7cc..2b78e51635 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.mk +++ b/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "UnexpectedMaker" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/board.c b/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/board.c +++ b/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h index a2fadd85ea..1b11b37d66 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h @@ -32,6 +32,8 @@ // #define MICROPY_HW_APA102_MOSI (&pin_GPIO40) // #define MICROPY_HW_APA102_SCK (&pin_GPIO45) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO38) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) diff --git a/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk index 10ddea75f1..1d48ea1076 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk +++ b/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "UnexpectedMaker" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 16MB diff --git a/ports/espressif/boards/unexpectedmaker_feathers3/board.c b/ports/espressif/boards/unexpectedmaker_feathers3/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers3/board.c +++ b/ports/espressif/boards/unexpectedmaker_feathers3/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.h index a341cf0464..67054b8664 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.h @@ -32,6 +32,8 @@ #define MICROPY_HW_NEOPIXEL (&pin_GPIO40) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO39) +#define MICROPY_HW_LED_STATUS (&pin_GPIO13) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) diff --git a/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.mk index eb6673b563..666185b6fd 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.mk +++ b/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "UnexpectedMaker" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 16MB diff --git a/ports/espressif/boards/unexpectedmaker_feathers3/pins.c b/ports/espressif/boards/unexpectedmaker_feathers3/pins.c index 43fdc3c579..9a2fde5a0c 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers3/pins.c +++ b/ports/espressif/boards/unexpectedmaker_feathers3/pins.c @@ -110,7 +110,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AMB), MP_ROM_PTR(&pin_GPIO4) }, // Ambient Light Sensor { MP_ROM_QSTR(MP_QSTR_LDO2), MP_ROM_PTR(&pin_GPIO39) }, // Second LDO Enable control - { MP_ROM_QSTR(MP_QSTR_I39), MP_ROM_PTR(&pin_GPIO39) }, // Second LDO Enable control + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, // Second LDO Enable control { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/espressif/boards/unexpectedmaker_pros3/board.c b/ports/espressif/boards/unexpectedmaker_pros3/board.c index 0432485111..8fd94f6c8b 100644 --- a/ports/espressif/boards/unexpectedmaker_pros3/board.c +++ b/ports/espressif/boards/unexpectedmaker_pros3/board.c @@ -35,14 +35,3 @@ void board_init(void) { common_hal_never_reset_pin(&pin_GPIO44); #endif /* DEBUG */ } - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} diff --git a/ports/espressif/boards/unexpectedmaker_pros3/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_pros3/mpconfigboard.mk index 4413a8b641..bf6e7a5105 100644 --- a/ports/espressif/boards/unexpectedmaker_pros3/mpconfigboard.mk +++ b/ports/espressif/boards/unexpectedmaker_pros3/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "UnexpectedMaker" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 16MB diff --git a/ports/espressif/boards/unexpectedmaker_pros3/pins.c b/ports/espressif/boards/unexpectedmaker_pros3/pins.c index bc0ca026f3..8c7e050ded 100644 --- a/ports/espressif/boards/unexpectedmaker_pros3/pins.c +++ b/ports/espressif/boards/unexpectedmaker_pros3/pins.c @@ -130,7 +130,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_LDO2), MP_ROM_PTR(&pin_GPIO17) }, // Second LDO Enable control - { MP_ROM_QSTR(MP_QSTR_I17), MP_ROM_PTR(&pin_GPIO17) }, // Second LDO Enable control + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, // Second LDO Enable control { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/espressif/boards/unexpectedmaker_tinypico/board.c b/ports/espressif/boards/unexpectedmaker_tinypico/board.c new file mode 100644 index 0000000000..e59af9528d --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_tinypico/board.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "components/driver/include/driver/gpio.h" +#include "components/hal/include/hal/gpio_hal.h" +#include "common-hal/microcontroller/Pin.h" + +void board_init(void) { + reset_board(); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + // Turn on APA102 power by default + gpio_set_direction(13, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(13, true); +} + +void board_deinit(void) { + // Turn off APA102 power + gpio_set_direction(13, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(13, false); +} diff --git a/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.h new file mode 100644 index 0000000000..2db308f623 --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#define MICROPY_HW_BOARD_NAME "TinyPICO" +#define MICROPY_HW_MCU_NAME "ESP32-PICO-D4" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO23, .miso = &pin_GPIO19}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.mk new file mode 100644 index 0000000000..e26981465b --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0xB0B00000 +CIRCUITPY_CREATION_ID = 0x00000001 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/unexpectedmaker_tinypico/pins.c b/ports/espressif/boards/unexpectedmaker_tinypico/pins.c new file mode 100644 index 0000000000..b4843960ae --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_tinypico/pins.c @@ -0,0 +1,84 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A27), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_A25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SDO), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_SDI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_A32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_A33), MP_ROM_PTR(&pin_GPIO33) }, + + // Battery voltage sense pin + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_VBAT), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_VBAT_SENSE), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO35) }, + + // 5V present sense pin + { MP_ROM_QSTR(MP_QSTR_VBUS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_GPIO2) }, // APA102 + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_GPIO12) }, // APA102 + { MP_ROM_QSTR(MP_QSTR_APA102_PWR), MP_ROM_PTR(&pin_GPIO13) }, // APA102 + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/unexpectedmaker_tinypico/sdkconfig b/ports/espressif/boards/unexpectedmaker_tinypico/sdkconfig new file mode 100644 index 0000000000..2d4d0d4ecc --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_tinypico/sdkconfig @@ -0,0 +1,20 @@ +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +# CONFIG_SPIRAM_SIZE is not set +CONFIG_ESP32_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set +CONFIG_SPIRAM_CACHE_WORKAROUND=y diff --git a/ports/espressif/boards/unexpectedmaker_tinypico_nano/board.c b/ports/espressif/boards/unexpectedmaker_tinypico_nano/board.c new file mode 100644 index 0000000000..d66ab9e5f1 --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_tinypico_nano/board.c @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "components/driver/include/driver/gpio.h" +#include "components/hal/include/hal/gpio_hal.h" +#include "common-hal/microcontroller/Pin.h" + +void board_init(void) { + reset_board(); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} + +void board_deinit(void) { +} diff --git a/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.h new file mode 100644 index 0000000000..87c582b3bf --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#define MICROPY_HW_BOARD_NAME "TinyPICO Nano" +#define MICROPY_HW_MCU_NAME "ESP32-PICO-D4" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO23, .miso = &pin_GPIO19}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.mk new file mode 100644 index 0000000000..f3d9ea4c92 --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0xB0B00000 +CIRCUITPY_CREATION_ID = 0x00000002 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/unexpectedmaker_tinypico_nano/pins.c b/ports/espressif/boards/unexpectedmaker_tinypico_nano/pins.c new file mode 100644 index 0000000000..61f65a089b --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_tinypico_nano/pins.c @@ -0,0 +1,117 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_SDI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SDO), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_A25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A27), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_A32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_A33), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_A34), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_A35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_A36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_A37), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_A38), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_A39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/unexpectedmaker_tinypico_nano/sdkconfig b/ports/espressif/boards/unexpectedmaker_tinypico_nano/sdkconfig new file mode 100644 index 0000000000..2d4d0d4ecc --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_tinypico_nano/sdkconfig @@ -0,0 +1,20 @@ +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +# CONFIG_SPIRAM_SIZE is not set +CONFIG_ESP32_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set +CONFIG_SPIRAM_CACHE_WORKAROUND=y diff --git a/ports/espressif/boards/unexpectedmaker_tinys2/board.c b/ports/espressif/boards/unexpectedmaker_tinys2/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/unexpectedmaker_tinys2/board.c +++ b/ports/espressif/boards/unexpectedmaker_tinys2/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/unexpectedmaker_tinys2/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_tinys2/mpconfigboard.mk index 8b1cd8bb51..39a9c38b36 100644 --- a/ports/espressif/boards/unexpectedmaker_tinys2/mpconfigboard.mk +++ b/ports/espressif/boards/unexpectedmaker_tinys2/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "UnexpectedMaker" IDF_TARGET = esp32s2 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/unexpectedmaker_tinys3/board.c b/ports/espressif/boards/unexpectedmaker_tinys3/board.c index 0432485111..b3c8cb4191 100644 --- a/ports/espressif/boards/unexpectedmaker_tinys3/board.c +++ b/ports/espressif/boards/unexpectedmaker_tinys3/board.c @@ -36,13 +36,4 @@ void board_init(void) { #endif /* DEBUG */ } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/unexpectedmaker_tinys3/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_tinys3/mpconfigboard.mk index 9de950e632..716a45b5ca 100644 --- a/ports/espressif/boards/unexpectedmaker_tinys3/mpconfigboard.mk +++ b/ports/espressif/boards/unexpectedmaker_tinys3/mpconfigboard.mk @@ -5,13 +5,6 @@ USB_MANUFACTURER = "UnexpectedMaker" IDF_TARGET = esp32s3 -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - -# The default queue depth of 16 overflows on release builds, -# so increase it to 32. -CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 - CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB diff --git a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c new file mode 100644 index 0000000000..070e3418da --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c @@ -0,0 +1,139 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#define DELAY 0x80 + + +// display init sequence according to Adafruit_CircuitPython_ST7735R +// https://github.com/adafruit/Adafruit_CircuitPython_ST7735R +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 0x96, + // SLPOUT and Delay + 0x11, 0 | DELAY, 0xFF, + 0xB1, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xB3, 0x06, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, // _FRMCTR3 + 0xB4, 0x01, 0x07, // _INVCTR line inversion + 0xC0, 0x03, 0xA2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xC1, 0x01, 0xC5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xC2, 0x02, 0x0A, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xC3, 0x02, 0x8A, 0x2A, + 0xC4, 0x02, 0x8A, 0xEE, + 0xC5, 0x01, 0x0E, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x20, 0x00, // _INVOFF + 0x36, 0x01, 0x18, // _MADCTL bottom to top refresh + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // fix on VTL + 0x3A, 0x01, 0x05, // COLMOD - 16bit color + 0xE0, 0x10, 0x02, 0x1C, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2D, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, // _GMCTRP1 Gamma + 0xE1, 0x10, 0x03, 0x1D, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, // _GMCTRN1 + 0x13, 0 | DELAY, 0x0A, // _NORON + 0x29, 0 | DELAY, 0x64, // _DISPON + // 0x36, 0x01, 0xC0, // _MADCTL Default rotation plus BGR encoding + 0x36, 0x01, 0xC8, // _MADCTL Default rotation plus RGB encoding + 0x21, 0x00, // _INVON +}; + +static void display_init(void) { + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + + common_hal_busio_spi_construct( + spi, + &pin_GPIO10, // CLK + &pin_GPIO11, // MOSI + NULL, // MISO not connected + false); // Not half-duplex + + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO18, // DC + &pin_GPIO9, // CS + &pin_GPIO21, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + + common_hal_displayio_display_construct( + display, + bus, + 160, // width (after rotation) + 80, // height (after rotation) + 26, // column start + 1, // row start + 90, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO45, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ + + // Display + display_init(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/mpconfigboard.h new file mode 100644 index 0000000000..f9cf2aa384 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/mpconfigboard.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S2-Pico-LCD" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO41) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO40) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO10) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO11) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO12) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/mpconfigboard.mk new file mode 100644 index 0000000000..e65760ec68 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x303a +USB_PID = 0x810c + +USB_PRODUCT = "ESP32-S2-Pico-LCD" +USB_MANUFACTURER = "Waveshare Electronics" + +IDF_TARGET = esp32s2 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=80m +CIRCUITPY_ESP_FLASH_SIZE=4MB diff --git a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/pins.c b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/pins.c new file mode 100644 index 0000000000..ac1e983202 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/pins.c @@ -0,0 +1,79 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_USB_IN), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_GP34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_GP35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_GP36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_GP37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_GP38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_GP39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_GP40), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_GP41), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_GP42), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_GP43), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_GP44), MP_ROM_PTR(&pin_GPIO44) }, + + // 0.96 inch LCD ST7735s + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BACKLIGHT), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/sdkconfig b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/sdkconfig new file mode 100644 index 0000000000..836fd46764 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/sdkconfig @@ -0,0 +1,37 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 +# end of SPI RAM config + +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +# +# PSRAM clock and cs IO for ESP32S2 +# +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM clock and cs IO for ESP32S2 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="waveshare" +# end of LWIP diff --git a/ports/espressif/boards/waveshare_esp32s2_pico/board.c b/ports/espressif/boards/waveshare_esp32s2_pico/board.c new file mode 100644 index 0000000000..b3c8cb4191 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32s2_pico/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h new file mode 100644 index 0000000000..6a10db6061 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S2-Pico" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO9) diff --git a/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.mk new file mode 100644 index 0000000000..2db911fb26 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.mk @@ -0,0 +1,10 @@ +USB_VID = 0x303a +USB_PID = 0x810a +USB_PRODUCT = "ESP32-S2-Pico" +USB_MANUFACTURER = "Waveshare Electronics" + +IDF_TARGET = esp32s2 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/waveshare_esp32s2_pico/pins.c b/ports/espressif/boards/waveshare_esp32s2_pico/pins.c new file mode 100644 index 0000000000..04054344ae --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32s2_pico/pins.c @@ -0,0 +1,44 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_GP34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_GP35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_GP36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_GP37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_GP38), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_GP39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_GP40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_GP41), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_GP42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_GP43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_GP44), MP_ROM_PTR(&pin_GPIO44) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig b/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig new file mode 100644 index 0000000000..c81fbb4837 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig @@ -0,0 +1,20 @@ +# +# SPI RAM config +# +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_MODE_QUAD=y +CONFIG_SPIRAM_SIZE=8388608 +CONFIG_SPIRAM_SPEED_120M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_USE_MEMMAP=y +CONFIG_SPIRAM_MEMTEST=y + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="waveshare" +# end of LWIP diff --git a/ports/espressif/common-hal/_bleio/Adapter.c b/ports/espressif/common-hal/_bleio/Adapter.c index 5eaf6e9cf4..3239c501cc 100644 --- a/ports/espressif/common-hal/_bleio/Adapter.c +++ b/ports/espressif/common-hal/_bleio/Adapter.c @@ -59,8 +59,8 @@ #include "esp_bt.h" #include "esp_nimble_hci.h" -#if CIRCUITPY_DOTENV -#include "shared-module/dotenv/__init__.h" +#if CIRCUITPY_OS_GETENV +#include "shared-module/os/__init__.h" #endif bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT]; @@ -101,22 +101,16 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable ble_hs_cfg.sync_cb = _on_sync; // ble_hs_cfg.store_status_cb = ble_store_util_status_rr; - #if CIRCUITPY_DOTENV - mp_int_t name_len = 0; - char ble_name[32]; - name_len = dotenv_get_key("/.env", "CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name) - 1); - if (name_len > 0) { - if (name_len > MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH) { - name_len = MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH; - } - ble_name[name_len] = '\0'; + #if CIRCUITPY_OS_GETENV + char ble_name[1 + MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH]; + os_getenv_err_t result = common_hal_os_getenv_str("CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name)); + if (result == GETENV_OK) { ble_svc_gap_device_name_set(ble_name); - } else { + } else + #endif + { ble_svc_gap_device_name_set("CIRCUITPY"); } - #else - ble_svc_gap_device_name_set("CIRCUITPY"); - #endif // Clear all of the internal connection objects. for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { diff --git a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c index fc3d0bbf06..96de70bf84 100644 --- a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c +++ b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c @@ -49,7 +49,19 @@ STATIC int characteristic_buffer_on_ble_evt(struct ble_gap_event *event, void *p event->notify_rx.attr_handle == self->characteristic->handle) { const struct os_mbuf *m = event->notify_rx.om; while (m != NULL) { - ringbuf_put_n(&self->ringbuf, m->om_data, m->om_len); + const uint8_t *data = m->om_data; + uint16_t len = m->om_len; + if (self->watch_for_interrupt_char) { + for (uint16_t i = 0; i < len; i++) { + if (data[i] == mp_interrupt_char) { + mp_sched_keyboard_interrupt(); + } else { + ringbuf_put(&self->ringbuf, data[i]); + } + } + } else { + ringbuf_put_n(&self->ringbuf, data, len); + } m = SLIST_NEXT(m, om_next); } } @@ -69,14 +81,12 @@ void _common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buff bleio_characteristic_obj_t *characteristic, mp_float_t timeout, uint8_t *buffer, size_t buffer_size, - void *static_handler_entry) { + void *static_handler_entry, + bool watch_for_interrupt_char) { self->characteristic = characteristic; self->timeout_ms = timeout * 1000; - - self->ringbuf.buf = (uint8_t *)buffer; - self->ringbuf.size = buffer_size; - self->ringbuf.iget = 0; - self->ringbuf.iput = 0; + self->watch_for_interrupt_char = watch_for_interrupt_char; + ringbuf_init(&self->ringbuf, buffer, buffer_size); if (static_handler_entry != NULL) { ble_event_add_handler_entry((ble_event_handler_entry_t *)static_handler_entry, characteristic_buffer_on_ble_evt, self); @@ -91,7 +101,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe mp_float_t timeout, size_t buffer_size) { uint8_t *buffer = m_malloc(buffer_size, true); - _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, buffer, buffer_size, NULL); + _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, buffer, buffer_size, NULL, false); } uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) { @@ -131,6 +141,7 @@ void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_o if (!common_hal_bleio_characteristic_buffer_deinited(self)) { ble_event_remove_handler(characteristic_buffer_on_ble_evt, self); self->characteristic = NULL; + ringbuf_deinit(&self->ringbuf); } } diff --git a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.h b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.h index e5247c20f7..30c3c426e6 100644 --- a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.h +++ b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.h @@ -27,6 +27,8 @@ #ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H #define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H +#include + #include "py/ringbuf.h" #include "shared-bindings/_bleio/Characteristic.h" @@ -36,6 +38,7 @@ typedef struct { uint32_t timeout_ms; // Ring buffer storing consecutive incoming values. ringbuf_t ringbuf; + bool watch_for_interrupt_char; } bleio_characteristic_buffer_obj_t; #endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H diff --git a/ports/espressif/common-hal/_bleio/PacketBuffer.c b/ports/espressif/common-hal/_bleio/PacketBuffer.c index 4e65bf309c..3b3e51df61 100644 --- a/ports/espressif/common-hal/_bleio/PacketBuffer.c +++ b/ports/espressif/common-hal/_bleio/PacketBuffer.c @@ -42,13 +42,13 @@ STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, const struct os_mbuf *mbuf) { size_t len = OS_MBUF_PKTLEN(mbuf); - if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) { + if (len + sizeof(uint16_t) > ringbuf_size(&self->ringbuf)) { // This shouldn't happen but can if our buffer size was much smaller than // the writes the client actually makes. return; } // 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++) { @@ -164,10 +164,7 @@ void _common_hal_bleio_packet_buffer_construct( } if (incoming) { - self->ringbuf.buf = (uint8_t *)incoming_buffer; - self->ringbuf.size = incoming_buffer_size; - self->ringbuf.iget = 0; - self->ringbuf.iput = 0; + ringbuf_init(&self->ringbuf, (uint8_t *)incoming_buffer, incoming_buffer_size); } self->packet_queued = false; @@ -219,8 +216,7 @@ void common_hal_bleio_packet_buffer_construct( size_t incoming_buffer_size = 0; uint32_t *incoming_buffer = NULL; if (incoming) { - incoming_buffer_size = buffer_size * (sizeof(uint16_t) + max_packet_size); - incoming_buffer = m_malloc(incoming_buffer_size, false); + ringbuf_init(&self->ringbuf, (uint8_t *)incoming_buffer, incoming_buffer_size); } uint32_t *outgoing1 = NULL; @@ -414,5 +410,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)) { ble_event_remove_handler(packet_buffer_on_ble_client_evt, self); + ringbuf_deinit(&self->ringbuf); } } diff --git a/ports/espressif/common-hal/alarm/SleepMemory.c b/ports/espressif/common-hal/alarm/SleepMemory.c index 764125ddb2..d375fdc778 100644 --- a/ports/espressif/common-hal/alarm/SleepMemory.c +++ b/ports/espressif/common-hal/alarm/SleepMemory.c @@ -31,7 +31,6 @@ #include "common-hal/alarm/SleepMemory.h" #include "shared-bindings/alarm/SleepMemory.h" -#include "esp_log.h" #include "esp_sleep.h" // Data storage for singleton instance of SleepMemory. @@ -39,7 +38,7 @@ static RTC_DATA_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; void alarm_sleep_memory_reset(void) { - // ESP-IDF build system takes care of doing esp_sleep_pd_config() or the equivalentwith + // ESP-IDF build system takes care of doing esp_sleep_pd_config() or the equivalent with // the correct settings, depending on which RTC mem we are using. // https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/system/sleep_modes.html#power-down-of-rtc-peripherals-and-memories } diff --git a/ports/espressif/common-hal/alarm/SleepMemory.h b/ports/espressif/common-hal/alarm/SleepMemory.h index 37d6cd371f..626f748a67 100644 --- a/ports/espressif/common-hal/alarm/SleepMemory.h +++ b/ports/espressif/common-hal/alarm/SleepMemory.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_ALARM_SLEEPMEMORY_H -#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_ALARM_SLEEPMEMORY_H +#pragma once #include "py/obj.h" @@ -49,5 +48,3 @@ typedef struct { } alarm_sleep_memory_obj_t; extern void alarm_sleep_memory_reset(void); - -#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_ALARM_SLEEPMEMORY_H diff --git a/ports/espressif/common-hal/alarm/__init__.c b/ports/espressif/common-hal/alarm/__init__.c index d65ab0bbb2..0c288d89b4 100644 --- a/ports/espressif/common-hal/alarm/__init__.c +++ b/ports/espressif/common-hal/alarm/__init__.c @@ -39,12 +39,19 @@ #include "shared-bindings/wifi/__init__.h" #include "shared-bindings/microcontroller/__init__.h" +#if CIRCUITPY_ESPULP +#include "bindings/espulp/ULPAlarm.h" +#endif + +#include "common-hal/digitalio/DigitalInOut.h" + #include "supervisor/port.h" #include "supervisor/shared/workflow.h" #include "esp_sleep.h" #include "soc/rtc_cntl_reg.h" +#include "components/driver/include/driver/gpio.h" #include "components/driver/include/driver/uart.h" // Singleton instance of SleepMemory. @@ -54,15 +61,22 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = { }, }; +// Non-heap alarm object recording alarm (if any) that woke up CircuitPython after light or deep sleep. +// This object lives across VM instantiations, so none of these objects can contain references to the heap. +alarm_wake_alarm_union_t alarm_wake_alarm; + void alarm_reset(void) { alarm_sleep_memory_reset(); alarm_pin_pinalarm_reset(); alarm_time_timealarm_reset(); alarm_touch_touchalarm_reset(); + #if CIRCUITPY_ESPULP + espulp_ulpalarm_reset(); + #endif esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); } -STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) { +STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(bool deep_sleep) { // First check if the modules remember what last woke up if (alarm_pin_pinalarm_woke_this_cycle()) { return ESP_SLEEP_WAKEUP_GPIO; @@ -73,34 +87,48 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) { if (alarm_touch_touchalarm_woke_this_cycle()) { return ESP_SLEEP_WAKEUP_TOUCHPAD; } + #if CIRCUITPY_ESPULP + if (espulp_ulpalarm_woke_this_cycle()) { + return ESP_SLEEP_WAKEUP_ULP; + } + #endif // If waking from true deep sleep, modules will have lost their state, // so check the deep wakeup cause manually - return esp_sleep_get_wakeup_cause(); + if (deep_sleep) { + return esp_sleep_get_wakeup_cause(); + } + return ESP_SLEEP_WAKEUP_UNDEFINED; } bool common_hal_alarm_woken_from_sleep(void) { - return _get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED; + return _get_wakeup_cause(false) != ESP_SLEEP_WAKEUP_UNDEFINED; } -mp_obj_t common_hal_alarm_create_wake_alarm(void) { +mp_obj_t common_hal_alarm_record_wake_alarm(void) { // If woken from deep sleep, create a copy alarm similar to what would have // been passed in originally. Otherwise, just return none - esp_sleep_wakeup_cause_t cause = _get_wakeup_cause(); + esp_sleep_wakeup_cause_t cause = _get_wakeup_cause(true); switch (cause) { case ESP_SLEEP_WAKEUP_TIMER: { - return alarm_time_timealarm_create_wakeup_alarm(); + return alarm_time_timealarm_record_wake_alarm(); } case ESP_SLEEP_WAKEUP_GPIO: case ESP_SLEEP_WAKEUP_EXT0: case ESP_SLEEP_WAKEUP_EXT1: { - return alarm_pin_pinalarm_create_wakeup_alarm(); + return alarm_pin_pinalarm_record_wake_alarm(); } case ESP_SLEEP_WAKEUP_TOUCHPAD: { - return alarm_touch_touchalarm_create_wakeup_alarm(); + return alarm_touch_touchalarm_record_wake_alarm(); } + #if CIRCUITPY_ESPULP + case ESP_SLEEP_WAKEUP_ULP: { + return espulp_ulpalarm_record_wake_alarm(); + } + #endif + case ESP_SLEEP_WAKEUP_UNDEFINED: default: // Not a deep sleep reset. @@ -114,6 +142,9 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms); alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms); alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); + #if CIRCUITPY_ESPULP + espulp_ulpalarm_set_alarm(deep_sleep, n_alarms, alarms); + #endif } mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { @@ -126,7 +157,7 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj RUN_BACKGROUND_TASKS; // Detect if interrupt was alarm or ctrl-C interrupt. if (common_hal_alarm_woken_from_sleep()) { - esp_sleep_wakeup_cause_t cause = _get_wakeup_cause(); + esp_sleep_wakeup_cause_t cause = _get_wakeup_cause(false); switch (cause) { case ESP_SLEEP_WAKEUP_TIMER: { wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms); @@ -140,6 +171,12 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj wake_alarm = alarm_touch_touchalarm_find_triggered_alarm(n_alarms,alarms); break; } + #if CIRCUITPY_ESPULP + case ESP_SLEEP_WAKEUP_ULP: { + wake_alarm = espulp_ulpalarm_find_triggered_alarm(n_alarms,alarms); + break; + } + #endif default: // Should not reach this, if all light sleep types are covered correctly break; @@ -158,13 +195,20 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj return wake_alarm; } -void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { +void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t *preserve_dios[]) { + digitalio_digitalinout_preserve_for_deep_sleep(n_dios, preserve_dios); _setup_sleep_alarms(true, n_alarms, alarms); } void NORETURN common_hal_alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); alarm_touch_touchalarm_prepare_for_deep_sleep(); + #if CIRCUITPY_ESPULP + espulp_ulpalarm_prepare_for_deep_sleep(); + #endif + + // We no longer need to remember the pin preservations, since any pin resets are all done. + clear_pin_preservations(); // The ESP-IDF caches the deep sleep settings and applies them before sleep. // We don't need to worry about resetting them in the interim. diff --git a/ports/espressif/common-hal/alarm/__init__.h b/ports/espressif/common-hal/alarm/__init__.h index ae7286db76..02e27e9806 100644 --- a/ports/espressif/common-hal/alarm/__init__.h +++ b/ports/espressif/common-hal/alarm/__init__.h @@ -24,13 +24,27 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_ALARM__INIT__H -#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_ALARM__INIT__H +#pragma once #include "common-hal/alarm/SleepMemory.h" +#include "common-hal/alarm/pin/PinAlarm.h" +#include "common-hal/alarm/time/TimeAlarm.h" +#include "common-hal/alarm/touch/TouchAlarm.h" -const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; +#if CIRCUITPY_ESPULP +#include "common-hal/espulp/ULPAlarm.h" +#endif + +typedef union { + #if CIRCUITPY_ESPULP + espulp_ulpalarm_obj_t ulp_alarm; + #endif + alarm_pin_pinalarm_obj_t pin_alarm; + alarm_time_timealarm_obj_t time_alarm; + alarm_touch_touchalarm_obj_t touch_alarm; +} alarm_wake_alarm_union_t; + +extern alarm_wake_alarm_union_t alarm_wake_alarm; +extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; extern void alarm_reset(void); - -#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_ALARM__INIT__H diff --git a/ports/espressif/common-hal/alarm/pin/PinAlarm.c b/ports/espressif/common-hal/alarm/pin/PinAlarm.c index 6318cc2cca..6db184a4dd 100644 --- a/ports/espressif/common-hal/alarm/pin/PinAlarm.c +++ b/ports/espressif/common-hal/alarm/pin/PinAlarm.c @@ -26,10 +26,10 @@ */ #include "py/runtime.h" +#include "supervisor/port.h" -#include "supervisor/esp_port.h" +#include "common-hal/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" -#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" #include "esp_sleep.h" @@ -90,11 +90,7 @@ STATIC void gpio_interrupt(void *arg) { gpio_ll_intr_disable(&GPIO, 32 + i); } } - BaseType_t high_task_wakeup; - vTaskNotifyGiveFromISR(circuitpython_task, &high_task_wakeup); - if (high_task_wakeup) { - portYIELD_FROM_ISR(); - } + port_wake_main_task_from_isr(); } bool alarm_pin_pinalarm_woke_this_cycle(void) { @@ -115,7 +111,7 @@ mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t return mp_const_none; } -mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) { +mp_obj_t alarm_pin_pinalarm_record_wake_alarm(void) { esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); // Pin status will persist into a fake deep sleep @@ -139,7 +135,8 @@ mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) { } } - alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t); + alarm_pin_pinalarm_obj_t *const alarm = &alarm_wake_alarm.pin_alarm; + alarm->base.type = &alarm_pin_pinalarm_type; alarm->pin = NULL; // Map the pin number back to a pin object. @@ -219,6 +216,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob if (esp_sleep_enable_ext1_wakeup(high_alarms, ESP_EXT1_WAKEUP_ANY_HIGH) != ESP_OK) { mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep.")); } + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); } size_t low_pins[2]; size_t j = 0; @@ -235,6 +233,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob if (esp_sleep_enable_ext1_wakeup(1ull << low_pins[1], ESP_EXT1_WAKEUP_ALL_LOW) != ESP_OK) { mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep.")); } + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); } if (low_count > 0) { if (esp_sleep_enable_ext0_wakeup(low_pins[0], 0) != ESP_OK) { @@ -277,16 +276,14 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[i], PIN_FUNC_GPIO); if (pull) { gpio_set_pull_mode(i, pull_mode); - size_t j = 0; - while (gpio_get_level(i) == false) { - j++; - } } never_reset_pin_number(i); // Sets interrupt type and wakeup bits. gpio_wakeup_enable(i, interrupt_mode); gpio_intr_enable(i); } + // Wait for any pulls to settle. + mp_hal_delay_ms(50); } diff --git a/ports/espressif/common-hal/alarm/pin/PinAlarm.h b/ports/espressif/common-hal/alarm/pin/PinAlarm.h index cbc20b996c..309b27c2e9 100644 --- a/ports/espressif/common-hal/alarm/pin/PinAlarm.h +++ b/ports/espressif/common-hal/alarm/pin/PinAlarm.h @@ -24,9 +24,13 @@ * THE SOFTWARE. */ +#pragma once + #include "py/obj.h" #include "py/objtuple.h" +#include "shared-bindings/microcontroller/Pin.h" + typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *pin; @@ -35,7 +39,7 @@ typedef struct { } alarm_pin_pinalarm_obj_t; mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void); +mp_obj_t alarm_pin_pinalarm_record_wake_alarm(void); void alarm_pin_pinalarm_prepare_for_deep_sleep(void); void alarm_pin_pinalarm_reset(void); diff --git a/ports/espressif/common-hal/alarm/time/TimeAlarm.c b/ports/espressif/common-hal/alarm/time/TimeAlarm.c index 256d96a75f..758e3c8f58 100644 --- a/ports/espressif/common-hal/alarm/time/TimeAlarm.c +++ b/ports/espressif/common-hal/alarm/time/TimeAlarm.c @@ -27,10 +27,11 @@ #include "esp_sleep.h" #include "py/runtime.h" -#include "supervisor/esp_port.h" +#include "supervisor/port.h" #include "components/esp_timer/include/esp_timer.h" +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/time/__init__.h" @@ -51,12 +52,13 @@ mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj return mp_const_none; } -mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) { - alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t); - timer->base.type = &alarm_time_timealarm_type; +mp_obj_t alarm_time_timealarm_record_wake_alarm(void) { + alarm_time_timealarm_obj_t *const alarm = &alarm_wake_alarm.time_alarm; + + alarm->base.type = &alarm_time_timealarm_type; // TODO: Set monotonic_time based on the RTC state. - timer->monotonic_time = 0.0f; - return timer; + alarm->monotonic_time = 0.0f; + return alarm; } esp_timer_handle_t pretend_sleep_timer; @@ -66,7 +68,7 @@ STATIC bool woke_up = false; STATIC void timer_callback(void *arg) { (void)arg; woke_up = true; - xTaskNotifyGive(circuitpython_task); + port_wake_main_task(); } bool alarm_time_timealarm_woke_this_cycle(void) { diff --git a/ports/espressif/common-hal/alarm/time/TimeAlarm.h b/ports/espressif/common-hal/alarm/time/TimeAlarm.h index 36986e06b2..c679c3cd9f 100644 --- a/ports/espressif/common-hal/alarm/time/TimeAlarm.h +++ b/ports/espressif/common-hal/alarm/time/TimeAlarm.h @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#pragma once #include "py/obj.h" @@ -33,7 +34,7 @@ typedef struct { } alarm_time_timealarm_obj_t; mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void); +mp_obj_t alarm_time_timealarm_record_wake_alarm(void); void alarm_time_timealarm_reset(void); void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); diff --git a/ports/espressif/common-hal/alarm/touch/TouchAlarm.c b/ports/espressif/common-hal/alarm/touch/TouchAlarm.c index 02f176cbf7..232614ce32 100644 --- a/ports/espressif/common-hal/alarm/touch/TouchAlarm.c +++ b/ports/espressif/common-hal/alarm/touch/TouchAlarm.c @@ -24,13 +24,14 @@ * THE SOFTWARE. */ +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/touch/TouchAlarm.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "esp_sleep.h" #include "peripherals/touch.h" -#include "supervisor/esp_port.h" +#include "supervisor/port.h" static uint16_t touch_channel_mask; static volatile bool woke_up = false; @@ -52,9 +53,9 @@ mp_obj_t alarm_touch_touchalarm_find_triggered_alarm(const size_t n_alarms, cons return mp_const_none; } -mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void) { - // Create TouchAlarm object. - alarm_touch_touchalarm_obj_t *alarm = m_new_obj(alarm_touch_touchalarm_obj_t); +mp_obj_t alarm_touch_touchalarm_record_wake_alarm(void) { + alarm_touch_touchalarm_obj_t *const alarm = &alarm_wake_alarm.touch_alarm; + alarm->base.type = &alarm_touch_touchalarm_type; alarm->pin = NULL; @@ -86,11 +87,7 @@ mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void) { STATIC void touch_interrupt(void *arg) { (void)arg; woke_up = true; - BaseType_t task_wakeup; - vTaskNotifyGiveFromISR(circuitpython_task, &task_wakeup); - if (task_wakeup) { - portYIELD_FROM_ISR(); - } + port_wake_main_task_from_isr(); } void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms) { @@ -100,7 +97,7 @@ void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alar for (size_t i = 0; i < n_alarms; i++) { if (mp_obj_is_type(alarms[i], &alarm_touch_touchalarm_type)) { if (deep_sleep && touch_alarm_set) { - mp_raise_ValueError(translate("Only one TouchAlarm can be set in deep sleep.")); + mp_raise_ValueError_varg(translate("Only one %q can be set in deep sleep."), MP_QSTR_TouchAlarm); } touch_alarm = MP_OBJ_TO_PTR(alarms[i]); touch_channel_mask |= 1 << touch_alarm->pin->number; diff --git a/ports/espressif/common-hal/alarm/touch/TouchAlarm.h b/ports/espressif/common-hal/alarm/touch/TouchAlarm.h index df2521c12a..0f35063ee4 100644 --- a/ports/espressif/common-hal/alarm/touch/TouchAlarm.h +++ b/ports/espressif/common-hal/alarm/touch/TouchAlarm.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H -#define MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H +#pragma once #include "py/obj.h" #include "common-hal/microcontroller/Pin.h" @@ -36,11 +35,9 @@ typedef struct { } alarm_touch_touchalarm_obj_t; mp_obj_t alarm_touch_touchalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void); +mp_obj_t alarm_touch_touchalarm_record_wake_alarm(void); void alarm_touch_touchalarm_prepare_for_deep_sleep(void); void alarm_touch_touchalarm_reset(void); void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms); bool alarm_touch_touchalarm_woke_this_cycle(void); - -#endif // MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H diff --git a/ports/espressif/common-hal/analogbufio/BufferedIn.c b/ports/espressif/common-hal/analogbufio/BufferedIn.c new file mode 100644 index 0000000000..f2ee8c19af --- /dev/null +++ b/ports/espressif/common-hal/analogbufio/BufferedIn.c @@ -0,0 +1,310 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2023 Milind Movasha + * + * SPDX-License-Identifier: BSD-3-Clause + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "common-hal/analogbufio/BufferedIn.h" +#include "shared-bindings/analogbufio/BufferedIn.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared/runtime/interrupt_char.h" +#include "py/runtime.h" +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "driver/adc.h" + +// #define DEBUG_ANALOGBUFIO + +#define NUM_SAMPLES_PER_INTERRUPT 256 +#define NUM_ADC_CHANNELS 1 +#define DMA_BUFFER_SIZE 1024 +#define ATTENUATION ADC_ATTEN_DB_0 +#define ADC_READ_TIMEOUT_MS 2000 + +#if defined(CONFIG_IDF_TARGET_ESP32) +#define ADC_RESULT_BYTE 2 +#define ADC_CONV_LIMIT_EN 1 // For ESP32, this should always be set to 1 +#elif defined(CONFIG_IDF_TARGET_ESP32S2) +#define ADC_RESULT_BYTE 2 +#define ADC_CONV_LIMIT_EN 0 +#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32H2) +#define ADC_RESULT_BYTE 4 +#define ADC_CONV_LIMIT_EN 0 +#elif defined(CONFIG_IDF_TARGET_ESP32S3) +#define ADC_RESULT_BYTE 4 +#define ADC_CONV_LIMIT_EN 0 +#endif + +static void start_dma(analogbufio_bufferedin_obj_t *self, adc_digi_convert_mode_t *convert_mode, adc_digi_output_format_t *output_format); +static void stop_dma(analogbufio_bufferedin_obj_t *self); + +void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *self, const mcu_pin_obj_t *pin, uint32_t sample_rate) { + self->pin = pin; + self->sample_rate = sample_rate; +} + +static void start_dma(analogbufio_bufferedin_obj_t *self, adc_digi_convert_mode_t *convert_mode, adc_digi_output_format_t *output_format) { + uint16_t adc1_chan_mask = 0; + uint16_t adc2_chan_mask = 0; + + const mcu_pin_obj_t *pin = self->pin; + uint32_t sample_rate = self->sample_rate; + + *output_format = ADC_DIGI_OUTPUT_FORMAT_TYPE1; + if (pin->adc_index == ADC_UNIT_1) { + *convert_mode = ADC_CONV_SINGLE_UNIT_1; + } else { + *convert_mode = ADC_CONV_SINGLE_UNIT_2; + } + + if (pin->adc_index == NO_ADC || pin->adc_channel == NO_ADC_CHANNEL) { + raise_ValueError_invalid_pin(); + } + + /* + * Chip version Conversion Mode Output Format Type + * ESP32 1 TYPE1 + * ESP32S2 1,2,BOTH,ALTER TYPE1, TYPE2 + * ESP32C3 ALTER TYPE2 + * ESP32S3 1,2,BOTH,ALTER TYPE2 + * ESP32H3 1,2,BOTH,ALTER TYPE2 + */ + + #if defined(CONFIG_IDF_TARGET_ESP32) + if (pin->adc_index != ADC_UNIT_1) { + /* + * ESP32 only supports ADC1 unit + * https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf + * Table 29-3 + */ + raise_ValueError_invalid_pin(); + } + #endif + + #if defined(CONFIG_IDF_TARGET_ESP32C3) + /* ESP32C3 only supports alter mode */ + *convert_mode = ADC_CONV_ALTER_UNIT; + #endif + + #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32H2) + *output_format = ADC_DIGI_OUTPUT_FORMAT_TYPE2; + #endif + + common_hal_mcu_pin_claim(pin); + + if (pin->adc_index == ADC_UNIT_1) { + adc1_chan_mask = 1 << pin->adc_channel; + } else { + adc2_chan_mask = 1 << pin->adc_channel; + } + + adc_digi_init_config_t adc_dma_config = { + .max_store_buf_size = DMA_BUFFER_SIZE, + .conv_num_each_intr = NUM_SAMPLES_PER_INTERRUPT, + .adc1_chan_mask = adc1_chan_mask, + .adc2_chan_mask = adc2_chan_mask, + }; + + #if defined(DEBUG_ANALOGBUFIO) + mp_printf(&mp_plat_print,"pin:%d, ADC channel:%d, ADC index:%d, adc1_chan_mask:0x%x, adc2_chan_mask:0x%x\n",pin->number,pin->adc_channel,pin->adc_index,adc1_chan_mask,adc2_chan_mask); + #endif // DEBUG_ANALOGBUFIO + esp_err_t err = adc_digi_initialize(&adc_dma_config); + if (ESP_OK != err) { + stop_dma(self); + common_hal_analogbufio_bufferedin_deinit(self); + mp_raise_ValueError_varg(translate("Unable to initialize ADC DMA controller, ErrorCode:%d"),err); + } + + adc_digi_configuration_t dig_cfg = { + .conv_limit_en = ADC_CONV_LIMIT_EN, + .conv_limit_num = 250, + .pattern_num = NUM_ADC_CHANNELS, + .sample_freq_hz = sample_rate, + .conv_mode = *convert_mode, + .format = *output_format, + }; + + #if defined(DEBUG_ANALOGBUFIO) + mp_printf(&mp_plat_print,"conversion_mode:%d, format:%d, conv_limit_en:%d, sample_rate:%d\n",*convert_mode,*output_format,ADC_CONV_LIMIT_EN,sample_rate); + #endif // DEBUG_ANALOGBUFIO + + adc_digi_pattern_config_t adc_pattern[NUM_ADC_CHANNELS] = {0}; + adc_pattern[0].atten = ATTENUATION; + adc_pattern[0].channel = pin->adc_channel; + if (pin->adc_index == ADC_UNIT_1) { + adc_pattern[0].unit = 0; + } else { + adc_pattern[0].unit = 1; + } + adc_pattern[0].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; + + dig_cfg.adc_pattern = adc_pattern; + #if defined(DEBUG_ANALOGBUFIO) + mp_printf(&mp_plat_print,"adc_pattern[0].channel:%d, adc_pattern[0].unit:%d, adc_pattern[0].atten:%d\n",adc_pattern[0].channel,adc_pattern[0].unit,adc_pattern[0].atten); + #endif // DEBUG_ANALOGBUFIO + + err = adc_digi_controller_configure(&dig_cfg); + if (ESP_OK != err) { + stop_dma(self); + common_hal_analogbufio_bufferedin_deinit(self); + mp_raise_ValueError_varg(translate("Unable to configure ADC DMA controller, ErrorCode:%d"),err); + } + err = adc_digi_start(); + if (ESP_OK != err) { + stop_dma(self); + common_hal_analogbufio_bufferedin_deinit(self); + mp_raise_ValueError_varg(translate("Unable to start ADC DMA controller, ErrorCode:%d"),err); + } +} + +static void stop_dma(analogbufio_bufferedin_obj_t *self) { + adc_digi_stop(); + adc_digi_deinitialize(); + // Release ADC Pin + reset_pin_number(self->pin->number); +} + +bool common_hal_analogbufio_bufferedin_deinited(analogbufio_bufferedin_obj_t *self) { + return self->pin == NULL; +} + +void common_hal_analogbufio_bufferedin_deinit(analogbufio_bufferedin_obj_t *self) { + if (common_hal_analogbufio_bufferedin_deinited(self)) { + return; + } + self->pin = NULL; +} + +static bool check_valid_data(const adc_digi_output_data_t *data, const mcu_pin_obj_t *pin, adc_digi_convert_mode_t convert_mode, adc_digi_output_format_t output_format) { + unsigned int unit = data->type2.unit; + if (output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE2) { + if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(unit)) { + return false; + } + if (pin->adc_channel != data->type2.channel) { + return false; + } + } else { + if (convert_mode == ADC_CONV_SINGLE_UNIT_1) { + unit = 0; + } else { + unit = 1; + } + #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) + if (data->type1.channel >= SOC_ADC_CHANNEL_NUM(unit)) { + return false; + } + if (pin->adc_channel != data->type1.channel) { + return false; + } + #endif + } + if (unit > 2) { + return false; + } + return true; +} + +uint32_t common_hal_analogbufio_bufferedin_readinto(analogbufio_bufferedin_obj_t *self, uint8_t *buffer, uint32_t len, uint8_t bytes_per_sample) { + uint8_t result[NUM_SAMPLES_PER_INTERRUPT] __attribute__ ((aligned(4))) = {0}; + uint32_t captured_samples = 0; + uint32_t captured_bytes = 0; + esp_err_t ret; + uint32_t ret_num = 0; + adc_digi_convert_mode_t convert_mode = ADC_CONV_SINGLE_UNIT_2; + adc_digi_output_format_t output_format = ADC_DIGI_OUTPUT_FORMAT_TYPE1; + + if (bytes_per_sample != 2) { + mp_raise_ValueError_varg(translate("%q must be array of type 'H'"), MP_QSTR_buffer); + } + + start_dma(self, &convert_mode, &output_format); + + #if defined(DEBUG_ANALOGBUFIO) + mp_printf(&mp_plat_print,"Required bytes: %d\n",len); + #endif // DEBUG_ANALOGBUFIO + + while (captured_bytes < len) { + ret_num = 0; + ret = adc_digi_read_bytes(result, NUM_SAMPLES_PER_INTERRUPT, &ret_num, ADC_READ_TIMEOUT_MS); + + if (ret == ESP_OK) { + for (uint32_t i = 0; i < ret_num; i += ADC_RESULT_BYTE) { + adc_digi_output_data_t *pResult = (adc_digi_output_data_t *)(void *)&result[i]; + if (check_valid_data(pResult, self->pin, convert_mode, output_format)) { + if (captured_bytes < len) { + uint16_t *pBuffer = (uint16_t *)(void *)&buffer[captured_bytes]; + if (output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE1) { + #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) + *pBuffer = pResult->type1.data; + #endif + } else { + *pBuffer = pResult->type2.data; + } + captured_bytes += sizeof(uint16_t); + captured_samples++; + } else { + stop_dma(self); + return captured_samples; + } + } else { + #if !defined(CONFIG_IDF_TARGET_ESP32C3) + // For all chips except for ESP32C3 we would receive samples only from one unit + // For ESP32C3 we may receive sample from alternating units and need to ignore them + #if defined(DEBUG_ANALOGBUFIO) + mp_printf(&mp_plat_print,"Invalid sample received: 0x%x\n",pResult->val); + #endif // DEBUG_ANALOGBUFIO + stop_dma(self); + return captured_samples; + #endif + } + } + } else if (ret == ESP_ERR_TIMEOUT) { + #if defined(DEBUG_ANALOGBUFIO) + mp_printf(&mp_plat_print,"ADC Timeout\n"); + #endif // DEBUG_ANALOGBUFIO + stop_dma(self); + return captured_samples; + } else { + #if defined(DEBUG_ANALOGBUFIO) + mp_printf(&mp_plat_print,"adc_digi_read_bytes failed error code:%d\n",ret); + #endif // DEBUG_ANALOGBUFIO + stop_dma(self); + return captured_samples; + } + } + + stop_dma(self); + #if defined(DEBUG_ANALOGBUFIO) + mp_printf(&mp_plat_print,"Captured bytes: %d\n",captured_bytes); + #endif // DEBUG_ANALOGBUFIO + return captured_samples; +} diff --git a/ports/espressif/common-hal/analogbufio/BufferedIn.h b/ports/espressif/common-hal/analogbufio/BufferedIn.h new file mode 100644 index 0000000000..909455ca06 --- /dev/null +++ b/ports/espressif/common-hal/analogbufio/BufferedIn.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2023 Milind Movasha + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32_COMMON_HAL_ANALOGBUFIO_BUFFEREDIN_H +#define MICROPY_INCLUDED_ESP32_COMMON_HAL_ANALOGBUFIO_BUFFEREDIN_H + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +// This is the analogbufio object +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; + uint32_t sample_rate; +} analogbufio_bufferedin_obj_t; + +#endif // MICROPY_INCLUDED_ESP32_COMMON_HAL_ANALOGBUFIO_BUFFEREDIN_H diff --git a/ports/espressif/common-hal/analogbufio/__init__.c b/ports/espressif/common-hal/analogbufio/__init__.c new file mode 100644 index 0000000000..b6c74b985b --- /dev/null +++ b/ports/espressif/common-hal/analogbufio/__init__.c @@ -0,0 +1 @@ +// No analogbufio module functions. diff --git a/ports/espressif/common-hal/audiobusio/__init__.c b/ports/espressif/common-hal/audiobusio/__init__.c index d6c3676d6a..e58aeefe88 100644 --- a/ports/espressif/common-hal/audiobusio/__init__.c +++ b/ports/espressif/common-hal/audiobusio/__init__.c @@ -80,11 +80,13 @@ void i2s_reset(void) { } } +#define I2S_WRITE_DELAY pdMS_TO_TICKS(1) + static void i2s_fill_buffer(i2s_t *self) { if (self->instance < 0 || self->instance >= I2S_NUM_MAX) { return; } -#define STACK_BUFFER_SIZE (512) +#define STACK_BUFFER_SIZE (4096) int16_t signed_samples[STACK_BUFFER_SIZE / sizeof(int16_t)]; if (!self->playing || self->paused || !self->sample || self->stopping) { @@ -92,7 +94,7 @@ static void i2s_fill_buffer(i2s_t *self) { size_t bytes_written = 0; do { - CHECK_ESP_RESULT(i2s_write(self->instance, signed_samples, sizeof(signed_samples), &bytes_written, 0)); + CHECK_ESP_RESULT(i2s_write(self->instance, signed_samples, sizeof(signed_samples), &bytes_written, I2S_WRITE_DELAY)); } while (bytes_written != 0); return; } @@ -120,9 +122,9 @@ static void i2s_fill_buffer(i2s_t *self) { size_t bytecount = self->sample_end - self->sample_data; if (self->samples_signed && self->channel_count == 2) { if (self->bytes_per_sample == 2) { - CHECK_ESP_RESULT(i2s_write(self->instance, self->sample_data, bytecount, &bytes_written, 0)); + CHECK_ESP_RESULT(i2s_write(self->instance, self->sample_data, bytecount, &bytes_written, I2S_WRITE_DELAY)); } else { - CHECK_ESP_RESULT(i2s_write_expand(self->instance, self->sample_data, bytecount, 8, 16, &bytes_written, 0)); + CHECK_ESP_RESULT(i2s_write_expand(self->instance, self->sample_data, bytecount, 8, 16, &bytes_written, I2S_WRITE_DELAY)); } } else { const size_t bytes_per_output_frame = 4; @@ -151,7 +153,7 @@ static void i2s_fill_buffer(i2s_t *self) { } } size_t expanded_bytes_written = 0; - CHECK_ESP_RESULT(i2s_write(self->instance, signed_samples, bytes_per_output_frame * framecount, &expanded_bytes_written, 0)); + CHECK_ESP_RESULT(i2s_write(self->instance, signed_samples, bytes_per_output_frame * framecount, &expanded_bytes_written, I2S_WRITE_DELAY)); assert(expanded_bytes_written % 4 == 0); bytes_written = expanded_bytes_written / bytes_per_output_frame * bytes_per_input_frame; } @@ -188,8 +190,8 @@ void port_i2s_allocate_init(i2s_t *self, bool left_justified) { .bits_per_sample = 16, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, .communication_format = left_justified ? I2S_COMM_FORMAT_STAND_I2S : I2S_COMM_FORMAT_STAND_I2S, - .dma_buf_count = 2, - .dma_buf_len = 128, // in _frames_, so 128 is 512 bytes per dma buf + .dma_buf_count = 3, + .dma_buf_len = 1024, // in _frames_, so 1024 is 4096 bytes per dma buf .use_apll = false, }; CHECK_ESP_RESULT(i2s_driver_install(self->instance, &i2s_config, I2S_QUEUE_SIZE, &i2s_queues[self->instance])); @@ -223,7 +225,11 @@ void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) { audiosample_reset_buffer(self->sample, false, 0); - CHECK_ESP_RESULT(i2s_set_sample_rates(self->instance, audiosample_sample_rate(sample))); + uint32_t sample_rate = audiosample_sample_rate(sample); + if (sample_rate != self->i2s_config.sample_rate) { + CHECK_ESP_RESULT(i2s_set_sample_rates(self->instance, audiosample_sample_rate(sample))); + self->i2s_config.sample_rate = sample_rate; + } background_callback_add(&self->callback, i2s_callback_fun, self); } diff --git a/ports/espressif/common-hal/busio/SPI.c b/ports/espressif/common-hal/busio/SPI.c index 0b894fa215..da9170a5b0 100644 --- a/ports/espressif/common-hal/busio/SPI.c +++ b/ports/espressif/common-hal/busio/SPI.c @@ -33,6 +33,7 @@ #include "driver/spi_common_internal.h" #define SPI_MAX_DMA_BITS (SPI_MAX_DMA_LEN * 8) +#define MAX_SPI_TRANSACTIONS 10 static bool spi_never_reset[SOC_SPI_PERIPH_NUM]; static spi_device_handle_t spi_handle[SOC_SPI_PERIPH_NUM]; @@ -59,7 +60,7 @@ static void set_spi_config(busio_spi_obj_t *self, .clock_speed_hz = baudrate, .mode = phase | (polarity << 1), .spics_io_num = -1, // No CS pin - .queue_size = 1, + .queue_size = MAX_SPI_TRANSACTIONS, .pre_cb = NULL }; esp_err_t result = spi_bus_add_device(self->host_id, &device_config, &spi_handle[self->host_id]); @@ -213,47 +214,61 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, mp_raise_ValueError(translate("No MISO Pin")); } - spi_transaction_t transaction = { 0 }; + spi_transaction_t transactions[MAX_SPI_TRANSACTIONS]; // Round to nearest whole set of bits int bits_to_send = len * 8 / self->bits * self->bits; if (len <= 4) { + memset(&transactions[0], 0, sizeof(spi_transaction_t)); if (data_out != NULL) { - memcpy(&transaction.tx_data, data_out, len); + memcpy(&transactions[0].tx_data, data_out, len); } - transaction.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA; - transaction.length = bits_to_send; - spi_device_transmit(spi_handle[self->host_id], &transaction); + transactions[0].flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA; + transactions[0].length = bits_to_send; + spi_device_transmit(spi_handle[self->host_id], &transactions[0]); if (data_in != NULL) { - memcpy(data_in, &transaction.rx_data, len); + memcpy(data_in, &transactions[0].rx_data, len); } } else { int offset = 0; int bits_remaining = bits_to_send; + int cur_trans = 0; while (bits_remaining && !mp_hal_is_interrupted()) { - memset(&transaction, 0, sizeof(transaction)); - transaction.length = - bits_remaining > SPI_MAX_DMA_BITS ? SPI_MAX_DMA_BITS : bits_remaining; + cur_trans = 0; + while (bits_remaining && (cur_trans != MAX_SPI_TRANSACTIONS)) { + memset(&transactions[cur_trans], 0, sizeof(spi_transaction_t)); - if (data_out != NULL) { - transaction.tx_buffer = data_out + offset; - } - if (data_in != NULL) { - transaction.rx_buffer = data_in + offset; + transactions[cur_trans].length = + bits_remaining > SPI_MAX_DMA_BITS ? SPI_MAX_DMA_BITS : bits_remaining; + + if (data_out != NULL) { + transactions[cur_trans].tx_buffer = data_out + offset; + } + if (data_in != NULL) { + transactions[cur_trans].rx_buffer = data_in + offset; + } + + bits_remaining -= transactions[cur_trans].length; + + // doesn't need ceil(); loop ends when bits_remaining is 0 + offset += transactions[cur_trans].length / 8; + cur_trans++; } - spi_device_transmit(spi_handle[self->host_id], &transaction); - bits_remaining -= transaction.length; + for (int i = 0; i < cur_trans; i++) { + spi_device_queue_trans(spi_handle[self->host_id], &transactions[i], portMAX_DELAY); + } - // doesn't need ceil(); loop ends when bits_remaining is 0 - offset += transaction.length / 8; - - RUN_BACKGROUND_TASKS; + spi_transaction_t *rtrans; + for (int x = 0; x < cur_trans; x++) { + RUN_BACKGROUND_TASKS; + spi_device_get_trans_result(spi_handle[self->host_id], &rtrans, portMAX_DELAY); + } } } return true; diff --git a/ports/espressif/common-hal/busio/UART.c b/ports/espressif/common-hal/busio/UART.c index cdaf25250f..c13bdedac0 100644 --- a/ports/espressif/common-hal/busio/UART.c +++ b/ports/espressif/common-hal/busio/UART.c @@ -49,8 +49,9 @@ static void uart_event_task(void *param) { while (true) { if (xQueueReceive(self->event_queue, &event, portMAX_DELAY)) { switch (event.type) { + case UART_BREAK: case UART_PATTERN_DET: - // When the console uart receives CTRL+C, wake the main task and schedule a keyboard interrupt + // When the console uart receives CTRL+C or BREAK, wake the main task and schedule a keyboard interrupt if (self->is_console) { port_wake_main_task(); if (mp_interrupt_char == CHAR_CTRL_C) { @@ -111,9 +112,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uart_config_t uart_config = {0}; bool have_rs485_dir = rs485_dir != NULL; - if (!have_tx && !have_rx) { - mp_raise_ValueError(translate("tx and rx cannot both be None")); - } + + // shared-bindings checks that TX and RX are not both None, so we don't need to check here. // Filter for sane settings for RS485 if (have_rs485_dir) { diff --git a/ports/espressif/common-hal/digitalio/DigitalInOut.c b/ports/espressif/common-hal/digitalio/DigitalInOut.c index a3e8f41147..61671dadb9 100644 --- a/ports/espressif/common-hal/digitalio/DigitalInOut.c +++ b/ports/espressif/common-hal/digitalio/DigitalInOut.c @@ -32,6 +32,20 @@ #include "components/hal/include/hal/gpio_hal.h" +STATIC bool _pin_is_input(uint8_t pin_number) { + const uint32_t iomux = READ_PERI_REG(GPIO_PIN_MUX_REG[pin_number]); + return (iomux & FUN_IE) != 0; +} + +void digitalio_digitalinout_preserve_for_deep_sleep(size_t n_dios, digitalio_digitalinout_obj_t *preserve_dios[]) { + // Mark the pin states of the given DigitalInOuts for preservation during deep sleep + for (size_t i = 0; i < n_dios; i++) { + if (!common_hal_digitalio_digitalinout_deinited(preserve_dios[i])) { + preserve_pin_number(preserve_dios[i]->pin->number); + } + } +} + void common_hal_digitalio_digitalinout_never_reset( digitalio_digitalinout_obj_t *self) { never_reset_pin_number(self->pin->number); @@ -68,10 +82,11 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self self->pin = NULL; } -void common_hal_digitalio_digitalinout_switch_to_input( +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { common_hal_digitalio_digitalinout_set_pull(self, pull); gpio_set_direction(self->pin->number, GPIO_MODE_INPUT); + return DIGITALINOUT_OK; } digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( @@ -83,8 +98,7 @@ digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( digitalio_digitalinout_obj_t *self) { - uint32_t iomux = READ_PERI_REG(GPIO_PIN_MUX_REG[self->pin->number]); - if ((iomux & FUN_IE) != 0) { + if (_pin_is_input(self->pin->number)) { return DIRECTION_INPUT; } return DIRECTION_OUTPUT; @@ -127,7 +141,7 @@ digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( return DRIVE_MODE_PUSH_PULL; } -void common_hal_digitalio_digitalinout_set_pull( +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { gpio_num_t number = self->pin->number; gpio_pullup_dis(number); @@ -137,6 +151,7 @@ void common_hal_digitalio_digitalinout_set_pull( } else if (pull == PULL_DOWN) { gpio_pulldown_en(number); } + return DIGITALINOUT_OK; } digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( diff --git a/ports/espressif/common-hal/digitalio/DigitalInOut.h b/ports/espressif/common-hal/digitalio/DigitalInOut.h index 2d42e79809..793d2a0986 100644 --- a/ports/espressif/common-hal/digitalio/DigitalInOut.h +++ b/ports/espressif/common-hal/digitalio/DigitalInOut.h @@ -36,4 +36,6 @@ typedef struct { bool output_value; } digitalio_digitalinout_obj_t; +extern void digitalio_digitalinout_preserve_for_deep_sleep(size_t n_dios, digitalio_digitalinout_obj_t *preserve_dios[]); + #endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_DIGITALIO_DIGITALINOUT_H diff --git a/ports/espressif/common-hal/dualbank/__init__.c b/ports/espressif/common-hal/dualbank/__init__.c index 91c7981dd9..9e3fb38627 100644 --- a/ports/espressif/common-hal/dualbank/__init__.c +++ b/ports/espressif/common-hal/dualbank/__init__.c @@ -57,14 +57,13 @@ void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t o if (update_partition == NULL) { update_partition = esp_ota_get_next_update_partition(NULL); + assert(update_partition != NULL); ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)", running->type, running->subtype, running->address); ESP_LOGI(TAG, "Writing partition type %d subtype %d (offset 0x%08x)\n", update_partition->type, update_partition->subtype, update_partition->address); - - assert(update_partition != NULL); } if (update_handle == 0) { @@ -86,14 +85,14 @@ void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t o // check new version with running version if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0) { ESP_LOGW(TAG, "New version is the same as running version."); - task_fatal_error(); + mp_raise_RuntimeError(translate("Firmware is duplicate")); } // check new version with last invalid partition if (last_invalid != NULL) { if (memcmp(new_app_info.version, invalid_app_info.version, sizeof(new_app_info.version)) == 0) { ESP_LOGW(TAG, "New version is the same as invalid version."); - task_fatal_error(); + mp_raise_RuntimeError(translate("Firmware is invalid")); } } @@ -104,7 +103,7 @@ void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t o } } else { ESP_LOGE(TAG, "received package is not fit len"); - task_fatal_error(); + mp_raise_RuntimeError(translate("Firmware is too big")); } } @@ -128,7 +127,7 @@ void common_hal_dualbank_switch(void) { if (err != ESP_OK) { if (err == ESP_ERR_OTA_VALIDATE_FAILED) { ESP_LOGE(TAG, "Image validation failed, image is corrupted"); - mp_raise_RuntimeError(translate("Firmware image is invalid")); + mp_raise_RuntimeError(translate("Firmware is invalid")); } ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err)); task_fatal_error(); diff --git a/ports/espressif/common-hal/espcamera/Camera.c b/ports/espressif/common-hal/espcamera/Camera.c new file mode 100644 index 0000000000..e3e5ef49f9 --- /dev/null +++ b/ports/espressif/common-hal/espcamera/Camera.c @@ -0,0 +1,317 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "bindings/espcamera/Camera.h" +#include "bindings/espidf/__init__.h" +#include "common-hal/espcamera/Camera.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "common-hal/microcontroller/Pin.h" + +#include "esp32-camera/driver/private_include/cam_hal.h" + +#if !CONFIG_SPIRAM +#error espcamera only works on boards configured with spiram, disable it in mpconfigboard.mk +#endif + +static void i2c_lock(espcamera_camera_obj_t *self) { + if (common_hal_busio_i2c_deinited(self->i2c)) { + raise_deinited_error(); + } + if (!common_hal_busio_i2c_try_lock(self->i2c)) { + mp_raise_OSError(MP_EWOULDBLOCK); + } +} + +static void i2c_unlock(espcamera_camera_obj_t *self) { + common_hal_busio_i2c_unlock(self->i2c); +} + +static void maybe_claim_pin(const mcu_pin_obj_t *pin) { + if (pin) { + claim_pin(pin); + } +} + +void common_hal_espcamera_camera_construct( + espcamera_camera_obj_t *self, + uint8_t data_pins[8], + const mcu_pin_obj_t *external_clock_pin, + const mcu_pin_obj_t *pixel_clock_pin, + const mcu_pin_obj_t *vsync_pin, + const mcu_pin_obj_t *href_pin, + const mcu_pin_obj_t *powerdown_pin, + const mcu_pin_obj_t *reset_pin, + busio_i2c_obj_t *i2c, + mp_int_t external_clock_frequency, + pixformat_t pixel_format, + framesize_t frame_size, + mp_int_t jpeg_quality, + mp_int_t framebuffer_count, + camera_grab_mode_t grab_mode) { + + if (common_hal_espidf_get_reserved_psram() == 0) { + mp_raise_msg(&mp_type_MemoryError, translate( + "espcamera.Camera requires reserved PSRAM to be configured. " + "See the documentation for instructions.")); + } + for (int i = 0; i < 8; i++) { + claim_pin_number(data_pins[i]); + } + maybe_claim_pin(external_clock_pin); + claim_pin(pixel_clock_pin); + claim_pin(vsync_pin); + claim_pin(href_pin); + maybe_claim_pin(powerdown_pin); + maybe_claim_pin(reset_pin); + + if (external_clock_pin) { + common_hal_pwmio_pwmout_construct(&self->pwm, external_clock_pin, 1, external_clock_frequency, true); + self->camera_config.ledc_timer = self->pwm.tim_handle.timer_num; + self->camera_config.ledc_channel = self->pwm.chan_handle.channel; + } else { + self->camera_config.ledc_channel = 0xff; // NO_CAMERA_LEDC_CHANNEL + } + + self->i2c = i2c; + + self->camera_config.pin_pwdn = common_hal_mcu_pin_number(powerdown_pin); + self->camera_config.pin_reset = common_hal_mcu_pin_number(reset_pin); + self->camera_config.pin_xclk = common_hal_mcu_pin_number(external_clock_pin); + + self->camera_config.pin_sccb_sda = NO_PIN; + self->camera_config.pin_sccb_scl = NO_PIN; + /* sccb i2c port set below */ + + self->camera_config.pin_d7 = data_pins[7]; + self->camera_config.pin_d6 = data_pins[6]; + self->camera_config.pin_d5 = data_pins[5]; + self->camera_config.pin_d4 = data_pins[4]; + self->camera_config.pin_d3 = data_pins[3]; + self->camera_config.pin_d2 = data_pins[2]; + self->camera_config.pin_d1 = data_pins[1]; + self->camera_config.pin_d0 = data_pins[0]; + + self->camera_config.pin_vsync = common_hal_mcu_pin_number(vsync_pin); + self->camera_config.pin_href = common_hal_mcu_pin_number(href_pin); + self->camera_config.pin_pclk = common_hal_mcu_pin_number(pixel_clock_pin); + + self->camera_config.xclk_freq_hz = external_clock_frequency; + + self->camera_config.pixel_format = pixel_format; + self->camera_config.frame_size = frame_size; + self->camera_config.jpeg_quality = jpeg_quality; + self->camera_config.fb_count = framebuffer_count; + self->camera_config.grab_mode = grab_mode; + + self->camera_config.sccb_i2c_port = i2c->i2c_num; + + i2c_lock(self); + esp_err_t result = esp_camera_init(&self->camera_config); + i2c_unlock(self); + + CHECK_ESP_RESULT(result); +} + +extern void common_hal_espcamera_camera_deinit(espcamera_camera_obj_t *self) { + if (common_hal_espcamera_camera_deinited(self)) { + return; + } + + common_hal_pwmio_pwmout_deinit(&self->pwm); + + reset_pin_number(self->camera_config.pin_pwdn); + reset_pin_number(self->camera_config.pin_reset); + reset_pin_number(self->camera_config.pin_xclk); + + reset_pin_number(self->camera_config.pin_d7); + reset_pin_number(self->camera_config.pin_d6); + reset_pin_number(self->camera_config.pin_d5); + reset_pin_number(self->camera_config.pin_d4); + reset_pin_number(self->camera_config.pin_d3); + reset_pin_number(self->camera_config.pin_d2); + reset_pin_number(self->camera_config.pin_d1); + reset_pin_number(self->camera_config.pin_d0); + + esp_camera_deinit(); + + self->camera_config.xclk_freq_hz = 0; +} + +bool common_hal_espcamera_camera_deinited(espcamera_camera_obj_t *self) { + return !self->camera_config.xclk_freq_hz; +} + +bool common_hal_espcamera_camera_available(espcamera_camera_obj_t *self) { + return esp_camera_fb_available(); +} + +camera_fb_t *common_hal_espcamera_camera_take(espcamera_camera_obj_t *self, int timeout_ms) { + if (self->buffer_to_return) { + esp_camera_fb_return(self->buffer_to_return); + self->buffer_to_return = NULL; + } + return self->buffer_to_return = esp_camera_fb_get_timeout(timeout_ms); +} + +#define SENSOR_GETSET(type, name, field_name, setter_function_name) \ + SENSOR_GET(type, name, field_name, setter_function_name) \ + SENSOR_SET(type, name, setter_function_name) + +#define SENSOR_STATUS_GETSET(type, name, status_field_name, setter_function_name) \ + SENSOR_GETSET(type, name, status.status_field_name, setter_function_name) + +#define SENSOR_GET(type, name, status_field_name, setter_function_name) \ + type common_hal_espcamera_camera_get_##name(espcamera_camera_obj_t * self) { \ + i2c_lock(self); \ + sensor_t *sensor = esp_camera_sensor_get(); \ + i2c_unlock(self); \ + if (!sensor->setter_function_name) { \ + mp_raise_AttributeError(translate("no such attribute")); \ + } \ + return sensor->status_field_name; \ + } + +#define SENSOR_SET(type, name, setter_function_name) \ + void common_hal_espcamera_camera_set_##name(espcamera_camera_obj_t * self, type value) { \ + i2c_lock(self); \ + sensor_t *sensor = esp_camera_sensor_get(); \ + i2c_unlock(self); \ + if (!sensor->setter_function_name) { \ + mp_raise_AttributeError(translate("no such attribute")); \ + } \ + if (sensor->setter_function_name(sensor, value) < 0) { \ + mp_raise_ValueError(translate("invalid setting")); \ + } \ + } + +pixformat_t common_hal_espcamera_camera_get_pixel_format(espcamera_camera_obj_t *self) { + return self->camera_config.pixel_format; +} + +framesize_t common_hal_espcamera_camera_get_frame_size(espcamera_camera_obj_t *self) { + return self->camera_config.frame_size; +} + +void common_hal_espcamera_camera_reconfigure(espcamera_camera_obj_t *self, framesize_t frame_size, pixformat_t pixel_format, camera_grab_mode_t grab_mode, mp_int_t framebuffer_count) { + sensor_t *sensor = esp_camera_sensor_get(); + camera_sensor_info_t *sensor_info = esp_camera_sensor_get_info(&sensor->id); + + if (PIXFORMAT_JPEG == pixel_format && (!sensor_info->support_jpeg)) { + raise_esp_error(ESP_ERR_NOT_SUPPORTED); + } + + if (frame_size > sensor_info->max_size) { + frame_size = sensor_info->max_size; + } + + i2c_lock(self); + cam_deinit(); + self->camera_config.pixel_format = pixel_format; + self->camera_config.frame_size = frame_size; + self->camera_config.grab_mode = grab_mode; + self->camera_config.fb_count = framebuffer_count; + sensor->set_pixformat(sensor, self->camera_config.pixel_format); + sensor->set_framesize(sensor, self->camera_config.frame_size); + cam_init(&self->camera_config); + cam_config(&self->camera_config, frame_size, sensor_info->pid); + i2c_unlock(self); + cam_start(); +} + +SENSOR_STATUS_GETSET(int, contrast, contrast, set_contrast); +SENSOR_STATUS_GETSET(int, brightness, brightness, set_brightness); +SENSOR_STATUS_GETSET(int, saturation, saturation, set_saturation); +SENSOR_STATUS_GETSET(int, sharpness, sharpness, set_sharpness); +SENSOR_STATUS_GETSET(int, denoise, denoise, set_denoise); +SENSOR_STATUS_GETSET(gainceiling_t, gainceiling, gainceiling, set_gainceiling); +SENSOR_STATUS_GETSET(int, quality, quality, set_quality); +SENSOR_STATUS_GETSET(bool, colorbar, colorbar, set_colorbar); +SENSOR_STATUS_GETSET(bool, whitebal, awb, set_whitebal); +SENSOR_STATUS_GETSET(bool, gain_ctrl, agc, set_gain_ctrl); +SENSOR_STATUS_GETSET(bool, exposure_ctrl, aec, set_exposure_ctrl); +SENSOR_STATUS_GETSET(bool, hmirror, hmirror, set_hmirror); +SENSOR_STATUS_GETSET(bool, vflip, vflip, set_vflip); +SENSOR_STATUS_GETSET(bool, aec2, aec2, set_aec2); +SENSOR_STATUS_GETSET(bool, awb_gain, awb_gain, set_awb_gain); +SENSOR_STATUS_GETSET(int, agc_gain, agc_gain, set_agc_gain); +SENSOR_STATUS_GETSET(int, aec_value, aec_value, set_aec_value); +SENSOR_STATUS_GETSET(int, special_effect, special_effect, set_special_effect); +SENSOR_STATUS_GETSET(int, wb_mode, wb_mode, set_wb_mode); +SENSOR_STATUS_GETSET(int, ae_level, ae_level, set_ae_level); +SENSOR_STATUS_GETSET(bool, dcw, dcw, set_dcw); +SENSOR_STATUS_GETSET(bool, bpc, bpc, set_bpc); +SENSOR_STATUS_GETSET(bool, wpc, wpc, set_wpc); +SENSOR_STATUS_GETSET(bool, raw_gma, raw_gma, set_raw_gma); +SENSOR_STATUS_GETSET(bool, lenc, lenc, set_lenc); + +const char *common_hal_espcamera_camera_get_sensor_name(espcamera_camera_obj_t *self) { + sensor_t *sensor = esp_camera_sensor_get(); + camera_sensor_info_t *sensor_info = esp_camera_sensor_get_info(&sensor->id); + return sensor_info->name; +} + +const bool common_hal_espcamera_camera_get_supports_jpeg(espcamera_camera_obj_t *self) { + sensor_t *sensor = esp_camera_sensor_get(); + camera_sensor_info_t *sensor_info = esp_camera_sensor_get_info(&sensor->id); + return sensor_info->support_jpeg; +} + +const framesize_t common_hal_espcamera_camera_get_max_frame_size(espcamera_camera_obj_t *self) { + sensor_t *sensor = esp_camera_sensor_get(); + camera_sensor_info_t *sensor_info = esp_camera_sensor_get_info(&sensor->id); + return sensor_info->max_size; +} + +const int common_hal_espcamera_camera_get_address(espcamera_camera_obj_t *self) { + sensor_t *sensor = esp_camera_sensor_get(); + camera_sensor_info_t *sensor_info = esp_camera_sensor_get_info(&sensor->id); + return sensor_info->sccb_addr; +} + +const int common_hal_espcamera_camera_get_width(espcamera_camera_obj_t *self) { + sensor_t *sensor = esp_camera_sensor_get(); + framesize_t framesize = sensor->status.framesize; + return resolution[framesize].width; +} + +const int common_hal_espcamera_camera_get_height(espcamera_camera_obj_t *self) { + sensor_t *sensor = esp_camera_sensor_get(); + framesize_t framesize = sensor->status.framesize; + return resolution[framesize].height; +} + +const camera_grab_mode_t common_hal_espcamera_camera_get_grab_mode(espcamera_camera_obj_t *self) { + return self->camera_config.grab_mode; +} + +const int common_hal_espcamera_camera_get_framebuffer_count(espcamera_camera_obj_t *self) { + return self->camera_config.fb_count; +} diff --git a/ports/espressif/common-hal/espcamera/Camera.h b/ports/espressif/common-hal/espcamera/Camera.h new file mode 100644 index 0000000000..007686a523 --- /dev/null +++ b/ports/espressif/common-hal/espcamera/Camera.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/obj.h" +#include "esp_camera.h" +#include "shared-bindings/pwmio/PWMOut.h" +#include "common-hal/busio/I2C.h" + +typedef struct espcamera_camera_obj { + mp_obj_base_t base; + camera_config_t camera_config; + camera_fb_t *buffer_to_return; + pwmio_pwmout_obj_t pwm; + busio_i2c_obj_t *i2c; +} espcamera_obj_t; diff --git a/ports/espressif/common-hal/espidf/__init__.c b/ports/espressif/common-hal/espidf/__init__.c new file mode 100644 index 0000000000..183ebb3817 --- /dev/null +++ b/ports/espressif/common-hal/espidf/__init__.c @@ -0,0 +1,194 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "bindings/espidf/__init__.h" +#include "supervisor/shared/translate/translate.h" +#include "supervisor/memory.h" +#include "py/runtime.h" + +#include "esp_log.h" +#define TAG "espidf" + +#ifdef CONFIG_SPIRAM +#include "esp32/spiram.h" +#include "esp_heap_caps.h" +#include "esp_heap_caps_init.h" +#include "soc/soc.h" +#ifdef CONFIG_IDF_TARGET_ESP32 +#include "esp32/himem.h" +#else +#define esp_himem_reserved_area_size() (0) +#endif +bool ok_to_reserve_psram = true; +size_t reserved_psram = DEFAULT_RESERVED_PSRAM; +#endif + +static size_t psram_size_usable(void) { + #ifdef CONFIG_SPIRAM + /* PSRAM chip may be larger than the size we can map into address space */ + size_t s = MIN(esp_spiram_get_size(), SOC_EXTRAM_DATA_SIZE); + return s - esp_himem_reserved_area_size(); + #else + return 0; + #endif +} + +bool common_hal_espidf_set_reserved_psram(size_t amount) { + #ifdef CONFIG_SPIRAM + if (!esp_spiram_is_initialized()) { + return false; + } + if (!ok_to_reserve_psram) { + return false; + } + if (amount > psram_size_usable()) { + return false; + } + reserved_psram = amount; + return true; + #else + return false; + #endif +} + +supervisor_allocation *psram_for_idf; + +void common_hal_espidf_reserve_psram(void) { + #ifdef CONFIG_SPIRAM + if (!psram_for_idf) { + ESP_LOGI(TAG, "Reserving %d bytes of psram", reserved_psram); + if (reserved_psram == 0) { + return; + } + psram_for_idf = allocate_memory(reserved_psram, true, false); + if (psram_for_idf) { + intptr_t psram_for_idf_start = (intptr_t)psram_for_idf->ptr; + intptr_t psram_for_idf_end = psram_for_idf_start + reserved_psram; + ESP_LOGI(TAG, "Reserved %x..%x", psram_for_idf_start, psram_for_idf_end); + heap_caps_add_region(psram_for_idf_start, psram_for_idf_end); + } else { + ESP_LOGE(TAG, "supervisor allocation failed"); + } + } + #endif +} + +size_t common_hal_espidf_get_reserved_psram(void) { + #ifdef CONFIG_SPIRAM + return reserved_psram; + #else + return 0; + #endif +} + +size_t common_hal_espidf_get_total_psram(void) { + return psram_size_usable(); +} + +intptr_t common_hal_espidf_get_psram_start(void) { + #ifdef CONFIG_SPIRAM + if (esp_spiram_is_initialized()) { + #ifdef CONFIG_IDF_TARGET_ESP32 + return SOC_EXTRAM_DATA_LOW; + #else + return SOC_EXTRAM_DATA_HIGH - psram_size_usable(); + #endif + } + #endif + return 0; +} + +intptr_t common_hal_espidf_get_psram_end(void) { + #ifdef CONFIG_SPIRAM + if (esp_spiram_is_initialized()) { + return common_hal_espidf_get_psram_start() + psram_size_usable(); + } + #endif + return 0; +} + +void raise_esp_error(esp_err_t err) { + const compressed_string_t *msg = NULL; + const mp_obj_type_t *exception_type = &mp_type_espidf_IDFError; + switch (err) { + case ESP_FAIL: + msg = translate("Generic Failure"); + break; + case ESP_ERR_NO_MEM: + exception_type = &mp_type_espidf_MemoryError; + msg = translate("Out of memory"); + break; + case ESP_ERR_INVALID_ARG: + msg = translate("Invalid argument"); + break; + case ESP_ERR_INVALID_STATE: + msg = translate("Invalid state"); + break; + case ESP_ERR_INVALID_SIZE: + msg = translate("Invalid size"); + break; + case ESP_ERR_NOT_FOUND: + msg = translate("Requested resource not found"); + break; + case ESP_ERR_NOT_SUPPORTED: + msg = translate("Operation or feature not supported"); + break; + case ESP_ERR_TIMEOUT: + msg = translate("Operation timed out"); + break; + case ESP_ERR_INVALID_RESPONSE: + msg = translate("Received response was invalid"); + break; + case ESP_ERR_INVALID_CRC: + msg = translate("CRC or checksum was invalid"); + break; + case ESP_ERR_INVALID_VERSION: + msg = translate("Version was invalid"); + break; + case ESP_ERR_INVALID_MAC: + msg = translate("MAC address was invalid"); + break; + } + if (msg) { + mp_raise_msg(exception_type, msg); + } + + const char *group = "ESP-IDF"; + + // tests must be in descending order + MP_STATIC_ASSERT(ESP_ERR_FLASH_BASE > ESP_ERR_MESH_BASE); + MP_STATIC_ASSERT(ESP_ERR_MESH_BASE > ESP_ERR_WIFI_BASE); + if (err >= ESP_ERR_FLASH_BASE) { + group = "Flash"; + } else if (err >= ESP_ERR_MESH_BASE) { + group = "Mesh"; + } else if (err >= ESP_ERR_WIFI_BASE) { + group = "WiFi"; + } + mp_raise_msg_varg(exception_type, translate("%s error 0x%x"), group, err); +} + +MP_REGISTER_MODULE(MP_QSTR_espidf, espidf_module, CIRCUITPY_ESPIDF); diff --git a/ports/espressif/common-hal/espidf/__init__.h b/ports/espressif/common-hal/espidf/__init__.h new file mode 100644 index 0000000000..0d168b105c --- /dev/null +++ b/ports/espressif/common-hal/espidf/__init__.h @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "bindings/espidf/__init__.h" diff --git a/ports/espressif/common-hal/espulp/ULP.c b/ports/espressif/common-hal/espulp/ULP.c new file mode 100644 index 0000000000..3350f6d45c --- /dev/null +++ b/ports/espressif/common-hal/espulp/ULP.c @@ -0,0 +1,165 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "bindings/espulp/__init__.h" +#include "bindings/espulp/ULP.h" + +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" + +#if defined(CONFIG_IDF_TARGET_ESP32) +#include "esp32/ulp.h" +#define ULP_COPROC_RESERVE_MEM (CONFIG_ESP32_ULP_COPROC_RESERVE_MEM) +#elif defined(CONFIG_IDF_TARGET_ESP32S2) +#include "esp32s2/ulp.h" +#include "esp32s2/ulp_riscv.h" +#define ULP_COPROC_RESERVE_MEM (CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM) +#elif defined(CONFIG_IDF_TARGET_ESP32S3) +#include "esp32s3/ulp.h" +#include "esp32s3/ulp_riscv.h" +#define ULP_COPROC_RESERVE_MEM (CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM) +#endif + +// To-do idf v5.0: remove following include +#include "soc/rtc_cntl_reg.h" + +STATIC bool ulp_used = false; +STATIC uint32_t pins_used = 0; + +void espulp_reset(void) { + // NOTE: This *doesn't* disable the ULP. It'll keep running even when CircuitPython isn't. + ulp_used = false; +} + +void common_hal_espulp_ulp_run(espulp_ulp_obj_t *self, uint32_t *program, size_t length, uint32_t pin_mask) { + if (length > ULP_COPROC_RESERVE_MEM) { + mp_raise_ValueError(translate("Program too long")); + } + + if ( + #ifdef CONFIG_IDF_TARGET_ESP32 + GET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN) + #else + GET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN) + #endif + ) { + mp_raise_RuntimeError(translate("Already running")); + } + + if (pin_mask >= (1 << 22)) { + raise_ValueError_invalid_pin(); + } + + for (uint8_t i = 0; i < 32; i++) { + if ((pin_mask & (1 << i)) != 0 && !pin_number_is_free(i)) { + mp_raise_ValueError_varg(translate("%q in use"), MP_QSTR_Pin); + } + } + + for (uint8_t i = 0; i < 32; i++) { + if ((pin_mask & (1 << i)) != 0) { + claim_pin_number(i); + never_reset_pin_number(i); + } + } + pins_used = pin_mask; + + ulp_set_wakeup_period(0, 20000); + + switch (self->arch) { + case FSM: + ulp_load_binary(0, (const uint8_t *)program, length); + ulp_run(0); + break; + case RISCV: + #ifndef CONFIG_IDF_TARGET_ESP32 + ulp_riscv_load_binary((const uint8_t *)program, length); + ulp_riscv_run(); + break; + #endif + default: + mp_raise_NotImplementedError(NULL); + break; + } +} + +void common_hal_espulp_ulp_halt(espulp_ulp_obj_t *self) { + #ifdef CONFIG_IDF_TARGET_ESP32 + mp_raise_NotImplementedError(NULL); + #else + // To-do idf v5.0: use following functions + // ulp_riscv_timer_stop(); + // ulp_riscv_halt(); + + // stop the ulp timer so that it doesn't restart the cpu + CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN); + + // suspends the ulp operation + SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_DONE); + + // resets the processor + SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN); + #endif + + // Release pins we were using. + for (uint8_t i = 0; i < 32; i++) { + if ((pins_used & (1 << i)) != 0) { + reset_pin_number(i); + } + } +} + +void common_hal_espulp_ulp_construct(espulp_ulp_obj_t *self, espulp_architecture_t arch) { + // Use a static variable to track ULP in use so that subsequent code runs can + // use a running ULP. This is only to prevent multiple portions of user code + // from using the ULP concurrently. + if (ulp_used) { + mp_raise_ValueError_varg(translate("%q in use"), MP_QSTR_ULP); + } + + #ifdef CONFIG_IDF_TARGET_ESP32 + if (self->arch == RISCV) { + mp_raise_NotImplementedError(NULL); + } + #endif + + self->arch = arch; + self->inited = true; +} + +bool common_hal_espulp_ulp_deinited(espulp_ulp_obj_t *self) { + return !self->inited; +} + +void common_hal_espulp_ulp_deinit(espulp_ulp_obj_t *self) { + if (common_hal_espulp_ulp_deinited(self)) { + return; + } + common_hal_espulp_ulp_halt(self); + self->inited = false; + ulp_used = false; +} diff --git a/ports/espressif/common-hal/espulp/ULP.h b/ports/espressif/common-hal/espulp/ULP.h new file mode 100644 index 0000000000..360dd0c9fd --- /dev/null +++ b/ports/espressif/common-hal/espulp/ULP.h @@ -0,0 +1,36 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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. + */ + +#pragma once + +#include "py/obj.h" +#include "bindings/espulp/Architecture.h" + +typedef struct { + mp_obj_base_t base; + espulp_architecture_t arch; + bool inited; +} espulp_ulp_obj_t; diff --git a/ports/espressif/common-hal/espulp/ULPAlarm.c b/ports/espressif/common-hal/espulp/ULPAlarm.c new file mode 100644 index 0000000000..3717d2ab71 --- /dev/null +++ b/ports/espressif/common-hal/espulp/ULPAlarm.c @@ -0,0 +1,130 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "bindings/espulp/ULPAlarm.h" + +#include "common-hal/alarm/__init__.h" +#include "supervisor/port.h" + +#include "driver/rtc_cntl.h" +#include "soc/rtc_cntl_reg.h" + +#include "esp_sleep.h" + +static volatile bool woke_up = false; +static bool alarm_set = false; + +void common_hal_espulp_ulpalarm_construct(espulp_ulpalarm_obj_t *self, espulp_ulp_obj_t *ulp) { + self->ulp = ulp; +} + +mp_obj_t espulp_ulpalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms) { + for (size_t i = 0; i < n_alarms; i++) { + if (mp_obj_is_type(alarms[i], &espulp_ulpalarm_type)) { + return alarms[i]; + } + } + return mp_const_none; +} + +mp_obj_t espulp_ulpalarm_record_wake_alarm(void) { + espulp_ulpalarm_obj_t *const alarm = &alarm_wake_alarm.ulp_alarm; + alarm->base.type = &espulp_ulpalarm_type; + return alarm; +} + +// This is used to wake the main CircuitPython task. +STATIC void ulp_interrupt(void *arg) { + (void)arg; + woke_up = true; + port_wake_main_task_from_isr(); +} + +void espulp_ulpalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms) { + espulp_ulpalarm_obj_t *alarm = MP_OBJ_NULL; + + for (size_t i = 0; i < n_alarms; i++) { + if (mp_obj_is_type(alarms[i], &espulp_ulpalarm_type)) { + if (alarm != MP_OBJ_NULL) { + mp_raise_ValueError_varg(translate("Only one %q can be set."), MP_QSTR_ULPAlarm); + } + alarm = MP_OBJ_TO_PTR(alarms[i]); + } + } + + if (alarm == MP_OBJ_NULL) { + return; + } + + // enable ulp interrupt + switch (alarm->ulp->arch) { + case FSM: + #ifdef CONFIG_IDF_TARGET_ESP32 + rtc_isr_register(&ulp_interrupt, NULL, RTC_CNTL_ULP_CP_INT_RAW); + #else + rtc_isr_register(&ulp_interrupt, NULL, RTC_CNTL_ULP_CP_INT_ST); + #endif + REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA); + break; + case RISCV: + #ifndef CONFIG_IDF_TARGET_ESP32 + rtc_isr_register(&ulp_interrupt, NULL, RTC_CNTL_COCPU_INT_ST); + REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_COCPU_INT_ENA); + break; + #endif + default: + mp_raise_NotImplementedError(NULL); + break; + } + + alarm_set = true; +} + +void espulp_ulpalarm_prepare_for_deep_sleep(void) { + if (!alarm_set) { + return; + } + + // disable ulp interrupt + rtc_isr_deregister(&ulp_interrupt, NULL); + REG_CLR_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_ULP_CP_INT_ENA); + #ifndef CONFIG_IDF_TARGET_ESP32 + REG_CLR_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_COCPU_INT_ENA); + #endif + + // enable ulp wakeup + esp_sleep_enable_ulp_wakeup(); + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON); +} + +bool espulp_ulpalarm_woke_this_cycle(void) { + return woke_up; +} + +void espulp_ulpalarm_reset(void) { + woke_up = false; + alarm_set = false; +} diff --git a/ports/espressif/common-hal/espulp/ULPAlarm.h b/ports/espressif/common-hal/espulp/ULPAlarm.h new file mode 100644 index 0000000000..99d21180fd --- /dev/null +++ b/ports/espressif/common-hal/espulp/ULPAlarm.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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. + */ + +#pragma once + +#include "py/obj.h" +#include "py/runtime.h" + +#include "bindings/espulp/ULP.h" + +typedef struct { + mp_obj_base_t base; + espulp_ulp_obj_t *ulp; +} espulp_ulpalarm_obj_t; + +mp_obj_t espulp_ulpalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms); +mp_obj_t espulp_ulpalarm_record_wake_alarm(void); + +void espulp_ulpalarm_prepare_for_deep_sleep(void); +void espulp_ulpalarm_reset(void); +void espulp_ulpalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms); +bool espulp_ulpalarm_woke_this_cycle(void); diff --git a/ports/espressif/common-hal/espulp/__init__.c b/ports/espressif/common-hal/espulp/__init__.c new file mode 100644 index 0000000000..5d403129a6 --- /dev/null +++ b/ports/espressif/common-hal/espulp/__init__.c @@ -0,0 +1,34 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "bindings/espulp/__init__.h" + +mp_int_t common_hal_espulp_get_rtc_gpio_number(const mcu_pin_obj_t *pin) { + if (pin->number <= 21) { + return pin->number; + } + return -1; +} diff --git a/ports/espressif/common-hal/i2cperipheral/__init__.c b/ports/espressif/common-hal/i2cperipheral/__init__.c deleted file mode 100644 index c67511c536..0000000000 --- a/ports/espressif/common-hal/i2cperipheral/__init__.c +++ /dev/null @@ -1 +0,0 @@ -// No i2cperipheral module functions. diff --git a/ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c b/ports/espressif/common-hal/i2ctarget/I2CTarget.c similarity index 76% rename from ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c rename to ports/espressif/common-hal/i2ctarget/I2CTarget.c index 6bd71cc797..ad0d09967a 100644 --- a/ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c +++ b/ports/espressif/common-hal/i2ctarget/I2CTarget.c @@ -24,15 +24,15 @@ * THE SOFTWARE. */ -#include "shared-bindings/i2cperipheral/I2CPeripheral.h" +#include "shared-bindings/i2ctarget/I2CTarget.h" #include "py/mperrno.h" #include "py/runtime.h" -#include "common-hal/i2cperipheral/I2CPeripheral.h" +#include "common-hal/i2ctarget/I2CTarget.h" #include "shared-bindings/microcontroller/Pin.h" -void common_hal_i2cperipheral_i2c_peripheral_construct(i2cperipheral_i2c_peripheral_obj_t *self, +void common_hal_i2ctarget_i2c_target_construct(i2ctarget_i2c_target_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint8_t *addresses, unsigned int num_addresses, bool smbus) { // Pins 45 and 46 are "strapping" pins that impact start up behavior. They usually need to @@ -73,7 +73,7 @@ void common_hal_i2cperipheral_i2c_peripheral_construct(i2cperipheral_i2c_periphe if (err == ESP_FAIL) { mp_raise_OSError(MP_EIO); } else { - mp_arg_error_invalid(MP_QSTR_I2CPeripheral); + mp_arg_error_invalid(MP_QSTR_I2CTarget); } } @@ -81,12 +81,12 @@ void common_hal_i2cperipheral_i2c_peripheral_construct(i2cperipheral_i2c_periphe claim_pin(scl); } -bool common_hal_i2cperipheral_i2c_peripheral_deinited(i2cperipheral_i2c_peripheral_obj_t *self) { +bool common_hal_i2ctarget_i2c_target_deinited(i2ctarget_i2c_target_obj_t *self) { return self->sda_pin == NULL; } -void common_hal_i2cperipheral_i2c_peripheral_deinit(i2cperipheral_i2c_peripheral_obj_t *self) { - if (common_hal_i2cperipheral_i2c_peripheral_deinited(self)) { +void common_hal_i2ctarget_i2c_target_deinit(i2ctarget_i2c_target_obj_t *self) { + if (common_hal_i2ctarget_i2c_target_deinited(self)) { return; } @@ -98,7 +98,7 @@ void common_hal_i2cperipheral_i2c_peripheral_deinit(i2cperipheral_i2c_peripheral self->scl_pin = NULL; } -int common_hal_i2cperipheral_i2c_peripheral_is_addressed(i2cperipheral_i2c_peripheral_obj_t *self, +int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart) { *address = self->addresses[0]; *is_read = true; @@ -106,21 +106,21 @@ int common_hal_i2cperipheral_i2c_peripheral_is_addressed(i2cperipheral_i2c_perip return 1; } -int common_hal_i2cperipheral_i2c_peripheral_read_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t *data) { +int common_hal_i2ctarget_i2c_target_read_byte(i2ctarget_i2c_target_obj_t *self, uint8_t *data) { i2c_slave_read_buffer(self->i2c_num, data, 128, 0); return 1; } -int common_hal_i2cperipheral_i2c_peripheral_write_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t data) { +int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self, uint8_t data) { i2c_reset_tx_fifo(self->i2c_num); i2c_slave_write_buffer(self->i2c_num, &data, 128, 0); return 1; } -void common_hal_i2cperipheral_i2c_peripheral_ack(i2cperipheral_i2c_peripheral_obj_t *self, bool ack) { +void common_hal_i2ctarget_i2c_target_ack(i2ctarget_i2c_target_obj_t *self, bool ack) { } -void common_hal_i2cperipheral_i2c_peripheral_close(i2cperipheral_i2c_peripheral_obj_t *self) { +void common_hal_i2ctarget_i2c_target_close(i2ctarget_i2c_target_obj_t *self) { } diff --git a/ports/espressif/common-hal/i2cperipheral/I2CPeripheral.h b/ports/espressif/common-hal/i2ctarget/I2CTarget.h similarity index 85% rename from ports/espressif/common-hal/i2cperipheral/I2CPeripheral.h rename to ports/espressif/common-hal/i2ctarget/I2CTarget.h index d3b324b39a..422bd720eb 100644 --- a/ports/espressif/common-hal/i2cperipheral/I2CPeripheral.h +++ b/ports/espressif/common-hal/i2ctarget/I2CTarget.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H -#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H +#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_TARGET_H +#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_TARGET_H #include "py/obj.h" #include "peripherals/i2c.h" @@ -38,6 +38,6 @@ typedef struct { uint8_t num_addresses; const mcu_pin_obj_t *scl_pin; const mcu_pin_obj_t *sda_pin; -} i2cperipheral_i2c_peripheral_obj_t; +} i2ctarget_i2c_target_obj_t; -#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H +#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_TARGET_H diff --git a/ports/espressif/common-hal/i2ctarget/__init__.c b/ports/espressif/common-hal/i2ctarget/__init__.c new file mode 100644 index 0000000000..4ec26465ad --- /dev/null +++ b/ports/espressif/common-hal/i2ctarget/__init__.c @@ -0,0 +1 @@ +// No i2ctarget module functions. diff --git a/ports/espressif/common-hal/mdns/Server.c b/ports/espressif/common-hal/mdns/Server.c index c6c2a748a9..18c0f0f5e4 100644 --- a/ports/espressif/common-hal/mdns/Server.c +++ b/ports/espressif/common-hal/mdns/Server.c @@ -33,19 +33,27 @@ #include "components/mdns/include/mdns.h" -STATIC bool inited = false; +// Track whether the underlying IDF mdns has been started so that we only +// create a single inited MDNS object to CircuitPython. (After deinit, another +// could be created.) +STATIC bool mdns_started = false; void mdns_server_construct(mdns_server_obj_t *self, bool workflow) { - if (inited) { + if (mdns_started) { + // Mark this object as deinited because another is already using MDNS. + self->inited = false; return; } mdns_init(); + mdns_started = true; uint8_t mac[6]; esp_netif_get_mac(common_hal_wifi_radio_obj.netif, mac); snprintf(self->default_hostname, sizeof(self->default_hostname), "cpy-%02x%02x%02x", mac[3], mac[4], mac[5]); common_hal_mdns_server_set_hostname(self, self->default_hostname); + self->inited = true; + if (workflow) { // Set a delegated entry to ourselves. This allows us to respond to "circuitpython.local" // queries as well. @@ -67,21 +75,23 @@ void common_hal_mdns_server_construct(mdns_server_obj_t *self, mp_obj_t network_ mp_raise_ValueError(translate("mDNS only works with built-in WiFi")); return; } - if (inited) { + mdns_server_construct(self, false); + if (common_hal_mdns_server_deinited(self)) { mp_raise_RuntimeError(translate("mDNS already initialized")); } - mdns_server_construct(self, false); } void common_hal_mdns_server_deinit(mdns_server_obj_t *self) { - inited = false; + if (common_hal_mdns_server_deinited(self)) { + return; + } + self->inited = false; + mdns_started = false; mdns_free(); } bool common_hal_mdns_server_deinited(mdns_server_obj_t *self) { - // This returns INVALID_STATE when not initialized and INVALID_PARAM when it - // is. - return mdns_instance_name_set(NULL) == ESP_ERR_INVALID_STATE; + return !self->inited; } const char *common_hal_mdns_server_get_hostname(mdns_server_obj_t *self) { @@ -204,5 +214,9 @@ mp_obj_t common_hal_mdns_server_find(mdns_server_obj_t *self, const char *servic } void common_hal_mdns_server_advertise_service(mdns_server_obj_t *self, const char *service_type, const char *protocol, mp_int_t port) { - mdns_service_add(NULL, service_type, protocol, port, NULL, 0); + if (mdns_service_exists(service_type, protocol, NULL)) { + mdns_service_port_set(service_type, protocol, port); + } else { + mdns_service_add(NULL, service_type, protocol, port, NULL, 0); + } } diff --git a/ports/espressif/common-hal/mdns/Server.h b/ports/espressif/common-hal/mdns/Server.h index 770f55ece4..ee463657f1 100644 --- a/ports/espressif/common-hal/mdns/Server.h +++ b/ports/espressif/common-hal/mdns/Server.h @@ -32,6 +32,7 @@ typedef struct { mp_obj_base_t base; const char *hostname; const char *instance_name; - // "cpy-" "XXXXXX" "\0" - char default_hostname[4 + 6 + 1]; + char default_hostname[sizeof("cpy-XXXXXX")]; + // Track if this object owns access to the underlying MDNS service. + bool inited; } mdns_server_obj_t; diff --git a/ports/espressif/common-hal/memorymap/AddressRange.c b/ports/espressif/common-hal/memorymap/AddressRange.c new file mode 100644 index 0000000000..ed46c159bb --- /dev/null +++ b/ports/espressif/common-hal/memorymap/AddressRange.c @@ -0,0 +1,107 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "shared-bindings/memorymap/AddressRange.h" + +#include "py/runtime.h" + +#include "soc/soc.h" + +size_t allow_ranges[][2] = { + // ULP accessible RAM + {SOC_RTC_DATA_LOW, SOC_RTC_DATA_HIGH}, + // CPU accessible RAM that is preserved during sleep if the RTC power domain is left on. + {SOC_RTC_DRAM_LOW, SOC_RTC_DRAM_HIGH}, + // RTC peripheral registers + {0x60008000, 0x60009000} + +}; + +void common_hal_memorymap_addressrange_construct(memorymap_addressrange_obj_t *self, uint8_t *start_address, size_t length) { + bool allowed = false; + for (size_t i = 0; i < MP_ARRAY_SIZE(allow_ranges); i++) { + uint8_t *allowed_start = (uint8_t *)allow_ranges[i][0]; + uint8_t *allowed_end = (uint8_t *)allow_ranges[i][1]; + if (allowed_start <= start_address && + (start_address + length) <= allowed_end) { + allowed = true; + break; + } + } + + if (!allowed) { + mp_raise_ValueError(translate("Address range not allowed")); + } + + self->start_address = start_address; + self->len = length; +} + +size_t common_hal_memorymap_addressrange_get_length(const memorymap_addressrange_obj_t *self) { + return self->len; +} + +bool common_hal_memorymap_addressrange_set_bytes(const memorymap_addressrange_obj_t *self, + size_t start_index, uint8_t *values, size_t len) { + uint8_t *address = self->start_address + start_index; + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + if (len == 1) { + *((uint8_t *)address) = values[0]; + } else if (len == sizeof(uint16_t) && (((size_t)address) % sizeof(uint16_t)) == 0) { + *((uint16_t *)address) = ((uint16_t *)values)[0]; + } else if (len == sizeof(uint32_t) && (((size_t)address) % sizeof(uint32_t)) == 0) { + *((uint32_t *)address) = ((uint32_t *)values)[0]; + } else if (len == sizeof(uint64_t) && (((size_t)address) % sizeof(uint64_t)) == 0) { + *((uint64_t *)address) = ((uint64_t *)values)[0]; + } else { + memcpy(address, values, len); + } + #pragma GCC diagnostic pop + + return true; +} + +void common_hal_memorymap_addressrange_get_bytes(const memorymap_addressrange_obj_t *self, + size_t start_index, size_t len, uint8_t *values) { + uint8_t *address = self->start_address + start_index; + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + if (len == 1) { + values[0] = *((uint8_t *)address); + } else if (len == sizeof(uint16_t) && (((size_t)address) % sizeof(uint16_t)) == 0) { + ((uint16_t *)values)[0] = *((uint16_t *)address); + } else if (len == sizeof(uint32_t) && (((size_t)address) % sizeof(uint32_t)) == 0) { + ((uint32_t *)values)[0] = *((uint32_t *)address); + } else if (len == sizeof(uint64_t) && (((size_t)address) % sizeof(uint64_t)) == 0) { + ((uint64_t *)values)[0] = *((uint64_t *)address); + } else { + memcpy(values, address, len); + } + #pragma GCC diagnostic pop +} diff --git a/ports/espressif/common-hal/memorymap/AddressRange.h b/ports/espressif/common-hal/memorymap/AddressRange.h new file mode 100644 index 0000000000..e67cf32f5f --- /dev/null +++ b/ports/espressif/common-hal/memorymap/AddressRange.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_MEMORYMAP_ADDRESSRANGE_H +#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_MEMORYMAP_ADDRESSRANGE_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t *start_address; + size_t len; +} memorymap_addressrange_obj_t; + +#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_MEMORYMAP_ADDRESSRANGE_H diff --git a/ports/espressif/common-hal/memorymap/__init__.c b/ports/espressif/common-hal/memorymap/__init__.c new file mode 100644 index 0000000000..c15b17f451 --- /dev/null +++ b/ports/espressif/common-hal/memorymap/__init__.c @@ -0,0 +1 @@ +// No memorymap module functions. diff --git a/ports/espressif/common-hal/microcontroller/Pin.c b/ports/espressif/common-hal/microcontroller/Pin.c index 201fa0ac2b..12081c7e40 100644 --- a/ports/espressif/common-hal/microcontroller/Pin.c +++ b/ports/espressif/common-hal/microcontroller/Pin.c @@ -33,28 +33,19 @@ #include "components/driver/include/driver/gpio.h" #include "components/hal/include/hal/gpio_hal.h" -STATIC uint64_t never_reset_pins; -STATIC uint64_t in_use; +STATIC uint64_t _never_reset_pin_mask; +STATIC uint64_t _preserved_pin_mask; +STATIC uint64_t _in_use_pin_mask; -// 64-bit pin mask for a single bit -#define PIN_BIT(pin_number) (((uint64_t)1) << pin_number) - -// Bit mask of all pins that should never ever be reset. +// Bit mask of all pins that should never EVER be reset. // Typically these are SPI flash and PSRAM control pins, and communication pins. +// "Reset forbidden" is stronger than "never reset" below, which may only be temporary. static const uint64_t pin_mask_reset_forbidden = #if defined(CONFIG_IDF_TARGET_ESP32) // Never ever reset serial pins for bootloader and possibly USB-serial converter. GPIO_SEL_1 | // TXD0 GPIO_SEL_3 | // RXD0 - // Never ever reset pins used to communicate with SPI flash and PSRAM. - GPIO_SEL_6 | // CLK - GPIO_SEL_9 | // (PSRAM) SD2 - GPIO_SEL_10 | // (PSRAM) SD3 - GPIO_SEL_11 | // CMD - GPIO_SEL_16 | // SPIHD - GPIO_SEL_17 | // SPIDO - GPIO_SEL_18 | // SPIWP - GPIO_SEL_23 | // SPIDI + // SPI flash and PSRAM pins are protected at runtime in supervisor/port.c. #endif // ESP32 #if defined(CONFIG_IDF_TARGET_ESP32C3) @@ -108,10 +99,12 @@ static const uint64_t pin_mask_reset_forbidden = void never_reset_pin_number(gpio_num_t pin_number) { - if (pin_number == NO_PIN) { + // Some CircuitPython APIs deal in uint8_t pin numbers, but NO_PIN is -1. + // Also allow pin 255 to be treated as NO_PIN to avoid crashes + if (pin_number == NO_PIN || pin_number == (uint8_t)NO_PIN) { return; } - never_reset_pins |= PIN_BIT(pin_number); + _never_reset_pin_mask |= PIN_BIT(pin_number); } void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) { @@ -125,35 +118,83 @@ MP_WEAK bool espressif_board_reset_pin_number(gpio_num_t pin_number) { return false; } +STATIC bool _reset_forbidden(gpio_num_t pin_number) { + return pin_mask_reset_forbidden & PIN_BIT(pin_number); +} + +STATIC bool _never_reset(gpio_num_t pin_number) { + return _never_reset_pin_mask & PIN_BIT(pin_number); +} + +STATIC bool _preserved_pin(gpio_num_t pin_number) { + return _preserved_pin_mask & PIN_BIT(pin_number); +} + STATIC void _reset_pin(gpio_num_t pin_number) { // Never ever reset pins used for flash, RAM, and basic communication. - if (pin_mask_reset_forbidden & PIN_BIT(pin_number)) { + if (_reset_forbidden(pin_number)) { return; } + // Disable any existing hold on this pin, + if (GPIO_IS_VALID_OUTPUT_GPIO(pin_number)) { + gpio_hold_dis(pin_number); + } + // Give the board a chance to reset the pin in a particular way. if (espressif_board_reset_pin_number(pin_number)) { return; } - gpio_reset_pin(pin_number); + bool pull_down = false; + + // Special case the status LED pin. + #if defined(MICROPY_HW_LED_STATUS) && (!defined(MICROPY_HW_LED_STATUS_INVERTED) || !MICROPY_HW_LED_STATUS_INVERTED) + pull_down = pull_down || pin_number == MICROPY_HW_LED_STATUS->number; + #endif #ifdef DOUBLE_TAP_PIN // Pull the double tap pin down so that resets come back to CircuitPython. - if (pin_number == DOUBLE_TAP_PIN->number) { + pull_down = pull_down || pin_number == DOUBLE_TAP_PIN->number; + #endif + + // This will pull the pin up. For pins needing pull down it shouldn't be a + // problem for a moment. + gpio_reset_pin(pin_number); + + if (pull_down) { gpio_pullup_dis(pin_number); gpio_pulldown_en(pin_number); } - #endif } +void preserve_pin_number(gpio_num_t pin_number) { + if (GPIO_IS_VALID_OUTPUT_GPIO(pin_number)) { + gpio_hold_en(pin_number); + _preserved_pin_mask |= PIN_BIT(pin_number); + } + if (_preserved_pin_mask) { + // Allow pin holds to work during deep sleep. This increases power consumption noticeably + // during deep sleep, so enable holds only if we actually are holding some pins. + // 270uA or so extra current is consumed even with no pins held. + gpio_deep_sleep_hold_en(); + } +} + +void clear_pin_preservations(void) { + _preserved_pin_mask = 0; +} + + // Mark pin as free and return it to a quiescent state. void reset_pin_number(gpio_num_t pin_number) { - if (pin_number == NO_PIN) { + // Some CircuitPython APIs deal in uint8_t pin numbers, but NO_PIN is -1. + // Also allow pin 255 to be treated as NO_PIN to avoid crashes + if (pin_number == NO_PIN || pin_number == (uint8_t)NO_PIN) { return; } - never_reset_pins &= ~PIN_BIT(pin_number); - in_use &= ~PIN_BIT(pin_number); + _never_reset_pin_mask &= ~PIN_BIT(pin_number); + _in_use_pin_mask &= ~PIN_BIT(pin_number); _reset_pin(pin_number); } @@ -170,22 +211,29 @@ void common_hal_reset_pin(const mcu_pin_obj_t *pin) { } void reset_all_pins(void) { + // Undo deep sleep holds in case we woke up from deep sleep. + // We still need to unhold individual pins, which is done by _reset_pin. + gpio_deep_sleep_hold_dis(); + for (uint8_t i = 0; i < GPIO_PIN_COUNT; i++) { uint32_t iomux_address = GPIO_PIN_MUX_REG[i]; if (iomux_address == 0 || - (never_reset_pins & PIN_BIT(i))) { + _never_reset(i) || + _preserved_pin(i)) { continue; } _reset_pin(i); } - in_use = never_reset_pins; + _in_use_pin_mask = _never_reset_pin_mask; } void claim_pin_number(gpio_num_t pin_number) { - if (pin_number == NO_PIN) { + // Some CircuitPython APIs deal in uint8_t pin numbers, but NO_PIN is -1. + // Also allow pin 255 to be treated as NO_PIN to avoid crashes + if (pin_number == NO_PIN || pin_number == (uint8_t)NO_PIN) { return; } - in_use |= PIN_BIT(pin_number); + _in_use_pin_mask |= PIN_BIT(pin_number); } void claim_pin(const mcu_pin_obj_t *pin) { @@ -197,7 +245,7 @@ void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) { } bool pin_number_is_free(gpio_num_t pin_number) { - return !(in_use & PIN_BIT(pin_number)); + return !(_in_use_pin_mask & PIN_BIT(pin_number)); } bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { diff --git a/ports/espressif/common-hal/microcontroller/Pin.h b/ports/espressif/common-hal/microcontroller/Pin.h index e74346ef65..55927fe068 100644 --- a/ports/espressif/common-hal/microcontroller/Pin.h +++ b/ports/espressif/common-hal/microcontroller/Pin.h @@ -31,21 +31,28 @@ #include "peripherals/pins.h" -void reset_all_pins(void); +// 64-bit pin mask for a single bit +#define PIN_BIT(pin_number) (((uint64_t)1) << pin_number) + +extern void common_hal_reset_pin(const mcu_pin_obj_t *pin); +extern void common_hal_never_reset_pin(const mcu_pin_obj_t *pin); + +extern void reset_all_pins(void); // reset_pin_number takes the pin number instead of the pointer so that objects don't // need to store a full pointer. -void reset_pin_number(gpio_num_t pin_number); -void common_hal_reset_pin(const mcu_pin_obj_t *pin); -void common_hal_never_reset_pin(const mcu_pin_obj_t *pin); -void claim_pin(const mcu_pin_obj_t *pin); -void claim_pin_number(gpio_num_t pin_number); -bool pin_number_is_free(gpio_num_t pin_number); -void never_reset_pin_number(gpio_num_t pin_number); +extern void reset_pin_number(gpio_num_t pin_number); +extern void claim_pin(const mcu_pin_obj_t *pin); +extern void claim_pin_number(gpio_num_t pin_number); +extern bool pin_number_is_free(gpio_num_t pin_number); +extern void never_reset_pin_number(gpio_num_t pin_number); + +extern void preserve_pin_number(gpio_num_t pin_number); +extern void clear_pin_preservations(void); // Allow the board to reset a pin in a board-specific way. This can be used // for LEDs or enable pins to put them in a state beside the default pull-up. // Return true to indicate that the pin was reset. Returning false will lead to // the port-default reset behavior. -bool espressif_board_reset_pin_number(gpio_num_t pin_number); +extern bool espressif_board_reset_pin_number(gpio_num_t pin_number); #endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/espressif/common-hal/microcontroller/Processor.c b/ports/espressif/common-hal/microcontroller/Processor.c index 9b97b98cbd..1f09742955 100644 --- a/ports/espressif/common-hal/microcontroller/Processor.c +++ b/ports/espressif/common-hal/microcontroller/Processor.c @@ -40,13 +40,13 @@ #include "soc/efuse_reg.h" -#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S3) +#if !defined(CONFIG_IDF_TARGET_ESP32) #include "driver/temp_sensor.h" #endif float common_hal_mcu_processor_get_temperature(void) { float tsens_out; - #if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32) + #if defined(CONFIG_IDF_TARGET_ESP32) mp_raise_NotImplementedError(NULL); #else temp_sensor_config_t temp_sensor = TSENS_CONFIG_DEFAULT(); // DEFAULT: range:-10℃ ~ 80℃, error < 1℃. @@ -139,6 +139,7 @@ mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { case ESP_SLEEP_WAKEUP_EXT0: case ESP_SLEEP_WAKEUP_EXT1: case ESP_SLEEP_WAKEUP_TOUCHPAD: + case ESP_SLEEP_WAKEUP_ULP: return RESET_REASON_DEEP_SLEEP_ALARM; case ESP_SLEEP_WAKEUP_UNDEFINED: diff --git a/ports/espressif/common-hal/microcontroller/__init__.c b/ports/espressif/common-hal/microcontroller/__init__.c index 1014ce9532..23c7c153e9 100644 --- a/ports/espressif/common-hal/microcontroller/__init__.c +++ b/ports/espressif/common-hal/microcontroller/__init__.c @@ -97,25 +97,27 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { #endif break; case RUNMODE_NORMAL: - #if defined(CONFIG_IDF_TARGET_ESP32) - safe_mode_on_next_reset(NO_SAFE_MODE); - #else // revert back to normal boot + #if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) REG_WRITE(RTC_RESET_CAUSE_REG, 0); // reset uf2 + #endif REG_WRITE(RTC_CNTL_STORE0_REG, 0); // reset safe mode + #if !defined(CONFIG_IDF_TARGET_ESP32) REG_WRITE(RTC_CNTL_OPTION1_REG, 0); // reset bootloader #endif break; case RUNMODE_SAFE_MODE: // enter safe mode on next boot - safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE); + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); break; case RUNMODE_BOOTLOADER: // DFU download - #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32C3) + #if defined(CONFIG_IDF_TARGET_ESP32) mp_arg_error_invalid(MP_QSTR_run_mode); #else + #if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) chip_usb_set_persist_flags(USBDC_BOOT_DFU); + #endif REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT); #endif break; diff --git a/ports/espressif/common-hal/paralleldisplay/ParallelBus.c b/ports/espressif/common-hal/paralleldisplay/ParallelBus.c index 1b6ee41c40..c9ba3edd06 100644 --- a/ports/espressif/common-hal/paralleldisplay/ParallelBus.c +++ b/ports/espressif/common-hal/paralleldisplay/ParallelBus.c @@ -118,7 +118,8 @@ void common_hal_paralleldisplay_parallelbus_construct(paralleldisplay_parallelbu const mcu_pin_obj_t *data_pins[8]; for (int i = 0; i < 8; i++) { snprintf(buf, sizeof(buf), "GPIO%d", data0->number + i); - data_pins[i] = validate_obj_is_free_pin(mp_obj_dict_get(MP_OBJ_FROM_PTR(&mcu_pin_globals), mp_obj_new_str(buf, strlen(buf)))); + data_pins[i] = validate_obj_is_free_pin( + mp_obj_dict_get(MP_OBJ_FROM_PTR(&mcu_pin_globals), mp_obj_new_str(buf, strlen(buf))), MP_QSTR_pin); } common_hal_paralleldisplay_parallelbus_construct_nonsequential(self, 8, data_pins, command, chip_select, write, read, reset, frequency); } diff --git a/ports/espressif/common-hal/pulseio/PulseIn.c b/ports/espressif/common-hal/pulseio/PulseIn.c index 41c1dcb189..bb6ef7f975 100644 --- a/ports/espressif/common-hal/pulseio/PulseIn.c +++ b/ports/espressif/common-hal/pulseio/PulseIn.c @@ -41,7 +41,12 @@ STATIC void update_internal_buffer(pulseio_pulsein_obj_t *self) { length /= 4; for (size_t i = 0; i < length; i++) { uint16_t pos = (self->start + self->len) % self->maxlen; - self->buffer[pos] = items[i].duration0 * 3; + uint32_t val = items[i].duration0 * 3; + // make sure the value returned does not exceed the max uint16 value. + if (val > 65535) { + val = 65535; + } + self->buffer[pos] = (uint16_t)val; if (self->len < self->maxlen) { self->len++; } else { @@ -50,7 +55,11 @@ STATIC void update_internal_buffer(pulseio_pulsein_obj_t *self) { // Check if second item exists if (items[i].duration1) { pos = (self->start + self->len) % self->maxlen; - self->buffer[pos] = items[i].duration1 * 3; + val = items[i].duration1 * 3; + if (val > 65535) { + val = 65535; + } + self->buffer[pos] = (uint16_t)val; if (self->len < self->maxlen) { self->len++; } else { diff --git a/ports/espressif/common-hal/pwmio/PWMOut.c b/ports/espressif/common-hal/pwmio/PWMOut.c index b96c154be6..2cb1e6254b 100644 --- a/ports/espressif/common-hal/pwmio/PWMOut.c +++ b/ports/espressif/common-hal/pwmio/PWMOut.c @@ -55,18 +55,14 @@ STATIC uint32_t calculate_duty_cycle(uint32_t frequency) { void pwmout_reset(void) { for (size_t i = 0; i < LEDC_CHANNEL_MAX; i++) { - if (reserved_channels[i] != INDEX_EMPTY) { + if (reserved_channels[i] != INDEX_EMPTY && !never_reset_chan[i]) { ledc_stop(LEDC_LOW_SPEED_MODE, i, 0); - } - if (!never_reset_chan[i]) { reserved_channels[i] = INDEX_EMPTY; } } for (size_t i = 0; i < LEDC_TIMER_MAX; i++) { - if (reserved_timer_freq[i]) { + if (reserved_timer_freq[i] && !never_reset_tim[i]) { ledc_timer_rst(LEDC_LOW_SPEED_MODE, i); - } - if (!never_reset_tim[i]) { reserved_timer_freq[i] = 0; varfreq_timers[i] = false; } @@ -168,11 +164,6 @@ void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { never_reset_pin_number(self->pin->number); } -void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { - never_reset_tim[self->tim_handle.timer_num] = false; - never_reset_chan[self->chan_handle.channel] = false; -} - bool common_hal_pwmio_pwmout_deinited(pwmio_pwmout_obj_t *self) { return self->deinited == true; } @@ -186,19 +177,29 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { ledc_stop(LEDC_LOW_SPEED_MODE, self->chan_handle.channel, 0); } reserved_channels[self->chan_handle.channel] = INDEX_EMPTY; + never_reset_chan[self->chan_handle.channel] = false; + // Search if any other channel is using the timer bool taken = false; + bool other_never_reset = false; for (size_t i = 0; i < LEDC_CHANNEL_MAX; i++) { if (reserved_channels[i] == self->tim_handle.timer_num) { taken = true; + other_never_reset = never_reset_chan[i]; + break; } } + // Clear the timer's never reset if the other channel isn't never reset. + if (!other_never_reset) { + never_reset_tim[self->tim_handle.timer_num] = false; + } // Variable frequency means there's only one channel on the timer if (!taken || self->variable_frequency) { ledc_timer_rst(LEDC_LOW_SPEED_MODE, self->tim_handle.timer_num); reserved_timer_freq[self->tim_handle.timer_num] = 0; // if timer isn't varfreq this will be off aleady varfreq_timers[self->tim_handle.timer_num] = false; + never_reset_tim[self->tim_handle.timer_num] = false; } common_hal_reset_pin(self->pin); self->deinited = true; diff --git a/ports/espressif/common-hal/socketpool/Socket.c b/ports/espressif/common-hal/socketpool/Socket.c index 45d5f1fea0..8b6cff30ef 100644 --- a/ports/espressif/common-hal/socketpool/Socket.c +++ b/ports/espressif/common-hal/socketpool/Socket.c @@ -31,6 +31,8 @@ #include "py/mperrno.h" #include "py/runtime.h" #include "shared-bindings/socketpool/SocketPool.h" +#include "shared-bindings/ssl/SSLSocket.h" +#include "common-hal/ssl/SSLSocket.h" #include "supervisor/port.h" #include "supervisor/shared/tick.h" #include "supervisor/workflow.h" @@ -44,7 +46,7 @@ StackType_t socket_select_stack[2 * configMINIMAL_STACK_SIZE]; STATIC int open_socket_fds[CONFIG_LWIP_MAX_SOCKETS]; -STATIC bool user_socket[CONFIG_LWIP_MAX_SOCKETS]; +STATIC socketpool_socket_obj_t *user_socket[CONFIG_LWIP_MAX_SOCKETS]; StaticTask_t socket_select_task_handle; STATIC int socket_change_fd = -1; @@ -60,32 +62,35 @@ STATIC void socket_select_task(void *arg) { FD_SET(socket_change_fd, &errfds); int max_fd = socket_change_fd; for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_fds); i++) { - if (open_socket_fds[i] < 0) { + int sockfd = open_socket_fds[i]; + if (sockfd < 0) { continue; } - max_fd = MAX(max_fd, open_socket_fds[i]); - FD_SET(open_socket_fds[i], &readfds); - FD_SET(open_socket_fds[i], &errfds); + max_fd = MAX(max_fd, sockfd); + FD_SET(sockfd, &readfds); + FD_SET(sockfd, &errfds); } int num_triggered = select(max_fd + 1, &readfds, NULL, &errfds, NULL); - if (num_triggered < 0) { - // Maybe bad file descriptor - for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_fds); i++) { - int sockfd = open_socket_fds[i]; - if (sockfd < 0) { - continue; - } - if (FD_ISSET(sockfd, &errfds)) { - int err; - int optlen = sizeof(int); - int ret = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, (socklen_t *)&optlen); - if (ret < 0) { - open_socket_fds[i] = -1; - // Try again. - continue; - } - } + // Check for bad file descriptor and queue up the background task before + // circling around. + if (num_triggered == -1 && errno == EBADF) { + // One for the change fd and one for the closed socket. + num_triggered = 2; + } + // Try and find the bad file and remove it from monitoring. + for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_fds); i++) { + int sockfd = open_socket_fds[i]; + if (sockfd < 0) { + continue; + } + int err; + int optlen = sizeof(int); + int ret = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, (socklen_t *)&optlen); + if (ret < 0) { + open_socket_fds[i] = -1; + // Raise num_triggered so that we skip the assert and queue the background task. + num_triggered = 2; } } assert(num_triggered >= 0); @@ -114,16 +119,16 @@ void socket_user_reset(void) { for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_fds); i++) { open_socket_fds[i] = -1; - user_socket[i] = false; + user_socket[i] = NULL; } socket_change_fd = eventfd(0, 0); - // This task runs at a lower priority than CircuitPython and is used to wake CircuitPython - // up when any open sockets have data to read. It allows us to sleep otherwise. + // Run this at the same priority as CP so that the web workflow background task can be + // queued while CP is running. Both tasks can still sleep and, therefore, sleep overall. (void)xTaskCreateStaticPinnedToCore(socket_select_task, "socket_select", 2 * configMINIMAL_STACK_SIZE, NULL, - 0, // Run this at IDLE priority. We only need it when CP isn't running (at 1). + uxTaskPriorityGet(NULL), socket_select_stack, &socket_select_task_handle, xPortGetCoreID()); @@ -131,12 +136,13 @@ void socket_user_reset(void) { for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_fds); i++) { if (open_socket_fds[i] >= 0 && user_socket[i]) { + common_hal_socketpool_socket_close(user_socket[i]); int num = open_socket_fds[i]; // Close automatically clears socket handle lwip_shutdown(num, SHUT_RDWR); lwip_close(num); open_socket_fds[i] = -1; - user_socket[i] = false; + user_socket[i] = NULL; } } } @@ -162,16 +168,18 @@ STATIC void unregister_open_socket(int fd) { if (open_socket_fds[i] == fd) { open_socket_fds[i] = -1; user_socket[i] = false; - write(socket_change_fd, &fd, sizeof(fd)); + // Write must be 8 bytes for an eventfd. + uint64_t signal = 1; + write(socket_change_fd, &signal, sizeof(signal)); return; } } } -STATIC void mark_user_socket(int fd) { +STATIC void mark_user_socket(int fd, socketpool_socket_obj_t *obj) { for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_fds); i++) { if (open_socket_fds[i] == fd) { - user_socket[i] = true; + user_socket[i] = obj; return; } } @@ -233,11 +241,11 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_ if (!socketpool_socket(self, family, type, sock)) { mp_raise_RuntimeError(translate("Out of sockets")); } - mark_user_socket(sock->num); + mark_user_socket(sock->num, sock); return sock; } -int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port) { +int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port, socketpool_socket_obj_t *accepted) { struct sockaddr_in accept_addr; socklen_t socklen = sizeof(accept_addr); int newsoc = -1; @@ -245,7 +253,9 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_ uint64_t start_ticks = supervisor_ticks_ms64(); // Allow timeouts and interrupts - while (newsoc == -1 && !timed_out) { + while (newsoc == -1 && + !timed_out && + !mp_hal_is_interrupted()) { if (self->timeout_ms != (uint)-1 && self->timeout_ms != 0) { timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms; } @@ -257,6 +267,9 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_ } } + // New client socket will not be non-blocking by default, so make it non-blocking. + lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK); + if (!timed_out) { // harmless on failure but avoiding memcpy is faster memcpy((void *)ip, (void *)&accept_addr.sin_addr.s_addr, sizeof(accept_addr.sin_addr.s_addr)); @@ -271,23 +284,35 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_ lwip_close(newsoc); return -MP_EBADF; } + + + if (accepted != NULL) { + // Close the active socket because we have another we accepted. + if (!common_hal_socketpool_socket_get_closed(accepted)) { + common_hal_socketpool_socket_close(accepted); + } + // Replace the old accepted socket with the new one. + accepted->num = newsoc; + accepted->pool = self->pool; + accepted->connected = true; + } + return newsoc; } socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port) { - int newsoc = socketpool_socket_accept(self, ip, port); + socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t); + int newsoc = socketpool_socket_accept(self, ip, port, NULL); if (newsoc > 0) { - mark_user_socket(newsoc); // Create the socket - socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t); + mark_user_socket(newsoc, sock); sock->base.type = &socketpool_socket_type; sock->num = newsoc; sock->pool = self->pool; sock->connected = true; - lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK); return sock; } else { mp_raise_OSError(-newsoc); @@ -322,6 +347,12 @@ bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *self, } void socketpool_socket_close(socketpool_socket_obj_t *self) { + if (self->ssl_socket) { + ssl_sslsocket_obj_t *ssl_socket = self->ssl_socket; + self->ssl_socket = NULL; + common_hal_ssl_sslsocket_close(ssl_socket); + return; + } self->connected = false; if (self->num >= 0) { lwip_shutdown(self->num, SHUT_RDWR); @@ -344,7 +375,7 @@ void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self, struct addrinfo *result_i; int error = lwip_getaddrinfo(host, NULL, &hints, &result_i); if (error != 0 || result_i == NULL) { - mp_raise_OSError(EHOSTUNREACH); + common_hal_socketpool_socketpool_raise_gaierror_noname(); } // Set parameters @@ -480,7 +511,7 @@ int socketpool_socket_recv_into(socketpool_socket_obj_t *self, mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) { int received = socketpool_socket_recv_into(self, buf, len); if (received < 0) { - mp_raise_OSError(received); + mp_raise_OSError(-received); } return received; } @@ -525,7 +556,7 @@ mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t *self, struct addrinfo *result_i; int error = lwip_getaddrinfo(host, NULL, &hints, &result_i); if (error != 0 || result_i == NULL) { - mp_raise_OSError(EHOSTUNREACH); + common_hal_socketpool_socketpool_raise_gaierror_noname(); } // Set parameters @@ -550,3 +581,51 @@ mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t *self, void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint32_t timeout_ms) { self->timeout_ms = timeout_ms; } + + +int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen) { + int err = lwip_setsockopt(self->num, level, optname, value, optlen); + if (err != 0) { + return -errno; + } + return 0; +} + +bool common_hal_socketpool_readable(socketpool_socket_obj_t *self) { + struct timeval immediate = {0, 0}; + + fd_set fds; + FD_ZERO(&fds); + FD_SET(self->num, &fds); + int num_triggered = select(self->num + 1, &fds, NULL, &fds, &immediate); + + // including returning true in the error case + return num_triggered != 0; +} + +bool common_hal_socketpool_writable(socketpool_socket_obj_t *self) { + struct timeval immediate = {0, 0}; + + fd_set fds; + FD_ZERO(&fds); + FD_SET(self->num, &fds); + int num_triggered = select(self->num + 1, NULL, &fds, &fds, &immediate); + + // including returning true in the error case + return num_triggered != 0; +} + +void socketpool_socket_move(socketpool_socket_obj_t *self, socketpool_socket_obj_t *sock) { + *sock = *self; + self->connected = false; + self->num = -1; +} + +void socketpool_socket_reset(socketpool_socket_obj_t *self) { + if (self->base.type == &socketpool_socket_type) { + return; + } + self->base.type = &socketpool_socket_type; + self->connected = false; + self->num = -1; +} diff --git a/ports/espressif/common-hal/socketpool/Socket.h b/ports/espressif/common-hal/socketpool/Socket.h index b91419807c..45e36e58ca 100644 --- a/ports/espressif/common-hal/socketpool/Socket.h +++ b/ports/espressif/common-hal/socketpool/Socket.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_SOCKETPOOL_SOCKET_H -#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_SOCKETPOOL_SOCKET_H +#pragma once #include "py/obj.h" @@ -34,6 +33,8 @@ #include "components/esp-tls/esp_tls.h" +typedef struct ssl_sslsocket_obj ssl_sslsocket_obj_t; + typedef struct { mp_obj_base_t base; int num; @@ -42,9 +43,8 @@ typedef struct { int ipproto; bool connected; socketpool_socketpool_obj_t *pool; + ssl_sslsocket_obj_t *ssl_socket; mp_uint_t timeout_ms; } socketpool_socket_obj_t; void socket_user_reset(void); - -#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_SOCKETPOOL_SOCKET_H diff --git a/ports/espressif/common-hal/socketpool/SocketPool.c b/ports/espressif/common-hal/socketpool/SocketPool.c index 1d1aafa638..780e90c42c 100644 --- a/ports/espressif/common-hal/socketpool/SocketPool.c +++ b/ports/espressif/common-hal/socketpool/SocketPool.c @@ -45,6 +45,16 @@ void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *sel mp_obj_t common_hal_socketpool_socketpool_gethostbyname(socketpool_socketpool_obj_t *self, const char *host) { + // As of 2022, the version of lwip in esp-idf does not handle the + // trailing-dot syntax of domain names, so emulate it. + // Remove this once https://github.com/espressif/esp-idf/issues/10013 has + // been implemented + size_t strlen_host = strlen(host); + if (strlen_host && host[strlen_host - 1] == '.') { + mp_obj_t nodot = mp_obj_new_str(host, strlen_host - 1); + host = mp_obj_str_get_str(nodot); + } + const struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM, diff --git a/ports/espressif/common-hal/ssl/SSLContext.c b/ports/espressif/common-hal/ssl/SSLContext.c index 866024bf00..1923a9c2a9 100644 --- a/ports/espressif/common-hal/ssl/SSLContext.c +++ b/ports/espressif/common-hal/ssl/SSLContext.c @@ -48,6 +48,7 @@ ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t sock->base.type = &ssl_sslsocket_type; sock->ssl_context = self; sock->sock = socket; + socket->ssl_socket = sock; // Create a copy of the ESP-TLS config object and store the server hostname // Note that ESP-TLS will use common_name for both SNI and verification @@ -87,3 +88,10 @@ bool common_hal_ssl_sslcontext_get_check_hostname(ssl_sslcontext_obj_t *self) { void common_hal_ssl_sslcontext_set_check_hostname(ssl_sslcontext_obj_t *self, bool value) { self->ssl_config.skip_common_name = !value; } + +void common_hal_ssl_sslcontext_load_cert_chain(ssl_sslcontext_obj_t *self, mp_buffer_info_t *cert_buf, mp_buffer_info_t *key_buf) { + self->ssl_config.clientcert_buf = cert_buf->buf; + self->ssl_config.clientcert_bytes = cert_buf->len + 1; + self->ssl_config.clientkey_buf = key_buf->buf; + self->ssl_config.clientkey_bytes = key_buf->len + 1; +} diff --git a/ports/espressif/common-hal/ssl/SSLSocket.c b/ports/espressif/common-hal/ssl/SSLSocket.c index 281e356d77..2446ce3005 100644 --- a/ports/espressif/common-hal/ssl/SSLSocket.c +++ b/ports/espressif/common-hal/ssl/SSLSocket.c @@ -96,7 +96,7 @@ bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog) { return common_hal_socketpool_socket_listen(self->sock, backlog); } -mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t *self, const uint8_t *buf, uint32_t len) { +mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t *self, uint8_t *buf, uint32_t len) { int received = 0; bool timed_out = false; int status = 0; @@ -158,7 +158,7 @@ mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t if (err == ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) { mp_raise_espidf_MemoryError(); - } else if (ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED) { + } else if (err == ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED) { mp_raise_OSError_msg_varg(translate("Failed SSL handshake")); } else { mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x %d"), esp_tls_code, flags, err, sent); diff --git a/ports/espressif/common-hal/ssl/SSLSocket.h b/ports/espressif/common-hal/ssl/SSLSocket.h index 097f19857b..6b65a56223 100644 --- a/ports/espressif/common-hal/ssl/SSLSocket.h +++ b/ports/espressif/common-hal/ssl/SSLSocket.h @@ -34,7 +34,7 @@ #include "components/esp-tls/esp_tls.h" -typedef struct { +typedef struct ssl_sslsocket_obj { mp_obj_base_t base; socketpool_socket_obj_t *sock; esp_tls_t *tls; diff --git a/ports/espressif/common-hal/touchio/TouchIn.c b/ports/espressif/common-hal/touchio/TouchIn.c index 523245f359..c2ef0d6e18 100644 --- a/ports/espressif/common-hal/touchio/TouchIn.c +++ b/ports/espressif/common-hal/touchio/TouchIn.c @@ -30,22 +30,9 @@ #include "peripherals/touch.h" #include "shared-bindings/microcontroller/Pin.h" -static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { - #if defined(CONFIG_IDF_TARGET_ESP32) - uint16_t touch_value; - #else - uint32_t touch_value; - #endif; - touch_pad_read_raw_data(self->pin->touch_channel, &touch_value); - if (touch_value > UINT16_MAX) { - return UINT16_MAX; - } - return (uint16_t)touch_value; -} - void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu_pin_obj_t *pin) { - if (pin->touch_channel == TOUCH_PAD_MAX) { + if (pin->touch_channel == NO_TOUCH_CHANNEL) { raise_ValueError_invalid_pin(); } claim_pin(pin); @@ -53,15 +40,12 @@ void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, // initialize touchpad peripherals_touch_init(pin->touch_channel); - // wait for touch data to reset - mp_hal_delay_ms(10); - // Set a "touched" threshold not too far above the initial value. // For simple finger touch, the values may vary as much as a factor of two, // but for touches using fruit or other objects, the difference is much less. self->pin = pin; - self->threshold = get_raw_reading(self) + 100; + self->threshold = common_hal_touchio_touchin_get_raw_value(self) + 100; } bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t *self) { @@ -77,11 +61,11 @@ void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t *self) { } bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self) { - return get_raw_reading(self) > self->threshold; + return common_hal_touchio_touchin_get_raw_value(self) > self->threshold; } uint16_t common_hal_touchio_touchin_get_raw_value(touchio_touchin_obj_t *self) { - return get_raw_reading(self); + return peripherals_touch_read(self->pin->touch_channel); } uint16_t common_hal_touchio_touchin_get_threshold(touchio_touchin_obj_t *self) { diff --git a/ports/espressif/common-hal/wifi/Network.c b/ports/espressif/common-hal/wifi/Network.c index 34cb15d603..9a20decd4a 100644 --- a/ports/espressif/common-hal/wifi/Network.c +++ b/ports/espressif/common-hal/wifi/Network.c @@ -55,40 +55,40 @@ mp_obj_t common_hal_wifi_network_get_country(wifi_network_obj_t *self) { } mp_obj_t common_hal_wifi_network_get_authmode(wifi_network_obj_t *self) { - uint8_t authmode_mask = 0; + uint32_t authmode_mask = 0; switch (self->record.authmode) { case WIFI_AUTH_OPEN: - authmode_mask = (1 << AUTHMODE_OPEN); + authmode_mask = AUTHMODE_OPEN; break; case WIFI_AUTH_WEP: - authmode_mask = (1 << AUTHMODE_WEP); + authmode_mask = AUTHMODE_WEP; break; case WIFI_AUTH_WPA_PSK: - authmode_mask = (1 << AUTHMODE_WPA) | (1 << AUTHMODE_PSK); + authmode_mask = AUTHMODE_WPA | AUTHMODE_PSK; break; case WIFI_AUTH_WPA2_PSK: - authmode_mask = (1 << AUTHMODE_WPA2) | (1 << AUTHMODE_PSK); + authmode_mask = AUTHMODE_WPA2 | AUTHMODE_PSK; break; case WIFI_AUTH_WPA_WPA2_PSK: - authmode_mask = (1 << AUTHMODE_WPA) | (1 << AUTHMODE_WPA2) | (1 << AUTHMODE_PSK); + authmode_mask = AUTHMODE_WPA | AUTHMODE_WPA2 | AUTHMODE_PSK; break; case WIFI_AUTH_WPA2_ENTERPRISE: - authmode_mask = (1 << AUTHMODE_WPA2) | (1 << AUTHMODE_ENTERPRISE); + authmode_mask = AUTHMODE_WPA2 | AUTHMODE_ENTERPRISE; break; case WIFI_AUTH_WPA3_PSK: - authmode_mask = (1 << AUTHMODE_WPA3) | (1 << AUTHMODE_PSK); + authmode_mask = AUTHMODE_WPA3 | AUTHMODE_PSK; break; case WIFI_AUTH_WPA2_WPA3_PSK: - authmode_mask = (1 << AUTHMODE_WPA2) | (1 << AUTHMODE_WPA3) | (1 << AUTHMODE_PSK); + authmode_mask = AUTHMODE_WPA2 | AUTHMODE_WPA3 | AUTHMODE_PSK; break; default: break; } mp_obj_t authmode_list = mp_obj_new_list(0, NULL); if (authmode_mask != 0) { - for (uint8_t i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 32; i++) { if ((authmode_mask >> i) & 1) { - mp_obj_list_append(authmode_list, cp_enum_find(&wifi_authmode_type, i)); + mp_obj_list_append(authmode_list, cp_enum_find(&wifi_authmode_type, 1 << i)); } } } diff --git a/ports/espressif/common-hal/wifi/Radio.c b/ports/espressif/common-hal/wifi/Radio.c index 545af1d6cb..acd6ae53bc 100644 --- a/ports/espressif/common-hal/wifi/Radio.c +++ b/ports/espressif/common-hal/wifi/Radio.c @@ -165,7 +165,7 @@ void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, const uint esp_wifi_set_mac(ESP_IF_WIFI_AP, mac); } -mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) { +mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, uint8_t start_channel, uint8_t stop_channel) { if (self->current_scan != NULL) { mp_raise_RuntimeError(translate("Already scanning for wifi networks")); } @@ -177,9 +177,12 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) { wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t); scan->base.type = &wifi_scannednetworks_type; self->current_scan = scan; - scan->start_channel = 1; - scan->end_channel = 11; + scan->current_channel_index = 0; + scan->start_channel = start_channel; + scan->end_channel = stop_channel; scan->radio_event_group = self->event_group_handle; + scan->done = false; + scan->channel_scan_in_progress = false; wifi_scannednetworks_scan_next_channel(scan); return scan; } @@ -202,20 +205,21 @@ void common_hal_wifi_radio_stop_station(wifi_radio_obj_t *self) { set_mode_station(self, false); } -void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint8_t authmode, uint8_t max_connections) { +void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint32_t authmodes, uint8_t max_connections) { set_mode_ap(self, true); - switch (authmode) { - case (1 << AUTHMODE_OPEN): + uint8_t authmode = 0; + switch (authmodes) { + case AUTHMODE_OPEN: authmode = WIFI_AUTH_OPEN; break; - case ((1 << AUTHMODE_WPA) | (1 << AUTHMODE_PSK)): + case AUTHMODE_WPA | AUTHMODE_PSK: authmode = WIFI_AUTH_WPA_PSK; break; - case ((1 << AUTHMODE_WPA2) | (1 << AUTHMODE_PSK)): + case AUTHMODE_WPA2 | AUTHMODE_PSK: authmode = WIFI_AUTH_WPA2_PSK; break; - case ((1 << AUTHMODE_WPA) | (1 << AUTHMODE_WPA2) | (1 << AUTHMODE_PSK)): + case AUTHMODE_WPA | AUTHMODE_WPA2 | AUTHMODE_PSK: authmode = WIFI_AUTH_WPA_WPA2_PSK; break; default: @@ -336,6 +340,9 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t return WIFI_RADIO_ERROR_NO_AP_FOUND; } return self->last_disconnect_reason; + } else { + // We're connected, allow us to retry if we get disconnected. + self->retries_left = self->starting_retries; } return WIFI_RADIO_ERROR_NONE; } diff --git a/ports/espressif/common-hal/wifi/ScannedNetworks.c b/ports/espressif/common-hal/wifi/ScannedNetworks.c index 25c2da0473..50df9f8c95 100644 --- a/ports/espressif/common-hal/wifi/ScannedNetworks.c +++ b/ports/espressif/common-hal/wifi/ScannedNetworks.c @@ -72,7 +72,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) return mp_const_none; } // If we are scanning, wait and then load them. - if (self->scanning) { + if (self->channel_scan_in_progress) { // We may have to scan more than one channel to get a result. while (!self->done) { if (!wifi_scannednetworks_wait_for_scan(self)) { @@ -81,7 +81,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) } esp_wifi_scan_get_ap_num(&self->total_results); - self->scanning = false; + self->channel_scan_in_progress = false; if (self->total_results > 0) { break; } @@ -112,7 +112,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) } } esp_wifi_scan_get_ap_records(&self->total_results, self->results); - self->scanning = false; + self->channel_scan_in_progress = false; } wifi_network_obj_t *entry = m_new_obj(wifi_network_obj_t); @@ -132,40 +132,49 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) } // We don't do a linear scan so that we look at a variety of spectrum up front. -static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14}; +static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14, 0}; void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self) { - uint8_t next_channel = sizeof(scan_pattern); + // There is no channel 0, so use that as a flag to indicate we've run out of channels to scan. + uint8_t next_channel = 0; while (self->current_channel_index < sizeof(scan_pattern)) { next_channel = scan_pattern[self->current_channel_index]; self->current_channel_index++; + // Scan only channels that are in the specified range. if (self->start_channel <= next_channel && next_channel <= self->end_channel) { break; } } wifi_scan_config_t config = { 0 }; config.channel = next_channel; - if (next_channel == sizeof(scan_pattern)) { + if (next_channel == 0) { wifi_scannednetworks_done(self); } else { esp_err_t result = esp_wifi_scan_start(&config, false); if (result != ESP_OK) { wifi_scannednetworks_done(self); } else { - self->scanning = true; + self->channel_scan_in_progress = true; } } } void wifi_scannednetworks_deinit(wifi_scannednetworks_obj_t *self) { // if a scan is active, make sure and clean up the idf's buffer of results. - if (self->scanning) { + if (self->channel_scan_in_progress) { esp_wifi_scan_stop(); if (wifi_scannednetworks_wait_for_scan(self)) { - // Ignore the number of records since we're throwing them away. - uint16_t number = 0; - esp_wifi_scan_get_ap_records(&number, NULL); - self->scanning = false; + // Discard the scanned records, one at a time, to avoid memory leaks. + uint16_t number; + do { + number = 1; + wifi_ap_record_t record; + esp_wifi_scan_get_ap_records(&number, &record); + } while (number > 0); + // TODO: available in ESP-IDF v5.0; do instead of the above. + // Discard scan results. + // esp_wifi_clear_ap_list(); + self->channel_scan_in_progress = false; } } wifi_scannednetworks_done(self); diff --git a/ports/espressif/common-hal/wifi/ScannedNetworks.h b/ports/espressif/common-hal/wifi/ScannedNetworks.h index f089f27e3f..0ad4b5e3dc 100644 --- a/ports/espressif/common-hal/wifi/ScannedNetworks.h +++ b/ports/espressif/common-hal/wifi/ScannedNetworks.h @@ -53,7 +53,7 @@ typedef struct { uint8_t end_channel; // Inclusive bool done; - bool scanning; + bool channel_scan_in_progress; } wifi_scannednetworks_obj_t; void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self); diff --git a/ports/espressif/common-hal/wifi/__init__.c b/ports/espressif/common-hal/wifi/__init__.c index 885cc98f96..cfcfaf024b 100644 --- a/ports/espressif/common-hal/wifi/__init__.c +++ b/ports/espressif/common-hal/wifi/__init__.c @@ -46,6 +46,10 @@ wifi_radio_obj_t common_hal_wifi_radio_obj; #include "supervisor/port.h" #include "supervisor/workflow.h" +#if CIRCUITPY_STATUS_BAR +#include "supervisor/shared/status_bar.h" +#endif + #include "esp_ipc.h" #ifdef CONFIG_IDF_TARGET_ESP32 @@ -55,7 +59,9 @@ wifi_radio_obj_t common_hal_wifi_radio_obj; static const char *TAG = "CP wifi"; STATIC void schedule_background_on_cp_core(void *arg) { - supervisor_workflow_request_background(); + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_request_update(false); + #endif // CircuitPython's VM is run in a separate FreeRTOS task from wifi callbacks. So, we have to // notify the main task every time in case it's waiting for us. @@ -166,7 +172,7 @@ void common_hal_wifi_init(bool user_initiated) { // Even though we just called esp_netif_create_default_wifi_sta, // station mode isn't actually ready for use until esp_wifi_set_mode() // is called and the configuration is loaded via esp_wifi_set_config(). - // Set both convienence flags to false so it's not forgotten. + // Set both convenience flags to false so it's not forgotten. self->sta_mode = 0; self->ap_mode = 0; diff --git a/ports/espressif/esp-idf b/ports/espressif/esp-idf index 0180c0cb80..630c2724fc 160000 --- a/ports/espressif/esp-idf +++ b/ports/espressif/esp-idf @@ -1 +1 @@ -Subproject commit 0180c0cb80f052919badc15df164e8edde6344ad +Subproject commit 630c2724fc8c69eeaaa1bb025de52b99c5cb11aa diff --git a/ports/espressif/esp-idf-config/partitions-16MB-no-uf2.csv b/ports/espressif/esp-idf-config/partitions-16MB-no-uf2.csv new file mode 100644 index 0000000000..c4b103aed1 --- /dev/null +++ b/ports/espressif/esp-idf-config/partitions-16MB-no-uf2.csv @@ -0,0 +1,8 @@ +# Name, Type, SubType, Offset, Size +# bootloader, app, boot, 0x1000/0x0, 28/32K +# partition_table, data, table, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K +otadata, data, ota, 0xe000, 8K +ota_0, app, ota_0, 0x10000, 2048K +ota_1, app, ota_1, 0x210000, 2048K +user_fs, data, fat, 0x410000, 12224K diff --git a/ports/espressif/esp-idf-config/partitions-16MB.csv b/ports/espressif/esp-idf-config/partitions-16MB.csv index 13ea81bea5..16c73da32b 100644 --- a/ports/espressif/esp-idf-config/partitions-16MB.csv +++ b/ports/espressif/esp-idf-config/partitions-16MB.csv @@ -1,10 +1,9 @@ -# ESP-IDF Partition Table -# Name, Type, SubType, Offset, Size, Flags -# bootloader.bin,, 0x1000, 32K -# partition table,, 0x8000, 4K -nvs, data, nvs, 0x9000, 20K, -otadata, data, ota, 0xe000, 8K, -ota_0, 0, ota_0, 0x10000, 2048K, -ota_1, 0, ota_1, 0x210000, 2048K, -uf2, app, factory,0x410000, 256K, -user_fs, data, fat, 0x450000, 11968K, +# Name, Type, SubType, Offset, Size +# bootloader, app, boot, 0x1000/0x0, 28/32K +# partition_table, data, table, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K +otadata, data, ota, 0xe000, 8K +ota_0, app, ota_0, 0x10000, 2048K +ota_1, app, ota_1, 0x210000, 2048K +uf2, app, factory, 0x410000, 256K +user_fs, data, fat, 0x450000, 11968K diff --git a/ports/espressif/esp-idf-config/partitions-2MB-no-ota-no-uf2.csv b/ports/espressif/esp-idf-config/partitions-2MB-no-ota-no-uf2.csv new file mode 100644 index 0000000000..1c38195565 --- /dev/null +++ b/ports/espressif/esp-idf-config/partitions-2MB-no-ota-no-uf2.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size +# bootloader, app, boot, 0x1000/0x0, 28/32K +# partition_table, data, table, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K +app, app, factory, 0x10000, 1408K, +user_fs, data, fat, 0x170000, 576K, diff --git a/ports/espressif/esp-idf-config/partitions-2MB-no-uf2.csv b/ports/espressif/esp-idf-config/partitions-2MB-no-uf2.csv deleted file mode 100644 index 869e7ac86e..0000000000 --- a/ports/espressif/esp-idf-config/partitions-2MB-no-uf2.csv +++ /dev/null @@ -1,7 +0,0 @@ -# ESP-IDF Partition Table -# Name, Type, SubType, Offset, Size, Flags -# bootloader.bin,, 0x1000, 32K -# partition table,, 0x8000, 4K -nvs, data, nvs, 0x9000, 20K, -app, app, factory, 0x10000, 1408K, -user_fs, data, fat, 0x170000, 576K, diff --git a/ports/espressif/esp-idf-config/partitions-32MB.csv b/ports/espressif/esp-idf-config/partitions-32MB.csv new file mode 100644 index 0000000000..42c4084f6c --- /dev/null +++ b/ports/espressif/esp-idf-config/partitions-32MB.csv @@ -0,0 +1,9 @@ +# Name, Type, SubType, Offset, Size +# bootloader, app, boot, 0x1000/0x0, 28/32K +# partition_table, data, table, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K +otadata, data, ota, 0xe000, 8K +ota_0, app, ota_0, 0x10000, 2048K +ota_1, app, ota_1, 0x210000, 2048K +uf2, app, factory, 0x410000, 256K +user_fs, data, fat, 0x450000, 28352K diff --git a/ports/espressif/esp-idf-config/partitions-4MB-no-uf2.csv b/ports/espressif/esp-idf-config/partitions-4MB-no-uf2.csv index 90bf05ce39..6d27e22e76 100644 --- a/ports/espressif/esp-idf-config/partitions-4MB-no-uf2.csv +++ b/ports/espressif/esp-idf-config/partitions-4MB-no-uf2.csv @@ -1,7 +1,8 @@ -# ESP-IDF Partition Table -# Name, Type, SubType, Offset, Size, Flags -# bootloader.bin,, 0x1000, 32K -# partition table,, 0x8000, 4K -nvs, data, nvs, 0x9000, 20K, -app, app, factory, 0x10000, 2048K, -user_fs, data, fat, 0x210000, 1984K, +# Name, Type, SubType, Offset, Size +# bootloader, app, boot, 0x1000/0x0, 28/32K +# partition_table, data, table, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K +otadata, data, ota, 0xe000, 8K +ota_0, app, ota_0, 0x10000, 1408K +ota_1, app, ota_1, 0x170000, 1408K +user_fs, data, fat, 0x2d0000, 1216K diff --git a/ports/espressif/esp-idf-config/partitions-4MB.csv b/ports/espressif/esp-idf-config/partitions-4MB.csv index cf9b3cca84..981aee0b17 100644 --- a/ports/espressif/esp-idf-config/partitions-4MB.csv +++ b/ports/espressif/esp-idf-config/partitions-4MB.csv @@ -1,10 +1,9 @@ -# ESP-IDF Partition Table -# Name, Type, SubType, Offset, Size, Flags -# bootloader.bin,, 0x1000, 32K -# partition table,, 0x8000, 4K -nvs, data, nvs, 0x9000, 20K, -otadata, data, ota, 0xe000, 8K, -ota_0, 0, ota_0, 0x10000, 1408K, -ota_1, 0, ota_1, 0x170000, 1408K, -uf2, app, factory,0x2d0000, 256K, -user_fs, data, fat, 0x310000, 960K, +# Name, Type, SubType, Offset, Size +# bootloader, app, boot, 0x1000/0x0, 28/32K +# partition_table, data, table, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K +otadata, data, ota, 0xe000, 8K +ota_0, app, ota_0, 0x10000, 1408K +ota_1, app, ota_1, 0x170000, 1408K +uf2, app, factory, 0x2d0000, 256K +user_fs, data, fat, 0x310000, 960K diff --git a/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv b/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv index ba92d9fc73..6d78fe8af5 100644 --- a/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv +++ b/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv @@ -1,9 +1,8 @@ -# ESP-IDF Partition Table -# Name, Type, SubType, Offset, Size, Flags -# bootloader.bin,, 0x1000, 32K -# partition table,, 0x8000, 4K -nvs, data, nvs, 0x9000, 20K, -otadata, data, ota, 0xe000, 8K, -ota_0, app, ota_0, 0x10000, 2048K, -ota_1, app, ota_1, 0x210000, 2048K, -user_fs, data, fat, 0x410000, 4032K, +# Name, Type, SubType, Offset, Size +# bootloader, app, boot, 0x1000/0x0, 28/32K +# partition_table, data, table, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K +otadata, data, ota, 0xe000, 8K +ota_0, app, ota_0, 0x10000, 2048K +ota_1, app, ota_1, 0x210000, 2048K +user_fs, data, fat, 0x410000, 4032K diff --git a/ports/espressif/esp-idf-config/partitions-8MB.csv b/ports/espressif/esp-idf-config/partitions-8MB.csv index f4ba9b60a1..40674d322c 100644 --- a/ports/espressif/esp-idf-config/partitions-8MB.csv +++ b/ports/espressif/esp-idf-config/partitions-8MB.csv @@ -1,10 +1,9 @@ -# ESP-IDF Partition Table -# Name, Type, SubType, Offset, Size, Flags -# bootloader.bin,, 0x1000, 32K -# partition table,, 0x8000, 4K -nvs, data, nvs, 0x9000, 20K, -otadata, data, ota, 0xe000, 8K, -ota_0, 0, ota_0, 0x10000, 2048K, -ota_1, 0, ota_1, 0x210000, 2048K, -uf2, app, factory,0x410000, 256K, -user_fs, data, fat, 0x450000, 3776K, +# Name, Type, SubType, Offset, Size +# bootloader, app, boot, 0x1000/0x0, 28/32K +# partition_table, data, table, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K +otadata, data, ota, 0xe000, 8K +ota_0, app, ota_0, 0x10000, 2048K +ota_1, app, ota_1, 0x210000, 2048K +uf2, app, factory, 0x410000, 256K +user_fs, data, fat, 0x450000, 3776K diff --git a/ports/espressif/esp-idf-config/sdkconfig-16MB-no-uf2.defaults b/ports/espressif/esp-idf-config/sdkconfig-16MB-no-uf2.defaults new file mode 100644 index 0000000000..6065abcd93 --- /dev/null +++ b/ports/espressif/esp-idf-config/sdkconfig-16MB-no-uf2.defaults @@ -0,0 +1,18 @@ +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="16MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +# end of Serial flasher config + +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-16MB-no-uf2.csv" +# +# Partition Table +# +CONFIG_PARTITION_TABLE_FILENAME="esp-idf-config/partitions-16MB-no-uf2.csv" +# end of Partition Table diff --git a/ports/espressif/esp-idf-config/sdkconfig-2MB-no-uf2.defaults b/ports/espressif/esp-idf-config/sdkconfig-2MB-no-ota-no-uf2.defaults similarity index 92% rename from ports/espressif/esp-idf-config/sdkconfig-2MB-no-uf2.defaults rename to ports/espressif/esp-idf-config/sdkconfig-2MB-no-ota-no-uf2.defaults index 7c4c4baddd..2d0b2ac5eb 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-2MB-no-uf2.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-2MB-no-ota-no-uf2.defaults @@ -10,9 +10,9 @@ CONFIG_ESPTOOLPY_FLASHSIZE="2MB" CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y # end of Serial flasher config -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-2MB-no-uf2.csv" +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-2MB-no-ota-no-uf2.csv" # # Partition Table # -CONFIG_PARTITION_TABLE_FILENAME="esp-idf-config/partitions-2MB-no-uf2.csv" +CONFIG_PARTITION_TABLE_FILENAME="esp-idf-config/partitions-2MB-no-ota-no-uf2.csv" # end of Partition Table diff --git a/ports/espressif/esp-idf-config/sdkconfig-32MB.defaults b/ports/espressif/esp-idf-config/sdkconfig-32MB.defaults new file mode 100644 index 0000000000..bbdd32afb8 --- /dev/null +++ b/ports/espressif/esp-idf-config/sdkconfig-32MB.defaults @@ -0,0 +1,19 @@ +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_32MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="32MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +# end of Serial flasher config + +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-32MB.csv" +# +# Partition Table +# +CONFIG_PARTITION_TABLE_FILENAME="esp-idf-config/partitions-32MB.csv" +# end of Partition Table diff --git a/ports/espressif/esp-idf-config/sdkconfig-debug.defaults b/ports/espressif/esp-idf-config/sdkconfig-debug.defaults index 9d02c62445..bef5ee5fe8 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-debug.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-debug.defaults @@ -5,6 +5,12 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set # end of Bootloader config # CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set @@ -60,6 +66,17 @@ CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 # end of Hardware Abstraction Layer (HAL) and Low Level (LL) +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +# end of Log output + CONFIG_LWIP_ESP_LWIP_ASSERT=y # # Deprecated options for backward compatibility diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults index 6c244f3bbe..b6c5a938b1 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults @@ -1,3 +1,6 @@ +# +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# CONFIG_IDF_TARGET_ARCH_XTENSA=y CONFIG_IDF_TARGET="esp32" CONFIG_IDF_TARGET_ESP32=y @@ -112,19 +115,6 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 # end of Serial flasher config -# -# Partition Table -# -# CONFIG_PARTITION_TABLE_SINGLE_APP is not set -# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set -# CONFIG_PARTITION_TABLE_TWO_OTA is not set -CONFIG_PARTITION_TABLE_CUSTOM=y -# CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-8MB-no-uf2.csv" -# CONFIG_PARTITION_TABLE_FILENAME="esp-idf-config/partitions-8MB-no-uf2.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 -CONFIG_PARTITION_TABLE_MD5=y -# end of Partition Table - # # Compiler options # @@ -323,8 +313,8 @@ CONFIG_SPIRAM_SPIWP_SD3_PIN=7 # CONFIG_ESP32_TRAX is not set CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32_ULP_COPROC_ENABLED is not set -CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32_ULP_COPROC_ENABLED=y +CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=4080 CONFIG_ESP32_DEBUG_OCDAWARE=y CONFIG_ESP32_BROWNOUT_DET=y CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y @@ -473,23 +463,16 @@ CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y # CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set # CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 # CONFIG_ESP_CONSOLE_UART_DEFAULT is not set -CONFIG_ESP_CONSOLE_UART_CUSTOM=y -# CONFIG_ESP_CONSOLE_NONE is not set -CONFIG_ESP_CONSOLE_UART=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +CONFIG_ESP_CONSOLE_NONE=y CONFIG_ESP_CONSOLE_MULTIPLE_UART=y -CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y -# CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_UART_TX_GPIO=8 -CONFIG_ESP_CONSOLE_UART_RX_GPIO=7 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_CONSOLE_UART_NUM=-1 CONFIG_ESP_INT_WDT=y CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y @@ -615,29 +598,10 @@ CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set # end of Heap memory debugging -# -# Log output -# -# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set -# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -CONFIG_LOG_DEFAULT_LEVEL_INFO=y -# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=3 -CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y -# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set -# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set -CONFIG_LOG_MAXIMUM_LEVEL=3 -CONFIG_LOG_COLORS=y -CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y -# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="Adafruit-Feather-ESP32-V2" # CONFIG_LWIP_NETIF_API is not set # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y @@ -812,7 +776,7 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y -CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="certificates/nina-fw/data/roots.pem" +CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="../../lib/certificates/nina-fw/data/roots.pem" # end of Certificate Bundle CONFIG_MBEDTLS_ECP_RESTARTABLE=y @@ -1081,7 +1045,6 @@ CONFIG_STACK_CHECK_NONE=y CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y CONFIG_ADC2_DISABLE_DAC=y -CONFIG_SPIRAM_SUPPORT=y CONFIG_TRACEMEM_RESERVE_DRAM=0x0 # CONFIG_ULP_COPROC_ENABLED is not set CONFIG_ULP_COPROC_RESERVE_MEM=0 @@ -1121,17 +1084,10 @@ CONFIG_ESP32S2_PANIC_PRINT_HALT=y # CONFIG_ESP32S2_PANIC_GDBSTUB is not set CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=8192 # CONFIG_CONSOLE_UART_DEFAULT is not set -CONFIG_CONSOLE_UART_CUSTOM=y -# CONFIG_ESP_CONSOLE_UART_NONE is not set -CONFIG_CONSOLE_UART=y -CONFIG_CONSOLE_UART_CUSTOM_NUM_0=y -# CONFIG_CONSOLE_UART_CUSTOM_NUM_1 is not set -CONFIG_CONSOLE_UART_NUM=0 -CONFIG_CONSOLE_UART_TX_GPIO=8 -CONFIG_CONSOLE_UART_RX_GPIO=7 -CONFIG_CONSOLE_UART_BAUDRATE=115200 +# CONFIG_CONSOLE_UART_CUSTOM is not set +CONFIG_ESP_CONSOLE_UART_NONE=y +CONFIG_CONSOLE_UART_NUM=-1 CONFIG_INT_WDT=y CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32c3.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32c3.defaults index 5b5df1837c..5fdb766add 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32c3.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32c3.defaults @@ -80,6 +80,12 @@ CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y # end of Hardware Settings +# +# PHY +# +CONFIG_ESP_PHY_ENABLE_USB=y +# end of PHY + # # ESP System Settings # @@ -97,8 +103,12 @@ CONFIG_ESP_SYSTEM_MEMPROT_MEM_ALIGN_SIZE=512 CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y # CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 + +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y +# CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG is not set # end of ESP System Settings + # # Wi-Fi # diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults index ac3e909dfc..bfd64ef90e 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults @@ -41,8 +41,9 @@ CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y # CONFIG_ESP32S2_TRAX is not set CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32S2_ULP_COPROC_ENABLED is not set -CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32S2_ULP_COPROC_ENABLED=y +CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=8176 +CONFIG_ESP32S2_ULP_COPROC_RISCV=y CONFIG_ESP32S2_DEBUG_OCDAWARE=y # CONFIG_ESP32S2_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32S2_BROWNOUT_DET=y @@ -65,7 +66,7 @@ CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 # CONFIG_ESP32S2_NO_BLOBS is not set # CONFIG_ESP32S2_KEEP_USB_ALIVE is not set -# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set +CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y # CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set # # MAC Config diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults index bfb867d923..f6fb80c752 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults @@ -67,8 +67,9 @@ CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32 # CONFIG_ESP32S3_TRAX is not set CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32S3_ULP_COPROC_ENABLED is not set -CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32S3_ULP_COPROC_ENABLED=y +CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=8176 +CONFIG_ESP32S3_ULP_COPROC_RISCV=y CONFIG_ESP32S3_BROWNOUT_DET=y CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y # CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set @@ -88,7 +89,7 @@ CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y # CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000 -# CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM is not set +CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM=y # CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE is not set # end of ESP32S3-Specific @@ -191,3 +192,30 @@ CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" # end of Deprecated options for backward compatibility + +# +# Camera configuration +# +CONFIG_OV7670_SUPPORT=y +# CONFIG_OV7725_SUPPORT is not set +# CONFIG_NT99141_SUPPORT is not set +CONFIG_OV2640_SUPPORT=y +CONFIG_OV3660_SUPPORT=y +CONFIG_OV5640_SUPPORT=y +# CONFIG_GC2145_SUPPORT is not set +# CONFIG_GC032A_SUPPORT is not set +# CONFIG_GC0308_SUPPORT is not set +# CONFIG_BF3005_SUPPORT is not set +# CONFIG_BF20A6_SUPPORT is not set +# CONFIG_SC101IOT_SUPPORT is not set +# CONFIG_SC030IOT_SUPPORT is not set +# CONFIG_SCCB_HARDWARE_I2C_PORT0 is not set +CONFIG_SCCB_HARDWARE_I2C_PORT1=y +CONFIG_SCCB_CLK_FREQ=100000 +CONFIG_CAMERA_CORE0=y +# CONFIG_CAMERA_CORE1 is not set +# CONFIG_CAMERA_NO_AFFINITY is not set +CONFIG_CAMERA_DMA_BUFFER_SIZE_MAX=32768 +# CONFIG_CAMERA_CONVERTER_ENABLED is not set +# end of Camera configuration +# end of Component config diff --git a/ports/espressif/esp-idf-config/sdkconfig-opt.defaults b/ports/espressif/esp-idf-config/sdkconfig-opt.defaults index e9b91113d5..1ccd6478fe 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-opt.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-opt.defaults @@ -5,6 +5,12 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set # end of Bootloader config # @@ -73,6 +79,17 @@ CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=1 # end of Hardware Abstraction Layer (HAL) and Low Level (LL) +# +# Log output +# +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +# end of Log output + # # LWIP # diff --git a/ports/espressif/esp-idf-config/sdkconfig.defaults b/ports/espressif/esp-idf-config/sdkconfig.defaults index f30e8c1109..b183cd630d 100644 --- a/ports/espressif/esp-idf-config/sdkconfig.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig.defaults @@ -294,7 +294,7 @@ CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384 CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 CONFIG_ESP_INT_WDT=y CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 @@ -572,7 +572,7 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y -CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="certificates/nina-fw/data/roots.pem" +CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="../../lib/certificates/nina-fw/data/roots.pem" # end of Certificate Bundle CONFIG_MBEDTLS_ECP_RESTARTABLE=y diff --git a/ports/espressif/esp32-camera b/ports/espressif/esp32-camera new file mode 160000 index 0000000000..4ff7f348d0 --- /dev/null +++ b/ports/espressif/esp32-camera @@ -0,0 +1 @@ +Subproject commit 4ff7f348d0713ea8eca022f73a059b0fe0934531 diff --git a/ports/espressif/mpconfigport.h b/ports/espressif/mpconfigport.h index 72a9b32478..c296be2024 100644 --- a/ports/espressif/mpconfigport.h +++ b/ports/espressif/mpconfigport.h @@ -33,6 +33,8 @@ #define MICROPY_USE_INTERNAL_PRINTF (0) #define MICROPY_PY_SYS_PLATFORM "Espressif" +#define CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY (1) + #include "py/circuitpy_mpconfig.h" #if CIRCUITPY_BLEIO @@ -90,4 +92,13 @@ #define CIRCUITPY_ESP_USB_SERIAL_JTAG (0) #endif +#ifndef DEFAULT_RESERVED_PSRAM +#define DEFAULT_RESERVED_PSRAM (0) +#endif + +#if defined(CONFIG_SPIRAM) +#undef CIRCUITPY_PORT_NUM_SUPERVISOR_ALLOCATIONS +#define CIRCUITPY_PORT_NUM_SUPERVISOR_ALLOCATIONS (1) +#endif + #endif // MICROPY_INCLUDED_ESPRESSIF_MPCONFIGPORT_H diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk index 457dd21a3d..79515619ea 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -1,73 +1,95 @@ +# Use internal flash for CIRCUITPY drive +INTERNAL_FLASH_FILESYSTEM = 1 + # Internal math library is substantially smaller than toolchain one INTERNAL_LIBM = 1 # Longints can be implemented as mpz, as longlong, or not LONGINT_IMPL = MPZ -# These modules are implemented in ports//common-hal: +# Enable more features CIRCUITPY_FULL_BUILD ?= 1 + +# These modules are implemented in ports//common-hal: CIRCUITPY_ALARM ?= 1 -CIRCUITPY_AUDIOCORE ?= 1 -CIRCUITPY_AUDIOMP3 ?= 0 +CIRCUITPY_ANALOGBUFIO ?= 1 CIRCUITPY_AUDIOBUSIO ?= 1 -CIRCUITPY_AUDIOBUSIO_PDMIN ?= 0 CIRCUITPY_AUDIOBUSIO_I2SOUT ?= 1 +CIRCUITPY_AUDIOBUSIO_PDMIN ?= 0 +CIRCUITPY_AUDIOCORE ?= 1 CIRCUITPY_AUDIOIO ?= 0 CIRCUITPY_AUDIOMIXER ?= 1 +CIRCUITPY_AUDIOMP3 ?= 0 +CIRCUITPY_BLEIO ?= 1 +CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_CANIO ?= 1 CIRCUITPY_COUNTIO ?= 1 CIRCUITPY_DUALBANK ?= 1 +CIRCUITPY_ESPCAMERA ?= 1 +CIRCUITPY_ESPIDF ?= 1 +CIRCUITPY_ESPULP ?= 1 CIRCUITPY_FRAMEBUFFERIO ?= 1 CIRCUITPY_FREQUENCYIO ?= 1 CIRCUITPY_HASHLIB ?= 1 -CIRCUITPY_IMAGECAPTURE ?= 1 -CIRCUITPY_I2CPERIPHERAL ?= 1 -CIRCUITPY_RGBMATRIX ?= 1 -CIRCUITPY_ROTARYIO ?= 1 +CIRCUITPY_I2CTARGET ?= 1 +CIRCUITPY_IMAGECAPTURE = 0 +CIRCUITPY_MEMORYMAP ?= 1 CIRCUITPY_NVM ?= 1 CIRCUITPY_PS2IO ?= 1 +CIRCUITPY_RGBMATRIX ?= 1 +CIRCUITPY_ROTARYIO ?= 1 CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1 -CIRCUITPY_WIFI ?= 1 CIRCUITPY_WATCHDOG ?= 1 +CIRCUITPY_WIFI ?= 1 -CIRCUITPY_ESPIDF ?= 1 - +# Conditionally turn off modules/features ifeq ($(IDF_TARGET),esp32) +# Modules CIRCUITPY_BLEIO = 0 -CIRCUITPY_BLEIO_HCI = 0 -CIRCUITPY_IMAGECAPTURE = 0 CIRCUITPY_PARALLELDISPLAY = 0 -# Protomatter needs to support ESP32. CIRCUITPY_RGBMATRIX = 0 +# Features CIRCUITPY_USB = 0 else ifeq ($(IDF_TARGET),esp32c3) -CIRCUITPY_AESIO = 0 +# Modules CIRCUITPY_ALARM = 0 CIRCUITPY_AUDIOBUSIO = 0 -CIRCUITPY_BLEIO = 1 -CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_COUNTIO = 0 -CIRCUITPY_DUALBANK = 0 +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_ESPULP = 0 CIRCUITPY_FREQUENCYIO = 0 -CIRCUITPY_IMAGECAPTURE = 0 +CIRCUITPY_MEMORYMAP = 0 CIRCUITPY_PARALLELDISPLAY = 0 -CIRCUITPY_PS2IO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_TOUCHIO ?= 1 CIRCUITPY_TOUCHIO_USE_NATIVE = 0 +# Features CIRCUITPY_USB = 0 -else ifeq ($(IDF_TARGET),esp32s3) -CIRCUITPY_BLEIO = 1 -CIRCUITPY_BLEIO_HCI = 0 -CIRCUITPY_IMAGECAPTURE = 0 -CIRCUITPY_PARALLELDISPLAY = 0 - else ifeq ($(IDF_TARGET),esp32s2) -# No BLE on S2 +# Modules CIRCUITPY_BLEIO = 0 -CIRCUITPY_BLEIO_HCI = 0 + +else ifeq ($(IDF_TARGET),esp32s3) +# Modules +CIRCUITPY_PARALLELDISPLAY = 0 +endif + +# No room for dualbank on boards with 2MB flash +ifeq ($(CIRCUITPY_ESP_FLASH_SIZE),2MB) +CIRCUITPY_DUALBANK = 0 +endif + +# Modules dependent on other modules +CIRCUITPY_GIFIO ?= $(CIRCUITPY_ESPCAMERA) +CIRCUITPY_QRIO ?= $(CIRCUITPY_ESPCAMERA) + +# Features dependent on other features +ifneq ($(CIRCUITPY_USB),0) +CIRCUITPY_BUILD_EXTENSIONS ?= bin,uf2 +else +CIRCUITPY_BUILD_EXTENSIONS ?= bin endif # From ESP32-S2/S3 Technical Reference Manual: diff --git a/ports/espressif/peripherals/rmt.c b/ports/espressif/peripherals/rmt.c index 362bf85748..8dea2c0ab1 100644 --- a/ports/espressif/peripherals/rmt.c +++ b/ports/espressif/peripherals/rmt.c @@ -40,6 +40,14 @@ void peripherals_rmt_reset(void) { rmt_channel_t peripherals_find_and_reserve_rmt(bool mode) { size_t start_channel = 0; size_t end_channel = RMT_CHANNEL_MAX; + // ESP32C3 can only send on channels 0-1 and receive on channels 2-3 + #if defined(CONFIG_IDF_TARGET_ESP32C3) + if (mode == RECEIVE_MODE) { + start_channel = 2; + } else { + end_channel = 2; + } + #endif // ESP32C3 #if SOC_RMT_CHANNELS_PER_GROUP > 4 if (mode == RECEIVE_MODE) { start_channel = 4; diff --git a/ports/espressif/peripherals/touch.c b/ports/espressif/peripherals/touch.c index e656bbddf1..9cf718b501 100644 --- a/ports/espressif/peripherals/touch.c +++ b/ports/espressif/peripherals/touch.c @@ -43,7 +43,7 @@ void peripherals_touch_never_reset(const bool enable) { void peripherals_touch_init(const touch_pad_t touchpad) { if (!touch_inited) { touch_pad_init(); - touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW); } // touch_pad_config() must be done before touch_pad_fsm_start() the first time. // Otherwise the calibration is wrong and we get maximum raw values if there is @@ -52,13 +52,27 @@ void peripherals_touch_init(const touch_pad_t touchpad) { touch_pad_config(touchpad, 0); #else touch_pad_config(touchpad); + touch_pad_fsm_start(); + #endif + touch_inited = true; +} + +uint16_t peripherals_touch_read(touch_pad_t touchpad) { + #if defined(CONFIG_IDF_TARGET_ESP32) + uint16_t touch_value; + touch_pad_read(touchpad, &touch_value); + // ESP32 touch_pad_read() returns a lower value when a pin is touched instead of a higher value. + // Flip the values around to be consistent with TouchIn assumptions. + return UINT16_MAX - touch_value; + #else + uint32_t touch_value; + touch_pad_sw_start(); + while (!touch_pad_meas_is_done()) { + } + touch_pad_read_raw_data(touchpad, &touch_value); + if (touch_value > UINT16_MAX) { + return UINT16_MAX; + } + return (uint16_t)touch_value; #endif - if (!touch_inited) { - #if defined(CONFIG_IDF_TARGET_ESP32) - touch_pad_sw_start(); - #else - touch_pad_fsm_start(); - #endif - touch_inited = true; - } } diff --git a/ports/espressif/peripherals/touch.h b/ports/espressif/peripherals/touch.h index c7cd1f6be1..5feba4410a 100644 --- a/ports/espressif/peripherals/touch.h +++ b/ports/espressif/peripherals/touch.h @@ -29,6 +29,7 @@ #include "driver/touch_pad.h" +extern uint16_t peripherals_touch_read(touch_pad_t touchpad); extern void peripherals_touch_reset(void); extern void peripherals_touch_never_reset(const bool enable); extern void peripherals_touch_init(const touch_pad_t touchpad); diff --git a/ports/espressif/supervisor/internal_flash.c b/ports/espressif/supervisor/internal_flash.c index 2f17b48f0c..d6e96732ba 100644 --- a/ports/espressif/supervisor/internal_flash.c +++ b/ports/espressif/supervisor/internal_flash.c @@ -24,6 +24,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + #include "supervisor/internal_flash.h" #include @@ -32,27 +33,52 @@ #include "extmod/vfs.h" #include "extmod/vfs_fat.h" + #include "py/mphal.h" #include "py/obj.h" #include "py/runtime.h" -#include "lib/oofatfs/ff.h" -#include "components/spi_flash/include/esp_partition.h" +#include "esp_ota_ops.h" +#include "esp_partition.h" +#include "supervisor/filesystem.h" #include "supervisor/flash.h" #include "supervisor/usb.h" -STATIC const esp_partition_t *_partition; +#define OP_READ 0 +#define OP_WRITE 1 // TODO: Split the caching out of supervisor/shared/external_flash so we can use it. #define SECTOR_SIZE 4096 STATIC uint8_t _cache[SECTOR_SIZE]; STATIC uint32_t _cache_lba = 0xffffffff; +#if CIRCUITPY_STORAGE_EXTEND +#if FF_MAX_SS == FF_MIN_SS +#define SECSIZE(fs) (FF_MIN_SS) +#else +#define SECSIZE(fs) ((fs)->ssize) +#endif // FF_MAX_SS == FF_MIN_SS +STATIC DWORD fatfs_bytes(void) { + FATFS *fatfs = filesystem_circuitpy(); + return (fatfs->csize * SECSIZE(fatfs)) * (fatfs->n_fatent - 2); +} +STATIC bool storage_extended = true; +STATIC const esp_partition_t *_partition[2]; +#else +STATIC const esp_partition_t *_partition[1]; +#endif // CIRCUITPY_STORAGE_EXTEND + void supervisor_flash_init(void) { - _partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, + if (_partition[0] != NULL) { + return; + } + _partition[0] = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL); + #if CIRCUITPY_STORAGE_EXTEND + _partition[1] = esp_ota_get_next_update_partition(NULL); + #endif } uint32_t supervisor_flash_get_block_size(void) { @@ -60,19 +86,61 @@ uint32_t supervisor_flash_get_block_size(void) { } uint32_t supervisor_flash_get_block_count(void) { - return _partition->size / FILESYSTEM_BLOCK_SIZE; + #if CIRCUITPY_STORAGE_EXTEND + return ((storage_extended) ? (_partition[0]->size + _partition[1]->size) : _partition[0]->size) / FILESYSTEM_BLOCK_SIZE; + #else + return _partition[0]->size / FILESYSTEM_BLOCK_SIZE; + #endif } void port_internal_flash_flush(void) { - } +STATIC void single_partition_rw(const esp_partition_t *partition, uint8_t *data, + const uint32_t offset, const uint32_t size_total, const bool op) { + if (op == OP_READ) { + esp_partition_read(partition, offset, data, size_total); + } else { + esp_partition_erase_range(partition, offset, size_total); + esp_partition_write(partition, offset, _cache, size_total); + } +} + +#if CIRCUITPY_STORAGE_EXTEND +STATIC void multi_partition_rw(uint8_t *data, + const uint32_t offset, const uint32_t size_total, const bool op) { + if (offset > _partition[0]->size) { + // only r/w partition 1 + single_partition_rw(_partition[1], data, (offset - _partition[0]->size), size_total, op); + } else if ((offset + size_total) > _partition[0]->size) { + // first r/w partition 0, then partition 1 + uint32_t size_0 = _partition[0]->size - offset; + uint32_t size_1 = size_total - size_0; + if (op == OP_READ) { + esp_partition_read(_partition[0], offset, data, size_0); + esp_partition_read(_partition[1], 0, (data + size_0), size_1); + } else { + esp_partition_erase_range(_partition[0], offset, size_0); + esp_partition_write(_partition[0], offset, _cache, size_0); + esp_partition_erase_range(_partition[1], 0, size_1); + esp_partition_write(_partition[1], 0, (_cache + size_0), size_1); + } + } else { + // only r/w partition 0 + single_partition_rw(_partition[0], data, offset, size_total, op); + } +} +#endif + mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { - esp_partition_read(_partition, - block * FILESYSTEM_BLOCK_SIZE, - dest, - num_blocks * FILESYSTEM_BLOCK_SIZE); - return 0; + const uint32_t offset = block * FILESYSTEM_BLOCK_SIZE; + const uint32_t read_total = num_blocks * FILESYSTEM_BLOCK_SIZE; + #if CIRCUITPY_STORAGE_EXTEND + multi_partition_rw(dest, offset, read_total, OP_READ); + #else + single_partition_rw(_partition[0], dest, offset, read_total, OP_READ); + #endif + return 0; // success } mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) { @@ -82,12 +150,8 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32 uint32_t block_address = lba + block; uint32_t sector_offset = block_address / blocks_per_sector * SECTOR_SIZE; uint8_t block_offset = block_address % blocks_per_sector; - if (_cache_lba != block_address) { - esp_partition_read(_partition, - sector_offset, - _cache, - SECTOR_SIZE); + supervisor_flash_read_blocks(_cache, sector_offset / FILESYSTEM_BLOCK_SIZE, blocks_per_sector); _cache_lba = sector_offset; } for (uint8_t b = block_offset; b < blocks_per_sector; b++) { @@ -100,15 +164,34 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32 FILESYSTEM_BLOCK_SIZE); block++; } - esp_partition_erase_range(_partition, sector_offset, SECTOR_SIZE); - esp_partition_write(_partition, - sector_offset, - _cache, - SECTOR_SIZE); + #if CIRCUITPY_STORAGE_EXTEND + multi_partition_rw(_cache, sector_offset, SECTOR_SIZE, OP_WRITE); + #else + single_partition_rw(_partition[0], _cache, sector_offset, SECTOR_SIZE, OP_READ); + #endif } - return 0; // success } void supervisor_flash_release_cache(void) { } + +void supervisor_flash_set_extended(bool extended) { + #if CIRCUITPY_STORAGE_EXTEND + storage_extended = extended; + #endif +} + +bool supervisor_flash_get_extended(void) { + #if CIRCUITPY_STORAGE_EXTEND + return storage_extended; + #else + return false; + #endif +} + +void supervisor_flash_update_extended(void) { + #if CIRCUITPY_STORAGE_EXTEND + storage_extended = (_partition[0]->size < fatfs_bytes()); + #endif +} diff --git a/ports/espressif/supervisor/port.c b/ports/espressif/supervisor/port.c index adefff3f71..a71825afa5 100644 --- a/ports/espressif/supervisor/port.c +++ b/ports/espressif/supervisor/port.c @@ -29,12 +29,15 @@ #include #include "supervisor/board.h" #include "supervisor/port.h" +#include "supervisor/filesystem.h" +#include "supervisor/shared/reload.h" #include "py/runtime.h" -#include "supervisor/esp_port.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "bindings/espidf/__init__.h" +#include "bindings/espulp/__init__.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/analogio/AnalogOut.h" #include "common-hal/busio/I2C.h" @@ -54,6 +57,7 @@ #include "shared-bindings/microcontroller/RunMode.h" #include "shared-bindings/rtc/__init__.h" #include "shared-bindings/socketpool/__init__.h" +#include "shared-module/os/__init__.h" #include "peripherals/rmt.h" #include "peripherals/timer.h" @@ -74,34 +78,30 @@ #include "shared-bindings/_bleio/__init__.h" #endif -#if CIRCUITPY_IMAGECAPTURE -#include "cam.h" +#if CIRCUITPY_ESPCAMERA +#include "esp_camera.h" #endif #ifndef CONFIG_IDF_TARGET_ESP32 #include "soc/cache_memory.h" #endif +#include "soc/efuse_reg.h" #include "soc/rtc_cntl_reg.h" #include "esp_debug_helpers.h" +#include "bootloader_flash_config.h" +#include "esp_efuse.h" #include "esp_ipc.h" +#include "esp_rom_efuse.h" -#ifdef CONFIG_SPIRAM -#include "esp32/spiram.h" #ifdef CONFIG_IDF_TARGET_ESP32 -#include "esp32/himem.h" -#else -#define esp_himem_reserved_area_size() (0) +#include "esp32/rom/efuse.h" #endif -static size_t spiram_size_usable(void) { - /* SPIRAM chip may be larger than the size we can map into address space */ - size_t s = MIN(esp_spiram_get_size(), SOC_EXTRAM_DATA_SIZE); - return s - esp_himem_reserved_area_size(); -} -#endif +#include "esp_log.h" +#define TAG "port" uint32_t *heap; uint32_t heap_size; @@ -135,6 +135,97 @@ STATIC void tick_timer_cb(void *arg) { void sleep_timer_cb(void *arg); +// The ESP-IDF determines these pins at runtime so we do too. This code is based on: +// https://github.com/espressif/esp-idf/blob/6d85d53ceec30c818a92c2fff8f5437d21c4720f/components/esp_hw_support/port/esp32/spiram_psram.c#L810 +// IO-pins for PSRAM. +// WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines +// hardcode the flash pins as well, making this code incompatible with either a setup +// that has the flash on non-standard pins or ESP32s with built-in flash. +#define PSRAM_SPIQ_SD0_IO 7 +#define PSRAM_SPID_SD1_IO 8 +#define PSRAM_SPIWP_SD3_IO 10 +#define PSRAM_SPIHD_SD2_IO 9 + +#define FLASH_HSPI_CLK_IO 14 +#define FLASH_HSPI_CS_IO 15 +#define PSRAM_HSPI_SPIQ_SD0_IO 12 +#define PSRAM_HSPI_SPID_SD1_IO 13 +#define PSRAM_HSPI_SPIWP_SD3_IO 2 +#define PSRAM_HSPI_SPIHD_SD2_IO 4 + +#ifdef CONFIG_SPIRAM +// PSRAM clock and cs IO should be configured based on hardware design. +// For ESP32-WROVER or ESP32-WROVER-B module, the clock IO is IO17, the cs IO is IO16, +// they are the default value for these two configs. +#define D0WD_PSRAM_CLK_IO CONFIG_D0WD_PSRAM_CLK_IO // Default value is 17 +#define D0WD_PSRAM_CS_IO CONFIG_D0WD_PSRAM_CS_IO // Default value is 16 + +#define D2WD_PSRAM_CLK_IO CONFIG_D2WD_PSRAM_CLK_IO // Default value is 9 +#define D2WD_PSRAM_CS_IO CONFIG_D2WD_PSRAM_CS_IO // Default value is 10 + +// There is no reason to change the pin of an embedded psram. +// So define the number of pin directly, instead of configurable. +#define D0WDR2_V3_PSRAM_CLK_IO 6 +#define D0WDR2_V3_PSRAM_CS_IO 16 + +// For ESP32-PICO chip, the psram share clock with flash. The flash clock pin is fixed, which is IO6. +#define PICO_PSRAM_CLK_IO 6 +#define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO // Default value is 10 + +#define PICO_V3_02_PSRAM_CLK_IO 10 +#define PICO_V3_02_PSRAM_CS_IO 9 +#endif // CONFIG_SPIRAM + +static void _never_reset_spi_ram_flash(void) { + #if defined(CONFIG_IDF_TARGET_ESP32) + #if defined(CONFIG_SPIRAM) + uint32_t pkg_ver = esp_efuse_get_pkg_ver(); + if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) { + never_reset_pin_number(D2WD_PSRAM_CLK_IO); + never_reset_pin_number(D2WD_PSRAM_CS_IO); + } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4 && esp_efuse_get_chip_ver() >= 3) { + // This chip is ESP32-PICO-V3 and doesn't have PSRAM. + } else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) { + never_reset_pin_number(PICO_PSRAM_CLK_IO); + never_reset_pin_number(PICO_PSRAM_CS_IO); + } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOV302) { + never_reset_pin_number(PICO_V3_02_PSRAM_CLK_IO); + never_reset_pin_number(PICO_V3_02_PSRAM_CS_IO); + } else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ6) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDQ5)) { + never_reset_pin_number(D0WD_PSRAM_CLK_IO); + never_reset_pin_number(D0WD_PSRAM_CS_IO); + } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D0WDR2V3) { + never_reset_pin_number(D0WDR2_V3_PSRAM_CLK_IO); + never_reset_pin_number(D0WDR2_V3_PSRAM_CS_IO); + } + #endif // CONFIG_SPIRAM + + const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); + if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) { + never_reset_pin_number(SPI_IOMUX_PIN_NUM_CLK); + never_reset_pin_number(SPI_IOMUX_PIN_NUM_CS); + never_reset_pin_number(PSRAM_SPIQ_SD0_IO); + never_reset_pin_number(PSRAM_SPID_SD1_IO); + never_reset_pin_number(PSRAM_SPIWP_SD3_IO); + never_reset_pin_number(PSRAM_SPIHD_SD2_IO); + } else if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_HSPI) { + never_reset_pin_number(FLASH_HSPI_CLK_IO); + never_reset_pin_number(FLASH_HSPI_CS_IO); + never_reset_pin_number(PSRAM_HSPI_SPIQ_SD0_IO); + never_reset_pin_number(PSRAM_HSPI_SPID_SD1_IO); + never_reset_pin_number(PSRAM_HSPI_SPIWP_SD3_IO); + never_reset_pin_number(PSRAM_HSPI_SPIHD_SD2_IO); + } else { + never_reset_pin_number(EFUSE_SPICONFIG_RET_SPICLK(spiconfig)); + never_reset_pin_number(EFUSE_SPICONFIG_RET_SPICS0(spiconfig)); + never_reset_pin_number(EFUSE_SPICONFIG_RET_SPIQ(spiconfig)); + never_reset_pin_number(EFUSE_SPICONFIG_RET_SPID(spiconfig)); + never_reset_pin_number(EFUSE_SPICONFIG_RET_SPIHD(spiconfig)); + never_reset_pin_number(bootloader_flash_get_wp_pin()); + } + #endif // CONFIG_IDF_TARGET_ESP32 +} + safe_mode_t port_init(void) { esp_timer_create_args_t args; args.callback = &tick_timer_cb; @@ -204,17 +295,21 @@ safe_mode_t port_init(void) { #endif #ifdef CONFIG_SPIRAM - if (esp_spiram_is_initialized()) { - size_t spiram_size = spiram_size_usable(); - #ifdef CONFIG_IDF_TARGET_ESP32 - heap = (uint32_t *)SOC_EXTRAM_DATA_LOW; - #else - heap = (uint32_t *)(SOC_EXTRAM_DATA_HIGH - spiram_size); - #endif - heap_size = spiram_size / sizeof(uint32_t); + { + intptr_t heap_start = common_hal_espidf_get_psram_start(); + intptr_t heap_end = common_hal_espidf_get_psram_end(); + size_t spiram_size = heap_end - heap_start; + if (spiram_size > 0) { + heap = (uint32_t *)heap_start; + heap_size = (heap_end - heap_start) / sizeof(uint32_t); + } else { + ESP_LOGE(TAG, "CONFIG_SPIRAM enabled but no spiram heap available"); + } } #endif + _never_reset_spi_ram_flash(); + if (heap == NULL) { size_t heap_total = heap_caps_get_total_size(MALLOC_CAP_8BIT); heap_size = MIN(heap_caps_get_largest_free_block(MALLOC_CAP_8BIT), heap_total / 2); @@ -223,37 +318,35 @@ safe_mode_t port_init(void) { } if (heap == NULL) { heap_size = 0; - return NO_HEAP; + return SAFE_MODE_NO_HEAP; } esp_reset_reason_t reason = esp_reset_reason(); switch (reason) { case ESP_RST_BROWNOUT: - return BROWNOUT; + return SAFE_MODE_BROWNOUT; case ESP_RST_PANIC: - return HARD_CRASH; + return SAFE_MODE_HARD_FAULT; case ESP_RST_INT_WDT: // The interrupt watchdog is used internally to make sure that latency sensitive // interrupt code isn't blocked. User watchdog resets come through ESP_RST_WDT. - return WATCHDOG_RESET; + return SAFE_MODE_WATCHDOG; case ESP_RST_WDT: default: break; } - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } void reset_port(void) { - #if CIRCUITPY_IMAGECAPTURE - cam_deinit(); + // TODO deinit for esp32-camera + #if CIRCUITPY_ESPCAMERA + esp_camera_deinit(); #endif reset_all_pins(); - // A larger delay so the idle task can run and do any IDF cleanup needed. - vTaskDelay(4); - #if CIRCUITPY_ANALOGIO analogout_reset(); #endif @@ -276,6 +369,10 @@ void reset_port(void) { dualbank_reset(); #endif + #if CIRCUITPY_ESPULP + espulp_reset(); + #endif + #if CIRCUITPY_FREQUENCYIO peripherals_timer_reset(); #endif @@ -308,6 +405,9 @@ void reset_port(void) { #if CIRCUITPY_WATCHDOG watchdog_reset(); #endif + + // Yield so the idle task can run and do any IDF cleanup needed. + port_yield(); } void reset_to_bootloader(void) { @@ -390,6 +490,18 @@ void port_wake_main_task() { xTaskNotifyGive(circuitpython_task); } +void port_wake_main_task_from_isr() { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + vTaskNotifyGiveFromISR(circuitpython_task, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} + +void port_yield() { + vTaskDelay(4); +} + void sleep_timer_cb(void *arg) { port_wake_main_task(); } @@ -405,11 +517,21 @@ void port_interrupt_after_ticks(uint32_t ticks) { // On the ESP we use FreeRTOS notifications instead of interrupts so this is a // bit of a misnomer. void port_idle_until_interrupt(void) { - if (!background_callback_pending()) { + if (!background_callback_pending() && !autoreload_pending()) { xTaskNotifyWait(0x01, 0x01, NULL, portMAX_DELAY); } } +void port_post_boot_py(bool heap_valid) { + if (!heap_valid && filesystem_present()) { + mp_int_t reserved; + if (common_hal_os_getenv_int("CIRCUITPY_RESERVED_PSRAM", &reserved) == GETENV_OK) { + common_hal_espidf_set_reserved_psram(reserved); + } + common_hal_espidf_reserve_psram(); + } +} + // Wrap main in app_main that the IDF expects. extern void main(void); extern void app_main(void); diff --git a/ports/espressif/supervisor/usb.c b/ports/espressif/supervisor/usb.c index a4f26b366c..61e6b5f09d 100644 --- a/ports/espressif/supervisor/usb.c +++ b/ports/espressif/supervisor/usb.c @@ -27,7 +27,6 @@ #include "py/runtime.h" #include "supervisor/usb.h" -#include "supervisor/esp_port.h" #include "supervisor/port.h" #include "shared/runtime/interrupt_char.h" #include "shared/readline/readline.h" diff --git a/ports/espressif/supervisor/usb_serial_jtag.c b/ports/espressif/supervisor/usb_serial_jtag.c index 064d7d668c..646d2c3a5e 100644 --- a/ports/espressif/supervisor/usb_serial_jtag.c +++ b/ports/espressif/supervisor/usb_serial_jtag.c @@ -28,19 +28,46 @@ #include "py/ringbuf.h" #include "py/runtime.h" #include "py/mphal.h" -#include "usb_serial_jtag.h" +#include "supervisor/port.h" +#include "supervisor/usb_serial_jtag.h" #include "hal/usb_serial_jtag_ll.h" #include "esp_intr_alloc.h" #include "soc/periph_defs.h" -#include "supervisor/esp_port.h" #define USB_SERIAL_JTAG_BUF_SIZE (64) STATIC ringbuf_t ringbuf; STATIC uint8_t buf[128]; -STATIC bool connected; +STATIC volatile bool connected; + +#if CIRCUITPY_ESP_USB_SERIAL_JTAG && !CONFIG_ESP_PHY_ENABLE_USB +#error "CONFIG_ESP_PHY_ENABLE_USB must be enabled in sdkconfig" +#endif + +// Make sure the recv interrupt is disabled during this. Otherwise, it could reorder data if it +// interrupts itself. +static void _copy_out_of_fifo(void) { + size_t req_len = ringbuf_num_empty(&ringbuf); + if (req_len == 0) { + // Disable the interrupt so that CircuitPython can run and process the ringbuf. It will + // re-enable the interrupt once the ringbuf is empty. + usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + } + if (req_len > USB_SERIAL_JTAG_BUF_SIZE) { + req_len = USB_SERIAL_JTAG_BUF_SIZE; + } + uint8_t rx_buf[USB_SERIAL_JTAG_BUF_SIZE]; + size_t len = usb_serial_jtag_ll_read_rxfifo(rx_buf, req_len); + for (size_t i = 0; i < len; ++i) { + if (rx_buf[i] == mp_interrupt_char) { + mp_sched_keyboard_interrupt(); + } else { + ringbuf_put(&ringbuf, rx_buf[i]); + } + } +} static void usb_serial_jtag_isr_handler(void *arg) { uint32_t flags = usb_serial_jtag_ll_get_intsts_mask(); @@ -49,40 +76,27 @@ static void usb_serial_jtag_isr_handler(void *arg) { usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SOF); } + if (flags & USB_SERIAL_JTAG_INTR_TOKEN_REC_IN_EP1) { + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_TOKEN_REC_IN_EP1); + connected = true; + } + if (flags & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) { usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); - size_t req_len = ringbuf_num_empty(&ringbuf); - if (req_len > USB_SERIAL_JTAG_BUF_SIZE) { - req_len = USB_SERIAL_JTAG_BUF_SIZE; - } - uint8_t rx_buf[USB_SERIAL_JTAG_BUF_SIZE]; - size_t len = usb_serial_jtag_ll_read_rxfifo(rx_buf, req_len); - for (size_t i = 0; i < len; ++i) { - if (rx_buf[i] == mp_interrupt_char) { - mp_sched_keyboard_interrupt(); - } else { - ringbuf_put(&ringbuf, rx_buf[i]); - } - } - vTaskNotifyGiveFromISR(circuitpython_task, NULL); + _copy_out_of_fifo(); + port_wake_main_task_from_isr(); } } void usb_serial_jtag_init(void) { - ringbuf_init(&ringbuf, buf, sizeof(buf)); - usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SOF | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); - usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SOF | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + ringbuf_init(&ringbuf, buf, sizeof(buf) - 1); + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SOF | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_TOKEN_REC_IN_EP1); + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SOF | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_TOKEN_REC_IN_EP1); ESP_ERROR_CHECK(esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, ESP_INTR_FLAG_LEVEL1, usb_serial_jtag_isr_handler, NULL, NULL)); } bool usb_serial_jtag_connected(void) { - // Make connected sticky. Otherwise we'll be disconnected every time the SOF - // index is 0. (It's only ~15 bits so it wraps around frequently.) - if (connected) { - return true; - } - connected = USB_SERIAL_JTAG.fram_num.sof_frame_index > 0; return connected; } @@ -90,22 +104,38 @@ char usb_serial_jtag_read_char(void) { if (ringbuf_num_filled(&ringbuf) == 0) { return -1; } - return ringbuf_get(&ringbuf); + char c = ringbuf_get(&ringbuf); + // Maybe re-enable the recv interrupt if we've emptied the ringbuf. + if (ringbuf_num_filled(&ringbuf) == 0) { + usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + _copy_out_of_fifo(); + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT); + } + return c; } bool usb_serial_jtag_bytes_available(void) { - return ringbuf_num_filled(&ringbuf); + return ringbuf_num_filled(&ringbuf) > 0; } void usb_serial_jtag_write(const char *text, uint32_t length) { - if (USB_SERIAL_JTAG.fram_num.sof_frame_index > 0) { - size_t total_written = 0; - uint32_t start_time = supervisor_ticks_ms32(); - // Time out after 5 milliseconds in case usb isn't actually reading CDC. - while (total_written < length && start_time - supervisor_ticks_ms32() < 5) { - total_written += usb_serial_jtag_ll_write_txfifo((const uint8_t *)(text + total_written), length - total_written); - RUN_BACKGROUND_TASKS; - } - usb_serial_jtag_ll_txfifo_flush(); + if (!usb_serial_jtag_connected()) { + return; } + size_t total_written = 0; + while (total_written < length) { + uint32_t start_time = supervisor_ticks_ms32(); + // Wait until we can write to the FIFO again. If it takes too long, then + // assume we're disconnected. + while (!usb_serial_jtag_ll_txfifo_writable()) { + uint32_t now = supervisor_ticks_ms32(); + if (now - start_time > 200) { + connected = false; + return; + } + } + total_written += usb_serial_jtag_ll_write_txfifo((const uint8_t *)(text + total_written), length - total_written); + RUN_BACKGROUND_TASKS; + } + usb_serial_jtag_ll_txfifo_flush(); } diff --git a/ports/espressif/tools/build_memory_info.py b/ports/espressif/tools/build_memory_info.py index df9d6a801e..a11bef82bc 100644 --- a/ports/espressif/tools/build_memory_info.py +++ b/ports/espressif/tools/build_memory_info.py @@ -6,13 +6,12 @@ # SPDX-License-Identifier: MIT import csv +import json import os -import re import sys from elftools.elf.elffile import ELFFile -print() internal_memory = { "esp32": [ @@ -117,8 +116,12 @@ with open(sys.argv[1], "rb") as stream: # This file is the bin used_flash = os.stat(sys.argv[3]).st_size - free_flash = firmware_region - used_flash + +with open(f"{sys.argv[4]}/firmware.size.json", "w") as f: + json.dump({"used_flash": used_flash, "firmware_region": firmware_region}, f) + +print() print( "{:7} bytes used, {:7} bytes free in flash firmware space out of {} bytes ({}kB).".format( used_flash, free_flash, firmware_region, firmware_region / 1024 diff --git a/ports/litex/.gitignore b/ports/litex/.gitignore deleted file mode 100644 index 414487d53e..0000000000 --- a/ports/litex/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build-*/ diff --git a/ports/litex/Makefile b/ports/litex/Makefile index 6b1e33c8d1..5556dea11d 100644 --- a/ports/litex/Makefile +++ b/ports/litex/Makefile @@ -22,37 +22,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Select the board to build for. -ifeq ($(BOARD),) - $(error You must provide a BOARD parameter) -else - ifeq ($(wildcard boards/$(BOARD)/.),) - $(error Invalid BOARD specified) - endif -endif - -# If the build directory is not given, make it reflect the board name. -BUILD ?= build-$(BOARD) - -include ../../py/mkenv.mk -# Board-specific -include boards/$(BOARD)/mpconfigboard.mk -# Port-specific -include mpconfigport.mk - -# CircuitPython-specific -include $(TOP)/py/circuitpy_mpconfig.mk - -# qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h - -# include py core make definitions -include $(TOP)/py/py.mk - -include $(TOP)/supervisor/supervisor.mk - -# Include make rules and variables common across CircuitPython builds. -include $(TOP)/py/circuitpy_defns.mk +include ../../py/circuitpy_mkenv.mk CROSS_COMPILE = riscv64-unknown-elf- @@ -117,7 +87,6 @@ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_VALENTYUSB_EPTRI -DCFG_TUD_CDC_RX_BUFSIZE=1024 SRC_C += \ background.c \ - fatfs_port.c \ mphalport.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c @@ -167,7 +136,7 @@ all: $(BUILD)/firmware.bin $(BUILD)/firmware.dfu $(BUILD)/firmware.elf: $(OBJ) $(STEPECHO) "LINK $@" $(Q)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group - $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LD_FILE) + $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LD_FILE) $(BUILD) $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(STEPECHO) "Create $@" diff --git a/ports/litex/background.c b/ports/litex/background.c index d2e94c5b8d..1329d5fd83 100644 --- a/ports/litex/background.c +++ b/ports/litex/background.c @@ -32,6 +32,8 @@ void port_background_task(void) { } +void port_background_tick(void) { +} void port_start_background_task(void) { } void port_finish_background_task(void) { diff --git a/ports/litex/boards/fomu/board.c b/ports/litex/boards/fomu/board.c index e5bff42b1a..43fc74fd42 100644 --- a/ports/litex/boards/fomu/board.c +++ b/ports/litex/boards/fomu/board.c @@ -66,14 +66,3 @@ void board_init(void) { ledda_write(3, LEDDPWRG); // Green ledda_write(98, LEDDPWRB); // Blue } - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} diff --git a/ports/litex/common-hal/digitalio/DigitalInOut.c b/ports/litex/common-hal/digitalio/DigitalInOut.c index a48d698fcb..7545722967 100644 --- a/ports/litex/common-hal/digitalio/DigitalInOut.c +++ b/ports/litex/common-hal/digitalio/DigitalInOut.c @@ -58,10 +58,11 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self self->pin = NULL; } -void common_hal_digitalio_digitalinout_switch_to_input( +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { (void)pull; touch_oe_write(touch_oe_read() & ~(1 << self->pin->number)); + return DIGITALINOUT_OK; } digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( @@ -111,10 +112,11 @@ digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( } } -void common_hal_digitalio_digitalinout_set_pull( +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { (void)self; (void)pull; + return DIGITALINOUT_OK; } digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( diff --git a/ports/litex/common-hal/microcontroller/__init__.c b/ports/litex/common-hal/microcontroller/__init__.c index 0a496d804e..1de55653fb 100644 --- a/ports/litex/common-hal/microcontroller/__init__.c +++ b/ports/litex/common-hal/microcontroller/__init__.c @@ -70,9 +70,8 @@ void common_hal_mcu_disable_interrupts(void) { __attribute__((section(".ramtext"))) void common_hal_mcu_enable_interrupts(void) { if (nesting_count == 0) { - // This is very very bad because it means there was mismatched disable/enables so we - // "HardFault". - asm ("ebreak"); + // This is very very bad because it means there was mismatched disable/enables. + reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); } nesting_count--; if (nesting_count > 0) { @@ -83,7 +82,7 @@ void common_hal_mcu_enable_interrupts(void) { void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { if (runmode == RUNMODE_SAFE_MODE) { - safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE); + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); } } diff --git a/ports/litex/mpconfigport.mk b/ports/litex/mpconfigport.mk index 57f5113b69..d8dc4eef1e 100644 --- a/ports/litex/mpconfigport.mk +++ b/ports/litex/mpconfigport.mk @@ -18,7 +18,7 @@ CIRCUITPY_BUSIO = 0 CIRCUITPY_COUNTIO = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_FREQUENCYIO = 0 -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_NVM = 0 CIRCUITPY_PWMIO = 0 CIRCUITPY_PULSEIO = 0 @@ -29,3 +29,5 @@ CIRCUITPY_SDCARDIO = 0 # Enable USB support CIRCUITPY_USB_HID = 1 CIRCUITPY_USB_MIDI = 1 + +CIRCUITPY_BUILD_EXTENSIONS ?= dfu diff --git a/ports/litex/supervisor/port.c b/ports/litex/supervisor/port.c index 42d3a63920..45f9b91976 100644 --- a/ports/litex/supervisor/port.c +++ b/ports/litex/supervisor/port.c @@ -71,7 +71,7 @@ safe_mode_t port_init(void) { irq_setmask(0); irq_setie(1); tick_init(); - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } extern uint32_t _ebss; diff --git a/ports/mimxrt10xx/.gitignore b/ports/mimxrt10xx/.gitignore deleted file mode 100644 index 414487d53e..0000000000 --- a/ports/mimxrt10xx/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build-*/ diff --git a/ports/mimxrt10xx/Makefile b/ports/mimxrt10xx/Makefile index 4b05c91714..b38f120ee2 100644 --- a/ports/mimxrt10xx/Makefile +++ b/ports/mimxrt10xx/Makefile @@ -23,36 +23,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Select the board to build for. -ifeq ($(BOARD),) - $(error You must provide a BOARD parameter) -else - ifeq ($(wildcard boards/$(BOARD)/.),) - $(error Invalid BOARD specified) - endif -endif - -# If the build directory is not given, make it reflect the board name. -BUILD ?= build-$(BOARD) - -include ../../py/mkenv.mk -# Board-specific -include boards/$(BOARD)/mpconfigboard.mk -# Port-specific -include mpconfigport.mk -# CircuitPython-specific -include $(TOP)/py/circuitpy_mpconfig.mk - -# qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h - -# include py core make definitions -include $(TOP)/py/py.mk - -include $(TOP)/supervisor/supervisor.mk - -# Include make rules and variables common across CircuitPython builds. -include $(TOP)/py/circuitpy_defns.mk +include ../../py/circuitpy_mkenv.mk CROSS_COMPILE = arm-none-eabi- @@ -138,6 +109,7 @@ SRC_SDK := \ drivers/fsl_ocotp.c \ drivers/fsl_pwm.c \ drivers/fsl_snvs_hp.c \ + drivers/fsl_snvs_lp.c \ drivers/fsl_tempmon.c \ drivers/fsl_trng.c \ system_$(CHIP_FAMILY).c \ @@ -150,7 +122,6 @@ SRC_C += \ boards/$(BOARD)/board.c \ boards/$(BOARD)/flash_config.c \ boards/$(BOARD)/pins.c \ - fatfs_port.c \ lib/tinyusb/src/portable/chipidea/ci_hs/dcd_ci_hs.c \ mphalport.c \ peripherals/mimxrt10xx/$(CHIP_FAMILY)/clocks.c \ diff --git a/ports/mimxrt10xx/background.c b/ports/mimxrt10xx/background.c index 9e531cea23..5815c222b4 100644 --- a/ports/mimxrt10xx/background.c +++ b/ports/mimxrt10xx/background.c @@ -28,10 +28,14 @@ #include "supervisor/port.h" void port_background_task(void) { +} + +void port_background_tick(void) { #if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO audio_dma_background(); #endif } + void port_start_background_task(void) { } void port_finish_background_task(void) { diff --git a/ports/mimxrt10xx/boards/feather_m7_1011/board.c b/ports/mimxrt10xx/boards/feather_m7_1011/board.c index e6c41681ba..9587ea71e8 100644 --- a/ports/mimxrt10xx/boards/feather_m7_1011/board.c +++ b/ports/mimxrt10xx/boards/feather_m7_1011/board.c @@ -26,31 +26,23 @@ */ #include "supervisor/board.h" -#include "boards/flash_config.h" -#include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { - // SWD Pins - common_hal_never_reset_pin(&pin_GPIO_AD_13);// SWDIO - common_hal_never_reset_pin(&pin_GPIO_AD_12);// SWCLK +// These pins should never ever be reset; doing so could interfere with basic operation. +// Used in common-hal/microcontroller/Pin.c +const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { + &pin_GPIO_AD_13,// SWDIO + &pin_GPIO_AD_12,// SWCLK // FLEX flash - common_hal_never_reset_pin(&pin_GPIO_SD_12); - common_hal_never_reset_pin(&pin_GPIO_SD_11); - common_hal_never_reset_pin(&pin_GPIO_SD_10); - common_hal_never_reset_pin(&pin_GPIO_SD_09); - common_hal_never_reset_pin(&pin_GPIO_SD_08); - common_hal_never_reset_pin(&pin_GPIO_SD_07); - common_hal_never_reset_pin(&pin_GPIO_SD_06); -} + &pin_GPIO_SD_12, + &pin_GPIO_SD_11, + &pin_GPIO_SD_10, + &pin_GPIO_SD_09, + &pin_GPIO_SD_08, + &pin_GPIO_SD_07, + &pin_GPIO_SD_06, + NULL, // Must end in NULL. +}; -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1011/board.c b/ports/mimxrt10xx/boards/feather_mimxrt1011/board.c index e6c41681ba..9587ea71e8 100644 --- a/ports/mimxrt10xx/boards/feather_mimxrt1011/board.c +++ b/ports/mimxrt10xx/boards/feather_mimxrt1011/board.c @@ -26,31 +26,23 @@ */ #include "supervisor/board.h" -#include "boards/flash_config.h" -#include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { - // SWD Pins - common_hal_never_reset_pin(&pin_GPIO_AD_13);// SWDIO - common_hal_never_reset_pin(&pin_GPIO_AD_12);// SWCLK +// These pins should never ever be reset; doing so could interfere with basic operation. +// Used in common-hal/microcontroller/Pin.c +const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { + &pin_GPIO_AD_13,// SWDIO + &pin_GPIO_AD_12,// SWCLK // FLEX flash - common_hal_never_reset_pin(&pin_GPIO_SD_12); - common_hal_never_reset_pin(&pin_GPIO_SD_11); - common_hal_never_reset_pin(&pin_GPIO_SD_10); - common_hal_never_reset_pin(&pin_GPIO_SD_09); - common_hal_never_reset_pin(&pin_GPIO_SD_08); - common_hal_never_reset_pin(&pin_GPIO_SD_07); - common_hal_never_reset_pin(&pin_GPIO_SD_06); -} + &pin_GPIO_SD_12, + &pin_GPIO_SD_11, + &pin_GPIO_SD_10, + &pin_GPIO_SD_09, + &pin_GPIO_SD_08, + &pin_GPIO_SD_07, + &pin_GPIO_SD_06, + NULL, // Must end in NULL. +}; -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1062/board.c b/ports/mimxrt10xx/boards/feather_mimxrt1062/board.c index 8cefabc937..5a8de5a522 100644 --- a/ports/mimxrt10xx/boards/feather_mimxrt1062/board.c +++ b/ports/mimxrt10xx/boards/feather_mimxrt1062/board.c @@ -26,30 +26,23 @@ */ #include "supervisor/board.h" -#include "boards/flash_config.h" -#include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { +// These pins should never ever be reset; doing so could interfere with basic operation. +// Used in common-hal/microcontroller/Pin.c +const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { // SWD Pins - common_hal_never_reset_pin(&pin_GPIO_AD_B0_06);// SWDIO - common_hal_never_reset_pin(&pin_GPIO_AD_B0_07);// SWCLK + &pin_GPIO_AD_B0_06,// SWDIO + &pin_GPIO_AD_B0_07,// SWCLK // FLEX flash - common_hal_never_reset_pin(&pin_GPIO_SD_B1_06); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_07); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_08); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_09); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_10); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_11); -} + &pin_GPIO_SD_B1_06, + &pin_GPIO_SD_B1_07, + &pin_GPIO_SD_B1_08, + &pin_GPIO_SD_B1_09, + &pin_GPIO_SD_B1_10, + &pin_GPIO_SD_B1_11, + NULL, // Must end in NULL. +}; -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/boards/imxrt1010_evk/board.c b/ports/mimxrt10xx/boards/imxrt1010_evk/board.c index eefbcc6deb..b839ffa666 100644 --- a/ports/mimxrt10xx/boards/imxrt1010_evk/board.c +++ b/ports/mimxrt10xx/boards/imxrt1010_evk/board.c @@ -26,33 +26,25 @@ */ #include "supervisor/board.h" -#include "boards/flash_config.h" -#include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { - // SWD Pins - common_hal_never_reset_pin(&pin_GPIO_AD_13); // SWDIO - common_hal_never_reset_pin(&pin_GPIO_AD_12); // SWCLK +// These pins should never ever be reset; doing so could interfere with basic operation. +// Used in common-hal/microcontroller/Pin.c +const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { + &pin_GPIO_AD_13, // SWDIO + &pin_GPIO_AD_12, // SWCLK // FLEX flash - common_hal_never_reset_pin(&pin_GPIO_SD_12); - common_hal_never_reset_pin(&pin_GPIO_SD_11); - common_hal_never_reset_pin(&pin_GPIO_SD_10); - common_hal_never_reset_pin(&pin_GPIO_SD_09); - common_hal_never_reset_pin(&pin_GPIO_SD_08); - common_hal_never_reset_pin(&pin_GPIO_SD_07); - common_hal_never_reset_pin(&pin_GPIO_SD_06); + &pin_GPIO_SD_12, + &pin_GPIO_SD_11, + &pin_GPIO_SD_10, + &pin_GPIO_SD_09, + &pin_GPIO_SD_08, + &pin_GPIO_SD_07, + &pin_GPIO_SD_06, // USB Pins - common_hal_never_reset_pin(&pin_GPIO_12); - common_hal_never_reset_pin(&pin_GPIO_13); -} + &pin_GPIO_12, + &pin_GPIO_13, + NULL, // Must end in NULL. +}; -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/boards/imxrt1020_evk/board.c b/ports/mimxrt10xx/boards/imxrt1020_evk/board.c index 42ab6bbd8c..afbc0c58b5 100644 --- a/ports/mimxrt10xx/boards/imxrt1020_evk/board.c +++ b/ports/mimxrt10xx/boards/imxrt1020_evk/board.c @@ -26,34 +26,27 @@ */ #include "supervisor/board.h" -#include "boards/flash_config.h" -#include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { +// These pins should never ever be reset; doing so could interfere with basic operation. +// Used in common-hal/microcontroller/Pin.c +const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { // SWD Pins - common_hal_never_reset_pin(&pin_GPIO_AD_B0_00);// SWDIO - common_hal_never_reset_pin(&pin_GPIO_AD_B0_01);// SWCLK + &pin_GPIO_AD_B0_00,// SWDIO + &pin_GPIO_AD_B0_01,// SWCLK // FLEX flash - common_hal_never_reset_pin(&pin_GPIO_SD_B1_06); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_07); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_08); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_09); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_10); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_11); + &pin_GPIO_SD_B1_06, + &pin_GPIO_SD_B1_07, + &pin_GPIO_SD_B1_08, + &pin_GPIO_SD_B1_09, + &pin_GPIO_SD_B1_10, + &pin_GPIO_SD_B1_11, // USB Pins - common_hal_never_reset_pin(&pin_GPIO_AD_B1_11); - common_hal_never_reset_pin(&pin_GPIO_AD_B1_12); -} + &pin_GPIO_AD_B1_11, + &pin_GPIO_AD_B1_12, + NULL, // Must end in NULL. +}; -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/boards/imxrt1060_evk/board.c b/ports/mimxrt10xx/boards/imxrt1060_evk/board.c index d85b615f0f..f27f549c64 100644 --- a/ports/mimxrt10xx/boards/imxrt1060_evk/board.c +++ b/ports/mimxrt10xx/boards/imxrt1060_evk/board.c @@ -26,40 +26,33 @@ */ #include "supervisor/board.h" -#include "boards/flash_config.h" -#include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { +// These pins should never ever be reset; doing so could interfere with basic operation. +// Used in common-hal/microcontroller/Pin.c +const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { // SWD Pins - common_hal_never_reset_pin(&pin_GPIO_AD_B0_06);// SWDIO - common_hal_never_reset_pin(&pin_GPIO_AD_B0_07);// SWCLK + &pin_GPIO_AD_B0_06, // SWDIO + &pin_GPIO_AD_B0_07, // SWCLK // FLEX flash - common_hal_never_reset_pin(&pin_GPIO_SD_B1_00); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_01); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_02); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_03); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_04); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_05); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_06); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_07); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_08); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_09); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_10); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_11); + &pin_GPIO_SD_B1_00, + &pin_GPIO_SD_B1_01, + &pin_GPIO_SD_B1_02, + &pin_GPIO_SD_B1_03, + &pin_GPIO_SD_B1_04, + &pin_GPIO_SD_B1_05, + &pin_GPIO_SD_B1_06, + &pin_GPIO_SD_B1_07, + &pin_GPIO_SD_B1_08, + &pin_GPIO_SD_B1_09, + &pin_GPIO_SD_B1_10, + &pin_GPIO_SD_B1_11, // USB Pins - common_hal_never_reset_pin(&pin_GPIO_AD_B0_01); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_03); -} + &pin_GPIO_AD_B0_01, + &pin_GPIO_AD_B0_03, + NULL, // Must end in NULL. +}; -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/boards/metro_m7_1011/board.c b/ports/mimxrt10xx/boards/metro_m7_1011/board.c index e6c41681ba..27cbd3eb96 100644 --- a/ports/mimxrt10xx/boards/metro_m7_1011/board.c +++ b/ports/mimxrt10xx/boards/metro_m7_1011/board.c @@ -26,31 +26,24 @@ */ #include "supervisor/board.h" -#include "boards/flash_config.h" -#include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { +// These pins should never ever be reset; doing so could interfere with basic operation. +// Used in common-hal/microcontroller/Pin.c +const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { // SWD Pins - common_hal_never_reset_pin(&pin_GPIO_AD_13);// SWDIO - common_hal_never_reset_pin(&pin_GPIO_AD_12);// SWCLK + &pin_GPIO_AD_13,// SWDIO + &pin_GPIO_AD_12,// SWCLK // FLEX flash - common_hal_never_reset_pin(&pin_GPIO_SD_12); - common_hal_never_reset_pin(&pin_GPIO_SD_11); - common_hal_never_reset_pin(&pin_GPIO_SD_10); - common_hal_never_reset_pin(&pin_GPIO_SD_09); - common_hal_never_reset_pin(&pin_GPIO_SD_08); - common_hal_never_reset_pin(&pin_GPIO_SD_07); - common_hal_never_reset_pin(&pin_GPIO_SD_06); -} + &pin_GPIO_SD_12, + &pin_GPIO_SD_11, + &pin_GPIO_SD_10, + &pin_GPIO_SD_09, + &pin_GPIO_SD_08, + &pin_GPIO_SD_07, + &pin_GPIO_SD_06, + NULL, // Must end in NULL. +}; -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/boards/metro_m7_1011/mpconfigboard.h b/ports/mimxrt10xx/boards/metro_m7_1011/mpconfigboard.h index 23009f353f..589b2a2b65 100644 --- a/ports/mimxrt10xx/boards/metro_m7_1011/mpconfigboard.h +++ b/ports/mimxrt10xx/boards/metro_m7_1011/mpconfigboard.h @@ -7,7 +7,7 @@ // make sure you don't overwrite code #define CIRCUITPY_INTERNAL_NVM_SIZE 0 -#define BOARD_FLASH_SIZE (4 * 1024 * 1024) +#define BOARD_FLASH_SIZE (8 * 1024 * 1024) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO_02) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO_01) diff --git a/ports/mimxrt10xx/boards/metro_m7_1011/mpconfigboard.mk b/ports/mimxrt10xx/boards/metro_m7_1011/mpconfigboard.mk index 2655217c78..56155aa4d0 100644 --- a/ports/mimxrt10xx/boards/metro_m7_1011/mpconfigboard.mk +++ b/ports/mimxrt10xx/boards/metro_m7_1011/mpconfigboard.mk @@ -5,7 +5,7 @@ USB_MANUFACTURER = "Adafruit" CHIP_VARIANT = MIMXRT1011DAE5A CHIP_FAMILY = MIMXRT1011 -FLASH = W25Q32JV +FLASH = W25Q64JV # Include these Python libraries in the firmware FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ESP32SPI diff --git a/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/board.c b/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/board.c index 1a1dc7e5ec..fda0b1d202 100644 --- a/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/board.c +++ b/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/board.c @@ -26,39 +26,31 @@ */ #include "supervisor/board.h" -#include "boards/flash_config.h" -#include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { - // FLEX flash - common_hal_never_reset_pin(&pin_GPIO_SD_B1_06); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_07); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_08); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_09); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_10); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_11); +// These pins should never ever be reset; doing so could interfere with basic operation. +// Used in common-hal/microcontroller/Pin.c +const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { + &pin_GPIO_SD_B1_06, + &pin_GPIO_SD_B1_07, + &pin_GPIO_SD_B1_08, + &pin_GPIO_SD_B1_09, + &pin_GPIO_SD_B1_10, + &pin_GPIO_SD_B1_11, // FLEX flash 2 - common_hal_never_reset_pin(&pin_GPIO_AD_B0_04); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_06); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_07); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_08); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_09); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_10); - common_hal_never_reset_pin(&pin_GPIO_EMC_01); - common_hal_never_reset_pin(&pin_GPIO_B0_13); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_11); + &pin_GPIO_AD_B0_04, + &pin_GPIO_AD_B0_06, + &pin_GPIO_AD_B0_07, + &pin_GPIO_AD_B0_08, + &pin_GPIO_AD_B0_09, + &pin_GPIO_AD_B0_10, + &pin_GPIO_EMC_01, + &pin_GPIO_B0_13, + &pin_GPIO_AD_B0_11, // Data strobe needs protection despite being grounded - common_hal_never_reset_pin(&pin_GPIO_SD_B1_05); -} + &pin_GPIO_SD_B1_05, + NULL, // Must end in NULL. +}; -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/boards/teensy40/board.c b/ports/mimxrt10xx/boards/teensy40/board.c index 1a1dc7e5ec..8ece1546d7 100644 --- a/ports/mimxrt10xx/boards/teensy40/board.c +++ b/ports/mimxrt10xx/boards/teensy40/board.c @@ -26,39 +26,32 @@ */ #include "supervisor/board.h" -#include "boards/flash_config.h" -#include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { +// These pins should never ever be reset; doing so could interfere with basic operation. +// Used in common-hal/microcontroller/Pin.c +const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { // FLEX flash - common_hal_never_reset_pin(&pin_GPIO_SD_B1_06); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_07); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_08); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_09); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_10); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_11); + &pin_GPIO_SD_B1_06, + &pin_GPIO_SD_B1_07, + &pin_GPIO_SD_B1_08, + &pin_GPIO_SD_B1_09, + &pin_GPIO_SD_B1_10, + &pin_GPIO_SD_B1_11, // FLEX flash 2 - common_hal_never_reset_pin(&pin_GPIO_AD_B0_04); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_06); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_07); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_08); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_09); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_10); - common_hal_never_reset_pin(&pin_GPIO_EMC_01); - common_hal_never_reset_pin(&pin_GPIO_B0_13); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_11); + &pin_GPIO_AD_B0_04, + &pin_GPIO_AD_B0_06, + &pin_GPIO_AD_B0_07, + &pin_GPIO_AD_B0_08, + &pin_GPIO_AD_B0_09, + &pin_GPIO_AD_B0_10, + &pin_GPIO_EMC_01, + &pin_GPIO_B0_13, + &pin_GPIO_AD_B0_11, // Data strobe needs protection despite being grounded - common_hal_never_reset_pin(&pin_GPIO_SD_B1_05); -} + &pin_GPIO_SD_B1_05, + NULL, // Must end in NULL. +}; -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/boards/teensy41/board.c b/ports/mimxrt10xx/boards/teensy41/board.c index 1a1dc7e5ec..8ece1546d7 100644 --- a/ports/mimxrt10xx/boards/teensy41/board.c +++ b/ports/mimxrt10xx/boards/teensy41/board.c @@ -26,39 +26,32 @@ */ #include "supervisor/board.h" -#include "boards/flash_config.h" -#include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" -void board_init(void) { +// These pins should never ever be reset; doing so could interfere with basic operation. +// Used in common-hal/microcontroller/Pin.c +const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { // FLEX flash - common_hal_never_reset_pin(&pin_GPIO_SD_B1_06); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_07); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_08); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_09); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_10); - common_hal_never_reset_pin(&pin_GPIO_SD_B1_11); + &pin_GPIO_SD_B1_06, + &pin_GPIO_SD_B1_07, + &pin_GPIO_SD_B1_08, + &pin_GPIO_SD_B1_09, + &pin_GPIO_SD_B1_10, + &pin_GPIO_SD_B1_11, // FLEX flash 2 - common_hal_never_reset_pin(&pin_GPIO_AD_B0_04); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_06); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_07); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_08); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_09); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_10); - common_hal_never_reset_pin(&pin_GPIO_EMC_01); - common_hal_never_reset_pin(&pin_GPIO_B0_13); - common_hal_never_reset_pin(&pin_GPIO_AD_B0_11); + &pin_GPIO_AD_B0_04, + &pin_GPIO_AD_B0_06, + &pin_GPIO_AD_B0_07, + &pin_GPIO_AD_B0_08, + &pin_GPIO_AD_B0_09, + &pin_GPIO_AD_B0_10, + &pin_GPIO_EMC_01, + &pin_GPIO_B0_13, + &pin_GPIO_AD_B0_11, // Data strobe needs protection despite being grounded - common_hal_never_reset_pin(&pin_GPIO_SD_B1_05); -} + &pin_GPIO_SD_B1_05, + NULL, // Must end in NULL. +}; -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c index 20430c91c8..086b8dee87 100644 --- a/ports/mimxrt10xx/common-hal/busio/UART.c +++ b/ports/mimxrt10xx/common-hal/busio/UART.c @@ -113,7 +113,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, bool sigint_enabled) { self->baudrate = baudrate; - self->character_bits = (uint8_t)mp_arg_validate_int_range(self->character_bits, 7, 8, MP_QSTR_bits); + self->character_bits = (uint8_t)mp_arg_validate_int_range(bits, 7, 8, MP_QSTR_bits); self->timeout_ms = timeout * 1000; @@ -179,7 +179,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, break; } } else { - mp_raise_ValueError(translate("Supply at least one UART pin")); + // TX and RX are both None. But this is already handled in shared-bindings, so + // we won't get here. } if (rx && !rx_config) { diff --git a/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c b/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c index dde7b3badd..7639204bc6 100644 --- a/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +++ b/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c @@ -88,12 +88,13 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self self->pin = NULL; } -void common_hal_digitalio_digitalinout_switch_to_input( +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { self->output = false; // This also sets direction to input. common_hal_digitalio_digitalinout_set_pull(self, pull); + return DIGITALINOUT_OK; } digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( @@ -150,7 +151,7 @@ digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( } } -void common_hal_digitalio_digitalinout_set_pull( +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { self->pull = pull; @@ -158,6 +159,7 @@ void common_hal_digitalio_digitalinout_set_pull( const gpio_pin_config_t config = { kGPIO_DigitalInput, 0, kGPIO_NoIntmode }; GPIO_PinInit(self->pin->gpio, self->pin->number, &config); + return DIGITALINOUT_OK; } digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Pin.c b/ports/mimxrt10xx/common-hal/microcontroller/Pin.c index 06a2a34fe1..3c8c7f2b27 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/Pin.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/Pin.c @@ -31,6 +31,22 @@ STATIC bool claimed_pins[IOMUXC_SW_PAD_CTL_PAD_COUNT]; STATIC bool never_reset_pins[IOMUXC_SW_PAD_CTL_PAD_COUNT]; +// Default is that no pins are forbidden to reset. +MP_WEAK const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { + NULL, +}; + +STATIC bool _reset_forbidden(const mcu_pin_obj_t *pin) { + const mcu_pin_obj_t **forbidden_pin = &mimxrt10xx_reset_forbidden_pins[0]; + while (*forbidden_pin) { + if (pin == *forbidden_pin) { + return true; + } + forbidden_pin++; + } + return false; +} + // There are two numbering systems used here: // IOMUXC index, used for iterating through pins and accessing reset information, // and GPIO port and number, used to store claimed and reset tagging. The two number @@ -44,17 +60,30 @@ void reset_all_pins(void) { if (never_reset_pins[pin->mux_idx]) { continue; } - *(uint32_t *)pin->mux_reg = pin->mux_reset; - *(uint32_t *)pin->cfg_reg = pin->pad_reset; + common_hal_reset_pin(pin); } } +MP_WEAK bool mimxrt10xx_board_reset_pin_number(const mcu_pin_obj_t *pin) { + return false; +} + // Since i.MX pins need extra register and reset information to reset properly, // resetting pins by number alone has been removed. void common_hal_reset_pin(const mcu_pin_obj_t *pin) { if (pin == NULL) { return; } + + if (_reset_forbidden(pin)) { + return; + } + + // Give the board a chance to reset the pin in a particular way, or not reset it at all. + if (mimxrt10xx_board_reset_pin_number(pin)) { + return; + } + never_reset_pins[pin->mux_idx] = false; claimed_pins[pin->mux_idx] = false; *(uint32_t *)pin->mux_reg = pin->mux_reset; diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Pin.h b/ports/mimxrt10xx/common-hal/microcontroller/Pin.h index 2638eb89b8..1bfbe41a18 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/Pin.h +++ b/ports/mimxrt10xx/common-hal/microcontroller/Pin.h @@ -35,4 +35,14 @@ void reset_all_pins(void); void claim_pin(const mcu_pin_obj_t *pin); +// List of pins that should never be reset. +extern const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[]; + +// Allow the board to reset a pin in a board-specific way. This can be used +// for LEDs or enable pins to put them in a state beside the default pull-up, +// or to simply not reset the pin at all. +// Return true to indicate that the pin was handled in a special way. Returning false will lead to +// the port-default reset behavior. +extern bool mimxrt10xx_board_reset_pin_number(const mcu_pin_obj_t *pin); + #endif // MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c index 8de63061ad..5388f404de 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c @@ -39,8 +39,6 @@ #include "supervisor/shared/safe_mode.h" #include "supervisor/shared/translate/translate.h" -#define DBL_TAP_REG SNVS->LPGPR[3] - void common_hal_mcu_delay_us(uint32_t delay) { mp_hal_delay_us(delay); } @@ -52,12 +50,10 @@ void common_hal_mcu_disable_interrupts(void) { nesting_count++; } -void HardFault_Handler(void); void common_hal_mcu_enable_interrupts(void) { if (nesting_count == 0) { - // This is very very bad because it means there was mismatched disable/enables so we - // "HardFault". - HardFault_Handler(); + // This is very very bad because it means there was mismatched disable/enables + reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); } nesting_count--; if (nesting_count > 0) { @@ -80,7 +76,7 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { DBL_TAP_REG = DBL_TAP_MAGIC_QUICK_BOOT; } if (runmode == RUNMODE_SAFE_MODE) { - safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE); + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); } } diff --git a/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c b/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c index 97892b1095..c2afb38664 100644 --- a/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +++ b/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -38,9 +38,19 @@ #include "supervisor/shared/translate/translate.h" #include "periph.h" -// Debug print support set to zero to enable debug printing -#define ENABLE_DEBUG_PRINTING 0 +static PWM_Type *const _flexpwms[] = PWM_BASE_PTRS; +// 4 bits for each submodule in each FlexPWM. +static uint16_t _pwm_never_reset[MP_ARRAY_SIZE(_flexpwms)]; +// Bitmask of whether state machines are use for variable frequency. +static uint8_t _pwm_variable_frequency[MP_ARRAY_SIZE(_flexpwms)]; +// Configured frequency for each submodule. +static uint32_t _pwm_sm_frequencies[MP_ARRAY_SIZE(_flexpwms)][FSL_FEATURE_PWM_SUBMODULE_COUNT]; +// Channels use is tracked using the OUTEN register. + +// The SDK gives use clocks per submodule but they all share the same value! So, ignore the +// submodule and only turn off the clock when no other submodules are in use. +static const clock_ip_name_t _flexpwm_clocks[][FSL_FEATURE_PWM_SUBMODULE_COUNT] = PWM_CLOCKS; static void config_periph_pin(const mcu_pwm_obj_t *periph) { IOMUXC_SetPinMux( @@ -61,13 +71,59 @@ static void config_periph_pin(const mcu_pwm_obj_t *periph) { | IOMUXC_SW_PAD_CTL_PAD_SRE(0)); } +static uint16_t _outen_mask(pwm_submodule_t submodule, pwm_channels_t channel) { + uint16_t outen_mask = 0; + uint8_t sm_mask = 1 << submodule; + switch (channel) { + case kPWM_PwmX: + outen_mask |= PWM_OUTEN_PWMX_EN(sm_mask); + break; + case kPWM_PwmA: + outen_mask |= PWM_OUTEN_PWMA_EN(sm_mask); + break; + case kPWM_PwmB: + outen_mask |= PWM_OUTEN_PWMB_EN(sm_mask); + break; + } + return outen_mask; +} + void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { + common_hal_never_reset_pin(self->pin); + _pwm_never_reset[self->flexpwm_index] |= (1 << (self->pwm->submodule * 4 + self->pwm->channel)); } -void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { +STATIC void _maybe_disable_clock(uint8_t instance) { + if ((_flexpwms[instance]->MCTRL & PWM_MCTRL_RUN_MASK) == 0) { + CLOCK_DisableClock(_flexpwm_clocks[instance][0]); + } } -void pwmout_reset(void) { +void reset_all_flexpwm(void) { + for (size_t i = 1; i < MP_ARRAY_SIZE(_pwm_never_reset); i++) { + PWM_Type *flexpwm = _flexpwms[i]; + for (size_t submodule = 0; submodule < FSL_FEATURE_PWM_SUBMODULE_COUNT; submodule++) { + uint8_t sm_mask = 1 << submodule; + for (size_t channel = 0; channel < 3; channel++) { + uint16_t channel_mask = 0x1 << (submodule * 4 + channel); + if ((_pwm_never_reset[i] & channel_mask) != 0) { + continue; + } + + // Turn off the channel. + flexpwm->OUTEN &= ~_outen_mask(submodule, channel); + } + uint16_t submodule_mask = 0xf << (submodule * 4); + if ((_pwm_never_reset[i] & submodule_mask) != 0) { + // Leave the submodule on since a channel is marked for never_reset. + continue; + } + flexpwm->MCTRL &= ~(sm_mask << PWM_MCTRL_RUN_SHIFT); + _pwm_variable_frequency[i] &= ~sm_mask; + _pwm_sm_frequencies[i][submodule] = 0; + } + _maybe_disable_clock(i); + } } #define PWM_SRC_CLK_FREQ CLOCK_GetFreq(kCLOCK_IpgClk) @@ -87,33 +143,6 @@ static int calculate_pulse_count(uint32_t frequency, uint8_t *prescaler) { return 0; } -// ========================================================== -// Debug code -// ========================================================== -#if ENABLE_DEBUG_PRINTING -#define DBGPrintf mp_printf -extern void debug_print_flexpwm_registers(PWM_Type *base); - -void debug_print_flexpwm_registers(PWM_Type *base) { - mp_printf(&mp_plat_print, - "\t\tPWM OUTEN:%x MASK:%x SWCOUT:%x DTSRCSEL:%x MCTRL:%x MCTRL2:%x FCTRL:%x FSTS:%x FFILT:%x FTST:%x FCTRL2:%x\n", - base->OUTEN, base->MASK, base->SWCOUT, base->DTSRCSEL, base->MCTRL, base->MCTRL2, base->FCTRL, - base->FSTS, base->FFILT, base->FTST, base->FCTRL2); - for (uint8_t i = 0; i < 4; i++) { - mp_printf(&mp_plat_print, - "\t\t(%u) INIT:%x CTRL2:%x CTRL:%x VAL0:%x VAL1:%x VAL2:%x VAL3:%x VAL4:%x VAL5:%x OCTRL:%x DTCNT0:%x DTCNT1:%x DISMAP: %x %x\n", i, - base->SM[i].INIT, base->SM[i].CTRL2, base->SM[i].CTRL, base->SM[i].VAL0, base->SM[i].VAL1, base->SM[i].VAL2, - base->SM[i].VAL3, base->SM[i].VAL4, base->SM[i].VAL5, base->SM[i].OCTRL, base->SM[i].DTCNT0, base->SM[i].DTCNT1, - base->SM[i].DISMAP[0], base->SM[i].DISMAP[1]); - } - -} -#else -#define DBGPrintf(p,...) -inline void debug_print_flexpwm_registers(PWM_Type *base) { -} -#endif - pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, const mcu_pin_obj_t *pin, uint16_t duty, @@ -122,12 +151,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, self->pin = pin; self->variable_frequency = variable_frequency; - const uint32_t pwm_count = sizeof(mcu_pwm_list) / sizeof(mcu_pwm_obj_t); - - DBGPrintf(&mp_plat_print, ">>> common_hal_pwmio_pwmout_construct called: pin: %p %u freq:%u duty:%u var:%u\n", - self->pin->gpio, self->pin->number, frequency, duty, variable_frequency); - - for (uint32_t i = 0; i < pwm_count; ++i) { + for (uint32_t i = 0; i < MP_ARRAY_SIZE(mcu_pwm_list); ++i) { if (mcu_pwm_list[i].pin != pin) { continue; } @@ -141,30 +165,20 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, return PWMOUT_INVALID_PIN; } - DBGPrintf(&mp_plat_print, "\tFound in PWM List\n"); + PWM_Type *flexpwm = self->pwm->pwm; + pwm_submodule_t submodule = self->pwm->submodule; + uint16_t sm_mask = 1 << submodule; + pwm_channels_t channel = self->pwm->channel; - config_periph_pin(self->pwm); + uint8_t flexpwm_index = 1; + for (; flexpwm_index < MP_ARRAY_SIZE(_flexpwms); flexpwm_index++) { + if (_flexpwms[flexpwm_index] == flexpwm) { + break; + } + } + self->flexpwm_index = flexpwm_index; - pwm_config_t pwmConfig; - - /* - * pwmConfig.enableDebugMode = false; - * pwmConfig.enableWait = false; - * pwmConfig.reloadSelect = kPWM_LocalReload; - * pwmConfig.faultFilterCount = 0; - * pwmConfig.faultFilterPeriod = 0; - * pwmConfig.clockSource = kPWM_BusClock; - * pwmConfig.prescale = kPWM_Prescale_Divide_1; - * pwmConfig.initializationControl = kPWM_Initialize_LocalSync; - * pwmConfig.forceTrigger = kPWM_Force_Local; - * pwmConfig.reloadFrequency = kPWM_LoadEveryOportunity; - * pwmConfig.reloadLogic = kPWM_ReloadImmediate; - * pwmConfig.pairOperation = kPWM_Independent; - */ - PWM_GetDefaultConfig(&pwmConfig); - - // pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle; - pwmConfig.enableDebugMode = true; + uint16_t outen_mask = _outen_mask(submodule, channel); self->pulse_count = calculate_pulse_count(frequency, &self->prescaler); @@ -172,69 +186,92 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, return PWMOUT_INVALID_FREQUENCY; } - pwmConfig.prescale = self->prescaler; - - DBGPrintf(&mp_plat_print, "\tCall PWM_Init\n"); - if (PWM_Init(self->pwm->pwm, self->pwm->submodule, &pwmConfig) == kStatus_Fail) { - return PWMOUT_INVALID_PIN; - } - - // Disable all fault inputs - self->pwm->pwm->SM[self->pwm->submodule].DISMAP[0] = 0; - self->pwm->pwm->SM[self->pwm->submodule].DISMAP[1] = 0; - - DBGPrintf(&mp_plat_print, "\tCall PWM_SetupPwm %p %x %u\n", self->pwm->pwm, self->pwm->submodule); - // ======================================================================================================== - // Not calling the PWM_SetupPwm as it was setup to only work for PWM output on chan A and B but not X - // I have done some experimenting, probably could try others, but again they do not work with X. - // Most of the code checks to see if A if not, then it assume B. - // - // Instead I set it up to work similar to what the Teensy 4.x code does. - // - // That is we set the PWM_CTRL_FULL_MASK, which then uses base->SM[submodule].VAL1 to control - // when the timer is reset, so it sets up your cycle/frequency. But then this implies that X channel - // which uses 0, 1 has to be handled specially. So for the different channels: - // A - Uses VAL2 to turn on (0) and VAL3=duty to turn off - // B - Uses VAL4 to turn on (0) and VAL5 to turn off - // X - As mentioned above VAL1 turns off, but it's set to the timing for frequency. so - // VAL0 turns on, so we set it to VAL1 - duty - // - PWM_Type *base = self->pwm->pwm; - uint8_t submodule = self->pwm->submodule; - - uint32_t mask = 1 << submodule; - uint32_t olddiv = base->SM[submodule].VAL1 + 1; - if (self->pulse_count != olddiv) { - base->MCTRL |= PWM_MCTRL_CLDOK(mask); - base->SM[submodule].CTRL = PWM_CTRL_PRSC_MASK | PWM_CTRL_PRSC(self->prescaler); - base->SM[submodule].VAL1 = self->pulse_count - 1; - base->SM[submodule].CTRL2 = PWM_CTRL2_INDEP_MASK | PWM_CTRL2_WAITEN_MASK | PWM_CTRL2_DBGEN_MASK; - - if (olddiv == 1) { - base->SM[submodule].CTRL = PWM_CTRL_FULL_MASK; - base->SM[submodule].VAL0 = 0; - base->SM[submodule].VAL2 = 0; - base->SM[submodule].VAL3 = 0; - base->SM[submodule].VAL4 = 0; - base->SM[submodule].VAL5 = 0; - } else { - base->SM[submodule].VAL0 = (base->SM[submodule].VAL0 * self->pulse_count) / olddiv; - base->SM[submodule].VAL3 = (base->SM[submodule].VAL3 * self->pulse_count) / olddiv; - base->SM[submodule].VAL5 = (base->SM[submodule].VAL5 * self->pulse_count) / olddiv; + // The submodule is already running + if (((flexpwm->MCTRL >> PWM_MCTRL_RUN_SHIFT) & sm_mask) != 0) { + // Another output has claimed this submodule for variable frequency already. + if ((_pwm_variable_frequency[flexpwm_index] & sm_mask) != 0) { + return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; + } + + // We want variable frequency but another class has already claim a fixed frequency. + if (variable_frequency) { + return PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE; + } + + // Another pin is already using this output. + if ((flexpwm->OUTEN & outen_mask) != 0) { + return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; + } + + if (frequency != _pwm_sm_frequencies[flexpwm_index][submodule]) { + return PWMOUT_INVALID_FREQUENCY_ON_PIN; + } + + // Submodule is already running at our target frequency and the output + // is free. + } else { + pwm_config_t pwmConfig; + + /* + * pwmConfig.enableDebugMode = false; + * pwmConfig.enableWait = false; + * pwmConfig.reloadSelect = kPWM_LocalReload; + * pwmConfig.faultFilterCount = 0; + * pwmConfig.faultFilterPeriod = 0; + * pwmConfig.clockSource = kPWM_BusClock; + * pwmConfig.prescale = kPWM_Prescale_Divide_1; + * pwmConfig.initializationControl = kPWM_Initialize_LocalSync; + * pwmConfig.forceTrigger = kPWM_Force_Local; + * pwmConfig.reloadFrequency = kPWM_LoadEveryOportunity; + * pwmConfig.reloadLogic = kPWM_ReloadImmediate; + * pwmConfig.pairOperation = kPWM_Independent; + */ + PWM_GetDefaultConfig(&pwmConfig); + + pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle; + pwmConfig.enableWait = true; + pwmConfig.enableDebugMode = true; + + pwmConfig.prescale = self->prescaler; + + if (PWM_Init(flexpwm, submodule, &pwmConfig) != kStatus_Success) { + return PWMOUT_INITIALIZATION_ERROR; + } + + // Disable all fault inputs + flexpwm->SM[submodule].DISMAP[0] = 0; + flexpwm->SM[submodule].DISMAP[1] = 0; + + PWM_SetPwmLdok(flexpwm, sm_mask, false); + flexpwm->SM[submodule].CTRL = PWM_CTRL_FULL_MASK | PWM_CTRL_PRSC(self->prescaler); + flexpwm->SM[submodule].CTRL2 = PWM_CTRL2_INDEP_MASK | PWM_CTRL2_WAITEN_MASK | PWM_CTRL2_DBGEN_MASK; + // Set the reload value to zero so we're in unsigned mode. + flexpwm->SM[submodule].INIT = 0; + // Set the top/reload value. + flexpwm->SM[submodule].VAL1 = self->pulse_count; + // Clear the other channels. + flexpwm->SM[submodule].VAL0 = 0; + flexpwm->SM[submodule].VAL2 = 0; + flexpwm->SM[submodule].VAL3 = 0; + flexpwm->SM[submodule].VAL4 = 0; + flexpwm->SM[submodule].VAL5 = 0; + PWM_SetPwmLdok(flexpwm, sm_mask, true); + + PWM_StartTimer(flexpwm, sm_mask); + _pwm_sm_frequencies[flexpwm_index][submodule] = frequency; + + if (variable_frequency) { + _pwm_variable_frequency[flexpwm_index] = sm_mask; } - base->MCTRL |= PWM_MCTRL_LDOK(mask); } - debug_print_flexpwm_registers(self->pwm->pwm); - PWM_SetPwmLdok(self->pwm->pwm, 1 << self->pwm->submodule, true); - - PWM_StartTimer(self->pwm->pwm, 1 << self->pwm->submodule); - - - DBGPrintf(&mp_plat_print, "\tCall common_hal_pwmio_pwmout_set_duty_cycle\n"); common_hal_pwmio_pwmout_set_duty_cycle(self, duty); - DBGPrintf(&mp_plat_print, "\tReturn OK\n"); + flexpwm->OUTEN |= outen_mask; + + // Configure the IOMUX once we know everything else is working. + config_periph_pin(self->pwm); + return PWMOUT_OK; } @@ -247,8 +284,29 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { return; } + _pwm_never_reset[self->flexpwm_index] &= ~(1 << (self->pwm->submodule * 4 + self->pwm->channel)); + + PWM_Type *flexpwm = self->pwm->pwm; + pwm_submodule_t submodule = self->pwm->submodule; + uint16_t sm_mask = 1 << submodule; + + // Reset the pin before we turn it off. common_hal_reset_pin(self->pin); self->pin = NULL; + + // Always disable the output. + flexpwm->OUTEN &= ~_outen_mask(submodule, self->pwm->channel); + + uint16_t all_sm_channels = _outen_mask(submodule, kPWM_PwmX) | _outen_mask(submodule, kPWM_PwmA) | _outen_mask(submodule, kPWM_PwmB); + + // Turn off the submodule if it doesn't have any outputs active. + if ((flexpwm->OUTEN & all_sm_channels) == 0) { + // Deinit ourselves because the SDK turns off the clock to the whole FlexPWM on deinit. + flexpwm->MCTRL &= ~(sm_mask << PWM_MCTRL_RUN_SHIFT); + _pwm_variable_frequency[self->flexpwm_index] &= ~sm_mask; + _pwm_sm_frequencies[self->flexpwm_index][submodule] = 0; + } + _maybe_disable_clock(self->flexpwm_index); } void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t *self, uint16_t duty) { @@ -261,39 +319,40 @@ void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t *self, uint16_t d // X - As mentioned above VAL1 turns off, but it's set to the timing for frequency. so // VAL0 turns on, so we set it to VAL1 - duty - DBGPrintf(&mp_plat_print, "common_hal_pwmio_pwmout_set_duty_cycle %u\n", duty); self->duty_cycle = duty; PWM_Type *base = self->pwm->pwm; - uint8_t mask = 1 << self->pwm->submodule; + uint8_t sm_mask = 1 << self->pwm->submodule; + uint16_t duty_scaled; if (duty == 65535) { - self->duty_scaled = self->pulse_count + 1; + // X channels can't do a full 100% duty cycle. + if (self->pwm->channel == kPWM_PwmX) { + mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_duty_cycle); + } + duty_scaled = self->pulse_count + 1; } else { - self->duty_scaled = ((uint32_t)duty * self->pulse_count + self->pulse_count / 2) / 65535; + duty_scaled = ((uint32_t)duty * self->pulse_count) / 65535; } + PWM_SetPwmLdok(self->pwm->pwm, sm_mask, false); switch (self->pwm->channel) { case kPWM_PwmX: - base->SM[self->pwm->submodule].VAL0 = self->pulse_count - self->duty_scaled; - base->OUTEN |= PWM_OUTEN_PWMX_EN(mask); + // PWM X Signals always having a falling edge at the reload value. (Otherwise we'd + // change the PWM frequency.) So, we adjust the rising edge to get the correct duty + // cycle. + base->SM[self->pwm->submodule].VAL0 = self->pulse_count - duty_scaled; break; case kPWM_PwmA: - base->SM[self->pwm->submodule].VAL3 = self->duty_scaled; - base->OUTEN |= PWM_OUTEN_PWMA_EN(mask); + // The other two channels always have their rising edge at 0 and vary their falling + // edge. + base->SM[self->pwm->submodule].VAL3 = duty_scaled; break; case kPWM_PwmB: - base->SM[self->pwm->submodule].VAL5 = self->duty_scaled; - base->OUTEN |= PWM_OUTEN_PWMB_EN(mask); + base->SM[self->pwm->submodule].VAL5 = duty_scaled; } - PWM_SetPwmLdok(self->pwm->pwm, 1 << self->pwm->submodule, true); - - debug_print_flexpwm_registers(self->pwm->pwm); - + PWM_SetPwmLdok(self->pwm->pwm, sm_mask, true); } uint16_t common_hal_pwmio_pwmout_get_duty_cycle(pwmio_pwmout_obj_t *self) { - if (self->duty_cycle == 65535) { - return 65535; - } - return ((uint32_t)self->duty_scaled * 65535 + 65535 / 2) / self->pulse_count; + return self->duty_cycle; } void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t *self, @@ -309,6 +368,8 @@ void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t *self, // a small glitch can occur when adjusting the prescaler, from the setting // of CTRL just below to the setting of the Ldok register in // set_duty_cycle. + // Clear LDOK so that we can update the values. + PWM_SetPwmLdok(self->pwm->pwm, 1 << self->pwm->submodule, false); uint32_t reg = self->pwm->pwm->SM[self->pwm->submodule].CTRL; reg &= ~(PWM_CTRL_PRSC_MASK); reg |= PWM_CTRL_PRSC(self->prescaler); diff --git a/ports/mimxrt10xx/common-hal/pwmio/PWMOut.h b/ports/mimxrt10xx/common-hal/pwmio/PWMOut.h index fa4ce46780..6542d67e1f 100644 --- a/ports/mimxrt10xx/common-hal/pwmio/PWMOut.h +++ b/ports/mimxrt10xx/common-hal/pwmio/PWMOut.h @@ -37,10 +37,12 @@ typedef struct { const mcu_pin_obj_t *pin; const mcu_pwm_obj_t *pwm; bool variable_frequency; + uint8_t flexpwm_index; uint8_t prescaler; - uint16_t duty_cycle, duty_scaled, pulse_count; + uint16_t duty_cycle; + uint16_t pulse_count; } pwmio_pwmout_obj_t; -void pwmout_reset(void); +void reset_all_flexpwm(void); #endif // MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_PWMIO_PWMOUT_H diff --git a/ports/mimxrt10xx/common-hal/rtc/RTC.c b/ports/mimxrt10xx/common-hal/rtc/RTC.c index 7ed65a3499..0cf5fe7713 100644 --- a/ports/mimxrt10xx/common-hal/rtc/RTC.c +++ b/ports/mimxrt10xx/common-hal/rtc/RTC.c @@ -36,18 +36,26 @@ #include "supervisor/shared/translate/translate.h" #include "fsl_snvs_hp.h" +#include "fsl_snvs_lp.h" void rtc_init(void) { - snvs_hp_rtc_config_t config; - SNVS_HP_RTC_GetDefaultConfig(&config); + snvs_hp_rtc_config_t hpconfig; + SNVS_HP_RTC_GetDefaultConfig(&hpconfig); - SNVS_HP_RTC_Init(SNVS, &config); + SNVS_HP_RTC_Init(SNVS, &hpconfig); + + snvs_lp_srtc_config_t lpconfig; + SNVS_LP_SRTC_GetDefaultConfig(&lpconfig); + + SNVS_LP_SRTC_Init(SNVS, &lpconfig); + + SNVS_LP_SRTC_StartTimer(SNVS); SNVS_HP_RTC_StartTimer(SNVS); } void common_hal_rtc_get_time(timeutils_struct_time_t *tm) { - snvs_hp_rtc_datetime_t rtcDate; - SNVS_HP_RTC_GetDatetime(SNVS, &rtcDate); + snvs_lp_srtc_datetime_t rtcDate; + SNVS_LP_SRTC_GetDatetime(SNVS, &rtcDate); tm->tm_year = rtcDate.year; tm->tm_mon = rtcDate.month; @@ -58,7 +66,7 @@ void common_hal_rtc_get_time(timeutils_struct_time_t *tm) { } void common_hal_rtc_set_time(timeutils_struct_time_t *tm) { - snvs_hp_rtc_datetime_t rtcDate; + snvs_lp_srtc_datetime_t rtcDate; rtcDate.year = tm->tm_year; rtcDate.month = tm->tm_mon; rtcDate.day = tm->tm_mday; @@ -66,7 +74,7 @@ void common_hal_rtc_set_time(timeutils_struct_time_t *tm) { rtcDate.minute = tm->tm_min; rtcDate.second = tm->tm_sec; - SNVS_HP_RTC_SetDatetime(SNVS, &rtcDate); + SNVS_LP_SRTC_SetDatetime(SNVS, &rtcDate); } int common_hal_rtc_get_calibration(void) { diff --git a/ports/mimxrt10xx/mpconfigport.mk b/ports/mimxrt10xx/mpconfigport.mk index e7e7abe141..cee2d9a698 100644 --- a/ports/mimxrt10xx/mpconfigport.mk +++ b/ports/mimxrt10xx/mpconfigport.mk @@ -14,10 +14,12 @@ CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_BUSDEVICE = 1 CIRCUITPY_COUNTIO = 0 CIRCUITPY_FREQUENCYIO = 0 -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_NVM = 0 CIRCUITPY_PARALLELDISPLAY = 0 CIRCUITPY_PULSEIO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_USB_MIDI = 1 LONGINT_IMPL = MPZ + +CIRCUITPY_BUILD_EXTENSIONS ?= hex,uf2 diff --git a/ports/mimxrt10xx/reset.h b/ports/mimxrt10xx/reset.h index ea56df02a1..0d458a907d 100644 --- a/ports/mimxrt10xx/reset.h +++ b/ports/mimxrt10xx/reset.h @@ -33,6 +33,7 @@ #include "py/mpconfig.h" // Copied from inc/uf2.h in https://github.com/Microsoft/uf2-samd21 +#define DBL_TAP_REG SNVS->LPGPR[3] #define DBL_TAP_MAGIC 0xf01669ef // Randomly selected, adjusted to have first and last bit set #define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef diff --git a/ports/mimxrt10xx/supervisor/port.c b/ports/mimxrt10xx/supervisor/port.c index fbf0e8a9d8..6997b4bae5 100644 --- a/ports/mimxrt10xx/supervisor/port.c +++ b/ports/mimxrt10xx/supervisor/port.c @@ -259,10 +259,10 @@ safe_mode_t port_init(void) { // run yet, which uses `never_reset` to protect critical pins from being reset by `reset_port`. if (board_requests_safe_mode()) { - return USER_SAFE_MODE; + return SAFE_MODE_USER; } - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } void reset_port(void) { @@ -284,7 +284,7 @@ void reset_port(void) { // eic_reset(); #if CIRCUITPY_PWMIO - pwmout_reset(); + reset_all_flexpwm(); #endif #if CIRCUITPY_RTC @@ -301,7 +301,7 @@ void reset_port(void) { } void reset_to_bootloader(void) { - SNVS->LPGPR[0] = DBL_TAP_MAGIC; + DBL_TAP_REG = DBL_TAP_MAGIC; reset(); } @@ -419,7 +419,7 @@ void port_idle_until_interrupt(void) { */ void MemManage_Handler(void); __attribute__((used)) void MemManage_Handler(void) { - reset_into_safe_mode(MEM_MANAGE); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } @@ -430,7 +430,7 @@ __attribute__((used)) void MemManage_Handler(void) { */ void BusFault_Handler(void); __attribute__((used)) void BusFault_Handler(void) { - reset_into_safe_mode(MEM_MANAGE); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } @@ -441,7 +441,7 @@ __attribute__((used)) void BusFault_Handler(void) { */ void UsageFault_Handler(void); __attribute__((used)) void UsageFault_Handler(void) { - reset_into_safe_mode(MEM_MANAGE); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } @@ -452,7 +452,7 @@ __attribute__((used)) void UsageFault_Handler(void) { */ void HardFault_Handler(void); __attribute__((used)) void HardFault_Handler(void) { - reset_into_safe_mode(HARD_CRASH); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } diff --git a/ports/nrf/.gitignore b/ports/nrf/.gitignore index cda23c7a90..91dce2841a 100644 --- a/ports/nrf/.gitignore +++ b/ports/nrf/.gitignore @@ -1,9 +1,2 @@ -# Old Nordic soft devices that don't allow redistribution -######################################################### -drivers/bluetooth/s132_nrf52_2.0.1/ - +# Softdevice .hex files that should be preserved !drivers/bluetooth/*/*.hex - -# Build files -##################### -build-*/ diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index bbe102ffc8..2267a582a4 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -22,42 +22,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Select the board to build for. -ifeq ($(BOARD),) - $(info You must provide a BOARD parameter with 'BOARD=') - $(info Possible values are:) - $(info $(sort $(subst /.,,$(subst boards/,,$(wildcard boards/*/.))))) - $(error BOARD not defined) -else - ifeq ($(wildcard boards/$(BOARD)/.),) - $(error Invalid BOARD specified) - endif -endif - -CLI_SD := $(SD) -SD_LOWER = $(shell echo $(SD) | tr '[:upper:]' '[:lower:]') - -# Build directory with SD if it's different from the default. -BUILD ?= $(if $(CLI_SD),build-$(BOARD)-$(SD_LOWER),build-$(BOARD)) - -include ../../py/mkenv.mk -# Board-specific -include boards/$(BOARD)/mpconfigboard.mk -# Port-specific -include mpconfigport.mk -# CircuitPython-specific -include $(TOP)/py/circuitpy_mpconfig.mk - -# qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h - -# include py core make definitions -include $(TOP)/py/py.mk - -include $(TOP)/supervisor/supervisor.mk - -# Include make rules and variables common across CircuitPython builds. -include $(TOP)/py/circuitpy_defns.mk +include ../../py/circuitpy_mkenv.mk ifneq ($(SD), ) include bluetooth/bluetooth_common.mk @@ -165,7 +130,6 @@ endif SRC_C += \ background.c \ - fatfs_port.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \ @@ -248,7 +212,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(GENERATED_LD_FILE) $(STEPECHO) "LINK $@" $(Q)echo $(OBJ) > $(BUILD)/firmware.objs $(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--start-group $(LIBS) -Wl,--end-group - $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(GENERATED_LD_FILE) + $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(GENERATED_LD_FILE) $(BUILD) $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(STEPECHO) "Create $@" @@ -311,7 +275,8 @@ endif ##################### .phony: dfu-gen dfu-flash -NRFUTIL = adafruit-nrfutil +NRFUTIL = nrfutil +ADAFRUIT_NRFUTIL = adafruit-nrfutil ifeq ($(MCU_SUB_VARIANT),nrf52840) DFU_TOUCH = --touch 1200 @@ -329,14 +294,19 @@ __check_defined = \ ## Flash with DFU serial dfu-flash: $(BUILD)/dfu-package.zip @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyUSB0) - $(NRFUTIL) --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank $(DFU_TOUCH) + $(ADAFRUIT_NRFUTIL) --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank $(DFU_TOUCH) ## Create DFU package file dfu-gen: $(BUILD)/dfu-package.zip $(BUILD)/dfu-package.zip: $(BUILD)/firmware.hex - $(NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $^ $(BUILD)/dfu-package.zip + $(ADAFRUIT_NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $^ $(BUILD)/dfu-package.zip +# Espruino DFU +$(BUILD)/firmware.espruino.zip: $(BUILD)/firmware.hex + $(Q)$(NRFUTIL) pkg generate $(BUILD)/firmware.espruino.zip --application $^ --application-version 0xff --hw-version 52 --sd-req 0xa9,0xae,0xb6 --key-file espruino_dfu_private_key.pem + +espruino-dfu-gen: $(BUILD)/firmware.espruino.zip include $(TOP)/py/mkrules.mk diff --git a/ports/nrf/background.c b/ports/nrf/background.c index f0822de521..b8d4df6324 100644 --- a/ports/nrf/background.c +++ b/ports/nrf/background.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include "background.h" + #include "py/runtime.h" #include "supervisor/filesystem.h" #include "supervisor/port.h" @@ -44,10 +46,11 @@ void port_start_background_task(void) { } + void port_finish_background_task(void) { } -void port_background_task(void) { +void port_background_tick(void) { #if CIRCUITPY_AUDIOPWMIO audiopwmout_background(); #endif @@ -55,3 +58,11 @@ void port_background_task(void) { i2s_background(); #endif } + +// Allow boards to override this. +MP_WEAK void board_background_task(void) { +} + +void port_background_task(void) { + board_background_task(); +} diff --git a/ports/nrf/background.h b/ports/nrf/background.h index 64a768cf9b..4fba46d031 100644 --- a/ports/nrf/background.h +++ b/ports/nrf/background.h @@ -27,4 +27,6 @@ #ifndef MICROPY_INCLUDED_NRF_BACKGROUND_H #define MICROPY_INCLUDED_NRF_BACKGROUND_H +void board_background_task(void); + #endif // MICROPY_INCLUDED_NRF_BACKGROUND_H diff --git a/ports/nrf/boards/ADM_B_NRF52840_1/board.c b/ports/nrf/boards/ADM_B_NRF52840_1/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/ADM_B_NRF52840_1/board.c +++ b/ports/nrf/boards/ADM_B_NRF52840_1/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/board.c b/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/board.c +++ b/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/pins.c b/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/pins.c index 00fa2c1ed5..8714f9bf8c 100644 --- a/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/pins.c +++ b/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/pins.c @@ -52,6 +52,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { {MP_ROM_QSTR(MP_QSTR_READ_BATT_ENABLE),MP_ROM_PTR(&pin_P0_14)}, {MP_ROM_QSTR(MP_QSTR_VBATT),MP_ROM_PTR(&pin_P0_31)}, {MP_ROM_QSTR(MP_QSTR_CHARGE_STATUS),MP_ROM_PTR(&pin_P0_17)}, + {MP_ROM_QSTR(MP_QSTR_CHARGE_RATE),MP_ROM_PTR(&pin_P0_13)}, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, diff --git a/ports/nrf/boards/TG-Watch/board.c b/ports/nrf/boards/TG-Watch/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/TG-Watch/board.c +++ b/ports/nrf/boards/TG-Watch/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/adafruit_led_glasses_nrf52840/board.c b/ports/nrf/boards/adafruit_led_glasses_nrf52840/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/adafruit_led_glasses_nrf52840/board.c +++ b/ports/nrf/boards/adafruit_led_glasses_nrf52840/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/aramcon2_badge/board.c b/ports/nrf/boards/aramcon2_badge/board.c index 6eb1789284..f8424734fb 100644 --- a/ports/nrf/boards/aramcon2_badge/board.c +++ b/ports/nrf/boards/aramcon2_badge/board.c @@ -26,18 +26,5 @@ */ #include "supervisor/board.h" -#include "common-hal/microcontroller/Pin.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/aramcon2_badge/mpconfigboard.h b/ports/nrf/boards/aramcon2_badge/mpconfigboard.h index 517ad7324b..58df3a4058 100644 --- a/ports/nrf/boards/aramcon2_badge/mpconfigboard.h +++ b/ports/nrf/boards/aramcon2_badge/mpconfigboard.h @@ -52,7 +52,7 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_P0_29) -#define BOARD_USER_SAFE_MODE_ACTION translate("pressing the left button at start up\n") +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed the left button at start up.") #define CIRCUITPY_INTERNAL_NVM_SIZE (4096) diff --git a/ports/nrf/boards/aramcon_badge_2019/board.c b/ports/nrf/boards/aramcon_badge_2019/board.c index 2ac061613a..32d1ca9483 100644 --- a/ports/nrf/boards/aramcon_badge_2019/board.c +++ b/ports/nrf/boards/aramcon_badge_2019/board.c @@ -26,18 +26,5 @@ */ #include "supervisor/board.h" -#include "common-hal/microcontroller/Pin.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/aramcon_badge_2019/mpconfigboard.mk b/ports/nrf/boards/aramcon_badge_2019/mpconfigboard.mk index 06cd9633d1..5bf2eb721b 100644 --- a/ports/nrf/boards/aramcon_badge_2019/mpconfigboard.mk +++ b/ports/nrf/boards/aramcon_badge_2019/mpconfigboard.mk @@ -9,5 +9,6 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "GD25Q16C" CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_PIXELMAP = 0 CIRCUITPY_REQUIRE_I2C_PULLUPS = 0 diff --git a/ports/nrf/boards/arduino_nano_33_ble/board.c b/ports/nrf/boards/arduino_nano_33_ble/board.c index 2f2c5e8388..0b6aa8f0db 100644 --- a/ports/nrf/boards/arduino_nano_33_ble/board.c +++ b/ports/nrf/boards/arduino_nano_33_ble/board.c @@ -53,14 +53,3 @@ void board_init(void) { // digitalWrite(PIN_ENABLE_SENSORS_3V3, HIGH); // digitalWrite(PIN_ENABLE_I2C_PULLUP, HIGH); } - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} diff --git a/ports/nrf/boards/bastble/board.c b/ports/nrf/boards/bastble/board.c index bcf952c89f..fb1ce4fb83 100644 --- a/ports/nrf/boards/bastble/board.c +++ b/ports/nrf/boards/bastble/board.c @@ -25,20 +25,5 @@ */ #include "supervisor/board.h" -#include "nrf.h" -#include "nrf_rtc.h" -void board_init(void) { - -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/bless_dev_board_multi_sensor/board.c b/ports/nrf/boards/bless_dev_board_multi_sensor/board.c index 5b0bdf1e1c..fb1ce4fb83 100644 --- a/ports/nrf/boards/bless_dev_board_multi_sensor/board.c +++ b/ports/nrf/boards/bless_dev_board_multi_sensor/board.c @@ -1,15 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/bluemicro833/board.c b/ports/nrf/boards/bluemicro833/board.c index 104cea6274..c96bc6a996 100644 --- a/ports/nrf/boards/bluemicro833/board.c +++ b/ports/nrf/boards/bluemicro833/board.c @@ -56,10 +56,4 @@ void board_deinit(void) { nrf_gpio_pin_write(POWER_SWITCH_PIN->number, false); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/bluemicro833/mpconfigboard.mk b/ports/nrf/boards/bluemicro833/mpconfigboard.mk index 6108f23102..9b230e9a53 100644 --- a/ports/nrf/boards/bluemicro833/mpconfigboard.mk +++ b/ports/nrf/boards/bluemicro833/mpconfigboard.mk @@ -13,4 +13,5 @@ CIRCUITPY_KEYPAD = 1 CIRCUITPY_NVM = 0 CIRCUITPY_ONEWIREIO = 0 CIRCUITPY_PIXELBUF = 1 +CIRCUITPY_PIXELMAP = 0 CIRCUITPY_TOUCHIO = 0 diff --git a/ports/nrf/boards/bluemicro840/board.c b/ports/nrf/boards/bluemicro840/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/bluemicro840/board.c +++ b/ports/nrf/boards/bluemicro840/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/challenger_840/board.c b/ports/nrf/boards/challenger_840/board.c index b4070e72dc..14a52fc4de 100644 --- a/ports/nrf/boards/challenger_840/board.c +++ b/ports/nrf/boards/challenger_840/board.c @@ -23,19 +23,3 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - -#include "supervisor/board.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} diff --git a/ports/nrf/boards/challenger_840/challenger_840.py b/ports/nrf/boards/challenger_840/challenger_840.py new file mode 100644 index 0000000000..bf3ae77170 --- /dev/null +++ b/ports/nrf/boards/challenger_840/challenger_840.py @@ -0,0 +1,16 @@ +import board +import digitalio + +_LDO_PIN = digitalio.DigitalInOut(board.LDO_CONTROL) +_LDO_PIN.direction = digitalio.Direction.OUTPUT +_LDO_PIN.value = True + + +def ldo_on(): + global _LDO_PIN + _LDO_PIN.value = True + + +def ldo_off(): + global _LDO_PIN + _LDO_PIN.value = False diff --git a/ports/nrf/boards/challenger_840/mpconfigboard.h b/ports/nrf/boards/challenger_840/mpconfigboard.h index e68fbc76fb..5226c818d4 100644 --- a/ports/nrf/boards/challenger_840/mpconfigboard.h +++ b/ports/nrf/boards/challenger_840/mpconfigboard.h @@ -10,6 +10,7 @@ #define SPI_FLASH_MISO_PIN (&pin_P0_11) #define SPI_FLASH_SCK_PIN (&pin_P0_14) #define SPI_FLASH_CS_PIN (&pin_P0_08) +#define SPI_FLASH_MAX_BAUDRATE 20000000 #endif #define CIRCUITPY_AUTORELOAD_DELAY_MS 500 diff --git a/ports/nrf/boards/challenger_840/mpconfigboard.mk b/ports/nrf/boards/challenger_840/mpconfigboard.mk index 61af9ac029..03cbc20b21 100644 --- a/ports/nrf/boards/challenger_840/mpconfigboard.mk +++ b/ports/nrf/boards/challenger_840/mpconfigboard.mk @@ -6,4 +6,8 @@ USB_MANUFACTURER = "Invector Labs AB" MCU_CHIP = nrf52840 SPI_FLASH_FILESYSTEM = 1 -EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ,W25Q32FV" +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ,W25Q32FV,W25Q32JVxQ,W25Q64FV,W25Q64JVxQ" + +FROZEN_MPY_DIRS += $(TOP)/ports/nrf/boards/challenger_840 +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BLE +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/nrf/boards/challenger_840/pins.c b/ports/nrf/boards/challenger_840/pins.c index 26d780fffe..e059c17a15 100644 --- a/ports/nrf/boards/challenger_840/pins.c +++ b/ports/nrf/boards/challenger_840/pins.c @@ -32,6 +32,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P0_06) }, { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_LDO_CONTROL), MP_ROM_PTR(&pin_P1_09) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_12) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_11) }, diff --git a/ports/nrf/boards/circuitplayground_bluefruit/board.c b/ports/nrf/boards/circuitplayground_bluefruit/board.c index 938d92aff1..412b249844 100644 --- a/ports/nrf/boards/circuitplayground_bluefruit/board.c +++ b/ports/nrf/boards/circuitplayground_bluefruit/board.c @@ -54,10 +54,8 @@ void board_deinit(void) { nrf_gpio_pin_write(POWER_SWITCH_PIN->number, true); } -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { board_reset_user_neopixels(&pin_P0_13, 10); } + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/clue_nrf52840_express/board.c b/ports/nrf/boards/clue_nrf52840_express/board.c index 18757cdc06..92ea3fefeb 100644 --- a/ports/nrf/boards/clue_nrf52840_express/board.c +++ b/ports/nrf/boards/clue_nrf52840_express/board.c @@ -84,8 +84,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_P1_05, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -94,14 +93,3 @@ void board_init(void) { false, // not SH1107 50000); // backlight pwm frequency } - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { - common_hal_displayio_release_displays(); -} diff --git a/ports/nrf/boards/electronut_labs_blip/board.c b/ports/nrf/boards/electronut_labs_blip/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/electronut_labs_blip/board.c +++ b/ports/nrf/boards/electronut_labs_blip/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk index 2b46f4397a..0e3b1b9048 100644 --- a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk +++ b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk @@ -5,6 +5,8 @@ USB_MANUFACTURER = "Electronut Labs" MCU_CHIP = nrf52840 +CIRCUITPY_BUILD_EXTENSIONS = hex + INTERNAL_FLASH_FILESYSTEM = 1 CIRCUITPY_AUDIOIO = 0 CIRCUITPY_DISPLAYIO = 1 diff --git a/ports/nrf/boards/electronut_labs_papyr/board.c b/ports/nrf/boards/electronut_labs_papyr/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/electronut_labs_papyr/board.c +++ b/ports/nrf/boards/electronut_labs_papyr/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/espruino_banglejs2/board.c b/ports/nrf/boards/espruino_banglejs2/board.c new file mode 100644 index 0000000000..49a37b7db5 --- /dev/null +++ b/ports/nrf/boards/espruino_banglejs2/board.c @@ -0,0 +1,97 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "background.h" +#include "mpconfigboard.h" + +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/framebufferio/FramebufferDisplay.h" +#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h" +#include "shared-module/displayio/__init__.h" + +digitalio_digitalinout_obj_t extcomin; +digitalio_digitalinout_obj_t display_on; + +uint32_t last_down_ticks_ms; + +void board_init(void) { + common_hal_digitalio_digitalinout_construct(&extcomin, &pin_P0_06); + common_hal_digitalio_digitalinout_switch_to_output(&extcomin, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_never_reset(&extcomin); + + common_hal_digitalio_digitalinout_construct(&display_on, &pin_P0_07); + common_hal_digitalio_digitalinout_switch_to_output(&display_on, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_never_reset(&display_on); + + sharpdisplay_framebuffer_obj_t *fb = &allocate_display_bus()->sharpdisplay; + fb->base.type = &sharpdisplay_framebuffer_type; + + busio_spi_obj_t *spi = &fb->inline_bus; + common_hal_busio_spi_construct(spi, &pin_P0_26, &pin_P0_27, NULL, false); + common_hal_busio_spi_never_reset(spi); + + common_hal_sharpdisplay_framebuffer_construct(fb, spi, &pin_P0_05, 500000, 176, 176, true); + + primary_display_t *display = allocate_display(); + framebufferio_framebufferdisplay_obj_t *self = &display->framebuffer_display; + self->base.type = &framebufferio_framebufferdisplay_type; + common_hal_framebufferio_framebufferdisplay_construct(self, fb, 0, true); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + nrf_gpio_cfg_input(17, NRF_GPIO_PIN_PULLUP); +} + +void board_deinit(void) { + // common_hal_displayio_release_displays(); +} + +void board_background_task(void) { + if (!nrf_gpio_pin_read(17)) { + if (last_down_ticks_ms == 0) { + last_down_ticks_ms = supervisor_ticks_ms32(); + } + } else { + last_down_ticks_ms = 0; + } + // If the button isn't pressed, then feed the watchdog. + if (last_down_ticks_ms == 0) { + NRF_WDT->RR[0] = 0x6E524635; + return; + } + // if the button has been pressed less than 5 seconds, then feed the watchdog. + uint32_t now = supervisor_ticks_ms32(); + if (now - last_down_ticks_ms < 5000) { + NRF_WDT->RR[0] = 0x6E524635; + } + // Don't feed the watchdog so that it'll expire and kick us to the bootloader. +} diff --git a/ports/nrf/boards/espruino_banglejs2/mpconfigboard.h b/ports/nrf/boards/espruino_banglejs2/mpconfigboard.h new file mode 100644 index 0000000000..6057cd56e7 --- /dev/null +++ b/ports/nrf/boards/espruino_banglejs2/mpconfigboard.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "Espruino Bangle.js 2" +#define MICROPY_HW_MCU_NAME "nRF52840" + +#define MICROPY_HW_LED_STATUS (&pin_P0_19) + +#if SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_15 +#define SPI_FLASH_MISO_PIN &pin_P0_13 +#define SPI_FLASH_SCK_PIN &pin_P0_16 +#define SPI_FLASH_CS_PIN &pin_P0_14 +#endif + +#define CIRCUITPY_BOOT_BUTTON (&pin_P0_17) + +#define BOARD_HAS_32KHZ_XTAL (1) diff --git a/ports/nrf/boards/espruino_banglejs2/mpconfigboard.mk b/ports/nrf/boards/espruino_banglejs2/mpconfigboard.mk new file mode 100644 index 0000000000..106b85cd75 --- /dev/null +++ b/ports/nrf/boards/espruino_banglejs2/mpconfigboard.mk @@ -0,0 +1,25 @@ +CIRCUITPY_CREATOR_ID = 0xBA000000 +CIRCUITPY_CREATION_ID = 0x0BA20001 +MCU_CHIP = nrf52840 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = "XT25F64B,GD25Q64C" + +CIRCUITPY_FULL_BUILD = 1 + +# Modules that aren't useful on the board. +CIRCUITPY_AESIO = 0 +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOCORE = 0 +CIRCUITPY_AUDIOMIXER = 0 +CIRCUITPY_AUDIOPWMIO = 0 +CIRCUITPY_COUNTIO = 0 +CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_ONEWIREIO = 0 +CIRCUITPY_RAINBOWIO = 0 +CIRCUITPY_RGBMATRIX = 0 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_USB = 0 + +CIRCUITPY_BUILD_EXTENSIONS = espruino.zip diff --git a/ports/nrf/boards/espruino_banglejs2/pins.c b/ports/nrf/boards/espruino_banglejs2/pins.c new file mode 100644 index 0000000000..b114c2f130 --- /dev/null +++ b/ports/nrf/boards/espruino_banglejs2/pins.c @@ -0,0 +1,41 @@ +#include "shared-bindings/board/__init__.h" + +#include "supervisor/board.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_PRESSURE_SCL), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_MEMLCD_CS), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_MEMLCD_EXTCOMIN), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_MEMLCD_DISP), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_BACKLIGHT), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_VIBRATE), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_HRM_POWER), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_HRM_INT), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_CHARGE_PORT), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_HRM_SDA), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_CHARGE_COMPLETE), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_MEMLCD_SCK), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_MEMLCD_MOSI), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_GPS_POWER), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_GPS_TX), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_GPS_RX), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_HRM_SCL), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_SDA), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_SCL), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_INT), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_ACCEL_SDA), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_ACCEL_SCL), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_COMPASS_SDA), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_COMPASS_SCL), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_PRESSURE_SDA), MP_ROM_PTR(&pin_P1_13) }, + + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/feather_bluefruit_sense/board.c b/ports/nrf/boards/feather_bluefruit_sense/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/feather_bluefruit_sense/board.c +++ b/ports/nrf/boards/feather_bluefruit_sense/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/feather_nrf52840_express/board.c b/ports/nrf/boards/feather_nrf52840_express/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/feather_nrf52840_express/board.c +++ b/ports/nrf/boards/feather_nrf52840_express/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/hiibot_bluefi/board.c b/ports/nrf/boards/hiibot_bluefi/board.c index 6ee4292e70..e5fc4279f8 100644 --- a/ports/nrf/boards/hiibot_bluefi/board.c +++ b/ports/nrf/boards/hiibot_bluefi/board.c @@ -85,8 +85,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_P1_13, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -95,13 +94,3 @@ void board_init(void) { false, // SH1107_addressing 50000); // backlight pwm frequency } - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} diff --git a/ports/nrf/boards/ikigaisense_vita/board.c b/ports/nrf/boards/ikigaisense_vita/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/ikigaisense_vita/board.c +++ b/ports/nrf/boards/ikigaisense_vita/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/itsybitsy_nrf52840_express/board.c b/ports/nrf/boards/itsybitsy_nrf52840_express/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/itsybitsy_nrf52840_express/board.c +++ b/ports/nrf/boards/itsybitsy_nrf52840_express/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/makerdiary_m60_keyboard/board.c b/ports/nrf/boards/makerdiary_m60_keyboard/board.c index b4070e72dc..8074c895dc 100644 --- a/ports/nrf/boards/makerdiary_m60_keyboard/board.c +++ b/ports/nrf/boards/makerdiary_m60_keyboard/board.c @@ -26,16 +26,5 @@ #include "supervisor/board.h" -void board_init(void) { -} -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/makerdiary_nrf52840_m2_devkit/board.c b/ports/nrf/boards/makerdiary_nrf52840_m2_devkit/board.c index db65ecbbd2..ce4241c9da 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_m2_devkit/board.c +++ b/ports/nrf/boards/makerdiary_nrf52840_m2_devkit/board.c @@ -85,8 +85,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_P0_20, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -95,13 +94,3 @@ void board_init(void) { false, // SH1107_addressing 50000); // backlight pwm frequency } - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c b/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk index 7da9ed1896..887bf0a7da 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/mpconfigboard.mk @@ -5,5 +5,7 @@ USB_MANUFACTURER = "makerdiary" MCU_CHIP = nrf52840 +CIRCUITPY_BUILD_EXTENSIONS = hex + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "MX25R6435F" diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk index c4fa121744..1a650d5d4d 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/mpconfigboard.mk @@ -5,4 +5,6 @@ USB_MANUFACTURER = "makerdiary" MCU_CHIP = nrf52840 +CIRCUITPY_BUILD_EXTENSIONS = hex,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 diff --git a/ports/nrf/boards/metro_nrf52840_express/board.c b/ports/nrf/boards/metro_nrf52840_express/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/metro_nrf52840_express/board.c +++ b/ports/nrf/boards/metro_nrf52840_express/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/microbit_v2/board.c b/ports/nrf/boards/microbit_v2/board.c index b87b342823..331653173e 100644 --- a/ports/nrf/boards/microbit_v2/board.c +++ b/ports/nrf/boards/microbit_v2/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/microbit_v2/mpconfigboard.mk b/ports/nrf/boards/microbit_v2/mpconfigboard.mk index 78e76d3b53..d0430ea403 100644 --- a/ports/nrf/boards/microbit_v2/mpconfigboard.mk +++ b/ports/nrf/boards/microbit_v2/mpconfigboard.mk @@ -3,6 +3,8 @@ CIRCUITPY_CREATION_ID = 0x80D8 MCU_CHIP = nrf52833 +CIRCUITPY_BUILD_EXTENSIONS = combined.hex + INTERNAL_FLASH_FILESYSTEM = 1 # USB pins aren't used. diff --git a/ports/nrf/boards/nice_nano/board.c b/ports/nrf/boards/nice_nano/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/nice_nano/board.c +++ b/ports/nrf/boards/nice_nano/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/ohs2020_badge/board.c b/ports/nrf/boards/ohs2020_badge/board.c index 14f1467c79..30c066d91e 100644 --- a/ports/nrf/boards/ohs2020_badge/board.c +++ b/ports/nrf/boards/ohs2020_badge/board.c @@ -84,8 +84,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_P0_02, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -94,13 +93,3 @@ void board_init(void) { false, // SH1107_addressing 50000); // backlight pwm frequency } - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} diff --git a/ports/nrf/boards/particle_argon/board.c b/ports/nrf/boards/particle_argon/board.c index 0aee79f590..7180deb278 100644 --- a/ports/nrf/boards/particle_argon/board.c +++ b/ports/nrf/boards/particle_argon/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/particle_boron/board.c b/ports/nrf/boards/particle_boron/board.c index 0aee79f590..7180deb278 100644 --- a/ports/nrf/boards/particle_boron/board.c +++ b/ports/nrf/boards/particle_boron/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/particle_xenon/board.c b/ports/nrf/boards/particle_xenon/board.c index 0aee79f590..7180deb278 100644 --- a/ports/nrf/boards/particle_xenon/board.c +++ b/ports/nrf/boards/particle_xenon/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/pca10056/board.c b/ports/nrf/boards/pca10056/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/pca10056/board.c +++ b/ports/nrf/boards/pca10056/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/pca10056/mpconfigboard.mk b/ports/nrf/boards/pca10056/mpconfigboard.mk index 48f68a30ae..b30e6ee7a2 100644 --- a/ports/nrf/boards/pca10056/mpconfigboard.mk +++ b/ports/nrf/boards/pca10056/mpconfigboard.mk @@ -5,5 +5,7 @@ USB_MANUFACTURER = "Nordic Semiconductor" MCU_CHIP = nrf52840 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "MX25R6435F" diff --git a/ports/nrf/boards/pca10059/board.c b/ports/nrf/boards/pca10059/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/pca10059/board.c +++ b/ports/nrf/boards/pca10059/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/pca10059/mpconfigboard.mk b/ports/nrf/boards/pca10059/mpconfigboard.mk index 9dc3cc71ed..fe702a50c9 100644 --- a/ports/nrf/boards/pca10059/mpconfigboard.mk +++ b/ports/nrf/boards/pca10059/mpconfigboard.mk @@ -5,4 +5,6 @@ USB_MANUFACTURER = "Nordic Semiconductor" MCU_CHIP = nrf52840 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + INTERNAL_FLASH_FILESYSTEM = 1 diff --git a/ports/nrf/boards/pca10100/board.c b/ports/nrf/boards/pca10100/board.c index 0aee79f590..7180deb278 100644 --- a/ports/nrf/boards/pca10100/board.c +++ b/ports/nrf/boards/pca10100/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/pillbug/board.c b/ports/nrf/boards/pillbug/board.c new file mode 100644 index 0000000000..fb1ce4fb83 --- /dev/null +++ b/ports/nrf/boards/pillbug/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/pillbug/mpconfigboard.h b/ports/nrf/boards/pillbug/mpconfigboard.h new file mode 100644 index 0000000000..d760b165d6 --- /dev/null +++ b/ports/nrf/boards/pillbug/mpconfigboard.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "PillBug" +#define MICROPY_HW_MCU_NAME "nRF52840" + +#define MICROPY_HW_LED_STATUS (&pin_P0_20) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_13) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_15) + +#define DEFAULT_SPI_BUS_SCK (&pin_P1_08) +#define DEFAULT_SPI_BUS_MOSI (&pin_P0_11) +#define DEFAULT_SPI_BUS_MISO (&pin_P0_26) + +#define DEFAULT_UART_BUS_RX (&pin_P0_08) +#define DEFAULT_UART_BUS_TX (&pin_P0_06) diff --git a/ports/nrf/boards/pillbug/mpconfigboard.mk b/ports/nrf/boards/pillbug/mpconfigboard.mk new file mode 100644 index 0000000000..d917ba0157 --- /dev/null +++ b/ports/nrf/boards/pillbug/mpconfigboard.mk @@ -0,0 +1,8 @@ +USB_VID = 0x16D0 +USB_PID = 0x10ED +USB_PRODUCT = "PillBug" +USB_MANUFACTURER = "Mechwild" + +MCU_CHIP = nrf52840 + +INTERNAL_FLASH_FILESYSTEM = 1 diff --git a/ports/nrf/boards/pillbug/pins.c b/ports/nrf/boards/pillbug/pins.c new file mode 100644 index 0000000000..503d6b0f1b --- /dev/null +++ b/ports/nrf/boards/pillbug/pins.c @@ -0,0 +1,64 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P0_06), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P0_08), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_P1_00), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, + + + { MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_AIN2), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_AIN5), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_AIN7), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_04) }, // Read battery voltage divider + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_04) }, + + { MP_ROM_QSTR(MP_QSTR_VCC_OFF), MP_ROM_PTR(&pin_P1_07) }, // External VCC by MOSFET + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_P0_20) }, // Blue LED, HIGH sets to on + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_15) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_11) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/pitaya_go/board.c b/ports/nrf/boards/pitaya_go/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/pitaya_go/board.c +++ b/ports/nrf/boards/pitaya_go/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/raytac_mdbt50q-db-40/board.c b/ports/nrf/boards/raytac_mdbt50q-db-40/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/raytac_mdbt50q-db-40/board.c +++ b/ports/nrf/boards/raytac_mdbt50q-db-40/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/raytac_mdbt50q-rx/board.c b/ports/nrf/boards/raytac_mdbt50q-rx/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/raytac_mdbt50q-rx/board.c +++ b/ports/nrf/boards/raytac_mdbt50q-rx/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/simmel/board.c b/ports/nrf/boards/simmel/board.c index 0aee79f590..7180deb278 100644 --- a/ports/nrf/boards/simmel/board.c +++ b/ports/nrf/boards/simmel/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/sparkfun_nrf52840_micromod/board.c b/ports/nrf/boards/sparkfun_nrf52840_micromod/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_micromod/board.c +++ b/ports/nrf/boards/sparkfun_nrf52840_micromod/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/board.c b/ports/nrf/boards/sparkfun_nrf52840_mini/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_mini/board.c +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/ssci_isp1807_dev_board/board.c b/ports/nrf/boards/ssci_isp1807_dev_board/board.c index 8d8e531d47..c8bd7e0b35 100644 --- a/ports/nrf/boards/ssci_isp1807_dev_board/board.c +++ b/ports/nrf/boards/ssci_isp1807_dev_board/board.c @@ -28,16 +28,4 @@ #include "nrf.h" #include "nrf_rtc.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/ssci_isp1807_micro_board/board.c b/ports/nrf/boards/ssci_isp1807_micro_board/board.c index 8d8e531d47..c8bd7e0b35 100644 --- a/ports/nrf/boards/ssci_isp1807_micro_board/board.c +++ b/ports/nrf/boards/ssci_isp1807_micro_board/board.c @@ -28,16 +28,4 @@ #include "nrf.h" #include "nrf_rtc.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/teknikio_bluebird/board.c b/ports/nrf/boards/teknikio_bluebird/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/teknikio_bluebird/board.c +++ b/ports/nrf/boards/teknikio_bluebird/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/tinkeringtech_scoutmakes_azul/board.c b/ports/nrf/boards/tinkeringtech_scoutmakes_azul/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/tinkeringtech_scoutmakes_azul/board.c +++ b/ports/nrf/boards/tinkeringtech_scoutmakes_azul/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/boards/warmbit_bluepixel/board.c b/ports/nrf/boards/warmbit_bluepixel/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/nrf/boards/warmbit_bluepixel/board.c +++ b/ports/nrf/boards/warmbit_bluepixel/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c index 5cebf2fa0f..1c3c829c5b 100644 --- a/ports/nrf/common-hal/_bleio/Adapter.c +++ b/ports/nrf/common-hal/_bleio/Adapter.c @@ -52,8 +52,9 @@ #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" +#include "shared-module/os/__init__.h" #endif #define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) @@ -90,7 +91,7 @@ const nvm_bytearray_obj_t common_hal_bleio_nvm_obj = { }; STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { - reset_into_safe_mode(NORDIC_SOFT_DEVICE_ASSERT); + reset_into_safe_mode(SAFE_MODE_SDK_FATAL_ERROR); } bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT]; @@ -343,20 +344,17 @@ STATIC void bleio_adapter_reset_name(bleio_adapter_obj_t *self) { default_ble_name[len - 1] = nibble_to_hex_lower[addr.addr[0] & 0xf]; default_ble_name[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings - mp_int_t name_len = 0; - - #if CIRCUITPY_DOTENV + #if CIRCUITPY_OS_GETENV char ble_name[32]; - name_len = dotenv_get_key("/.env", "CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name) - 1); - if (name_len > 0) { - ble_name[name_len] = '\0'; - common_hal_bleio_adapter_set_name(self, (char *)ble_name); + + os_getenv_err_t result = common_hal_os_getenv_str("CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name)); + if (result == GETENV_OK) { + common_hal_bleio_adapter_set_name(self, ble_name); + return; } #endif - if (name_len <= 0) { - common_hal_bleio_adapter_set_name(self, (char *)default_ble_name); - } + common_hal_bleio_adapter_set_name(self, (char *)default_ble_name); } static void bluetooth_adapter_background(void *data) { @@ -449,15 +447,23 @@ bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_addre return sd_ble_gap_addr_set(&local_address) == NRF_SUCCESS; } +uint16_t bleio_adapter_get_name(char *buf, uint16_t len) { + uint16_t full_len = 0; + sd_ble_gap_device_name_get(NULL, &full_len); + + uint32_t err_code = sd_ble_gap_device_name_get((uint8_t *)buf, &len); + if (err_code != NRF_SUCCESS) { + return 0; + } + return full_len; +} + mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) { uint16_t len = 0; sd_ble_gap_device_name_get(NULL, &len); - uint8_t buf[len]; - uint32_t err_code = sd_ble_gap_device_name_get(buf, &len); - if (err_code != NRF_SUCCESS) { - return NULL; - } - return mp_obj_new_str((char *)buf, len); + char buf[len]; + bleio_adapter_get_name(buf, len); + return mp_obj_new_str(buf, len); } void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *name) { diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c index 5772616ee5..58dc94fe25 100644 --- a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c +++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c @@ -45,7 +45,17 @@ STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) { uint8_t is_nested_critical_region; sd_nvic_critical_region_enter(&is_nested_critical_region); - ringbuf_put_n(&self->ringbuf, data, len); + if (self->watch_for_interrupt_char) { + for (uint16_t i = 0; i < len; i++) { + if (data[i] == mp_interrupt_char) { + mp_sched_keyboard_interrupt(); + } else { + ringbuf_put(&self->ringbuf, data[i]); + } + } + } else { + ringbuf_put_n(&self->ringbuf, data, len); + } sd_nvic_critical_region_exit(is_nested_critical_region); } @@ -85,15 +95,14 @@ void _common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buff bleio_characteristic_obj_t *characteristic, mp_float_t timeout, uint8_t *buffer, size_t buffer_size, - void *static_handler_entry) { + void *static_handler_entry, + bool watch_for_interrupt_char) { self->characteristic = characteristic; self->timeout_ms = timeout * 1000; + self->watch_for_interrupt_char = watch_for_interrupt_char; - self->ringbuf.buf = (uint8_t *)buffer; - self->ringbuf.size = buffer_size; - self->ringbuf.iget = 0; - self->ringbuf.iput = 0; + ringbuf_init(&self->ringbuf, buffer, buffer_size); if (static_handler_entry != NULL) { ble_drv_add_event_handler_entry((ble_drv_evt_handler_entry_t *)static_handler_entry, characteristic_buffer_on_ble_evt, self); @@ -108,7 +117,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe mp_float_t timeout, size_t buffer_size) { uint8_t *buffer = m_malloc(buffer_size, true); - _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, buffer, buffer_size, NULL); + _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, buffer, buffer_size, NULL, false); } uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) { @@ -159,6 +168,7 @@ void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_o if (!common_hal_bleio_characteristic_buffer_deinited(self)) { ble_drv_remove_event_handler(characteristic_buffer_on_ble_evt, self); self->characteristic = NULL; + ringbuf_deinit(&self->ringbuf); } } diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h index f0949251cd..ba3d7ba3fc 100644 --- a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h +++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h @@ -27,6 +27,8 @@ #ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H #define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H +#include + #include "nrf_soc.h" #include "py/ringbuf.h" @@ -38,6 +40,7 @@ typedef struct { uint32_t timeout_ms; // Ring buffer storing consecutive incoming values. ringbuf_t ringbuf; + bool watch_for_interrupt_char; } bleio_characteristic_buffer_obj_t; #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.c b/ports/nrf/common-hal/_bleio/PacketBuffer.c index 38dcdd9041..52402a93f1 100644 --- a/ports/nrf/common-hal/_bleio/PacketBuffer.c +++ b/ports/nrf/common-hal/_bleio/PacketBuffer.c @@ -43,7 +43,7 @@ #include "supervisor/shared/bluetooth/serial.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 but can if our buffer size was much smaller than // the writes the client actually makes. return; @@ -52,7 +52,7 @@ STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uin uint8_t is_nested_critical_region; sd_nvic_critical_region_enter(&is_nested_critical_region); // 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++) { @@ -233,10 +233,7 @@ void _common_hal_bleio_packet_buffer_construct( } if (incoming) { - self->ringbuf.buf = (uint8_t *)incoming_buffer; - self->ringbuf.size = incoming_buffer_size; - self->ringbuf.iget = 0; - self->ringbuf.iput = 0; + ringbuf_init(&self->ringbuf, (uint8_t *)incoming_buffer, incoming_buffer_size); } self->packet_queued = false; @@ -502,7 +499,9 @@ 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)) { ble_drv_remove_event_handler(packet_buffer_on_ble_client_evt, self); + ringbuf_deinit(&self->ringbuf); } } diff --git a/ports/nrf/common-hal/alarm/SleepMemory.h b/ports/nrf/common-hal/alarm/SleepMemory.h index 8fd702ea83..bb50c36e89 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.h +++ b/ports/nrf/common-hal/alarm/SleepMemory.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM_SLEEPMEMORY_H -#define MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM_SLEEPMEMORY_H +#pragma once #include "py/obj.h" @@ -37,5 +36,3 @@ typedef struct { extern void set_memory_retention(void); extern void alarm_sleep_memory_reset(void); - -#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM_SLEEPMEMORY_H diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 043be0b319..b3f9979ae0 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -56,6 +56,10 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = { }, }; +// Non-heap alarm object recording alarm (if any) that woke up CircuitPython after light or deep sleep. +// This object lives across VM instantiations, so none of these objects can contain references to the heap. +alarm_wake_alarm_union_t alarm_wake_alarm; + void alarm_reset(void) { alarm_sleep_memory_reset(); alarm_pin_pinalarm_reset(); @@ -115,19 +119,19 @@ bool common_hal_alarm_woken_from_sleep(void) { || cause == NRF_SLEEP_WAKEUP_TOUCHPAD; } -mp_obj_t common_hal_alarm_create_wake_alarm(void) { +mp_obj_t common_hal_alarm_record_wake_alarm(void) { // If woken from deep sleep, create a copy alarm similar to what would have // been passed in originally. Otherwise, just return none nrf_sleep_source_t cause = _get_wakeup_cause(); switch (cause) { case NRF_SLEEP_WAKEUP_TIMER: { - return alarm_time_timealarm_create_wakeup_alarm(); + return alarm_time_timealarm_record_wake_alarm(); } case NRF_SLEEP_WAKEUP_TOUCHPAD: { - return alarm_touch_touchalarm_create_wakeup_alarm(); + return alarm_touch_touchalarm_record_wake_alarm(); } case NRF_SLEEP_WAKEUP_GPIO: { - return alarm_pin_pinalarm_create_wakeup_alarm(); + return alarm_pin_pinalarm_record_wake_alarm(); } default: break; @@ -247,7 +251,10 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj return wake_alarm; } -void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { +void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t **preserve_dios) { + if (n_dios > 0) { + mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_preserve_dios); + } _setup_sleep_alarms(true, n_alarms, alarms); } diff --git a/ports/nrf/common-hal/alarm/__init__.h b/ports/nrf/common-hal/alarm/__init__.h index 47051dbd72..7c4634610d 100644 --- a/ports/nrf/common-hal/alarm/__init__.h +++ b/ports/nrf/common-hal/alarm/__init__.h @@ -25,10 +25,12 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM__INIT__H -#define MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM__INIT__H +#pragma once #include "common-hal/alarm/SleepMemory.h" +#include "common-hal/alarm/pin/PinAlarm.h" +#include "common-hal/alarm/time/TimeAlarm.h" +#include "common-hal/alarm/touch/TouchAlarm.h" typedef enum { NRF_SLEEP_WAKEUP_UNDEFINED, @@ -40,6 +42,13 @@ typedef enum { NRF_SLEEP_WAKEUP_ZZZ } nrf_sleep_source_t; +typedef union { + alarm_pin_pinalarm_obj_t pin_alarm; + alarm_time_timealarm_obj_t time_alarm; + alarm_touch_touchalarm_obj_t touch_alarm; +} alarm_wake_alarm_union_t; + +extern alarm_wake_alarm_union_t alarm_wake_alarm; extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; enum { @@ -52,5 +61,3 @@ extern uint8_t sleepmem_wakeup_event; extern uint8_t sleepmem_wakeup_pin; extern void alarm_reset(void); - -#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM__INIT__H diff --git a/ports/nrf/common-hal/alarm/coproc/CoprocAlarm.c b/ports/nrf/common-hal/alarm/coproc/CoprocAlarm.c new file mode 100644 index 0000000000..4bd8276f34 --- /dev/null +++ b/ports/nrf/common-hal/alarm/coproc/CoprocAlarm.c @@ -0,0 +1 @@ +// empty file diff --git a/ports/nrf/common-hal/alarm/coproc/CoprocAlarm.h b/ports/nrf/common-hal/alarm/coproc/CoprocAlarm.h new file mode 100644 index 0000000000..4bd8276f34 --- /dev/null +++ b/ports/nrf/common-hal/alarm/coproc/CoprocAlarm.h @@ -0,0 +1 @@ +// empty file diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 9d0f8f4b88..5bef48773e 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -30,10 +30,9 @@ #include #include +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "common-hal/alarm/__init__.h" #include "nrfx.h" #include "nrf_gpio.h" @@ -101,8 +100,9 @@ mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t return mp_const_none; } -mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) { - alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t); +mp_obj_t alarm_pin_pinalarm_record_wake_alarm(void) { + alarm_pin_pinalarm_obj_t *const alarm = &alarm_wake_alarm.pin_alarm; + alarm->base.type = &alarm_pin_pinalarm_type; alarm->pin = NULL; // Map the pin number back to a pin object. diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.h b/ports/nrf/common-hal/alarm/pin/PinAlarm.h index 87b7b9833c..9181cb6094 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.h +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.h @@ -24,9 +24,13 @@ * THE SOFTWARE. */ +#pragma once + #include "py/obj.h" #include "py/objtuple.h" +#include "shared-bindings/microcontroller/Pin.h" + typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *pin; @@ -35,7 +39,7 @@ typedef struct { } alarm_pin_pinalarm_obj_t; mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void); +mp_obj_t alarm_pin_pinalarm_record_wake_alarm(void); void alarm_pin_pinalarm_reset(void); void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.c b/ports/nrf/common-hal/alarm/time/TimeAlarm.c index 03b91068f9..a69e299bc2 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.c +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.c @@ -28,7 +28,7 @@ #include "py/runtime.h" #include -#include "common-hal/alarm/__init__.h" +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/time/__init__.h" @@ -49,12 +49,13 @@ mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj return mp_const_none; } -mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) { - alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t); - timer->base.type = &alarm_time_timealarm_type; +mp_obj_t alarm_time_timealarm_record_wake_alarm(void) { + alarm_time_timealarm_obj_t *const alarm = &alarm_wake_alarm.time_alarm; + + alarm->base.type = &alarm_time_timealarm_type; // TODO: Set monotonic_time based on the RTC state. - timer->monotonic_time = 0.0f; - return timer; + alarm->monotonic_time = 0.0f; + return alarm; } bool alarm_time_timealarm_woke_this_cycle(void) { diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.h b/ports/nrf/common-hal/alarm/time/TimeAlarm.h index 734feb1c87..c5f76c8003 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.h +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.h @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#pragma once #include "py/obj.h" @@ -37,7 +38,7 @@ extern void port_disable_interrupt_after_ticks_ch(uint32_t channel); extern void port_interrupt_after_ticks_ch(uint32_t channel, uint32_t ticks); mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void); +mp_obj_t alarm_time_timealarm_record_wake_alarm(void); bool alarm_time_timealarm_woke_this_cycle(void); void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); diff --git a/ports/nrf/common-hal/alarm/touch/TouchAlarm.c b/ports/nrf/common-hal/alarm/touch/TouchAlarm.c index f8daf50f54..5c1d489262 100644 --- a/ports/nrf/common-hal/alarm/touch/TouchAlarm.c +++ b/ports/nrf/common-hal/alarm/touch/TouchAlarm.c @@ -25,6 +25,7 @@ */ #include "py/runtime.h" + #include "shared-bindings/alarm/touch/TouchAlarm.h" #include "shared-bindings/microcontroller/__init__.h" @@ -39,7 +40,7 @@ mp_obj_t alarm_touch_touchalarm_find_triggered_alarm(const size_t n_alarms, cons return mp_const_none; } -mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void) { +mp_obj_t alarm_touch_touchalarm_record_wake_alarm(void) { return mp_const_none; } diff --git a/ports/nrf/common-hal/alarm/touch/TouchAlarm.h b/ports/nrf/common-hal/alarm/touch/TouchAlarm.h index 58ad8c20fe..31aa30117a 100644 --- a/ports/nrf/common-hal/alarm/touch/TouchAlarm.h +++ b/ports/nrf/common-hal/alarm/touch/TouchAlarm.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H -#define MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H +#pragma once #include "py/obj.h" #include "common-hal/microcontroller/Pin.h" @@ -37,11 +36,9 @@ typedef struct { // Find the alarm object that caused us to wake up or create an equivalent one. mp_obj_t alarm_touch_touchalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void); +mp_obj_t alarm_touch_touchalarm_record_wake_alarm(void); // Check for the wake up alarm from pretend deep sleep. void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms); void alarm_touch_touchalarm_prepare_for_deep_sleep(void); bool alarm_touch_touchalarm_woke_this_cycle(void); void alarm_touch_touchalarm_reset(void); - -#endif // MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 04c502a4bd..10a34e09df 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -183,9 +183,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, mp_raise_ValueError(translate("All UART peripherals are in use")); } - if ((tx == NULL) && (rx == NULL)) { - mp_raise_ValueError(translate("tx and rx cannot both be None")); - } + // shared-bindings checks that TX and RX are not both None, so we don't need to check here. mp_arg_validate_int_min(receiver_buffer_size, 1, MP_QSTR_receiver_buffer_size); @@ -213,24 +211,20 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // Init buffer for rx if (rx != NULL) { - self->allocated_ringbuf = true; // Use the provided buffer when given. if (receiver_buffer != NULL) { - self->ringbuf.buf = receiver_buffer; - self->ringbuf.size = receiver_buffer_size - 1; - self->ringbuf.iput = 0; - self->ringbuf.iget = 0; - self->allocated_ringbuf = false; + ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); + } else { // Initially allocate the UART's buffer in the long-lived part of the // heap. UARTs are generally long-lived objects, but the "make long- // lived" machinery is incapable of moving internal pointers like // self->buffer, so do it manually. (However, as long as internal // pointers like this are NOT moved, allocating the buffer // in the long-lived pool is not strictly necessary) - // (This is a macro.) - } else if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { - nrfx_uarte_uninit(self->uarte); - m_malloc_fail(receiver_buffer_size); + if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { + nrfx_uarte_uninit(self->uarte); + m_malloc_fail(receiver_buffer_size); + } } self->rx_pin_number = rx->number; @@ -282,9 +276,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { self->rx_pin_number = NO_PIN; self->rts_pin_number = NO_PIN; self->cts_pin_number = NO_PIN; - if (self->allocated_ringbuf) { - ringbuf_free(&self->ringbuf); - } + ringbuf_deinit(&self->ringbuf); for (size_t i = 0; i < MP_ARRAY_SIZE(nrfx_uartes); i++) { if (self->uarte == &nrfx_uartes[i]) { @@ -305,7 +297,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // check removed to reduce code size /* - if (len > ringbuf_capacity(&self->ringbuf)) { + if (len > ringbuf_size(&self->ringbuf)) { mp_raise_ValueError(translate("Reading >receiver_buffer_size bytes is not supported")); } */ @@ -337,6 +329,11 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg)); + if (rx_bytes == 0) { + *errcode = EAGAIN; + return MP_STREAM_ERROR; + } + return rx_bytes; } diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h index 140f8d0c0a..2eaf584403 100644 --- a/ports/nrf/common-hal/busio/UART.h +++ b/ports/nrf/common-hal/busio/UART.h @@ -44,7 +44,6 @@ typedef struct { ringbuf_t ringbuf; uint8_t rx_char; // EasyDMA buf bool rx_paused; // set by irq if no space in rbuf - bool allocated_ringbuf; uint8_t tx_pin_number; uint8_t rx_pin_number; diff --git a/ports/nrf/common-hal/digitalio/DigitalInOut.c b/ports/nrf/common-hal/digitalio/DigitalInOut.c index 95e488f3b7..a6440228f1 100644 --- a/ports/nrf/common-hal/digitalio/DigitalInOut.c +++ b/ports/nrf/common-hal/digitalio/DigitalInOut.c @@ -59,10 +59,11 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self self->pin = NULL; } -void common_hal_digitalio_digitalinout_switch_to_input( +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { nrf_gpio_cfg_input(self->pin->number, NRF_GPIO_PIN_NOPULL); common_hal_digitalio_digitalinout_set_pull(self, pull); + return DIGITALINOUT_OK; } digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( @@ -120,7 +121,7 @@ digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( } } -void common_hal_digitalio_digitalinout_set_pull( +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { nrf_gpio_pin_pull_t hal_pull = NRF_GPIO_PIN_NOPULL; @@ -137,6 +138,7 @@ void common_hal_digitalio_digitalinout_set_pull( } nrf_gpio_cfg_input(self->pin->number, hal_pull); + return DIGITALINOUT_OK; } digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c index d84cc58455..cd4114dcfb 100644 --- a/ports/nrf/common-hal/microcontroller/__init__.c +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -68,9 +68,8 @@ void common_hal_mcu_disable_interrupts() { void common_hal_mcu_enable_interrupts() { if (nesting_count == 0) { - // This is very very bad because it means there was mismatched disable/enables so we - // crash. - reset_into_safe_mode(HARD_CRASH); + // This is very very bad because it means there was mismatched disable/enables. + reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); } nesting_count--; if (nesting_count > 0) { @@ -82,13 +81,13 @@ void common_hal_mcu_enable_interrupts() { void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { enum { DFU_MAGIC_UF2_RESET = 0x57 }; - if (runmode == RUNMODE_BOOTLOADER) { - NRF_POWER->GPREGRET = DFU_MAGIC_UF2_RESET; + if (runmode == RUNMODE_BOOTLOADER || runmode == RUNMODE_UF2) { + sd_power_gpregret_set(0,DFU_MAGIC_UF2_RESET); } else { - NRF_POWER->GPREGRET = 0; + sd_power_gpregret_set(0,0); } if (runmode == RUNMODE_SAFE_MODE) { - safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE); + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); } } diff --git a/ports/nrf/common-hal/pulseio/PulseOut.c b/ports/nrf/common-hal/pulseio/PulseOut.c index 2f822b4184..c2d59ffdba 100644 --- a/ports/nrf/common-hal/pulseio/PulseOut.c +++ b/ports/nrf/common-hal/pulseio/PulseOut.c @@ -74,6 +74,11 @@ static void pulseout_event_handler(nrf_timer_event_t event_type, void *p_context nrfx_timer_pause(timer); pulse_array_index++; + // Ignore a zero-length pulse + while (pulse_array_index < pulse_array_length && + pulse_array[pulse_array_index] == 0) { + pulse_array_index++; + } // No more pulses. Turn off output and don't restart. if (pulse_array_index >= pulse_array_length) { diff --git a/ports/nrf/common-hal/pwmio/PWMOut.c b/ports/nrf/common-hal/pwmio/PWMOut.c index 1bd38e7a6e..f73e3d3952 100644 --- a/ports/nrf/common-hal/pwmio/PWMOut.c +++ b/ports/nrf/common-hal/pwmio/PWMOut.c @@ -67,25 +67,11 @@ STATIC int pwm_idx(NRF_PWM_Type *pwm) { } void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { - for (size_t i = 0; i < MP_ARRAY_SIZE(pwms); i++) { - NRF_PWM_Type *pwm = pwms[i]; - if (pwm == self->pwm) { - never_reset_pwm[i] += 1; - } - } + never_reset_pwm[pwm_idx(self->pwm)] |= 1 << self->channel; common_hal_never_reset_pin(self->pin); } -void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { - for (size_t i = 0; i < MP_ARRAY_SIZE(pwms); i++) { - NRF_PWM_Type *pwm = pwms[i]; - if (pwm == self->pwm) { - never_reset_pwm[i] -= 1; - } - } -} - STATIC void reset_single_pwmout(uint8_t i) { NRF_PWM_Type *pwm = pwms[i]; @@ -114,7 +100,13 @@ STATIC void reset_single_pwmout(uint8_t i) { void pwmout_reset(void) { for (size_t i = 0; i < MP_ARRAY_SIZE(pwms); i++) { - if (never_reset_pwm[i] > 0) { + for (size_t c = 0; c < CHANNELS_PER_PWM; c++) { + if ((never_reset_pwm[i] & (1 << c)) != 0) { + continue; + } + pwms[i]->PSEL.OUT[c] = 0xFFFFFFFF; + } + if (never_reset_pwm[i] != 0) { continue; } reset_single_pwmout(i); @@ -270,6 +262,8 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { nrf_gpio_cfg_default(self->pin->number); + never_reset_pwm[pwm_idx(self->pwm)] &= ~(1 << self->channel); + NRF_PWM_Type *pwm = self->pwm; self->pwm = NULL; diff --git a/ports/nrf/common-hal/watchdog/WatchDogTimer.c b/ports/nrf/common-hal/watchdog/WatchDogTimer.c index cd7aa449bf..99c360c46d 100644 --- a/ports/nrf/common-hal/watchdog/WatchDogTimer.c +++ b/ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -96,7 +96,7 @@ void common_hal_watchdog_feed(watchdog_watchdogtimer_obj_t *self) { void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { if (self->mode == WATCHDOGMODE_RESET) { if (gc_alloc_possible()) { - mp_raise_NotImplementedError(translate("WatchDogTimer cannot be deinitialized once mode is set to RESET")); + mp_raise_RuntimeError(translate("WatchDogTimer cannot be deinitialized once mode is set to RESET")); } // Don't change anything because RESET cannot be undone. return; diff --git a/ports/nrf/espruino_dfu_private_key.pem b/ports/nrf/espruino_dfu_private_key.pem new file mode 100644 index 0000000000..79c70f76ee --- /dev/null +++ b/ports/nrf/espruino_dfu_private_key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIK5uG3MovsdlHdw0xKzHsiv7hCRlFFQbwF30wW2KT4YJoAoGCCqGSM49 +AwEHoUQDQgAElQMkm+myar6SNwygD8seLeccsydVakcn3kHvxVK5AUnTCcYEFKPY +B9RfTIE/mwpHoaXs8e4swKX9nPBeC2mTZQ== +-----END EC PRIVATE KEY----- diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 6aff88b289..04c4f3bce6 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -4,6 +4,8 @@ LD_TEMPLATE_FILE = boards/common.template.ld INTERNAL_LIBM = 1 +CIRCUITPY_BUILD_EXTENSIONS ?= uf2 + # Number of USB endpoint pairs. USB_NUM_ENDPOINT_PAIRS = 8 @@ -25,7 +27,7 @@ CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_BLEIO ?= 1 # No I2CPeripheral implementation -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_RTC ?= 1 diff --git a/ports/nrf/peripherals/nrf/cache.c b/ports/nrf/peripherals/nrf/cache.c index 6eb590d770..54bb77980b 100644 --- a/ports/nrf/peripherals/nrf/cache.c +++ b/ports/nrf/peripherals/nrf/cache.c @@ -29,8 +29,18 @@ // Turn off cache and invalidate all data in it. void nrf_peripherals_disable_and_clear_cache(void) { + // Memory fence for hardware and compiler reasons. If this routine is inlined, the compiler + // needs to know that everything written out be stored before this is called. + // -O2 optimization needed this on SAMD51. Assuming nRF may have the same issue. + // __sync_synchronize() includes volatile asm(), which tells the compiler not to assume + // state across this call. + __sync_synchronize(); + // Disabling cache also invalidates all cache entries. NRF_NVMC->ICACHECNF &= ~(1 << NVMC_ICACHECNF_CACHEEN_Pos); + + // Memory fence for hardware and compiler reasons. + __sync_synchronize(); } // Enable cache diff --git a/ports/nrf/supervisor/internal_flash.c b/ports/nrf/supervisor/internal_flash.c index cce48a4c32..4229ec771b 100644 --- a/ports/nrf/supervisor/internal_flash.c +++ b/ports/nrf/supervisor/internal_flash.c @@ -75,7 +75,7 @@ void port_internal_flash_flush(void) { // Skip if data is the same if (memcmp(_flash_cache, (void *)_flash_page_addr, FLASH_PAGE_SIZE) != 0) { if (!nrf_nvm_safe_flash_page_write(_flash_page_addr, _flash_cache)) { - reset_into_safe_mode(FLASH_WRITE_FAIL); + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); } } } diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 0d1f71e886..313ecd7e44 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -64,11 +64,11 @@ #include "lib/tinyusb/src/device/usbd.h" -#ifdef CIRCUITPY_AUDIOBUSIO +#if CIRCUITPY_AUDIOBUSIO #include "common-hal/audiobusio/I2SOut.h" #endif -#ifdef CIRCUITPY_AUDIOPWMIO +#if CIRCUITPY_AUDIOPWMIO #include "common-hal/audiopwmio/PWMAudioOut.h" #endif @@ -77,7 +77,7 @@ extern void qspi_disable(void); #endif static void power_warning_handler(void) { - reset_into_safe_mode(BROWNOUT); + reset_into_safe_mode(SAFE_MODE_BROWNOUT); } uint32_t reset_reason_saved = 0; @@ -204,11 +204,11 @@ safe_mode_t port_init(void) { // If USB is connected, then the user might be editing `code.py`, // in which case we should reboot into Safe Mode. if (usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk) { - return WATCHDOG_RESET; + return SAFE_MODE_WATCHDOG; } } - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } void reset_port(void) { @@ -399,14 +399,8 @@ void port_idle_until_interrupt(void) { extern void HardFault_Handler(void); void HardFault_Handler(void) { - reset_into_safe_mode(HARD_CRASH); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } - -#if CIRCUITPY_ALARM -// in case boards/xxx/board.c does not provide board_deinit() -MP_WEAK void board_deinit(void) { -} -#endif diff --git a/ports/raspberrypi/.gitignore b/ports/raspberrypi/.gitignore deleted file mode 100644 index 414487d53e..0000000000 --- a/ports/raspberrypi/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build-*/ diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index 67de654255..fafc817ca2 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -22,89 +22,123 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Select the board to build for. -ifeq ($(BOARD),) - $(error You must provide a BOARD parameter) -else - ifeq ($(wildcard boards/$(BOARD)/.),) - $(error Invalid BOARD specified) - endif -endif - -# If the build directory is not given, make it reflect the board name. -BUILD ?= build-$(BOARD) - -include ../../py/mkenv.mk -# Board-specific -include boards/$(BOARD)/mpconfigboard.mk -# Port-specific -include mpconfigport.mk -# CircuitPython-specific -include $(TOP)/py/circuitpy_mpconfig.mk - -# qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h - -# include py core make definitions -include $(TOP)/py/py.mk - -include $(TOP)/supervisor/supervisor.mk - -# Include make rules and variables common across CircuitPython builds. -include $(TOP)/py/circuitpy_defns.mk +include ../../py/circuitpy_mkenv.mk CROSS_COMPILE = arm-none-eabi- HAL_DIR=hal/$(MCU_SERIES) -INC += -I. \ - -I../.. \ - -I../lib/mp-readline \ - -I../shared/timeutils \ - -Iboards/$(BOARD) \ - -Iboards/ \ - -isystem sdk/ \ - -isystem sdk/src/common/pico_base/include/ \ - -isystem sdk/src/common/pico_binary_info/include/ \ - -isystem sdk/src/common/pico_stdlib/include/ \ - -isystem sdk/src/common/pico_sync/include/ \ - -isystem sdk/src/common/pico_time/include/ \ - -isystem sdk/src/common/pico_util/include/ \ - -isystem sdk/src/rp2040/hardware_regs/include/ \ - -isystem sdk/src/rp2040/hardware_structs/include/ \ - -isystem sdk/src/rp2_common/hardware_adc/include/ \ - -isystem sdk/src/rp2_common/hardware_base/include/ \ - -isystem sdk/src/rp2_common/hardware_claim/include/ \ - -isystem sdk/src/rp2_common/hardware_clocks/include/ \ - -isystem sdk/src/rp2_common/hardware_divider/include/ \ - -isystem sdk/src/rp2_common/hardware_dma/include/ \ - -isystem sdk/src/rp2_common/hardware_flash/include/ \ - -isystem sdk/src/rp2_common/hardware_gpio/include/ \ - -isystem sdk/src/rp2_common/hardware_irq/include/ \ - -isystem sdk/src/rp2_common/hardware_i2c/include/ \ - -isystem sdk/src/rp2_common/hardware_pio/include/ \ - -isystem sdk/src/rp2_common/hardware_pll/include/ \ - -isystem sdk/src/rp2_common/hardware_resets/include/ \ - -isystem sdk/src/rp2_common/hardware_rtc/include/ \ - -isystem sdk/src/rp2_common/hardware_spi/include/ \ - -isystem sdk/src/rp2_common/hardware_sync/include/ \ - -isystem sdk/src/rp2_common/hardware_timer/include/ \ - -isystem sdk/src/rp2_common/hardware_uart/include/ \ - -isystem sdk/src/rp2_common/hardware_watchdog/include/ \ - -isystem sdk/src/rp2_common/hardware_xosc/include/ \ - -isystem sdk/src/rp2_common/pico_multicore/include/ \ - -isystem sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/include/ \ - -isystem sdk/src/rp2_common/pico_stdio/include/ \ - -isystem sdk/src/rp2_common/pico_printf/include/ \ - -isystem sdk/src/rp2_common/pico_float/include/ \ - -isystem sdk/src/rp2_common/pico_platform/include/ \ - -isystem sdk/src/rp2_common/pico_runtime/printf/include/ \ - -isystem sdk/src/rp2_common/pico_bootrom/include/ \ - -isystem sdk/src/rp2_common/pico_unique_id/include/ \ - -Isdk_config \ - -I../../lib/tinyusb/src \ - -I../../supervisor/shared/usb \ - -I$(BUILD) +ifeq ($(CIRCUITPY_CYW43),1) +INC_CYW43 := \ + -isystem lib/cyw43-driver/firmware \ + -isystem lib/cyw43-driver/src \ + -isystem lib/lwip/src/include \ + -isystem sdk/src/rp2_common/pico_async_context/include/ \ + -isystem sdk/src/rp2_common/pico_cyw43_arch/include/ \ + -isystem sdk/src/rp2_common/pico_cyw43_driver/include/ \ + -isystem sdk/src/rp2_common/pico_lwip/include/ \ + -isystem sdk/src/rp2_common/pico_rand/include/ \ + +CFLAGS_CYW43 := -DCYW43_LWIP=1 -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_USE_SPI -DIGNORE_GPIO25 -DIGNORE_GPIO23 -DIGNORE_GPIO24 -DCYW43_LOGIC_DEBUG=0 -DCYW43_NETUTILS=1 +SRC_SDK_CYW43 := \ + src/common/pico_sync/sem.c \ + src/rp2_common/pico_async_context/async_context_base.c \ + src/rp2_common/pico_async_context/async_context_threadsafe_background.c \ + src/rp2_common/pico_cyw43_arch/cyw43_arch.c \ + src/rp2_common/pico_cyw43_arch/cyw43_arch_threadsafe_background.c \ + src/rp2_common/pico_cyw43_driver/cyw43_driver.c \ + src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.c \ + src/rp2_common/pico_lwip/lwip_nosys.c \ + src/rp2_common/pico_rand/rand.c \ + +SRC_LWIP := \ + shared/netutils/netutils.c \ + shared/netutils/trace.c \ + shared/netutils/dhcpserver.c \ + $(wildcard lib/lwip/src/apps/mdns/*.c) \ + $(wildcard lib/lwip/src/core/*.c) \ + $(wildcard lib/lwip/src/core/ipv4/*.c) \ + lib/lwip/src/netif/ethernet.c \ + $(wildcard lwip_src/*.c) \ + +SRC_CYW43 := \ + $(wildcard bindings/cyw43/*.c) \ + lib/cyw43-driver/src/cyw43_stats.c \ + lib/cyw43-driver/src/cyw43_ctrl.c \ + lib/cyw43-driver/src/cyw43_ll.c \ + lib/cyw43-driver/src/cyw43_lwip.c \ + +PIOASM = $(BUILD)/pioasm/pioasm/pioasm +.PHONY: PioasmBuild +PioasmBuild: $(PIOASM) +$(PIOASM): + $(Q)cmake -S pioasm -B $(BUILD)/pioasm + $(Q)$(MAKE) -C $(BUILD)/pioasm PioasmBuild + +$(BUILD)/cyw43_bus_pio_spi.pio.h: sdk/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.pio $(PIOASM) + $(Q)$(PIOASM) -o c-sdk $< $@ +$(BUILD)/sdk/src/rp2_common/pico_cyw43_driver/cyw43_bus_pio_spi.o: $(BUILD)/cyw43_bus_pio_spi.pio.h + +else +INC_CYW43 := +CFLAGS_CYW43 := +SRC_SDK_CYW43 := +SRC_CYW43 := +SRC_LWIP := +endif + +INC += \ + -I. \ + -Ilwip_inc \ + -I../.. \ + -I../lib/mp-readline \ + -I../shared/timeutils \ + -Iboards/$(BOARD) \ + -Iboards/ \ + -isystem ./../../lib/cmsis/inc \ + -isystem sdk/ \ + -isystem sdk/src/common/pico_base/include/ \ + -isystem sdk/src/common/pico_binary_info/include/ \ + -isystem sdk/src/common/pico_stdlib/include/ \ + -isystem sdk/src/common/pico_sync/include/ \ + -isystem sdk/src/common/pico_time/include/ \ + -isystem sdk/src/common/pico_util/include/ \ + -isystem sdk/src/rp2040/hardware_regs/include/ \ + -isystem sdk/src/rp2040/hardware_structs/include/ \ + -isystem sdk/src/rp2_common/hardware_adc/include/ \ + -isystem sdk/src/rp2_common/hardware_base/include/ \ + -isystem sdk/src/rp2_common/hardware_claim/include/ \ + -isystem sdk/src/rp2_common/hardware_clocks/include/ \ + -isystem sdk/src/rp2_common/hardware_divider/include/ \ + -isystem sdk/src/rp2_common/hardware_dma/include/ \ + -isystem sdk/src/rp2_common/hardware_flash/include/ \ + -isystem sdk/src/rp2_common/hardware_gpio/include/ \ + -isystem sdk/src/rp2_common/hardware_irq/include/ \ + -isystem sdk/src/rp2_common/hardware_i2c/include/ \ + -isystem sdk/src/rp2_common/hardware_pio/include/ \ + -isystem sdk/src/rp2_common/hardware_pll/include/ \ + -isystem sdk/src/rp2_common/hardware_resets/include/ \ + -isystem sdk/src/rp2_common/hardware_rtc/include/ \ + -isystem sdk/src/rp2_common/hardware_spi/include/ \ + -isystem sdk/src/rp2_common/hardware_sync/include/ \ + -isystem sdk/src/rp2_common/hardware_timer/include/ \ + -isystem sdk/src/rp2_common/hardware_uart/include/ \ + -isystem sdk/src/rp2_common/hardware_watchdog/include/ \ + -isystem sdk/src/rp2_common/hardware_xosc/include/ \ + -isystem sdk/src/rp2_common/pico_multicore/include/ \ + -isystem sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/include/ \ + -isystem sdk/src/rp2_common/pico_stdio/include/ \ + -isystem sdk/src/rp2_common/pico_printf/include/ \ + -isystem sdk/src/rp2_common/pico_float/include/ \ + -isystem sdk/src/rp2_common/pico_platform/include/ \ + -isystem sdk/src/rp2_common/pico_runtime/printf/include/ \ + -isystem sdk/src/rp2_common/pico_bootrom/include/ \ + -isystem sdk/src/rp2_common/pico_unique_id/include/ \ + $(INC_CYW43) \ + -Isdk_config \ + -I../../lib/tinyusb/src \ + -I../../supervisor/shared/usb \ + -I$(BUILD) # Pico specific configuration CFLAGS += -DRASPBERRYPI -DPICO_ON_DEVICE=1 -DPICO_NO_BINARY_INFO=0 -DPICO_TIME_DEFAULT_ALARM_POOL_DISABLED=0 -DPICO_DIVIDER_CALL_IDIV0=0 -DPICO_DIVIDER_CALL_LDIV0=0 -DPICO_DIVIDER_HARDWARE=1 -DPICO_DOUBLE_ROM=1 -DPICO_FLOAT_ROM=1 -DPICO_MULTICORE=1 -DPICO_BITS_IN_RAM=0 -DPICO_DIVIDER_IN_RAM=0 -DPICO_DOUBLE_PROPAGATE_NANS=0 -DPICO_DOUBLE_IN_RAM=0 -DPICO_MEM_IN_RAM=0 -DPICO_FLOAT_IN_RAM=0 -DPICO_FLOAT_PROPAGATE_NANS=1 -DPICO_NO_FLASH=0 -DPICO_COPY_TO_RAM=0 -DPICO_DISABLE_SHARED_IRQ_HANDLERS=0 -DPICO_NO_BI_BOOTSEL_VIA_DOUBLE_RESET=0 @@ -115,6 +149,9 @@ CFLAGS += -DTUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX=1 -DCFG_TUSB_MCU=OPT_MCU_R # option to override default optimization level, set in boards/$(BOARD)/mpconfigboard.mk CFLAGS += $(OPTIMIZATION_FLAGS) +# flags specific to wifi / cyw43 + +CFLAGS += $(CFLAGS_CYW43) #Debugging/Optimization ifeq ($(DEBUG), 1) CFLAGS += -ggdb3 -O3 @@ -130,7 +167,7 @@ else endif # Remove -Wno-stringop-overflow after we can test with CI's GCC 10. Mac's looks weird. -DISABLE_WARNINGS = -Wno-stringop-overflow -Wno-unused-function -Wno-unused-variable -Wno-strict-overflow -Wno-cast-align -Wno-strict-prototypes -Wno-nested-externs -Wno-double-promotion -Wno-sign-compare +DISABLE_WARNINGS = -Wno-stringop-overflow -Wno-cast-align CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) $(DISABLE_WARNINGS) -Werror=missing-prototypes @@ -142,13 +179,15 @@ CFLAGS += \ -msoft-float \ -mfloat-abi=soft -PICO_LDFLAGS = --specs=nosys.specs -Wl,--wrap=__aeabi_ldiv0 -Wl,--wrap=__aeabi_idiv0 -Wl,--wrap=__aeabi_lmul -Wl,--wrap=__clzsi2 -Wl,--wrap=__clzdi2 -Wl,--wrap=__ctzsi2 -Wl,--wrap=__ctzdi2 -Wl,--wrap=__popcountsi2 -Wl,--wrap=__popcountdi2 -Wl,--wrap=__clz -Wl,--wrap=__clzl -Wl,--wrap=__clzll -Wl,--wrap=__aeabi_idiv -Wl,--wrap=__aeabi_idivmod -Wl,--wrap=__aeabi_ldivmod -Wl,--wrap=__aeabi_uidiv -Wl,--wrap=__aeabi_uidivmod -Wl,--wrap=__aeabi_uldivmod -Wl,--wrap=__aeabi_dadd -Wl,--wrap=__aeabi_ddiv -Wl,--wrap=__aeabi_dmul -Wl,--wrap=__aeabi_drsub -Wl,--wrap=__aeabi_dsub -Wl,--wrap=__aeabi_cdcmpeq -Wl,--wrap=__aeabi_cdrcmple -Wl,--wrap=__aeabi_cdcmple -Wl,--wrap=__aeabi_dcmpeq -Wl,--wrap=__aeabi_dcmplt -Wl,--wrap=__aeabi_dcmple -Wl,--wrap=__aeabi_dcmpge -Wl,--wrap=__aeabi_dcmpgt -Wl,--wrap=__aeabi_dcmpun -Wl,--wrap=__aeabi_i2d -Wl,--wrap=__aeabi_l2d -Wl,--wrap=__aeabi_ui2d -Wl,--wrap=__aeabi_ul2d -Wl,--wrap=__aeabi_d2iz -Wl,--wrap=__aeabi_d2lz -Wl,--wrap=__aeabi_d2uiz -Wl,--wrap=__aeabi_d2ulz -Wl,--wrap=__aeabi_d2f -Wl,--wrap=sqrt -Wl,--wrap=cos -Wl,--wrap=sin -Wl,--wrap=tan -Wl,--wrap=atan2 -Wl,--wrap=exp -Wl,--wrap=log -Wl,--wrap=ldexp -Wl,--wrap=copysign -Wl,--wrap=trunc -Wl,--wrap=floor -Wl,--wrap=ceil -Wl,--wrap=round -Wl,--wrap=sincos -Wl,--wrap=asin -Wl,--wrap=acos -Wl,--wrap=atan -Wl,--wrap=sinh -Wl,--wrap=cosh -Wl,--wrap=tanh -Wl,--wrap=asinh -Wl,--wrap=acosh -Wl,--wrap=atanh -Wl,--wrap=exp2 -Wl,--wrap=log2 -Wl,--wrap=exp10 -Wl,--wrap=log10 -Wl,--wrap=pow -Wl,--wrap=powint -Wl,--wrap=hypot -Wl,--wrap=cbrt -Wl,--wrap=fmod -Wl,--wrap=drem -Wl,--wrap=remainder -Wl,--wrap=remquo -Wl,--wrap=expm1 -Wl,--wrap=log1p -Wl,--wrap=fma -Wl,--wrap=__aeabi_fadd -Wl,--wrap=__aeabi_fdiv -Wl,--wrap=__aeabi_fmul -Wl,--wrap=__aeabi_frsub -Wl,--wrap=__aeabi_fsub -Wl,--wrap=__aeabi_cfcmpeq -Wl,--wrap=__aeabi_cfrcmple -Wl,--wrap=__aeabi_cfcmple -Wl,--wrap=__aeabi_fcmpeq -Wl,--wrap=__aeabi_fcmplt -Wl,--wrap=__aeabi_fcmple -Wl,--wrap=__aeabi_fcmpge -Wl,--wrap=__aeabi_fcmpgt -Wl,--wrap=__aeabi_fcmpun -Wl,--wrap=__aeabi_i2f -Wl,--wrap=__aeabi_l2f -Wl,--wrap=__aeabi_ui2f -Wl,--wrap=__aeabi_ul2f -Wl,--wrap=__aeabi_f2iz -Wl,--wrap=__aeabi_f2lz -Wl,--wrap=__aeabi_f2uiz -Wl,--wrap=__aeabi_f2ulz -Wl,--wrap=__aeabi_f2d -Wl,--wrap=sqrtf -Wl,--wrap=cosf -Wl,--wrap=sinf -Wl,--wrap=tanf -Wl,--wrap=atan2f -Wl,--wrap=expf -Wl,--wrap=logf -Wl,--wrap=ldexpf -Wl,--wrap=copysignf -Wl,--wrap=truncf -Wl,--wrap=floorf -Wl,--wrap=ceilf -Wl,--wrap=roundf -Wl,--wrap=sincosf -Wl,--wrap=asinf -Wl,--wrap=acosf -Wl,--wrap=atanf -Wl,--wrap=sinhf -Wl,--wrap=coshf -Wl,--wrap=tanhf -Wl,--wrap=asinhf -Wl,--wrap=acoshf -Wl,--wrap=atanhf -Wl,--wrap=exp2f -Wl,--wrap=log2f -Wl,--wrap=exp10f -Wl,--wrap=log10f -Wl,--wrap=powf -Wl,--wrap=powintf -Wl,--wrap=hypotf -Wl,--wrap=cbrtf -Wl,--wrap=fmodf -Wl,--wrap=dremf -Wl,--wrap=remainderf -Wl,--wrap=remquof -Wl,--wrap=expm1f -Wl,--wrap=log1pf -Wl,--wrap=fmaf -Wl,--wrap=memcpy -Wl,--wrap=memset -Wl,--wrap=__aeabi_memcpy -Wl,--wrap=__aeabi_memset -Wl,--wrap=__aeabi_memcpy4 -Wl,--wrap=__aeabi_memset4 -Wl,--wrap=__aeabi_memcpy8 -Wl,--wrap=__aeabi_memset8 +PICO_LDFLAGS = --specs=nosys.specs --specs=nano.specs -Wl,--wrap=__aeabi_ldiv0 -Wl,--wrap=__aeabi_idiv0 -Wl,--wrap=__aeabi_lmul -Wl,--wrap=__clzsi2 -Wl,--wrap=__clzdi2 -Wl,--wrap=__ctzsi2 -Wl,--wrap=__ctzdi2 -Wl,--wrap=__popcountsi2 -Wl,--wrap=__popcountdi2 -Wl,--wrap=__clz -Wl,--wrap=__clzl -Wl,--wrap=__clzll -Wl,--wrap=__aeabi_idiv -Wl,--wrap=__aeabi_idivmod -Wl,--wrap=__aeabi_ldivmod -Wl,--wrap=__aeabi_uidiv -Wl,--wrap=__aeabi_uidivmod -Wl,--wrap=__aeabi_uldivmod -Wl,--wrap=__aeabi_dadd -Wl,--wrap=__aeabi_ddiv -Wl,--wrap=__aeabi_dmul -Wl,--wrap=__aeabi_drsub -Wl,--wrap=__aeabi_dsub -Wl,--wrap=__aeabi_cdcmpeq -Wl,--wrap=__aeabi_cdrcmple -Wl,--wrap=__aeabi_cdcmple -Wl,--wrap=__aeabi_dcmpeq -Wl,--wrap=__aeabi_dcmplt -Wl,--wrap=__aeabi_dcmple -Wl,--wrap=__aeabi_dcmpge -Wl,--wrap=__aeabi_dcmpgt -Wl,--wrap=__aeabi_dcmpun -Wl,--wrap=__aeabi_i2d -Wl,--wrap=__aeabi_l2d -Wl,--wrap=__aeabi_ui2d -Wl,--wrap=__aeabi_ul2d -Wl,--wrap=__aeabi_d2iz -Wl,--wrap=__aeabi_d2lz -Wl,--wrap=__aeabi_d2uiz -Wl,--wrap=__aeabi_d2ulz -Wl,--wrap=__aeabi_d2f -Wl,--wrap=sqrt -Wl,--wrap=cos -Wl,--wrap=sin -Wl,--wrap=tan -Wl,--wrap=atan2 -Wl,--wrap=exp -Wl,--wrap=log -Wl,--wrap=ldexp -Wl,--wrap=copysign -Wl,--wrap=trunc -Wl,--wrap=floor -Wl,--wrap=ceil -Wl,--wrap=round -Wl,--wrap=sincos -Wl,--wrap=asin -Wl,--wrap=acos -Wl,--wrap=atan -Wl,--wrap=sinh -Wl,--wrap=cosh -Wl,--wrap=tanh -Wl,--wrap=asinh -Wl,--wrap=acosh -Wl,--wrap=atanh -Wl,--wrap=exp2 -Wl,--wrap=log2 -Wl,--wrap=exp10 -Wl,--wrap=log10 -Wl,--wrap=pow -Wl,--wrap=powint -Wl,--wrap=hypot -Wl,--wrap=cbrt -Wl,--wrap=fmod -Wl,--wrap=drem -Wl,--wrap=remainder -Wl,--wrap=remquo -Wl,--wrap=expm1 -Wl,--wrap=log1p -Wl,--wrap=fma -Wl,--wrap=__aeabi_fadd -Wl,--wrap=__aeabi_fdiv -Wl,--wrap=__aeabi_fmul -Wl,--wrap=__aeabi_frsub -Wl,--wrap=__aeabi_fsub -Wl,--wrap=__aeabi_cfcmpeq -Wl,--wrap=__aeabi_cfrcmple -Wl,--wrap=__aeabi_cfcmple -Wl,--wrap=__aeabi_fcmpeq -Wl,--wrap=__aeabi_fcmplt -Wl,--wrap=__aeabi_fcmple -Wl,--wrap=__aeabi_fcmpge -Wl,--wrap=__aeabi_fcmpgt -Wl,--wrap=__aeabi_fcmpun -Wl,--wrap=__aeabi_i2f -Wl,--wrap=__aeabi_l2f -Wl,--wrap=__aeabi_ui2f -Wl,--wrap=__aeabi_ul2f -Wl,--wrap=__aeabi_f2iz -Wl,--wrap=__aeabi_f2lz -Wl,--wrap=__aeabi_f2uiz -Wl,--wrap=__aeabi_f2ulz -Wl,--wrap=__aeabi_f2d -Wl,--wrap=sqrtf -Wl,--wrap=cosf -Wl,--wrap=sinf -Wl,--wrap=tanf -Wl,--wrap=atan2f -Wl,--wrap=expf -Wl,--wrap=logf -Wl,--wrap=ldexpf -Wl,--wrap=copysignf -Wl,--wrap=truncf -Wl,--wrap=floorf -Wl,--wrap=ceilf -Wl,--wrap=roundf -Wl,--wrap=sincosf -Wl,--wrap=asinf -Wl,--wrap=acosf -Wl,--wrap=atanf -Wl,--wrap=sinhf -Wl,--wrap=coshf -Wl,--wrap=tanhf -Wl,--wrap=asinhf -Wl,--wrap=acoshf -Wl,--wrap=atanhf -Wl,--wrap=exp2f -Wl,--wrap=log2f -Wl,--wrap=exp10f -Wl,--wrap=log10f -Wl,--wrap=powf -Wl,--wrap=powintf -Wl,--wrap=hypotf -Wl,--wrap=cbrtf -Wl,--wrap=fmodf -Wl,--wrap=dremf -Wl,--wrap=remainderf -Wl,--wrap=remquof -Wl,--wrap=expm1f -Wl,--wrap=log1pf -Wl,--wrap=fmaf -Wl,--wrap=memcpy -Wl,--wrap=memset -Wl,--wrap=__aeabi_memcpy -Wl,--wrap=__aeabi_memset -Wl,--wrap=__aeabi_memcpy4 -Wl,--wrap=__aeabi_memset4 -Wl,--wrap=__aeabi_memcpy8 -Wl,--wrap=__aeabi_memset8 # Use toolchain libm if we're not using our own. ifndef INTERNAL_LIBM LIBS += -lm endif +LIBS += -lc + SRC_SDK := \ src/common/pico_sync/critical_section.c \ src/common/pico_sync/lock_core.c \ @@ -185,9 +224,10 @@ SRC_SDK := \ src/rp2_common/pico_runtime/runtime.c \ src/rp2_common/pico_stdio/stdio.c \ src/rp2_common/pico_unique_id/unique_id.c \ + $(SRC_SDK_CYW43) \ SRC_SDK := $(addprefix sdk/, $(SRC_SDK)) -$(patsubst %.c,$(BUILD)/%.o,$(SRC_SDK)): CFLAGS += -Wno-missing-prototypes -Wno-undef +$(patsubst %.c,$(BUILD)/%.o,$(SRC_SDK) $(SRC_CYW43)): CFLAGS += -Wno-missing-prototypes -Wno-undef -Wno-unused-function -Wno-nested-externs -Wno-strict-prototypes -Wno-double-promotion -Wno-sign-compare -Wno-unused-variable -Wno-strict-overflow -Ilib/cyw43-driver SRC_C += \ boards/$(BOARD)/board.c \ @@ -200,10 +240,98 @@ SRC_C += \ background.c \ peripherals/pins.c \ lib/crypto-algorithms/sha256.c \ - fatfs_port.c \ lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c \ lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c \ mphalport.c \ + $(SRC_CYW43) \ + $(SRC_LWIP) \ + +ifeq ($(CIRCUITPY_SSL),1) +CFLAGS += -isystem $(TOP)/mbedtls/include +SRC_MBEDTLS := $(addprefix lib/mbedtls/library/, \ + aes.c \ + aesni.c \ + arc4.c \ + asn1parse.c \ + asn1write.c \ + base64.c \ + bignum.c \ + blowfish.c \ + camellia.c \ + ccm.c \ + certs.c \ + chacha20.c \ + chachapoly.c \ + cipher.c \ + cipher_wrap.c \ + cmac.c \ + ctr_drbg.c \ + debug.c \ + des.c \ + dhm.c \ + ecdh.c \ + ecdsa.c \ + ecjpake.c \ + ecp.c \ + ecp_curves.c \ + entropy.c \ + entropy_poll.c \ + gcm.c \ + havege.c \ + hmac_drbg.c \ + md2.c \ + md4.c \ + md5.c \ + md.c \ + md_wrap.c \ + oid.c \ + padlock.c \ + pem.c \ + pk.c \ + pkcs11.c \ + pkcs12.c \ + pkcs5.c \ + pkparse.c \ + pk_wrap.c \ + pkwrite.c \ + platform.c \ + platform_util.c \ + poly1305.c \ + ripemd160.c \ + rsa.c \ + rsa_internal.c \ + sha1.c \ + sha256.c \ + sha512.c \ + ssl_cache.c \ + ssl_ciphersuites.c \ + ssl_cli.c \ + ssl_cookie.c \ + ssl_srv.c \ + ssl_ticket.c \ + ssl_tls.c \ + timing.c \ + x509.c \ + x509_create.c \ + x509_crl.c \ + x509_crt.c \ + x509_csr.c \ + x509write_crt.c \ + x509write_csr.c \ + xtea.c \ + ) +SRC_C += $(SRC_MBEDTLS) mbedtls/mbedtls_port.c mbedtls/crt_bundle.c +CFLAGS += \ + -isystem $(TOP)/lib/mbedtls/include \ + -DMBEDTLS_CONFIG_FILE='"mbedtls/mbedtls_config.h"' \ + +$(BUILD)/x509_crt_bundle.S: $(TOP)/lib/certificates/nina-fw/data/roots.pem $(TOP)/tools/gen_crt_bundle.py + $(Q)$(PYTHON) $(TOP)/tools/gen_crt_bundle.py -i $< -o $@ --asm +OBJ_MBEDTLS := $(BUILD)/x509_crt_bundle.o +$(patsubst %.c,$(BUILD)/%.o,$(SRC_MBEDTLS))): CFLAGS += -Wno-suggest-attribute=format +else +OBJ_MBEDTLS := +endif SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ @@ -243,8 +371,9 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S_UPPER:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) OBJ += $(BUILD)/boot2_padded_checksummed.o +OBJ += $(OBJ_MBEDTLS) -$(BUILD)/boot2_padded_checksummed.o: $(BUILD)/boot2_padded_checksummed.S +$(BUILD)/%.o: $(BUILD)/%.S $(STEPECHO) "CC $<" $(Q)$(CC) $(CFLAGS) -c -o $@ $< @@ -276,12 +405,13 @@ SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_M all: $(BUILD)/firmware.uf2 -$(BUILD)/firmware.elf: $(OBJ) link.ld +LINK_LD := $(firstword $(wildcard boards/$(BOARD)/link.ld link.ld)) +$(BUILD)/firmware.elf: $(OBJ) $(LINK_LD) $(STEPECHO) "LINK $@" $(Q)echo $(OBJ) > $(BUILD)/firmware.objs $(Q)echo $(PICO_LDFLAGS) > $(BUILD)/firmware.ldflags - $(Q)$(CC) -o $@ $(CFLAGS) @$(BUILD)/firmware.ldflags -Wl,-T,link.ld -Wl,-Map=$@.map -Wl,-cref -Wl,--gc-sections @$(BUILD)/firmware.objs - $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py link.ld + $(Q)$(CC) -o $@ $(CFLAGS) @$(BUILD)/firmware.ldflags -Wl,-T,$(LINK_LD) -Wl,-Map=$@.map -Wl,-cref -Wl,--gc-sections @$(BUILD)/firmware.objs -Wl,-lc + $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LINK_LD) $(BUILD) $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(STEPECHO) "Create $@" diff --git a/ports/raspberrypi/background.c b/ports/raspberrypi/background.c index 4b5190aa27..8e5e3fcd91 100644 --- a/ports/raspberrypi/background.c +++ b/ports/raspberrypi/background.c @@ -30,8 +30,12 @@ void port_start_background_task(void) { } + void port_finish_background_task(void) { } +void port_background_tick(void) { +} + void port_background_task(void) { } diff --git a/ports/raspberrypi/bindings/cyw43/__init__.c b/ports/raspberrypi/bindings/cyw43/__init__.c new file mode 100644 index 0000000000..778da1ab62 --- /dev/null +++ b/ports/raspberrypi/bindings/cyw43/__init__.c @@ -0,0 +1,158 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "bindings/cyw43/__init__.h" + + +static int power_management_value = PM_DISABLED; + +void cyw43_enter_deep_sleep(void) { +#define WL_REG_ON 23 + gpio_set_dir(WL_REG_ON, GPIO_OUT); + gpio_put(WL_REG_ON, false); +} + +void bindings_cyw43_wifi_enforce_pm() { + cyw43_wifi_pm(&cyw43_state, power_management_value); +} + +//| class CywPin: +//| """A class that represents a GPIO pin attached to the wifi chip. +//| +//| Cannot be constructed at runtime, but may be the type of a pin object +//| in :py:mod:`board`. A `CywPin` can be used as a DigitalInOut, but not with other +//| peripherals such as `PWMOut`.""" +//| +const mp_obj_type_t cyw43_pin_type = { + { &mp_type_type }, + .flags = MP_TYPE_FLAG_EXTENDED, + .name = MP_QSTR_CywPin, + .print = shared_bindings_microcontroller_pin_print, + MP_TYPE_EXTENDED_FIELDS( + .unary_op = mp_generic_unary_op, + ) +}; + +//| PM_STANDARD: int +//| """The standard power management mode""" +//| PM_AGGRESSIVE: int +//| """Aggressive power management mode for optimal power usage at the cost of performance""" +//| PM_PERFORMANCE: int +//| """Performance power management mode where more power is used to increase performance""" +//| PM_DISABLED: int +//| """Disable power management and always use highest power mode. CircuitPython sets this value at reset time, because it provides the best connectivity reliability.""" +//| +//| def set_power_management(value: int) -> None: +//| """Set the power management register +//| +//| For transmitter power, see ``wifi.Radio.txpower``. +//| This controls software power saving features inside the cyw43 chip. +//| it does not control transmitter power. +//| +//| The value is interpreted as a 24-bit hexadecimal number of the form +//| ``0x00adbrrm``. +//| +//| The low 4 bits, ``m``, are the power management mode: +//| * 0: disabled +//| * 1: aggressive power saving which reduces wifi throughput +//| * 2: Power saving with high througput +//| +//| The next 8 bits, ``r``, specify "the maximum time to wait before going back to sleep" for power management mode 2. The units of ``r`` are 10ms. +//| +//| The next 4 bits, ``b``, are the "wake period is measured in beacon periods". +//| +//| The next 4 bits, ``d``, specify the "wake interval measured in DTIMs. If this is set to 0, the wake interval is measured in beacon periods". +//| +//| The top 4 bits, ``a``, specifies the "wake interval sent to the access point" +//| +//| Several ``PM_`` constants gathered from various sources are included +//| in this module. According to Raspberry Pi documentation, the value 0xa11140 +//| (called `cyw43.PM_DISABLED` here) increases responsiveness at the cost of higher power +//| usage. +//| """ +//| +STATIC mp_obj_t cyw43_set_power_management(const mp_obj_t value_in) { + mp_int_t value = mp_obj_get_int(value_in); + power_management_value = value; + bindings_cyw43_wifi_enforce_pm(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(cyw43_set_power_management_obj, cyw43_set_power_management); + +//| def get_power_management() -> int: +//| """Retrieve the power management register""" +//| +STATIC mp_obj_t cyw43_get_power_management() { + return mp_obj_new_int(power_management_value); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(cyw43_get_power_management_obj, cyw43_get_power_management); + +const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj, qstr arg_name) { + if (!mp_obj_is_type(obj, &mcu_pin_type) && !mp_obj_is_type(obj, &cyw43_pin_type)) { + mp_raise_TypeError_varg(translate("%q must be of type %q or %q, not %q"), arg_name, mcu_pin_type.name, cyw43_pin_type.name, mp_obj_get_type(obj)->name); + } + return MP_OBJ_TO_PTR(obj); +} + +const mcu_pin_obj_t *validate_obj_is_free_pin_or_gpio29(mp_obj_t obj, qstr arg_name) { + const mcu_pin_obj_t *pin = validate_obj_is_pin(obj, arg_name); + if (obj != &pin_GPIO29) { + assert_pin_free(pin); + } + return pin; +} + +const mcu_pin_obj_t *validate_obj_is_free_pin_including_cyw43(mp_obj_t obj, qstr arg_name) { + const mcu_pin_obj_t *pin = validate_obj_is_pin_including_cyw43(obj, arg_name); + assert_pin_free(pin); + return pin; +} + +STATIC const mp_rom_map_elem_t cyw43_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cyw43) }, + { MP_ROM_QSTR(MP_QSTR_CywPin), MP_ROM_PTR(&cyw43_pin_type) }, + { MP_ROM_QSTR(MP_QSTR_set_power_management), &cyw43_set_power_management_obj }, + { MP_ROM_QSTR(MP_QSTR_get_power_management), &cyw43_get_power_management_obj }, + { MP_ROM_QSTR(MP_QSTR_PM_STANDARD), MP_ROM_INT(PM_STANDARD) }, + { MP_ROM_QSTR(MP_QSTR_PM_AGGRESSIVE), MP_ROM_INT(PM_AGGRESSIVE) }, + { MP_ROM_QSTR(MP_QSTR_PM_PERFORMANCE), MP_ROM_INT(PM_PERFORMANCE) }, + { MP_ROM_QSTR(MP_QSTR_PM_DISABLED), MP_ROM_INT(PM_DISABLED) }, +}; + +STATIC MP_DEFINE_CONST_DICT(cyw43_module_globals, cyw43_module_globals_table); + +const mp_obj_module_t cyw43_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&cyw43_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_cyw43, cyw43_module, CIRCUITPY_CYW43); diff --git a/ports/raspberrypi/bindings/cyw43/__init__.h b/ports/raspberrypi/bindings/cyw43/__init__.h new file mode 100644 index 0000000000..26c1aa008f --- /dev/null +++ b/ports/raspberrypi/bindings/cyw43/__init__.h @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * Copyright (c) 2016 Scott Shawcroft + * + * 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. + */ + +#pragma once + +#include "py/obj.h" +#include "common-hal/microcontroller/Pin.h" + +extern const mp_obj_type_t cyw43_pin_type; +const mcu_pin_obj_t *validate_obj_is_free_pin_including_cyw43(mp_obj_t obj, qstr arg_name); +const mcu_pin_obj_t *validate_obj_is_free_pin_or_gpio29(mp_obj_t obj, qstr arg_name); +const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj, qstr arg_name); + +#define CONSTANT_CYW43_PM_VALUE(pm_mode, pm2_sleep_ret_ms, li_beacon_period, li_dtim_period, li_assoc) \ + (li_assoc << 20 | /* listen interval sent to ap */ \ + li_dtim_period << 16 | \ + li_beacon_period << 12 | \ + (pm2_sleep_ret_ms / 10) << 4 | /* cyw43_ll_wifi_pm multiplies this by 10 */ \ + pm_mode /* CYW43_PM2_POWERSAVE_MODE etc */) + +// CYW43_DEFAULT_PM (except a compile-time constant) +#define PM_STANDARD CONSTANT_CYW43_PM_VALUE(CYW43_PM2_POWERSAVE_MODE, 200, 1, 1, 10) +// CYW43_AGGRESSIVE_PM (except a compile-time constant) +#define PM_AGGRESSIVE CONSTANT_CYW43_PM_VALUE(CYW43_PM2_POWERSAVE_MODE, 2000, 1, 1, 10) +// CYW43_PERFORMANCE_PM (except a compile-time constant) +#define PM_PERFORMANCE CONSTANT_CYW43_PM_VALUE(CYW43_PM2_POWERSAVE_MODE, 20, 1, 1, 1) +// The 0xa11140 magic value +#define PM_DISABLED CONSTANT_CYW43_PM_VALUE(CYW43_NO_POWERSAVE_MODE, 200, 1, 1, 10) + +extern void bindings_cyw43_wifi_enforce_pm(void); +void cyw43_enter_deep_sleep(void); diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.c b/ports/raspberrypi/bindings/rp2pio/StateMachine.c index 1203f4abac..ada9f46020 100644 --- a/ports/raspberrypi/bindings/rp2pio/StateMachine.c +++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.c @@ -57,47 +57,47 @@ //| in either PIO. State machines with the same program will be placed in the //| same PIO if possible.""" //| -//| def __init__(self, -//| program: ReadableBuffer, -//| frequency: int, -//| *, -//| init: Optional[ReadableBuffer] = None, -//| first_out_pin: Optional[microcontroller.Pin] = None, -//| out_pin_count: int = 1, -//| initial_out_pin_state: int = 0, -//| initial_out_pin_direction: int = 0xffffffff, -//| first_in_pin: Optional[microcontroller.Pin] = None, -//| in_pin_count: int = 1, -//| pull_in_pin_up: int = 0, -//| pull_in_pin_down: int = 0, -//| first_set_pin: Optional[microcontroller.Pin] = None, -//| set_pin_count: int = 1, -//| initial_set_pin_state: int = 0, -//| initial_set_pin_direction: int = 0x1f, -//| first_sideset_pin: Optional[microcontroller.Pin] = None, -//| sideset_pin_count: int = 1, -//| initial_sideset_pin_state: int = 0, -//| initial_sideset_pin_direction: int = 0x1f, -//| sideset_enable: bool = False, -//| jmp_pin: Optional[microcontroller.Pin] = None, -//| jmp_pin_pull: Optional[digitalio.Pull] = None, -//| exclusive_pin_use: bool = True, -//| auto_pull: bool = False, -//| pull_threshold: int = 32, -//| out_shift_right: bool = True, -//| wait_for_txstall: bool = True, -//| auto_push: bool = False, -//| push_threshold: int = 32, -//| in_shift_right: bool = True, -//| user_interruptible: bool = True, -//| wrap_target: int = 0, -//| wrap: int = -1, -//| ) -> None: -//| +//| def __init__( +//| self, +//| program: ReadableBuffer, +//| frequency: int, +//| *, +//| init: Optional[ReadableBuffer] = None, +//| first_out_pin: Optional[microcontroller.Pin] = None, +//| out_pin_count: int = 1, +//| initial_out_pin_state: int = 0, +//| initial_out_pin_direction: int = 0xFFFFFFFF, +//| first_in_pin: Optional[microcontroller.Pin] = None, +//| in_pin_count: int = 1, +//| pull_in_pin_up: int = 0, +//| pull_in_pin_down: int = 0, +//| first_set_pin: Optional[microcontroller.Pin] = None, +//| set_pin_count: int = 1, +//| initial_set_pin_state: int = 0, +//| initial_set_pin_direction: int = 0x1F, +//| first_sideset_pin: Optional[microcontroller.Pin] = None, +//| sideset_pin_count: int = 1, +//| initial_sideset_pin_state: int = 0, +//| initial_sideset_pin_direction: int = 0x1F, +//| sideset_enable: bool = False, +//| jmp_pin: Optional[microcontroller.Pin] = None, +//| jmp_pin_pull: Optional[digitalio.Pull] = None, +//| exclusive_pin_use: bool = True, +//| auto_pull: bool = False, +//| pull_threshold: int = 32, +//| out_shift_right: bool = True, +//| wait_for_txstall: bool = True, +//| auto_push: bool = False, +//| push_threshold: int = 32, +//| in_shift_right: bool = True, +//| user_interruptible: bool = True, +//| wrap_target: int = 0, +//| wrap: int = -1, +//| ) -> None: //| """Construct a StateMachine object on the given pins with the given program. //| //| :param ReadableBuffer program: the program to run with the state machine -//| :param int frequency: the target clock frequency of the state machine. Actual may be less. +//| :param int frequency: the target clock frequency of the state machine. Actual may be less. Use 0 for system clock speed. //| :param ReadableBuffer init: a program to run once at start up. This is run after program //| is started so instructions may be intermingled //| :param ~microcontroller.Pin first_out_pin: the first pin to use with the OUT instruction @@ -148,7 +148,6 @@ //| last instruction of the program. //| """ //| ... -//| STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { rp2pio_statemachine_obj_t *self = m_new_obj(rp2pio_statemachine_obj_t); @@ -222,19 +221,25 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n mp_get_buffer(args[ARG_init].u_obj, &init_bufinfo, MP_BUFFER_READ); // We don't validate pin in use here because we may be ok sharing them within a PIO. - const mcu_pin_obj_t *first_out_pin = validate_obj_is_pin_or_none(args[ARG_first_out_pin].u_obj); + const mcu_pin_obj_t *first_out_pin = + validate_obj_is_pin_or_none(args[ARG_first_out_pin].u_obj, MP_QSTR_first_out_pin); mp_int_t out_pin_count = mp_arg_validate_int_min(args[ARG_out_pin_count].u_int, 1, MP_QSTR_out_pin_count); - const mcu_pin_obj_t *first_in_pin = validate_obj_is_pin_or_none(args[ARG_first_in_pin].u_obj); + const mcu_pin_obj_t *first_in_pin = + validate_obj_is_pin_or_none(args[ARG_first_in_pin].u_obj, MP_QSTR_first_in_pin); mp_int_t in_pin_count = mp_arg_validate_int_min(args[ARG_in_pin_count].u_int, 1, MP_QSTR_in_pin_count); - const mcu_pin_obj_t *first_set_pin = validate_obj_is_pin_or_none(args[ARG_first_set_pin].u_obj); + const mcu_pin_obj_t *first_set_pin = + validate_obj_is_pin_or_none(args[ARG_first_set_pin].u_obj, MP_QSTR_first_set_pin); mp_int_t set_pin_count = mp_arg_validate_int_range(args[ARG_set_pin_count].u_int, 1, 5, MP_QSTR_set_pin_count); - const mcu_pin_obj_t *first_sideset_pin = validate_obj_is_pin_or_none(args[ARG_first_sideset_pin].u_obj); - mp_int_t sideset_pin_count = mp_arg_validate_int_range(args[ARG_sideset_pin_count].u_int, 1, 5, MP_QSTR_set_pin_count); + const mcu_pin_obj_t *first_sideset_pin = + validate_obj_is_pin_or_none(args[ARG_first_sideset_pin].u_obj, MP_QSTR_first_sideset_pin); + mp_int_t sideset_pin_count = + mp_arg_validate_int_range(args[ARG_sideset_pin_count].u_int, 1, 5, MP_QSTR_set_pin_count); - const mcu_pin_obj_t *jmp_pin = validate_obj_is_pin_or_none(args[ARG_jmp_pin].u_obj); + const mcu_pin_obj_t *jmp_pin = + validate_obj_is_pin_or_none(args[ARG_jmp_pin].u_obj, MP_QSTR_jmp_pin); digitalio_pull_t jmp_pin_pull = validate_pull(args[ARG_jmp_pin_pull].u_rom_obj, MP_QSTR_jmp_pull); mp_int_t pull_threshold = @@ -247,7 +252,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n mp_raise_ValueError(translate("Program size invalid")); } - mp_arg_validate_length_range(init_bufinfo.len, 2, 64, MP_QSTR_init); + mp_arg_validate_length_range(init_bufinfo.len, 0, 64, MP_QSTR_init); if (init_bufinfo.len % 2 != 0) { mp_raise_ValueError(translate("Init program size invalid")); } @@ -259,10 +264,10 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n bufinfo.buf, bufinfo.len / 2, args[ARG_frequency].u_int, init_bufinfo.buf, init_bufinfo.len / 2, - first_out_pin, args[ARG_out_pin_count].u_int, args[ARG_initial_out_pin_state].u_int, args[ARG_initial_out_pin_direction].u_int, - first_in_pin, args[ARG_in_pin_count].u_int, args[ARG_pull_in_pin_up].u_int, args[ARG_pull_in_pin_down].u_int, - first_set_pin, args[ARG_set_pin_count].u_int, args[ARG_initial_set_pin_state].u_int, args[ARG_initial_set_pin_direction].u_int, - first_sideset_pin, args[ARG_sideset_pin_count].u_int, args[ARG_initial_sideset_pin_state].u_int, args[ARG_initial_sideset_pin_direction].u_int, + first_out_pin, out_pin_count, args[ARG_initial_out_pin_state].u_int, args[ARG_initial_out_pin_direction].u_int, + first_in_pin, in_pin_count, args[ARG_pull_in_pin_up].u_int, args[ARG_pull_in_pin_down].u_int, + first_set_pin, set_pin_count, args[ARG_initial_set_pin_state].u_int, args[ARG_initial_set_pin_direction].u_int, + first_sideset_pin, sideset_pin_count, args[ARG_initial_sideset_pin_state].u_int, args[ARG_initial_sideset_pin_direction].u_int, args[ARG_sideset_enable].u_bool, jmp_pin, jmp_pin_pull, 0, @@ -278,7 +283,6 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n //| def deinit(self) -> None: //| """Turn off the state machine and release its resources.""" //| ... -//| STATIC mp_obj_t rp2pio_statemachine_obj_deinit(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_rp2pio_statemachine_deinit(self); @@ -290,13 +294,11 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_deinit_obj, rp2pio_statemachine_ob //| """No-op used by Context Managers. //| Provided by context manager helper.""" //| ... -//| //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t rp2pio_statemachine_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_rp2pio_statemachine_deinit(args[0]); @@ -313,9 +315,8 @@ STATIC void check_for_deinit(rp2pio_statemachine_obj_t *self) { //| def restart(self) -> None: //| """Resets this state machine, runs any init and enables the clock.""" -// TODO: "and any others given. They must share an underlying PIO. An exception will be raised otherwise."" //| ... -//| +// TODO: "and any others given. They must share an underlying PIO. An exception will be raised otherwise."" STATIC mp_obj_t rp2pio_statemachine_restart(mp_obj_t self_obj) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_obj); check_for_deinit(self); @@ -328,12 +329,11 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_restart_obj, rp2pio_statemachine_r //| def run(self, instructions: ReadableBuffer) -> None: //| """Runs all given instructions. They will likely be interleaved with -//| in-memory instructions. Make sure this doesn't wait for input! +//| in-memory instructions. Make sure this doesn't wait for input! //| -//| This can be used to output internal state to the RX FIFO and then -//| read with `readinto`.""" +//| This can be used to output internal state to the RX FIFO and then +//| read with `readinto`.""" //| ... -//| STATIC mp_obj_t rp2pio_statemachine_run(mp_obj_t self_obj, mp_obj_t instruction_obj) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_obj); check_for_deinit(self); @@ -349,7 +349,6 @@ MP_DEFINE_CONST_FUN_OBJ_2(rp2pio_statemachine_run_obj, rp2pio_statemachine_run); //| def stop(self) -> None: //| """Stops the state machine clock. Use `restart` to enable it.""" //| ... -//| STATIC mp_obj_t rp2pio_statemachine_stop(mp_obj_t self_obj) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_obj); check_for_deinit(self); @@ -359,7 +358,14 @@ STATIC mp_obj_t rp2pio_statemachine_stop(mp_obj_t self_obj) { } MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_stop_obj, rp2pio_statemachine_stop); -//| def write(self, buffer: ReadableBuffer, *, start: int = 0, end: Optional[int] = None, swap: bool = False) -> None: +//| def write( +//| self, +//| buffer: ReadableBuffer, +//| *, +//| start: int = 0, +//| end: Optional[int] = None, +//| swap: bool = False, +//| ) -> None: //| """Write the data contained in ``buffer`` to the state machine. If the buffer is empty, nothing happens. //| //| Writes to the FIFO will match the input buffer's element size. For example, bytearray elements @@ -374,7 +380,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_stop_obj, rp2pio_statemachine_stop //| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)`` //| :param bool swap: For 2- and 4-byte elements, swap (reverse) the byte order""" //| ... -//| STATIC mp_obj_t rp2pio_statemachine_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end, ARG_swap }; static const mp_arg_t allowed_args[] = { @@ -390,18 +395,22 @@ STATIC mp_obj_t rp2pio_statemachine_write(size_t n_args, const mp_obj_t *pos_arg mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); - int32_t start = args[ARG_start].u_int; - size_t length = bufinfo.len; - normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); - if (length == 0) { - return mp_const_none; - } - - uint8_t *original_pointer = bufinfo.buf; int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); if (stride_in_bytes > 4) { mp_raise_ValueError(translate("Buffer elements must be 4 bytes long or less")); } + int32_t start = args[ARG_start].u_int; + size_t length = bufinfo.len / stride_in_bytes; + // Normalize in element size units, not bytes. + normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + + if (length == 0) { + return mp_const_none; + } bool ok = common_hal_rp2pio_statemachine_write(self, ((uint8_t *)bufinfo.buf) + start, length, stride_in_bytes, args[ARG_swap].u_bool); if (mp_hal_is_interrupted()) { @@ -414,10 +423,16 @@ STATIC mp_obj_t rp2pio_statemachine_write(size_t n_args, const mp_obj_t *pos_arg } MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine_write); -//| def background_write(self, once: Optional[ReadableBuffer]=None, *, loop: Optional[ReadableBuffer]=None, swap: bool=False) -> None: +//| def background_write( +//| self, +//| once: Optional[ReadableBuffer] = None, +//| *, +//| loop: Optional[ReadableBuffer] = None, +//| swap: bool = False, +//| ) -> None: //| """Write data to the TX fifo in the background, with optional looping. //| -//| First, if any previous ``once`` or ``loop`` buffer has not been started, this function blocks until they have. +//| First, if any previous ``once`` or ``loop`` buffer has not been started, this function blocks until they have been started. //| This means that any ``once`` or ``loop`` buffer will be written at least once. //| Then the ``once`` and/or ``loop`` buffers are queued. and the function returns. //| The ``once`` buffer (if specified) will be written just once. @@ -451,7 +466,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine //| :param bool swap: For 2- and 4-byte elements, swap (reverse) the byte order //| """ //| ... -//| STATIC void fill_buf_info(sm_buf_info *info, mp_obj_t obj, size_t *stride_in_bytes) { if (obj != mp_const_none) { @@ -507,7 +521,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_background_write_obj, 1, rp2pio_s //| """Immediately stop a background write, if one is in progress. Any //| DMA in progress is halted, but items already in the TX FIFO are not //| affected.""" -//| STATIC mp_obj_t rp2pio_statemachine_obj_stop_background_write(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); bool ok = common_hal_rp2pio_statemachine_stop_background_write(self); @@ -521,10 +534,8 @@ STATIC mp_obj_t rp2pio_statemachine_obj_stop_background_write(mp_obj_t self_in) } MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_stop_background_write_obj, rp2pio_statemachine_obj_stop_background_write); -//| @property -//| def writing(self) -> bool: -//| """Returns True if a background write is in progress""" -//| +//| writing: bool +//| """Returns True if a background write is in progress""" STATIC mp_obj_t rp2pio_statemachine_obj_get_writing(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_rp2pio_statemachine_get_writing(self)); @@ -539,12 +550,10 @@ const mp_obj_property_t rp2pio_statemachine_writing_obj = { }; -//| @property -//| def pending(self) -> int: -//| """Returns the number of pending buffers for background writing. -//| -//| If the number is 0, then a `StateMachine.background_write` call will not block.""" +//| pending: int +//| """Returns the number of pending buffers for background writing. //| +//| If the number is 0, then a `StateMachine.background_write` call will not block.""" STATIC mp_obj_t rp2pio_statemachine_obj_get_pending(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_rp2pio_statemachine_get_pending(self)); @@ -558,7 +567,14 @@ const mp_obj_property_t rp2pio_statemachine_pending_obj = { MP_ROM_NONE}, }; -//| def readinto(self, buffer: WriteableBuffer, *, start: int = 0, end: Optional[int] = None, swap: bool=False) -> None: +//| def readinto( +//| self, +//| buffer: WriteableBuffer, +//| *, +//| start: int = 0, +//| end: Optional[int] = None, +//| swap: bool = False, +//| ) -> None: //| """Read into ``buffer``. If the number of bytes to read is 0, nothing happens. The buffer //| includes any data added to the fifo even if it was added before this was called. //| @@ -575,7 +591,6 @@ const mp_obj_property_t rp2pio_statemachine_pending_obj = { //| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)`` //| :param bool swap: For 2- and 4-byte elements, swap (reverse) the byte order""" //| ... -//| STATIC mp_obj_t rp2pio_statemachine_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end, ARG_swap }; @@ -592,19 +607,20 @@ STATIC mp_obj_t rp2pio_statemachine_readinto(size_t n_args, const mp_obj_t *pos_ mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); - int32_t start = args[ARG_start].u_int; - size_t length = bufinfo.len; - normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); - - if (length == 0) { - return mp_const_none; - } - - uint8_t *original_pointer = bufinfo.buf; int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); if (stride_in_bytes > 4) { mp_raise_ValueError(translate("Buffer elements must be 4 bytes long or less")); } + int32_t start = args[ARG_start].u_int; + size_t length = bufinfo.len / stride_in_bytes; + normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + if (length == 0) { + return mp_const_none; + } bool ok = common_hal_rp2pio_statemachine_readinto(self, ((uint8_t *)bufinfo.buf) + start, length, stride_in_bytes, args[ARG_swap].u_bool); if (!ok) { @@ -614,7 +630,16 @@ STATIC mp_obj_t rp2pio_statemachine_readinto(size_t n_args, const mp_obj_t *pos_ } MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_readinto_obj, 2, rp2pio_statemachine_readinto); -//| def write_readinto(self, buffer_out: ReadableBuffer, buffer_in: WriteableBuffer, *, out_start: int = 0, out_end: Optional[int] = None, in_start: int = 0, in_end: Optional[int] = None) -> None: +//| def write_readinto( +//| self, +//| buffer_out: ReadableBuffer, +//| buffer_in: WriteableBuffer, +//| *, +//| out_start: int = 0, +//| out_end: Optional[int] = None, +//| in_start: int = 0, +//| in_end: Optional[int] = None, +//| ) -> None: //| """Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``. //| The lengths of the slices defined by ``buffer_out[out_start:out_end]`` and ``buffer_in[in_start:in_end]`` //| may be different. The function will return once both are filled. @@ -633,9 +658,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_readinto_obj, 2, rp2pio_statemach //| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]`` //| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)`` //| :param bool swap_out: For 2- and 4-byte elements, swap (reverse) the byte order for the buffer being transmitted (written) -//| :param bool swap_in: For 2- and 4-rx elements, swap (reverse) the byte order for the buffer being received (read)""" +//| :param bool swap_in: For 2- and 4-rx elements, swap (reverse) the byte order for the buffer being received (read) +//| """ //| ... -//| STATIC mp_obj_t rp2pio_statemachine_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end, ARG_swap_out, ARG_swap_in }; @@ -656,28 +681,32 @@ STATIC mp_obj_t rp2pio_statemachine_write_readinto(size_t n_args, const mp_obj_t mp_buffer_info_t buf_out_info; mp_get_buffer_raise(args[ARG_buffer_out].u_obj, &buf_out_info, MP_BUFFER_READ); + int out_stride_in_bytes = mp_binary_get_size('@', buf_out_info.typecode, NULL); + if (out_stride_in_bytes > 4) { + mp_raise_ValueError(translate("Out-buffer elements must be <= 4 bytes long")); + } int32_t out_start = args[ARG_out_start].u_int; - size_t out_length = buf_out_info.len; + size_t out_length = buf_out_info.len / out_stride_in_bytes; normalize_buffer_bounds(&out_start, args[ARG_out_end].u_int, &out_length); mp_buffer_info_t buf_in_info; mp_get_buffer_raise(args[ARG_buffer_in].u_obj, &buf_in_info, MP_BUFFER_WRITE); - int32_t in_start = args[ARG_in_start].u_int; - size_t in_length = buf_in_info.len; - normalize_buffer_bounds(&in_start, args[ARG_in_end].u_int, &in_length); - - if (out_length == 0 && in_length == 0) { - return mp_const_none; - } - int in_stride_in_bytes = mp_binary_get_size('@', buf_in_info.typecode, NULL); if (in_stride_in_bytes > 4) { mp_raise_ValueError(translate("In-buffer elements must be <= 4 bytes long")); } + int32_t in_start = args[ARG_in_start].u_int; + size_t in_length = buf_in_info.len / in_stride_in_bytes; + normalize_buffer_bounds(&in_start, args[ARG_in_end].u_int, &in_length); - int out_stride_in_bytes = mp_binary_get_size('@', buf_out_info.typecode, NULL); - if (out_stride_in_bytes > 4) { - mp_raise_ValueError(translate("Out-buffer elements must be <= 4 bytes long")); + // Treat start and length in terms of bytes from now on. + out_start *= out_stride_in_bytes; + out_length *= out_stride_in_bytes; + in_start *= in_stride_in_bytes; + in_length *= in_stride_in_bytes; + + if (out_length == 0 && in_length == 0) { + return mp_const_none; } bool ok = common_hal_rp2pio_statemachine_write_readinto(self, @@ -697,7 +726,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_readinto_obj, 2, rp2pio_sta //| def clear_rxfifo(self) -> None: //| """Clears any unread bytes in the rxfifo.""" //| ... -//| STATIC mp_obj_t rp2pio_statemachine_obj_clear_rxfifo(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_rp2pio_statemachine_clear_rxfifo(self); @@ -708,7 +736,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_clear_rxfifo_obj, rp2pio_statemach //| def clear_txstall(self) -> None: //| """Clears the txstall flag.""" //| ... -//| STATIC mp_obj_t rp2pio_statemachine_obj_clear_txstall(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_rp2pio_statemachine_clear_txstall(self); @@ -720,7 +747,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_clear_txstall_obj, rp2pio_statemac //| frequency: int //| """The actual state machine frequency. This may not match the frequency requested //| due to internal limitations.""" -//| STATIC mp_obj_t rp2pio_statemachine_obj_get_frequency(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -745,7 +771,6 @@ MP_PROPERTY_GETSET(rp2pio_statemachine_frequency_obj, //| txstall: bool //| """True when the state machine has stalled due to a full TX FIFO since the last //| `clear_txstall` call.""" -//| STATIC mp_obj_t rp2pio_statemachine_obj_get_txstall(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -765,7 +790,6 @@ const mp_obj_property_t rp2pio_statemachine_txstall_obj = { //| rxstall: bool //| """True when the state machine has stalled due to a full RX FIFO since the last //| `clear_rxfifo` call.""" -//| STATIC mp_obj_t rp2pio_statemachine_obj_get_rxstall(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -823,10 +847,3 @@ const mp_obj_type_t rp2pio_statemachine_type = { .make_new = rp2pio_statemachine_make_new, .locals_dict = (mp_obj_dict_t *)&rp2pio_statemachine_locals_dict, }; - -static rp2pio_statemachine_obj_t *validate_obj_is_statemachine(mp_obj_t obj) { - if (!mp_obj_is_type(obj, &rp2pio_statemachine_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), rp2pio_statemachine_type.name); - } - return MP_OBJ_TO_PTR(obj); -} diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.h b/ports/raspberrypi/bindings/rp2pio/StateMachine.h index 3ec70a8703..6f07ac1fa1 100644 --- a/ports/raspberrypi/bindings/rp2pio/StateMachine.h +++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.h @@ -64,7 +64,7 @@ void common_hal_rp2pio_statemachine_restart(rp2pio_statemachine_obj_t *self); void common_hal_rp2pio_statemachine_stop(rp2pio_statemachine_obj_t *self); void common_hal_rp2pio_statemachine_run(rp2pio_statemachine_obj_t *self, const uint16_t *instructions, size_t len); -// Writes out the given data. +// Lengths are in bytes. bool common_hal_rp2pio_statemachine_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len, uint8_t stride_in_bytes, bool swap); bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, const sm_buf_info *once_obj, const sm_buf_info *loop_obj, uint8_t stride_in_bytes, bool swap); bool common_hal_rp2pio_statemachine_stop_background_write(rp2pio_statemachine_obj_t *self); diff --git a/ports/raspberrypi/bindings/rp2pio/__init__.c b/ports/raspberrypi/bindings/rp2pio/__init__.c index 941ede2e12..193a3a2025 100644 --- a/ports/raspberrypi/bindings/rp2pio/__init__.c +++ b/ports/raspberrypi/bindings/rp2pio/__init__.c @@ -44,11 +44,17 @@ //| """Return True if the pins have sequential GPIO numbers, False otherwise""" //| ... //| -STATIC mp_obj_t rp2pio_pins_are_sequential(const mp_obj_t pins) { +STATIC mp_obj_t rp2pio_pins_are_sequential(mp_obj_t pins_obj) { size_t len; mp_obj_t *items; - mp_obj_get_array(pins, &len, &items); - return mp_obj_new_bool(common_hal_rp2pio_pins_are_sequential(len, items)); + mp_obj_get_array(pins_obj, &len, &items); + + const mcu_pin_obj_t *pins[len]; + for (size_t i = 0; i < len; i++) { + pins[i] = validate_obj_is_pin(items[i], MP_QSTR_pins); + } + + return mp_obj_new_bool(common_hal_rp2pio_pins_are_sequential(len, pins)); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_pins_are_sequential_obj, rp2pio_pins_are_sequential); diff --git a/ports/raspberrypi/bindings/rp2pio/__init__.h b/ports/raspberrypi/bindings/rp2pio/__init__.h index 89dc7ff98f..5cf73cbde3 100644 --- a/ports/raspberrypi/bindings/rp2pio/__init__.h +++ b/ports/raspberrypi/bindings/rp2pio/__init__.h @@ -26,4 +26,6 @@ #pragma once -bool common_hal_rp2pio_pins_are_sequential(size_t len, mp_obj_t *items); +#include "shared-bindings/microcontroller/Pin.h" + +bool common_hal_rp2pio_pins_are_sequential(size_t len, const mcu_pin_obj_t **pins); diff --git a/ports/raspberrypi/boards/0xcb_helios/board.c b/ports/raspberrypi/boards/0xcb_helios/board.c new file mode 100644 index 0000000000..7d8b03d5f4 --- /dev/null +++ b/ports/raspberrypi/boards/0xcb_helios/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Conor Burns for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/0xcb_helios/mpconfigboard.h b/ports/raspberrypi/boards/0xcb_helios/mpconfigboard.h new file mode 100644 index 0000000000..fcc3f7d277 --- /dev/null +++ b/ports/raspberrypi/boards/0xcb_helios/mpconfigboard.h @@ -0,0 +1,14 @@ +#define MICROPY_HW_BOARD_NAME "0xCB Helios" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO17) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/0xcb_helios/mpconfigboard.mk b/ports/raspberrypi/boards/0xcb_helios/mpconfigboard.mk new file mode 100644 index 0000000000..db3e55ed1f --- /dev/null +++ b/ports/raspberrypi/boards/0xcb_helios/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x1209 +USB_PID = 0xCB74 +USB_PRODUCT = "Helios" +USB_MANUFACTURER = "0xCB" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" diff --git a/ports/raspberrypi/boards/0xcb_helios/pico-sdk-configboard.h b/ports/raspberrypi/boards/0xcb_helios/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/0xcb_helios/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/0xcb_helios/pins.c b/ports/raspberrypi/boards/0xcb_helios/pins.c new file mode 100644 index 0000000000..3d1b22b0a4 --- /dev/null +++ b/ports/raspberrypi/boards/0xcb_helios/pins.c @@ -0,0 +1,69 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Left side top to bottom + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + + + // Right side top to bottom + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SDI), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SDO), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + + // Bottom side left to right + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + + // Internal Pins + { MP_ROM_QSTR(MP_QSTR_RGB), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/42keebs_frood/board.c b/ports/raspberrypi/boards/42keebs_frood/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/42keebs_frood/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/42keebs_frood/mpconfigboard.h b/ports/raspberrypi/boards/42keebs_frood/mpconfigboard.h new file mode 100644 index 0000000000..7f8bcda931 --- /dev/null +++ b/ports/raspberrypi/boards/42keebs_frood/mpconfigboard.h @@ -0,0 +1,12 @@ +#define MICROPY_HW_BOARD_NAME "42. Keebs Frood" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/42keebs_frood/mpconfigboard.mk b/ports/raspberrypi/boards/42keebs_frood/mpconfigboard.mk new file mode 100644 index 0000000000..955d8d63f5 --- /dev/null +++ b/ports/raspberrypi/boards/42keebs_frood/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x1209 +USB_PID = 0x4203 +USB_PRODUCT = "Frood" +USB_MANUFACTURER = "42. Keebs" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "ZD25WQ16B" diff --git a/ports/raspberrypi/boards/42keebs_frood/pico-sdk-configboard.h b/ports/raspberrypi/boards/42keebs_frood/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/42keebs_frood/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/42keebs_frood/pins.c b/ports/raspberrypi/boards/42keebs_frood/pins.c new file mode 100644 index 0000000000..972d5354b6 --- /dev/null +++ b/ports/raspberrypi/boards/42keebs_frood/pins.c @@ -0,0 +1,55 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040/board.c index eac54ce460..331653173e 100644 --- a/ports/raspberrypi/boards/adafruit_feather_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040/board.c @@ -26,18 +26,4 @@ #include "supervisor/board.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/mpconfigboard.h new file mode 100644 index 0000000000..94b6fcee7b --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/mpconfigboard.h @@ -0,0 +1,14 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather RP2040 Scorpio" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO16) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO14) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO8) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/mpconfigboard.mk new file mode 100644 index 0000000000..db06fd728b --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x239A +USB_PID = 0x8122 +USB_PRODUCT = "Feather RP2040 Scorpio" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/pico-sdk-configboard.h @@ -0,0 +1,4 @@ +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/pins.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/pins.c new file mode 100644 index 0000000000..9bf3a71e25 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_scorpio/pins.c @@ -0,0 +1,48 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL0), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL2), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL3), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL4), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL5), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL6), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL7), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/board.c b/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/adafruit_kb2040/board.c b/ports/raspberrypi/boards/adafruit_kb2040/board.c index eac54ce460..331653173e 100644 --- a/ports/raspberrypi/boards/adafruit_kb2040/board.c +++ b/ports/raspberrypi/boards/adafruit_kb2040/board.c @@ -26,18 +26,4 @@ #include "supervisor/board.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c index 7aa9feee1b..b5cef1639d 100644 --- a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c @@ -97,7 +97,6 @@ void board_init(void) { NULL, 0x81, 1.0f, // brightness - false, // auto_brightness true, // single_byte_bounds true, // data as commands true, // auto_refresh @@ -107,14 +106,9 @@ void board_init(void) { 50000); // backlight pwm frequency } -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { // turn off any left over LED board_reset_user_neopixels(&pin_GPIO19, 12); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/adafruit_qt2040_trinkey/board.c b/ports/raspberrypi/boards/adafruit_qt2040_trinkey/board.c index eac54ce460..c94078ae60 100644 --- a/ports/raspberrypi/boards/adafruit_qt2040_trinkey/board.c +++ b/ports/raspberrypi/boards/adafruit_qt2040_trinkey/board.c @@ -29,15 +29,4 @@ #include "shared-bindings/microcontroller/Pin.h" #include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/adafruit_qtpy_rp2040/board.c b/ports/raspberrypi/boards/adafruit_qtpy_rp2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/adafruit_qtpy_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_qtpy_rp2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/arduino_nano_rp2040_connect/board.c b/ports/raspberrypi/boards/arduino_nano_rp2040_connect/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/arduino_nano_rp2040_connect/board.c +++ b/ports/raspberrypi/boards/arduino_nano_rp2040_connect/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/bwshockley_figpi/board.c b/ports/raspberrypi/boards/bwshockley_figpi/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/bwshockley_figpi/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.h b/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.h new file mode 100644 index 0000000000..fbd03379dd --- /dev/null +++ b/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.h @@ -0,0 +1,15 @@ +#define MICROPY_HW_BOARD_NAME "Fig Pi" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO13) +#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO1) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO17, .sda = &pin_GPIO16}, \ + {.scl = &pin_GPIO19, .sda = &pin_GPIO18}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO6, .mosi = &pin_GPIO7, .miso = &pin_GPIO4}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO24, .rx = &pin_GPIO25}} diff --git a/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.mk b/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.mk new file mode 100644 index 0000000000..95bd9715d6 --- /dev/null +++ b/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x2019 +USB_PID = 0x7103 +USB_PRODUCT = "Fig Pi" +USB_MANUFACTURER = "Benjamin Shockley" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" diff --git a/ports/raspberrypi/boards/bwshockley_figpi/pico-sdk-configboard.h b/ports/raspberrypi/boards/bwshockley_figpi/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/bwshockley_figpi/pico-sdk-configboard.h @@ -0,0 +1,4 @@ +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/bwshockley_figpi/pins.c b/ports/raspberrypi/boards/bwshockley_figpi/pins.c new file mode 100644 index 0000000000..1bec6fd91b --- /dev/null +++ b/ports/raspberrypi/boards/bwshockley_figpi/pins.c @@ -0,0 +1,62 @@ +#include "shared-bindings/board/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(stemma_i2c, i2c, 1) + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_stemma_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/challenger_nb_rp2040_wifi/board.c b/ports/raspberrypi/boards/challenger_nb_rp2040_wifi/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/challenger_nb_rp2040_wifi/board.c +++ b/ports/raspberrypi/boards/challenger_nb_rp2040_wifi/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/challenger_rp2040_lora/board.c b/ports/raspberrypi/boards/challenger_rp2040_lora/board.c index e8208ee5d3..b66ea0e27f 100644 --- a/ports/raspberrypi/boards/challenger_rp2040_lora/board.c +++ b/ports/raspberrypi/boards/challenger_rp2040_lora/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/challenger_rp2040_lte/board.c b/ports/raspberrypi/boards/challenger_rp2040_lte/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/challenger_rp2040_lte/board.c +++ b/ports/raspberrypi/boards/challenger_rp2040_lte/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/challenger_rp2040_sdrtc/board.c b/ports/raspberrypi/boards/challenger_rp2040_sdrtc/board.c new file mode 100644 index 0000000000..b66ea0e27f --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_sdrtc/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Pontus Oldberg, Invector Labs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/challenger_rp2040_sdrtc/mpconfigboard.h b/ports/raspberrypi/boards/challenger_rp2040_sdrtc/mpconfigboard.h new file mode 100644 index 0000000000..b8f08b9956 --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_sdrtc/mpconfigboard.h @@ -0,0 +1,10 @@ +#define MICROPY_HW_BOARD_NAME "Challenger RP2040 SD/RTC" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_UART_BUS_TX (&pin_GPIO16) +#define DEFAULT_UART_BUS_RX (&pin_GPIO17) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO0) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO1) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20) diff --git a/ports/raspberrypi/boards/challenger_rp2040_sdrtc/mpconfigboard.mk b/ports/raspberrypi/boards/challenger_rp2040_sdrtc/mpconfigboard.mk new file mode 100644 index 0000000000..022dbd143c --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_sdrtc/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x2e8a +USB_PID = 0x102d +USB_PRODUCT = "Challenger RP2040 SD/RTC" +USB_MANUFACTURER = "Invector Labs" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" + +CIRCUITPY__EVE = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD diff --git a/ports/raspberrypi/boards/challenger_rp2040_sdrtc/pico-sdk-configboard.h b/ports/raspberrypi/boards/challenger_rp2040_sdrtc/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_sdrtc/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/challenger_rp2040_sdrtc/pins.c b/ports/raspberrypi/boards/challenger_rp2040_sdrtc/pins.c new file mode 100644 index 0000000000..7f4f620b59 --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_sdrtc/pins.c @@ -0,0 +1,76 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + // RFM95W connections + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_SD_SDO), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SD_SDI), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SD_CARD_DETECT), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/challenger_rp2040_subghz/board.c b/ports/raspberrypi/boards/challenger_rp2040_subghz/board.c new file mode 100644 index 0000000000..b66ea0e27f --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_subghz/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Pontus Oldberg, Invector Labs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/challenger_rp2040_subghz/mpconfigboard.h b/ports/raspberrypi/boards/challenger_rp2040_subghz/mpconfigboard.h new file mode 100644 index 0000000000..0e41e9f3a5 --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_subghz/mpconfigboard.h @@ -0,0 +1,10 @@ +#define MICROPY_HW_BOARD_NAME "Challenger RP2040 SubGHz" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_UART_BUS_TX (&pin_GPIO16) +#define DEFAULT_UART_BUS_RX (&pin_GPIO17) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO0) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO1) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20) diff --git a/ports/raspberrypi/boards/challenger_rp2040_subghz/mpconfigboard.mk b/ports/raspberrypi/boards/challenger_rp2040_subghz/mpconfigboard.mk new file mode 100644 index 0000000000..8bd9ac2318 --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_subghz/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x2e8a +USB_PID = 0x1032 +USB_PRODUCT = "Challenger RP2040 SubGHz" +USB_MANUFACTURER = "Invector Labs" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" + +CIRCUITPY__EVE = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_RFM69 diff --git a/ports/raspberrypi/boards/challenger_rp2040_subghz/pico-sdk-configboard.h b/ports/raspberrypi/boards/challenger_rp2040_subghz/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_subghz/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/challenger_rp2040_subghz/pins.c b/ports/raspberrypi/boards/challenger_rp2040_subghz/pins.c new file mode 100644 index 0000000000..f5275e84dc --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_subghz/pins.c @@ -0,0 +1,85 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + // RFM69HCW connections + { MP_ROM_QSTR(MP_QSTR_RFM69HCW_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_RFM69HCW_SCK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_RFM69HCW_SDO), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_RFM69HCW_SDI), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_RFM69HCW_RST), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_RFM69HCW_DIO0), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_RFM69HCW_DIO1), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_RFM69HCW_DIO2), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/challenger_rp2040_wifi/board.c b/ports/raspberrypi/boards/challenger_rp2040_wifi/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/challenger_rp2040_wifi/board.c +++ b/ports/raspberrypi/boards/challenger_rp2040_wifi/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/fatfs_port.c b/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/board.c similarity index 79% rename from ports/stm/fatfs_port.c rename to ports/raspberrypi/boards/challenger_rp2040_wifi_ble/board.c index 631f7f0982..de6e424ed9 100644 --- a/ports/stm/fatfs_port.c +++ b/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/board.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,10 +24,17 @@ * THE SOFTWARE. */ -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" +#include "supervisor/board.h" -DWORD get_fattime(void) { - // TODO: Implement this function. For now, fake it. - return ((2016 - 1980) << 25) | ((12) << 21) | ((4) << 16) | ((00) << 11) | ((18) << 5) | (23 / 2); +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} + +void board_deinit(void) { } diff --git a/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/mpconfigboard.h b/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/mpconfigboard.h new file mode 100644 index 0000000000..76c0748079 --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/mpconfigboard.h @@ -0,0 +1,10 @@ +#define MICROPY_HW_BOARD_NAME "Challenger RP2040 WiFi/BLE" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_UART_BUS_TX (&pin_GPIO16) +#define DEFAULT_UART_BUS_RX (&pin_GPIO17) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO0) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO1) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20) diff --git a/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/mpconfigboard.mk b/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/mpconfigboard.mk new file mode 100644 index 0000000000..5b1502fdd0 --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x2e8a +USB_PID = 0x102c +USB_PRODUCT = "Challenger RP2040 WiFi/BLE" +USB_MANUFACTURER = "Invector Labs" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/pico-sdk-configboard.h b/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/pins.c b/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/pins.c new file mode 100644 index 0000000000..57d7ecc698 --- /dev/null +++ b/ports/raspberrypi/boards/challenger_rp2040_wifi_ble/pins.c @@ -0,0 +1,78 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_WIFI_MODE), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_WIFI_RESET), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/cosmo_pico/board.c b/ports/raspberrypi/boards/cosmo_pico/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/cosmo_pico/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/cosmo_pico/mpconfigboard.h b/ports/raspberrypi/boards/cosmo_pico/mpconfigboard.h new file mode 100644 index 0000000000..d313e6097f --- /dev/null +++ b/ports/raspberrypi/boards/cosmo_pico/mpconfigboard.h @@ -0,0 +1,2 @@ +#define MICROPY_HW_BOARD_NAME "COSMO-Pico" +#define MICROPY_HW_MCU_NAME "rp2040" diff --git a/ports/raspberrypi/boards/cosmo_pico/mpconfigboard.mk b/ports/raspberrypi/boards/cosmo_pico/mpconfigboard.mk new file mode 100644 index 0000000000..f4278e0c1b --- /dev/null +++ b/ports/raspberrypi/boards/cosmo_pico/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x2E8A +USB_PID = 0x104C +USB_PRODUCT = "COSMO-Pico" +USB_MANUFACTURER = "Raspberry Pi" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/cosmo_pico/pico-sdk-configboard.h b/ports/raspberrypi/boards/cosmo_pico/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/cosmo_pico/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/cosmo_pico/pins.c b/ports/raspberrypi/boards/cosmo_pico/pins.c new file mode 100644 index 0000000000..f2c094cb4d --- /dev/null +++ b/ports/raspberrypi/boards/cosmo_pico/pins.c @@ -0,0 +1,44 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/cytron_maker_nano_rp2040/board.c b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/board.c index b583e7bf11..22f2970c9e 100644 --- a/ports/raspberrypi/boards/cytron_maker_nano_rp2040/board.c +++ b/ports/raspberrypi/boards/cytron_maker_nano_rp2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/cytron_maker_pi_rp2040/board.c b/ports/raspberrypi/boards/cytron_maker_pi_rp2040/board.c index b583e7bf11..22f2970c9e 100644 --- a/ports/raspberrypi/boards/cytron_maker_pi_rp2040/board.c +++ b/ports/raspberrypi/boards/cytron_maker_pi_rp2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/e_fidget/board.c b/ports/raspberrypi/boards/e_fidget/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/e_fidget/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/e_fidget/mpconfigboard.h b/ports/raspberrypi/boards/e_fidget/mpconfigboard.h new file mode 100644 index 0000000000..5c34c77f94 --- /dev/null +++ b/ports/raspberrypi/boards/e_fidget/mpconfigboard.h @@ -0,0 +1,5 @@ +#define MICROPY_HW_BOARD_NAME "E-Fidget" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) +#define MICROPY_HW_NEOPIXEL_COUNT (3) diff --git a/ports/raspberrypi/boards/e_fidget/mpconfigboard.mk b/ports/raspberrypi/boards/e_fidget/mpconfigboard.mk new file mode 100644 index 0000000000..62195e46f3 --- /dev/null +++ b/ports/raspberrypi/boards/e_fidget/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x1209 +USB_PID = 0xEF00 +USB_PRODUCT = "E-Fidget" +USB_MANUFACTURER = "2231puppy" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/e_fidget/pico-sdk-configboard.h b/ports/raspberrypi/boards/e_fidget/pico-sdk-configboard.h new file mode 100644 index 0000000000..5f7eb47ae3 --- /dev/null +++ b/ports/raspberrypi/boards/e_fidget/pico-sdk-configboard.h @@ -0,0 +1,2 @@ +// Put board-specific pico-sdk definitions here. This file must exist. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/e_fidget/pins.c b/ports/raspberrypi/boards/e_fidget/pins.c new file mode 100644 index 0000000000..dbb27b782d --- /dev/null +++ b/ports/raspberrypi/boards/e_fidget/pins.c @@ -0,0 +1,32 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + {MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0)}, + {MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1)}, + {MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2)}, + {MP_ROM_QSTR(MP_QSTR_BTN1), MP_ROM_PTR(&pin_GPIO3)}, + {MP_ROM_QSTR(MP_QSTR_BTN3), MP_ROM_PTR(&pin_GPIO4)}, + {MP_ROM_QSTR(MP_QSTR_BTN2), MP_ROM_PTR(&pin_GPIO5)}, + {MP_ROM_QSTR(MP_QSTR_M1), MP_ROM_PTR(&pin_GPIO7)}, + {MP_ROM_QSTR(MP_QSTR_M2), MP_ROM_PTR(&pin_GPIO11)}, + {MP_ROM_QSTR(MP_QSTR_M3), MP_ROM_PTR(&pin_GPIO13)}, + {MP_ROM_QSTR(MP_QSTR_M4), MP_ROM_PTR(&pin_GPIO9)}, + {MP_ROM_QSTR(MP_QSTR_M5), MP_ROM_PTR(&pin_GPIO8)}, + {MP_ROM_QSTR(MP_QSTR_M6), MP_ROM_PTR(&pin_GPIO10)}, + {MP_ROM_QSTR(MP_QSTR_M7), MP_ROM_PTR(&pin_GPIO12)}, + {MP_ROM_QSTR(MP_QSTR_M8), MP_ROM_PTR(&pin_GPIO14)}, + {MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18)}, + + {MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23)}, + + {MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO24)}, + + {MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26)}, + {MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26)}, + {MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26)}, + + {MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/elecfreaks_picoed/board.c b/ports/raspberrypi/boards/elecfreaks_picoed/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/elecfreaks_picoed/board.c +++ b/ports/raspberrypi/boards/elecfreaks_picoed/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/electrolama_minik/board.c b/ports/raspberrypi/boards/electrolama_minik/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/electrolama_minik/board.c +++ b/ports/raspberrypi/boards/electrolama_minik/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/hack_club_sprig/board.c b/ports/raspberrypi/boards/hack_club_sprig/board.c new file mode 100644 index 0000000000..775e6ca5df --- /dev/null +++ b/ports/raspberrypi/boards/hack_club_sprig/board.c @@ -0,0 +1,128 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 ajs256 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "supervisor/shared/board.h" + +displayio_fourwire_obj_t board_display_obj; + +// display init sequence from CircuitPython library https://github.com/adafruit/Adafruit_CircuitPython_ST7735R/blob/dfae353330cf051d1f31db9e4b681c8d70900cc5/adafruit_st7735r.py +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0x80, 0x96, + // sleep out and delay + 0x11, 0x80, 0xFF, + // _FRMCTR1 + 0xB1, 0x03, 0x01, 0x2C, 0x2D, + // _FRMCTR2 + 0xB2, 0x03, 0x01, 0x2C, 0x2D, + // _FRMCTR3 + 0xB3, 0x06, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, + // _INVCTR line inversion + 0xB4, 0x01, 0x07, + // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xC0, 0x03, 0xA2, 0x02, 0x84, + // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xC1, 0x01, 0xC5, + // _PWCTR3 Opamp current small, Boost frequency + 0xC2, 0x02, 0x0A, 0x00, + 0xC3, 0x02, 0x8A, 0x2A, + 0xC4, 0x02, 0x8A, 0xEE, + // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0xC5, 0x01, 0x0E, + // _INVOFF + 0x20, 0x00, + // _MADCTL bottom to top refresh + 0x36, 0x01, 0x18, + // COLMOD - 16 bit color + 0x3A, 0x01, 0x05, + // _GMCTRP1 Gamma + 0xE0, 0x10, 0x02, 0x1C, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2D, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, + // _GMCTRN1 + 0xE1, 0x10, 0x03, 0x1d, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, + // _NORON + 0x13, 0x80, 0x0A, + // _DISPON + 0x29, 0x80, 0x64, + // _MADCTL Default rotation + BGR encoding + 0x36, 0x01, 0xC0, +}; + + +void board_init(void) { + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, &pin_GPIO16, false); + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_GPIO22, // DC + &pin_GPIO20, // CS + &pin_GPIO26, // RST + 30000000, + 0, + 0); + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 160, // Width + 128, // Height + 0, // column start + 0, // row start + 270, // rotation + 16, // Color depth + false, // Grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_bytes_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO17, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000); // backlight pwm frequency +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/hack_club_sprig/mpconfigboard.h b/ports/raspberrypi/boards/hack_club_sprig/mpconfigboard.h new file mode 100644 index 0000000000..442e455c5e --- /dev/null +++ b/ports/raspberrypi/boards/hack_club_sprig/mpconfigboard.h @@ -0,0 +1,4 @@ +#define MICROPY_HW_BOARD_NAME "Hack Club Sprig" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO4) diff --git a/ports/raspberrypi/boards/hack_club_sprig/mpconfigboard.mk b/ports/raspberrypi/boards/hack_club_sprig/mpconfigboard.mk new file mode 100644 index 0000000000..1bde636031 --- /dev/null +++ b/ports/raspberrypi/boards/hack_club_sprig/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x1209 +USB_PID = 0x9000 +USB_PRODUCT = "Sprig" +USB_MANUFACTURER = "Hack Club" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/hack_club_sprig/pico-sdk-configboard.h b/ports/raspberrypi/boards/hack_club_sprig/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/hack_club_sprig/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/hack_club_sprig/pins.c b/ports/raspberrypi/boards/hack_club_sprig/pins.c new file mode 100644 index 0000000000..f82b8fafc5 --- /dev/null +++ b/ports/raspberrypi/boards/hack_club_sprig/pins.c @@ -0,0 +1,85 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + + + // Start Sprig-specific definitions + + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_W), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_S), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_D), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_AUDIO_DIN), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_AUDIO_BCLK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_AUDIO_LRCLK), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_I), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_J), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_K), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_L), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_CARD_CS), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_WHITE_LED), MP_ROM_PTR(&pin_GPIO28) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/jpconstantineau_encoderpad_rp2040/board.c b/ports/raspberrypi/boards/jpconstantineau_encoderpad_rp2040/board.c index 831bf96cdf..1c16e2fc4f 100644 --- a/ports/raspberrypi/boards/jpconstantineau_encoderpad_rp2040/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_encoderpad_rp2040/board.c @@ -30,17 +30,9 @@ #include "supervisor/shared/board.h" #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { // turn off any left over LED board_reset_user_neopixels(&pin_GPIO15, 9); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c b/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c index e4e5a8bc57..5b1190727f 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c @@ -29,17 +29,9 @@ #include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" #include "supervisor/shared/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { // turn off any left over LED - board_reset_user_neopixels(&pin_GPIO29, 62); + board_reset_user_neopixels(&pin_GPIO29, 19); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/jpconstantineau_pykey44/board.c b/ports/raspberrypi/boards/jpconstantineau_pykey44/board.c index e4e5a8bc57..4e0aa74450 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey44/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey44/board.c @@ -29,17 +29,9 @@ #include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" #include "supervisor/shared/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { // turn off any left over LED - board_reset_user_neopixels(&pin_GPIO29, 62); + board_reset_user_neopixels(&pin_GPIO29, 45); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/jpconstantineau_pykey60/board.c b/ports/raspberrypi/boards/jpconstantineau_pykey60/board.c index e4e5a8bc57..4785f742ec 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey60/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey60/board.c @@ -29,17 +29,9 @@ #include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" #include "supervisor/shared/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { // turn off any left over LED board_reset_user_neopixels(&pin_GPIO29, 62); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/jpconstantineau_pykey87/board.c b/ports/raspberrypi/boards/jpconstantineau_pykey87/board.c index e4e5a8bc57..a77563c663 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey87/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey87/board.c @@ -29,17 +29,9 @@ #include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" #include "supervisor/shared/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { // turn off any left over LED - board_reset_user_neopixels(&pin_GPIO29, 62); + board_reset_user_neopixels(&pin_GPIO29, 88); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/melopero_shake_rp2040/board.c b/ports/raspberrypi/boards/melopero_shake_rp2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/melopero_shake_rp2040/board.c +++ b/ports/raspberrypi/boards/melopero_shake_rp2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/nullbits_bit_c_pro/board.c b/ports/raspberrypi/boards/nullbits_bit_c_pro/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/nullbits_bit_c_pro/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/nullbits_bit_c_pro/mpconfigboard.h b/ports/raspberrypi/boards/nullbits_bit_c_pro/mpconfigboard.h new file mode 100644 index 0000000000..d2a514006a --- /dev/null +++ b/ports/raspberrypi/boards/nullbits_bit_c_pro/mpconfigboard.h @@ -0,0 +1,17 @@ +#define MICROPY_HW_BOARD_NAME "nullbits Bit-C PRO" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_RGB_STATUS_INVERTED_PWM +#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) +#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO17) +#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO18) diff --git a/ports/raspberrypi/boards/nullbits_bit_c_pro/mpconfigboard.mk b/ports/raspberrypi/boards/nullbits_bit_c_pro/mpconfigboard.mk new file mode 100644 index 0000000000..81271d3721 --- /dev/null +++ b/ports/raspberrypi/boards/nullbits_bit_c_pro/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x2E8A +USB_PID = 0x1048 +USB_PRODUCT = "Bit-C PRO" +USB_MANUFACTURER = "nullbits" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q32C" diff --git a/ports/raspberrypi/boards/nullbits_bit_c_pro/pico-sdk-configboard.h b/ports/raspberrypi/boards/nullbits_bit_c_pro/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/nullbits_bit_c_pro/pico-sdk-configboard.h @@ -0,0 +1,4 @@ +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/nullbits_bit_c_pro/pins.c b/ports/raspberrypi/boards/nullbits_bit_c_pro/pins.c new file mode 100644 index 0000000000..ac1b1a8065 --- /dev/null +++ b/ports/raspberrypi/boards/nullbits_bit_c_pro/pins.c @@ -0,0 +1,49 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/odt_bread_2040/board.c b/ports/raspberrypi/boards/odt_bread_2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/odt_bread_2040/board.c +++ b/ports/raspberrypi/boards/odt_bread_2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/odt_cast_away_rp2040/board.c b/ports/raspberrypi/boards/odt_cast_away_rp2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/odt_cast_away_rp2040/board.c +++ b/ports/raspberrypi/boards/odt_cast_away_rp2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_badger2040/board.c b/ports/raspberrypi/boards/pimoroni_badger2040/board.c index 666bb5f62f..9eea472925 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_badger2040/board.c @@ -260,6 +260,10 @@ const uint8_t display_stop_sequence[] = { POF, 0x00 // Power off }; +const uint8_t refresh_sequence[] = { + DRF, 0x00 +}; + void board_init(void) { // Drive the EN_3V3 pin high so the board stays awake on battery power enable_pin_obj.base.type = &digitalio_digitalinout_type; @@ -293,6 +297,7 @@ void board_init(void) { display, bus, display_start_sequence, sizeof(display_start_sequence), + 0, // start up time display_stop_sequence, sizeof(display_stop_sequence), 296, // width 128, // height @@ -310,23 +315,17 @@ void board_init(void) { DTM1, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color - DRF, // refresh_display_command + refresh_sequence, sizeof(refresh_sequence), // refresh_display_command 1.0, // refresh_time &pin_GPIO26, // busy_pin false, // busy_state 2.0, // seconds_per_frame false, // always_toggle_chip_select false, // grayscale + false, // acep false); // two_byte_sequence_length } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - void board_deinit(void) { displayio_epaperdisplay_obj_t *display = &displays[0].epaper_display; if (display->base.type == &displayio_epaperdisplay_type) { @@ -338,3 +337,5 @@ void board_deinit(void) { } common_hal_displayio_release_displays(); } + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/board.c b/ports/raspberrypi/boards/pimoroni_interstate75/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/pimoroni_interstate75/board.c +++ b/ports/raspberrypi/boards/pimoroni_interstate75/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/pins.c b/ports/raspberrypi/boards/pimoroni_interstate75/pins.c index 2460ebc76a..801a418015 100644 --- a/ports/raspberrypi/boards/pimoroni_interstate75/pins.c +++ b/ports/raspberrypi/boards/pimoroni_interstate75/pins.c @@ -22,6 +22,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO18) }, diff --git a/ports/raspberrypi/boards/pimoroni_keybow2040/board.c b/ports/raspberrypi/boards/pimoroni_keybow2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/pimoroni_keybow2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_keybow2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_motor2040/board.c b/ports/raspberrypi/boards/pimoroni_motor2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/pimoroni_motor2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_motor2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_pga2040/board.c b/ports/raspberrypi/boards/pimoroni_pga2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/pimoroni_pga2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_pga2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c +++ b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c +++ b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/board.c b/ports/raspberrypi/boards/pimoroni_picosystem/board.c index 0a07f3b0dd..600089f129 100644 --- a/ports/raspberrypi/boards/pimoroni_picosystem/board.c +++ b/ports/raspberrypi/boards/pimoroni_picosystem/board.c @@ -101,8 +101,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_GPIO12, // backlight pin NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - true, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -112,12 +111,4 @@ void board_init(void) { 50000); // backlight pwm frequency } -void board_deinit(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/board.c b/ports/raspberrypi/boards/pimoroni_plasma2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/pimoroni_plasma2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_servo2040/board.c b/ports/raspberrypi/boards/pimoroni_servo2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/pimoroni_servo2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_servo2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_tiny2040/board.c b/ports/raspberrypi/boards/pimoroni_tiny2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/pimoroni_tiny2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_tiny2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_tiny2040_2mb/board.c b/ports/raspberrypi/boards/pimoroni_tiny2040_2mb/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/pimoroni_tiny2040_2mb/board.c +++ b/ports/raspberrypi/boards/pimoroni_tiny2040_2mb/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/board.c b/ports/raspberrypi/boards/raspberry_pi_pico/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico/board.c +++ b/ports/raspberrypi/boards/raspberry_pi_pico/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h index efb2fc3402..548af930ba 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h +++ b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h @@ -1,2 +1,7 @@ #define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico" #define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO25) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/pins.c b/ports/raspberrypi/boards/raspberry_pi_pico/pins.c index 87ff27fa46..2d56b93757 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico/pins.c +++ b/ports/raspberrypi/boards/raspberry_pi_pico/pins.c @@ -50,5 +50,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/raspberry_pi_pico_w/board.c b/ports/raspberrypi/boards/raspberry_pi_pico_w/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico_w/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/raspberry_pi_pico_w/link.ld b/ports/raspberrypi/boards/raspberry_pi_pico_w/link.ld new file mode 100644 index 0000000000..2777b41720 --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico_w/link.ld @@ -0,0 +1,294 @@ +/* Based on GCC ARM embedded samples. + Defines the following symbols for use by code: + __exidx_start + __exidx_end + __etext + __data_start__ + __preinit_array_start + __preinit_array_end + __init_array_start + __init_array_end + __fini_array_start + __fini_array_end + __data_end__ + __bss_start__ + __bss_end__ + __end__ + end + __HeapLimit + __StackLimit + __StackTop + __stack (== StackTop) +*/ + +MEMORY +{ + FLASH_FIRMWARE (rx) : ORIGIN = 0x10000000, LENGTH = 1532k + /* Followed by: 4kB of NVRAM and at least 512kB of CIRCUITPY */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256k + SCRATCH_X (rwx) : ORIGIN = 0x20040000, LENGTH = 4k + SCRATCH_Y (rwx) : ORIGIN = 0x20041000, LENGTH = 4k +} + +ENTRY(_entry_point) + +SECTIONS +{ + /* Second stage bootloader is prepended to the image. It must be 256 bytes big + and checksummed. It is usually built by the boot_stage2 target + in the Pico SDK + */ + + .flash_begin : { + __flash_binary_start = .; + } > FLASH_FIRMWARE + + .boot2 : { + __boot2_start__ = .; + KEEP (*(.boot2)) + __boot2_end__ = .; + } > FLASH_FIRMWARE + + ASSERT(__boot2_end__ - __boot2_start__ == 256, + "ERROR: Pico second stage bootloader must be 256 bytes in size") + + /* The second stage will always enter the image at the start of .text. + The debugger will use the ELF entry point, which is the _entry_point + symbol if present, otherwise defaults to start of .text. + This can be used to transfer control back to the bootrom on debugger + launches only, to perform proper flash setup. + */ + + .text : { + __logical_binary_start = .; + KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.reset)) + /* TODO revisit this now memset/memcpy/float in ROM */ + /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from + * FLASH ... we will include any thing excluded here in .data below by default */ + *(.init) + + __property_getter_start = .; + *(.property_getter) + __property_getter_end = .; + __property_getset_start = .; + *(.property_getset) + __property_getset_end = .; + + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH_FIRMWARE + + .rodata : { + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > FLASH_FIRMWARE + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH_FIRMWARE + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH_FIRMWARE + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > FLASH_FIRMWARE + __binary_info_end = .; + . = ALIGN(4); + + /* End of .text-like segments */ + __etext = .; + + .ram_vector_table (COPY): { + *(.ram_vector_table) + } > RAM + + .data : { + __data_start__ = .; + *(vtable) + + *(.time_critical*) + + /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ + *(.text*) + . = ALIGN(4); + *(.rodata*) + . = ALIGN(4); + + *(.data*) + + . = ALIGN(4); + *(.after_data.*) + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__mutex_array_start = .); + KEEP(*(SORT(.mutex_array.*))) + KEEP(*(.mutex_array)) + PROVIDE_HIDDEN (__mutex_array_end = .); + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(SORT(.preinit_array.*))) + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM AT> FLASH_FIRMWARE + + .itcm : + { + . = ALIGN(4); + *(.itcm.*) + + . = ALIGN(4); + } > RAM AT> FLASH_FIRMWARE + _ld_itcm_destination = ADDR(.itcm); + _ld_itcm_flash_copy = LOADADDR(.itcm); + _ld_itcm_size = SIZEOF(.itcm); + + .dtcm_data : + { + . = ALIGN(4); + + *(.dtcm_data.*) + + . = ALIGN(4); + } > RAM AT> FLASH_FIRMWARE + _ld_dtcm_data_destination = ADDR(.dtcm_data); + _ld_dtcm_data_flash_copy = LOADADDR(.dtcm_data); + _ld_dtcm_data_size = SIZEOF(.dtcm_data); + + .dtcm_bss : + { + . = ALIGN(4); + + *(.dtcm_bss.*) + + . = ALIGN(4); + } > RAM AT> RAM + _ld_dtcm_bss_start = ADDR(.dtcm_bss); + _ld_dtcm_bss_size = SIZEOF(.dtcm_bss); + + .uninitialized_data (COPY): { + . = ALIGN(4); + *(.uninitialized_data*) + } > RAM + + /* Start and end symbols must be word-aligned */ + .scratch_x : { + __scratch_x_start__ = .; + *(.scratch_x.*) + . = ALIGN(4); + __scratch_x_end__ = .; + } > SCRATCH_X AT > FLASH_FIRMWARE + __scratch_x_source__ = LOADADDR(.scratch_x); + + .scratch_y : { + __scratch_y_start__ = .; + *(.scratch_y.*) + . = ALIGN(4); + __scratch_y_end__ = .; + } > SCRATCH_Y AT > FLASH_FIRMWARE + __scratch_y_source__ = LOADADDR(.scratch_y); + + .bss : { + . = ALIGN(4); + __bss_start__ = .; + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + end = __end__; + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack*_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later + * + * stack1 section may be empty/missing if platform_launch_core1 is not used */ + + /* by default we put core 0 stack at the end of scratch Y, so that if core 1 + * stack is not used then all of SCRATCH_X is free. + */ + .stack1_dummy (COPY): + { + *(.stack1*) + } > SCRATCH_X + .stack_dummy (COPY): + { + *(.stack*) + } > SCRATCH_Y + + .flash_end : { + __flash_binary_end = .; + } > FLASH_FIRMWARE + + /* stack limit is poorly named, but historically is maximum heap ptr */ + __StackLimit = ORIGIN(RAM) + LENGTH(RAM); + __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); + __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); + __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); + __StackBottom = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") + + ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") + /* todo assert on extra code */ +} diff --git a/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.h b/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.h new file mode 100644 index 0000000000..a31ee7327c --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.h @@ -0,0 +1,10 @@ +#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico W" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (1) +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE (1) + +#define MICROPY_HW_LED_STATUS (&pin_CYW0) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} diff --git a/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk b/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk new file mode 100644 index 0000000000..a050391505 --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk @@ -0,0 +1,24 @@ +USB_VID = 0x239A +USB_PID = 0x8120 +USB_PRODUCT = "Pico W" +USB_MANUFACTURER = "Raspberry Pi" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY__EVE = 1 + +CIRCUITPY_CYW43 = 1 +CIRCUITPY_SSL = 1 +CIRCUITPY_SSL_MBEDTLS = 1 +CIRCUITPY_HASHLIB = 1 +CIRCUITPY_WEB_WORKFLOW = 1 +CIRCUITPY_MDNS = 1 +CIRCUITPY_SOCKETPOOL = 1 +CIRCUITPY_WIFI = 1 + +CFLAGS += -DCYW43_PIN_WL_HOST_WAKE=24 -DCYW43_PIN_WL_REG_ON=23 -DCYW43_WL_GPIO_COUNT=3 -DCYW43_WL_GPIO_LED_PIN=0 +# Must be accompanied by a linker script change +CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/raspberry_pi_pico_w/pico-sdk-configboard.h b/ports/raspberrypi/boards/raspberry_pi_pico_w/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico_w/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/raspberry_pi_pico_w/pins.c b/ports/raspberrypi/boards/raspberry_pi_pico_w/pins.c new file mode 100644 index 0000000000..8c85642597 --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico_w/pins.c @@ -0,0 +1,54 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_CYW1) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_CYW0) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_CYW2) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/seeeduino_xiao_rp2040/board.c b/ports/raspberrypi/boards/seeeduino_xiao_rp2040/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/seeeduino_xiao_rp2040/board.c +++ b/ports/raspberrypi/boards/seeeduino_xiao_rp2040/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/silicognition_rp2040_shim/board.c b/ports/raspberrypi/boards/silicognition_rp2040_shim/board.c index eac54ce460..331653173e 100644 --- a/ports/raspberrypi/boards/silicognition_rp2040_shim/board.c +++ b/ports/raspberrypi/boards/silicognition_rp2040_shim/board.c @@ -26,18 +26,4 @@ #include "supervisor/board.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/solderparty_bbq20kbd/board.c b/ports/raspberrypi/boards/solderparty_bbq20kbd/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/solderparty_bbq20kbd/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/solderparty_bbq20kbd/mpconfigboard.h b/ports/raspberrypi/boards/solderparty_bbq20kbd/mpconfigboard.h new file mode 100644 index 0000000000..4f5f2c1106 --- /dev/null +++ b/ports/raspberrypi/boards/solderparty_bbq20kbd/mpconfigboard.h @@ -0,0 +1,7 @@ +#define MICROPY_HW_BOARD_NAME "BBQ20KBD" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO23) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO18) + +#define DEFAULT_UART_BUS_TX (&pin_GPIO20) diff --git a/ports/raspberrypi/boards/solderparty_bbq20kbd/mpconfigboard.mk b/ports/raspberrypi/boards/solderparty_bbq20kbd/mpconfigboard.mk new file mode 100644 index 0000000000..3f3acc46be --- /dev/null +++ b/ports/raspberrypi/boards/solderparty_bbq20kbd/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x1209 +USB_PID = 0xB182 +USB_PRODUCT = "BBQ20 Keyboard" +USB_MANUFACTURER = "Solder Party" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q16C" + +CIRCUITPY__EVE = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID diff --git a/ports/raspberrypi/boards/solderparty_bbq20kbd/pico-sdk-configboard.h b/ports/raspberrypi/boards/solderparty_bbq20kbd/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/solderparty_bbq20kbd/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/solderparty_bbq20kbd/pins.c b/ports/raspberrypi/boards/solderparty_bbq20kbd/pins.c new file mode 100644 index 0000000000..c5eab180a0 --- /dev/null +++ b/ports/raspberrypi/boards/solderparty_bbq20kbd/pins.c @@ -0,0 +1,41 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_PERIPHERAL_SDA), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_PERIPHERAL_SCL), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_ROW1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_ROW2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_ROW3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_ROW4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_ROW5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_ROW6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_ROW7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_COL1), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_COL2), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_COL3), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_COL4), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_COL5), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_COL6), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_BTN1), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_BACKLIGHT), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_TP_RESET), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_TP_MOTION), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_TP_SHUTDOWN), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/solderparty_rp2040_stamp/board.c b/ports/raspberrypi/boards/solderparty_rp2040_stamp/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/solderparty_rp2040_stamp/board.c +++ b/ports/raspberrypi/boards/solderparty_rp2040_stamp/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/board.c b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/board.c index eac54ce460..331653173e 100644 --- a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/board.c +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/board.c @@ -26,18 +26,4 @@ #include "supervisor/board.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/board.c b/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/board.c index eac54ce460..331653173e 100644 --- a/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/board.c +++ b/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/board.c @@ -26,18 +26,4 @@ #include "supervisor/board.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/board.c b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/board.c index eac54ce460..331653173e 100644 --- a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/board.c +++ b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/board.c @@ -26,18 +26,4 @@ #include "supervisor/board.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" - -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/board.c b/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/mpconfigboard.h new file mode 100644 index 0000000000..901ae068dd --- /dev/null +++ b/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/mpconfigboard.h @@ -0,0 +1,5 @@ +#define MICROPY_HW_BOARD_NAME "takayoshiotake Octave RP2040" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO12) +#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO11) diff --git a/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/mpconfigboard.mk b/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/mpconfigboard.mk new file mode 100644 index 0000000000..6a7234809c --- /dev/null +++ b/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x1209 +USB_PID = 0x8CAE +USB_PRODUCT = "Octave RP2040" +USB_MANUFACTURER = "takayoshiotake" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" diff --git a/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/pico-sdk-configboard.h @@ -0,0 +1,4 @@ +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/pins.c b/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/pins.c new file mode 100644 index 0000000000..4218f9cdea --- /dev/null +++ b/ports/raspberrypi/boards/takayoshiotake_octave_rp2040/pins.c @@ -0,0 +1,45 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GPIO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GPIO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GPIO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GPIO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GPIO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GPIO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GPIO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GPIO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GPIO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GPIO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GPIO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GPIO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GPIO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GPIO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GPIO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GPIO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GPIO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GPIO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GPIO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GPIO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GPIO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GPIO24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GPIO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GPIO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GPIO27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GPIO28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GPIO29), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_ADC0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_ADC1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_ADC2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_ADC3), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIX), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIX_POWER), MP_ROM_PTR(&pin_GPIO11) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/board.c b/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/board.c new file mode 100644 index 0000000000..76973aee30 --- /dev/null +++ b/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Fabian Affolter + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/mpconfigboard.h new file mode 100644 index 0000000000..83875289d5 --- /dev/null +++ b/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/mpconfigboard.h @@ -0,0 +1,4 @@ +#define MICROPY_HW_BOARD_NAME "VCC-GND Studio YD RP2040" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO23) diff --git a/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/mpconfigboard.mk b/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/mpconfigboard.mk new file mode 100644 index 0000000000..a42b251903 --- /dev/null +++ b/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x2E8A +USB_PID = 0x102E +USB_PRODUCT = "YD-RP2040" +USB_MANUFACTURER = "VCC-GND Studio" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ,W25Q32JVxQ,W25Q128JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/pins.c b/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/pins.c new file mode 100644 index 0000000000..c2b39dd740 --- /dev/null +++ b/ports/raspberrypi/boards/vcc_gnd_yd_rp2040/pins.c @@ -0,0 +1,56 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_RGB), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/board.c b/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/mpconfigboard.h b/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/mpconfigboard.h new file mode 100644 index 0000000000..db90970b7f --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/mpconfigboard.h @@ -0,0 +1,2 @@ +#define MICROPY_HW_BOARD_NAME "Waveshare RP2040-LCD-1.28" +#define MICROPY_HW_MCU_NAME "rp2040" diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/mpconfigboard.mk b/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/mpconfigboard.mk new file mode 100644 index 0000000000..8c5c9f5f50 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x2E8A +USB_PID = 0x1039 +USB_PRODUCT = "Waveshare RP2040-LCD-1.28" +USB_MANUFACTURER = "Waveshare Electronics" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" + +CIRCUITPY__EVE = 1 + +# TODO: Add custom QMI8658 driver +# FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython_qmi8658 + +# TODO: Add custom GC9A01 driver +# FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython_gc9a01 diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/pico-sdk-configboard.h b/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/pins.c b/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/pins.c new file mode 100644 index 0000000000..9153e8f78a --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_1_28/pins.c @@ -0,0 +1,70 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_SDA), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_SCL), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_DIN), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + + + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_INT1), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_INT2), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO29) }, // Battery voltage readout, 0.50 bias +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/waveshare_rp2040_zero/board.c b/ports/raspberrypi/boards/waveshare_rp2040_zero/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/waveshare_rp2040_zero/board.c +++ b/ports/raspberrypi/boards/waveshare_rp2040_zero/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/weact_studio_pico/board.c b/ports/raspberrypi/boards/weact_studio_pico/board.c index e992ec063c..76973aee30 100644 --- a/ports/raspberrypi/boards/weact_studio_pico/board.c +++ b/ports/raspberrypi/boards/weact_studio_pico/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/weact_studio_pico_16mb/board.c b/ports/raspberrypi/boards/weact_studio_pico_16mb/board.c new file mode 100644 index 0000000000..76973aee30 --- /dev/null +++ b/ports/raspberrypi/boards/weact_studio_pico_16mb/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Fabian Affolter + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/weact_studio_pico_16mb/mpconfigboard.h b/ports/raspberrypi/boards/weact_studio_pico_16mb/mpconfigboard.h new file mode 100644 index 0000000000..2dabc3eb1b --- /dev/null +++ b/ports/raspberrypi/boards/weact_studio_pico_16mb/mpconfigboard.h @@ -0,0 +1,2 @@ +#define MICROPY_HW_BOARD_NAME "WeAct Studio Pico 16MB" +#define MICROPY_HW_MCU_NAME "rp2040" diff --git a/ports/raspberrypi/boards/weact_studio_pico_16mb/mpconfigboard.mk b/ports/raspberrypi/boards/weact_studio_pico_16mb/mpconfigboard.mk new file mode 100644 index 0000000000..55209e1eb4 --- /dev/null +++ b/ports/raspberrypi/boards/weact_studio_pico_16mb/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x239A +USB_PID = 0x102E +USB_PRODUCT = "Pico" +USB_MANUFACTURER = "WeAct Studio" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/weact_studio_pico_16mb/pico-sdk-configboard.h b/ports/raspberrypi/boards/weact_studio_pico_16mb/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/weact_studio_pico_16mb/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/weact_studio_pico_16mb/pins.c b/ports/raspberrypi/boards/weact_studio_pico_16mb/pins.c new file mode 100644 index 0000000000..8632d9c322 --- /dev/null +++ b/ports/raspberrypi/boards/weact_studio_pico_16mb/pins.c @@ -0,0 +1,53 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/board.c b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/board.c index de6e424ed9..331653173e 100644 --- a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/board.c +++ b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/board.c @@ -26,15 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/board.c b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.h b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.h new file mode 100644 index 0000000000..00faa83742 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.h @@ -0,0 +1,9 @@ +#define MICROPY_HW_BOARD_NAME "W5500-EVB-Pico" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO16) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk new file mode 100644 index 0000000000..3789a76e0b --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x2E8A +USB_PID = 0x1029 +USB_PRODUCT = "W5500-EVB-Pico" +USB_MANUFACTURER = "WIZnet" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pico-sdk-configboard.h b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c new file mode 100644 index 0000000000..87ff27fa46 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c @@ -0,0 +1,54 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/zrichard_rp2.65-f/board.c b/ports/raspberrypi/boards/zrichard_rp2.65-f/board.c index 635e767a8f..aa189002ba 100644 --- a/ports/raspberrypi/boards/zrichard_rp2.65-f/board.c +++ b/ports/raspberrypi/boards/zrichard_rp2.65-f/board.c @@ -29,17 +29,9 @@ #include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" #include "supervisor/shared/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { // turn off any left over LED board_reset_user_neopixels(&pin_GPIO25, 62); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/common-hal/alarm/SleepMemory.c b/ports/raspberrypi/common-hal/alarm/SleepMemory.c index c1765296dc..1f0dddfc51 100644 --- a/ports/raspberrypi/common-hal/alarm/SleepMemory.c +++ b/ports/raspberrypi/common-hal/alarm/SleepMemory.c @@ -34,7 +34,6 @@ void alarm_sleep_memory_reset(void) { } uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) { - mp_raise_NotImplementedError(translate("Sleep Memory not available")); return 0; } diff --git a/ports/raspberrypi/common-hal/alarm/SleepMemory.h b/ports/raspberrypi/common-hal/alarm/SleepMemory.h index 59d0429c3b..14848cd5a0 100644 --- a/ports/raspberrypi/common-hal/alarm/SleepMemory.h +++ b/ports/raspberrypi/common-hal/alarm/SleepMemory.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM_SLEEPMEMORY_H -#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM_SLEEPMEMORY_H +#pragma once #include "py/obj.h" @@ -34,5 +33,3 @@ typedef struct { } alarm_sleep_memory_obj_t; extern void alarm_sleep_memory_reset(void); - -#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM_SLEEPMEMORY_H diff --git a/ports/raspberrypi/common-hal/alarm/__init__.c b/ports/raspberrypi/common-hal/alarm/__init__.c index 0d6734568b..f6d36f702e 100644 --- a/ports/raspberrypi/common-hal/alarm/__init__.c +++ b/ports/raspberrypi/common-hal/alarm/__init__.c @@ -38,6 +38,10 @@ #include "shared-bindings/microcontroller/__init__.h" +#if CIRCUITPY_CYW43 +#include "bindings/cyw43/__init__.h" +#endif + #include "supervisor/port.h" #include "supervisor/shared/workflow.h" @@ -92,6 +96,10 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = { }, }; +// Non-heap alarm object recording alarm (if any) that woke up CircuitPython after light or deep sleep. +// This object lives across VM instantiations, so none of these objects can contain references to the heap. +alarm_wake_alarm_union_t alarm_wake_alarm; + void alarm_reset(void) { alarm_sleep_memory_reset(); alarm_pin_pinalarm_reset(); @@ -127,17 +135,17 @@ bool common_hal_alarm_woken_from_sleep(void) { return _get_wakeup_cause() != RP_SLEEP_WAKEUP_UNDEF; } -mp_obj_t common_hal_alarm_create_wake_alarm(void) { +mp_obj_t common_hal_alarm_record_wake_alarm(void) { // If woken from deep sleep, create a copy alarm similar to what would have // been passed in originally. Otherwise, just return none uint8_t cause = _get_wakeup_cause(); switch (cause) { case RP_SLEEP_WAKEUP_RTC: { - return alarm_time_timealarm_create_wakeup_alarm(); + return alarm_time_timealarm_record_wake_alarm(); } case RP_SLEEP_WAKEUP_GPIO: { - return alarm_pin_pinalarm_create_wakeup_alarm(); + return alarm_pin_pinalarm_record_wake_alarm(); } case RP_SLEEP_WAKEUP_UNDEF: @@ -194,13 +202,20 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj return wake_alarm; } -void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { +void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t **preserve_dios) { + if (n_dios > 0) { + mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_preserve_dios); + } _setup_sleep_alarms(true, n_alarms, alarms); } void NORETURN common_hal_alarm_enter_deep_sleep(void) { bool timealarm_set = alarm_time_timealarm_is_set(); + #if CIRCUITPY_CYW43 + cyw43_enter_deep_sleep(); + #endif + // If there's a timealarm, just enter a very deep light sleep if (timealarm_set) { // Prune the clock for sleep @@ -219,6 +234,9 @@ void NORETURN common_hal_alarm_enter_deep_sleep(void) { // Reset uses the watchdog. Use scratch registers to store wake reason watchdog_hw->scratch[RP_WKUP_SCRATCH_REG] = _get_wakeup_cause(); + + // Just before reset, enable the pinalarm interrupt. + alarm_pin_pinalarm_entering_deep_sleep(); reset_cpu(); } diff --git a/ports/raspberrypi/common-hal/alarm/__init__.h b/ports/raspberrypi/common-hal/alarm/__init__.h index 3d5d86f8dc..284e3ddb4e 100644 --- a/ports/raspberrypi/common-hal/alarm/__init__.h +++ b/ports/raspberrypi/common-hal/alarm/__init__.h @@ -24,10 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM__INIT__H -#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM__INIT__H +#pragma once #include "common-hal/alarm/SleepMemory.h" +#include "common-hal/alarm/pin/PinAlarm.h" +#include "common-hal/alarm/time/TimeAlarm.h" #include "hardware/regs/clocks.h" @@ -35,8 +36,12 @@ #define RP_SLEEP_WAKEUP_GPIO 1 #define RP_SLEEP_WAKEUP_RTC 2 +typedef union { + alarm_pin_pinalarm_obj_t pin_alarm; + alarm_time_timealarm_obj_t time_alarm; +} alarm_wake_alarm_union_t; + +extern alarm_wake_alarm_union_t alarm_wake_alarm; extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; extern void alarm_reset(void); - -#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM__INIT__H diff --git a/ports/raspberrypi/common-hal/alarm/coproc/CoprocAlarm.c b/ports/raspberrypi/common-hal/alarm/coproc/CoprocAlarm.c new file mode 100644 index 0000000000..4bd8276f34 --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/coproc/CoprocAlarm.c @@ -0,0 +1 @@ +// empty file diff --git a/ports/raspberrypi/common-hal/alarm/coproc/CoprocAlarm.h b/ports/raspberrypi/common-hal/alarm/coproc/CoprocAlarm.h new file mode 100644 index 0000000000..4bd8276f34 --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/coproc/CoprocAlarm.h @@ -0,0 +1 @@ +// empty file diff --git a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c index 53cbfca57b..93b8ff3165 100644 --- a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c +++ b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c @@ -26,10 +26,10 @@ #include "py/runtime.h" +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/microcontroller/__init__.h" #include "common-hal/microcontroller/__init__.h" -#include "shared-bindings/microcontroller/Pin.h" #include "pico/stdlib.h" #include "hardware/gpio.h" @@ -38,7 +38,7 @@ STATIC bool woke_up; STATIC uint64_t alarm_triggered_pins; // 36 actual pins STATIC uint64_t alarm_reserved_pins; // 36 actual pins -STATIC bool _pinalarm_set = false; +STATIC bool _not_yet_deep_sleeping = false; #define GPIO_IRQ_ALL_EVENTS 0x15u @@ -46,12 +46,21 @@ STATIC void gpio_callback(uint gpio, uint32_t events) { alarm_triggered_pins |= (1 << gpio); woke_up = true; - // does this need to be called, to prevent IRQ from constantly going off? - gpio_acknowledge_irq(gpio, events); + // gpio_acknowledge_irq(gpio, events) is called automatically, before this callback is called. - // Disable IRQ automatically - gpio_set_irq_enabled(gpio, events, false); - gpio_set_dormant_irq_enabled(gpio, events, false); + if (_not_yet_deep_sleeping) { + // Event went off prematurely, before we went to sleep, so set it again. + gpio_set_irq_enabled(gpio, events, false); + } else { + // Went off during sleep. + // Disable IRQ automatically. + gpio_set_irq_enabled(gpio, events, false); + gpio_set_dormant_irq_enabled(gpio, events, false); + } +} + +void alarm_pin_pinalarm_entering_deep_sleep() { + _not_yet_deep_sleeping = false; } void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, const mcu_pin_obj_t *pin, bool value, bool edge, bool pull) { @@ -94,10 +103,12 @@ mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t return mp_const_none; } -mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) { - alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t); +mp_obj_t alarm_pin_pinalarm_record_wake_alarm(void) { + alarm_pin_pinalarm_obj_t *const alarm = &alarm_wake_alarm.pin_alarm; + alarm->base.type = &alarm_pin_pinalarm_type; // TODO: how to obtain the correct pin from memory? + alarm->pin = NULL; return alarm; } @@ -111,7 +122,7 @@ void alarm_pin_pinalarm_reset(void) { } // Reset pins and pin IRQs - for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) { + for (size_t i = 0; i < NUM_BANK0_GPIOS; i++) { if (alarm_reserved_pins & (1 << i)) { gpio_set_irq_enabled(i, GPIO_IRQ_ALL_EVENTS, false); reset_pin_number(i); @@ -154,11 +165,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob gpio_set_dormant_irq_enabled((uint)alarm->pin->number, event, true); } - _pinalarm_set = true; + _not_yet_deep_sleeping = true; } } } - -bool alarm_pin_pinalarm_is_set(void) { - return _pinalarm_set; -} diff --git a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h index d31ac6c878..26c6c49a5e 100644 --- a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h +++ b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h @@ -24,9 +24,13 @@ * THE SOFTWARE. */ +#pragma once + #include "py/obj.h" #include "py/objtuple.h" +#include "shared-bindings/microcontroller/Pin.h" + typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *pin; @@ -36,10 +40,10 @@ typedef struct { } alarm_pin_pinalarm_obj_t; mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void); +mp_obj_t alarm_pin_pinalarm_record_wake_alarm(void); void alarm_pin_pinalarm_reset(void); void alarm_pin_pinalarm_light_reset(void); void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); bool alarm_pin_pinalarm_woke_this_cycle(void); -bool alarm_pin_pinalarm_is_set(void); +void alarm_pin_pinalarm_entering_deep_sleep(void); diff --git a/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c index 16ac8fc31e..9bfe5cf262 100644 --- a/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c +++ b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c @@ -26,6 +26,7 @@ #include "py/runtime.h" +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/time/__init__.h" @@ -58,12 +59,13 @@ mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj return mp_const_none; } -mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) { - alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t); - timer->base.type = &alarm_time_timealarm_type; +mp_obj_t alarm_time_timealarm_record_wake_alarm(void) { + alarm_time_timealarm_obj_t *const alarm = &alarm_wake_alarm.time_alarm; + + alarm->base.type = &alarm_time_timealarm_type; // TODO: Set monotonic_time based on the RTC state. - timer->monotonic_time = 0.0f; - return timer; + alarm->monotonic_time = 0.0f; + return alarm; } bool alarm_time_timealarm_woke_this_cycle(void) { diff --git a/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h index d5248551ae..0b4c8bce06 100644 --- a/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h +++ b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#pragma once #include "py/obj.h" @@ -33,7 +34,7 @@ typedef struct { } alarm_time_timealarm_obj_t; mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void); +mp_obj_t alarm_time_timealarm_record_wake_alarm(void); void alarm_time_timealarm_reset(void); void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); diff --git a/ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.h b/ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.h index f631293511..6badde145f 100644 --- a/ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.h +++ b/ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H -#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H +#pragma once #include "py/obj.h" #include "common-hal/microcontroller/Pin.h" @@ -34,5 +33,3 @@ typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *pin; } alarm_touch_touchalarm_obj_t; - -#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H diff --git a/ports/raspberrypi/common-hal/analogbufio/BufferedIn.c b/ports/raspberrypi/common-hal/analogbufio/BufferedIn.c new file mode 100644 index 0000000000..bc5f9028b7 --- /dev/null +++ b/ports/raspberrypi/common-hal/analogbufio/BufferedIn.c @@ -0,0 +1,190 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2022 Lee Atkinson, MeanStride Technology, Inc. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. + * https://github.com/raspberrypi/pico-examples/blob/master/adc/dma_capture/dma_capture.c + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "common-hal/analogbufio/BufferedIn.h" +#include "shared-bindings/analogbufio/BufferedIn.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared/runtime/interrupt_char.h" +#include "py/runtime.h" +#include "supervisor/shared/translate/translate.h" +#include "src/rp2_common/hardware_adc/include/hardware/adc.h" +#include "src/rp2_common/hardware_dma/include/hardware/dma.h" +#include "src/common/pico_stdlib/include/pico/stdlib.h" + +#define ADC_FIRST_PIN_NUMBER 26 +#define ADC_PIN_COUNT 4 + +#define ADC_CLOCK_INPUT 48000000 +#define ADC_MAX_CLOCK_DIV (1 << (ADC_DIV_INT_MSB - ADC_DIV_INT_LSB + 1)) + +void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *self, const mcu_pin_obj_t *pin, uint32_t sample_rate) { + // Make sure pin number is in range for ADC + if (pin->number < ADC_FIRST_PIN_NUMBER || pin->number >= (ADC_FIRST_PIN_NUMBER + ADC_PIN_COUNT)) { + raise_ValueError_invalid_pins(); + } + + // Validate sample rate here + sample_rate = (uint32_t)mp_arg_validate_int_range(sample_rate, ADC_CLOCK_INPUT / ADC_MAX_CLOCK_DIV, ADC_CLOCK_INPUT / 96, MP_QSTR_sample_rate); + + // Set pin and channel + self->pin = pin; + claim_pin(pin); + + // TODO: find a way to accept ADC4 for temperature + self->chan = pin->number - ADC_FIRST_PIN_NUMBER; + + // Init GPIO for analogue use: hi-Z, no pulls, disable digital input buffer. + // TODO: Make sure we share the ADC well. Right now we just assume it is + // unused. + adc_init(); + adc_gpio_init(pin->number); + adc_select_input(self->chan); // chan = pin - 26 ?? + + // Divisor of 0 -> full speed. Free-running capture with the divider is + // equivalent to pressing the ADC_CS_START_ONCE button once per `div + 1` + // cycles (div not necessarily an integer). Each conversion takes 96 + // cycles, so in general you want a divider of 0 (hold down the button + // continuously) or > 95 (take samples less frequently than 96 cycle + // intervals). This is all timed by the 48 MHz ADC clock. + // sample rate determines divisor, not zero. + + // sample_rate is forced to be >= 1 in shared-bindings + float clk_div = (float)ADC_CLOCK_INPUT / (float)sample_rate; + adc_set_clkdiv(clk_div); + + // Set up the DMA to start transferring data as soon as it appears in FIFO + uint dma_chan = dma_claim_unused_channel(true); + self->dma_chan = dma_chan; + + // Set Config + self->cfg = dma_channel_get_default_config(dma_chan); + + // Reading from constant address, writing to incrementing byte addresses + channel_config_set_read_increment(&(self->cfg), false); + channel_config_set_write_increment(&(self->cfg), true); + + // Pace transfers based on availability of ADC samples + channel_config_set_dreq(&(self->cfg), DREQ_ADC); + + // clear any previous activity + adc_fifo_drain(); + adc_run(false); +} + +bool common_hal_analogbufio_bufferedin_deinited(analogbufio_bufferedin_obj_t *self) { + return self->pin == NULL; +} + +void common_hal_analogbufio_bufferedin_deinit(analogbufio_bufferedin_obj_t *self) { + if (common_hal_analogbufio_bufferedin_deinited(self)) { + return; + } + + // Release ADC Pin + reset_pin_number(self->pin->number); + self->pin = NULL; + + // Release DMA Channel + dma_channel_unclaim(self->dma_chan); +} + +uint32_t common_hal_analogbufio_bufferedin_readinto(analogbufio_bufferedin_obj_t *self, uint8_t *buffer, uint32_t len, uint8_t bytes_per_sample) { + // RP2040 Implementation Detail + // Fills the supplied buffer with ADC values using DMA transfer. + // If the buffer is 8-bit, then values are 8-bit shifted and error bit is off. + // If buffer is 16-bit, then values are 12-bit and error bit is present. We + // stretch the 12-bit value to 16-bits and truncate the number of valid + // samples at the first sample with the error bit set. + // Number of transfers is always the number of samples which is the array + // byte length divided by the bytes_per_sample. + uint dma_size = DMA_SIZE_8; + bool show_error_bit = false; + if (bytes_per_sample == 2) { + dma_size = DMA_SIZE_16; + show_error_bit = true; + } + + adc_fifo_setup( + true, // Write each completed conversion to the sample FIFO + true, // Enable DMA data request (DREQ) + 1, // DREQ (and IRQ) asserted when at least 1 sample present + show_error_bit, // See the ERR bit + bytes_per_sample == 1 // Shift each sample to 8 bits when pushing to FIFO + ); + + uint32_t sample_count = len / bytes_per_sample; + + channel_config_set_transfer_data_size(&(self->cfg), dma_size); + + dma_channel_configure(self->dma_chan, &(self->cfg), + buffer, // dst + &adc_hw->fifo, // src + sample_count, // transfer count + true // start immediately + ); + + // Start the ADC + adc_run(true); + + // Once DMA finishes, stop any new conversions from starting, and clean up + // the FIFO in case the ADC was still mid-conversion. + uint32_t remaining_transfers = sample_count; + while (dma_channel_is_busy(self->dma_chan) && + !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + } + remaining_transfers = dma_channel_hw_addr(self->dma_chan)->transfer_count; + + // Clean up + adc_run(false); + // Stopping early so abort. + if (dma_channel_is_busy(self->dma_chan)) { + dma_channel_abort(self->dma_chan); + } + adc_fifo_drain(); + + size_t captured_count = sample_count - remaining_transfers; + if (dma_size == DMA_SIZE_16) { + uint16_t *buf16 = (uint16_t *)buffer; + for (size_t i = 0; i < captured_count; i++) { + uint16_t value = buf16[i]; + // Check the error bit and "truncate" the buffer if there is an error. + if ((value & ADC_FIFO_ERR_BITS) != 0) { + captured_count = i; + break; + } + // Scale the values to the standard 16 bit range. + buf16[i] = (value << 4) | (value >> 8); + } + } + return captured_count; +} diff --git a/ports/raspberrypi/common-hal/analogbufio/BufferedIn.h b/ports/raspberrypi/common-hal/analogbufio/BufferedIn.h new file mode 100644 index 0000000000..8ed4cf3a2c --- /dev/null +++ b/ports/raspberrypi/common-hal/analogbufio/BufferedIn.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2022 Lee Atkinson, MeanStride Technology, Inc. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. + * https://github.com/raspberrypi/pico-examples/blob/master/adc/dma_capture/dma_capture.c + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ANALOGBUFIO_BUFFEREDIN_H +#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ANALOGBUFIO_BUFFEREDIN_H + +#include "common-hal/microcontroller/Pin.h" +#include "src/rp2_common/hardware_dma/include/hardware/dma.h" + +#include "py/obj.h" + +// This is the analogbufio object +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; + uint8_t chan; + uint dma_chan; + dma_channel_config cfg; +} analogbufio_bufferedin_obj_t; + +#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ANALOGBUFIO_BUFFEREDIN_H diff --git a/ports/raspberrypi/common-hal/analogbufio/__init__.c b/ports/raspberrypi/common-hal/analogbufio/__init__.c new file mode 100644 index 0000000000..b6c74b985b --- /dev/null +++ b/ports/raspberrypi/common-hal/analogbufio/__init__.c @@ -0,0 +1 @@ +// No analogbufio module functions. diff --git a/ports/raspberrypi/common-hal/analogio/AnalogIn.c b/ports/raspberrypi/common-hal/analogio/AnalogIn.c index b827068e1a..afa31e3c83 100644 --- a/ports/raspberrypi/common-hal/analogio/AnalogIn.c +++ b/ports/raspberrypi/common-hal/analogio/AnalogIn.c @@ -26,6 +26,7 @@ #include "common-hal/analogio/AnalogIn.h" #include "shared-bindings/analogio/AnalogIn.h" +#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "py/runtime.h" #include "supervisor/shared/translate/translate.h" @@ -35,16 +36,31 @@ #define ADC_FIRST_PIN_NUMBER 26 #define ADC_PIN_COUNT 4 +// Voltage monitor is special on Pico W, because this pin is shared between the +// voltage monitor function and the wifi function. Special handling is required +// to read the analog voltage. +#if CIRCUITPY_CYW43 +#include "bindings/cyw43/__init__.h" +#define SPECIAL_PIN(pin) (pin->number == 29) + +const mcu_pin_obj_t *common_hal_analogio_analogin_validate_pin(mp_obj_t obj) { + return validate_obj_is_free_pin_or_gpio29(obj, MP_QSTR_pin); +} +#else +#define SPECIAL_PIN(pin) false +#endif + void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const mcu_pin_obj_t *pin) { if (pin->number < ADC_FIRST_PIN_NUMBER || pin->number > ADC_FIRST_PIN_NUMBER + ADC_PIN_COUNT) { raise_ValueError_invalid_pin(); } adc_init(); + if (!SPECIAL_PIN(pin)) { + adc_gpio_init(pin->number); + claim_pin(pin); + } - adc_gpio_init(pin->number); - - claim_pin(pin); self->pin = pin; } @@ -57,14 +73,30 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { return; } - reset_pin_number(self->pin->number); + if (!SPECIAL_PIN(self->pin)) { + reset_pin_number(self->pin->number); + } self->pin = NULL; } uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { - adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER); - uint16_t value = adc_read(); - + uint16_t value; + if (SPECIAL_PIN(self->pin)) { + common_hal_mcu_disable_interrupts(); + uint32_t old_pad = padsbank0_hw->io[self->pin->number]; + uint32_t old_ctrl = iobank0_hw->io[self->pin->number].ctrl; + adc_gpio_init(self->pin->number); + adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER); + common_hal_mcu_delay_us(100); + value = adc_read(); + gpio_init(self->pin->number); + padsbank0_hw->io[self->pin->number] = old_pad; + iobank0_hw->io[self->pin->number].ctrl = old_ctrl; + common_hal_mcu_enable_interrupts(); + } else { + adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER); + value = adc_read(); + } // Stretch 12-bit ADC reading to 16-bit range return (value << 4) | (value >> 8); } diff --git a/ports/raspberrypi/common-hal/busio/I2C.c b/ports/raspberrypi/common-hal/busio/I2C.c index 6b15bee512..c68499591c 100644 --- a/ports/raspberrypi/common-hal/busio/I2C.c +++ b/ports/raspberrypi/common-hal/busio/I2C.c @@ -190,7 +190,7 @@ STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return status; } - int result = i2c_write_timeout_us(self->peripheral, addr, data, len, !transmit_stop_bit, BUS_TIMEOUT_US); + size_t result = i2c_write_timeout_us(self->peripheral, addr, data, len, !transmit_stop_bit, BUS_TIMEOUT_US); if (result == len) { return 0; } @@ -211,7 +211,7 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { - int result = i2c_read_timeout_us(self->peripheral, addr, data, len, false, BUS_TIMEOUT_US); + size_t result = i2c_read_timeout_us(self->peripheral, addr, data, len, false, BUS_TIMEOUT_US); if (result == len) { return 0; } diff --git a/ports/raspberrypi/common-hal/busio/SPI.c b/ports/raspberrypi/common-hal/busio/SPI.c index a7b97823f9..67323790bf 100644 --- a/ports/raspberrypi/common-hal/busio/SPI.c +++ b/ports/raspberrypi/common-hal/busio/SPI.c @@ -151,6 +151,15 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, spi_set_format(self->peripheral, bits, polarity, phase, SPI_MSB_FIRST); + // Workaround to start with clock line high if polarity=1. The hw SPI peripheral does not do this + // automatically. See https://github.com/raspberrypi/pico-sdk/issues/868 and + // https://forums.raspberrypi.com/viewtopic.php?t=336142 + // TODO: scheduled to be be fixed in pico-sdk 1.5.0. + if (polarity) { + hw_clear_bits(&spi_get_hw(self->peripheral)->cr1, SPI_SSPCR1_SSE_BITS); // disable the SPI + hw_set_bits(&spi_get_hw(self->peripheral)->cr1, SPI_SSPCR1_SSE_BITS); // re-enable the SPI + } + self->polarity = polarity; self->phase = phase; self->bits = bits; diff --git a/ports/raspberrypi/common-hal/busio/UART.c b/ports/raspberrypi/common-hal/busio/UART.c index c06bb21903..156a5e11ce 100644 --- a/ports/raspberrypi/common-hal/busio/UART.c +++ b/ports/raspberrypi/common-hal/busio/UART.c @@ -111,7 +111,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uint8_t uart_id = ((((tx != NULL) ? tx->number : rx->number) + 4) / 8) % NUM_UARTS; if (uart_status[uart_id] != STATUS_FREE) { - mp_raise_RuntimeError(translate("All UART peripherals are in use")); + mp_raise_ValueError(translate("UART peripheral in use")); } // These may raise exceptions if pins are already in use. self->tx_pin = pin_init(uart_id, tx, 0); @@ -155,27 +155,33 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uart_set_hw_flow(self->uart, (cts != NULL), (rts != NULL)); if (rx != NULL) { - // Initially allocate the UART's buffer in the long-lived part of the - // heap. UARTs are generally long-lived objects, but the "make long- - // lived" machinery is incapable of moving internal pointers like - // self->buffer, so do it manually. (However, as long as internal - // pointers like this are NOT moved, allocating the buffer - // in the long-lived pool is not strictly necessary) - // (This is a macro.) - if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { - m_malloc_fail(receiver_buffer_size); - } - active_uarts[uart_id] = self; - if (uart_id == 1) { - self->uart_irq_id = UART1_IRQ; - irq_set_exclusive_handler(self->uart_irq_id, uart1_callback); + // Use the provided buffer when given. + if (receiver_buffer != NULL) { + ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); } else { - self->uart_irq_id = UART0_IRQ; - irq_set_exclusive_handler(self->uart_irq_id, uart0_callback); + // Initially allocate the UART's buffer in the long-lived part of the + // heap. UARTs are generally long-lived objects, but the "make long- + // lived" machinery is incapable of moving internal pointers like + // self->buffer, so do it manually. (However, as long as internal + // pointers like this are NOT moved, allocating the buffer + // in the long-lived pool is not strictly necessary) + if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { + uart_deinit(self->uart); + m_malloc_fail(receiver_buffer_size); + } } - irq_set_enabled(self->uart_irq_id, true); - uart_set_irq_enables(self->uart, true /* rx has data */, false /* tx needs data */); } + + active_uarts[uart_id] = self; + if (uart_id == 1) { + self->uart_irq_id = UART1_IRQ; + irq_set_exclusive_handler(self->uart_irq_id, uart1_callback); + } else { + self->uart_irq_id = UART0_IRQ; + irq_set_exclusive_handler(self->uart_irq_id, uart0_callback); + } + irq_set_enabled(self->uart_irq_id, true); + uart_set_irq_enables(self->uart, true /* rx has data */, false /* tx needs data */); } bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { @@ -187,7 +193,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { return; } uart_deinit(self->uart); - ringbuf_free(&self->ringbuf); + ringbuf_deinit(&self->ringbuf); active_uarts[self->uart_id] = NULL; uart_status[self->uart_id] = STATUS_FREE; reset_pin_number(self->tx_pin); @@ -333,3 +339,18 @@ bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { } return uart_is_writable(self->uart); } + +STATIC void pin_never_reset(uint8_t pin) { + if (pin != NO_PIN) { + never_reset_pin_number(pin); + } +} + +void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) { + never_reset_uart(self->uart_id); + pin_never_reset(self->tx_pin); + pin_never_reset(self->rx_pin); + pin_never_reset(self->cts_pin); + pin_never_reset(self->rs485_dir_pin); + pin_never_reset(self->rts_pin); +} diff --git a/ports/raspberrypi/common-hal/countio/Counter.c b/ports/raspberrypi/common-hal/countio/Counter.c index 44db126656..b51d182c3a 100644 --- a/ports/raspberrypi/common-hal/countio/Counter.c +++ b/ports/raspberrypi/common-hal/countio/Counter.c @@ -31,7 +31,6 @@ void common_hal_countio_counter_construct(countio_counter_obj_t *self, mp_raise_RuntimeError(translate("PWM slice already in use")); } - uint8_t ab_channel = pwm_gpio_to_channel(self->pin); if (!pwmio_claim_slice_ab_channels(self->slice_num)) { mp_raise_RuntimeError(translate("PWM slice channel A already in use")); } diff --git a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c index ef431d8506..d90c0db81b 100644 --- a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +++ b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c @@ -31,11 +31,22 @@ #include "py/mphal.h" #include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/digitalio/DigitalInOut.h" #include "supervisor/shared/translate/translate.h" #include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#if CIRCUITPY_CYW43 +#include "pico/cyw43_arch.h" +#include "bindings/cyw43/__init__.h" +#define IS_CYW(self) ((self)->pin->base.type == &cyw43_pin_type) + +const mcu_pin_obj_t *common_hal_digitalio_validate_pin(mp_obj_t obj) { + return validate_obj_is_free_pin_including_cyw43(obj, MP_QSTR_pin); +} +#endif + digitalinout_result_t common_hal_digitalio_digitalinout_construct( digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin) { claim_pin(pin); @@ -43,6 +54,12 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct( self->output = false; self->open_drain = false; + #if CIRCUITPY_CYW43 + if (IS_CYW(self)) { + return DIGITALINOUT_OK; + } + #endif + // Set to input. No output value. gpio_init(pin->number); return DIGITALINOUT_OK; @@ -61,20 +78,31 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self if (common_hal_digitalio_digitalinout_deinited(self)) { return; } - reset_pin_number(self->pin->number); + common_hal_reset_pin(self->pin); self->pin = NULL; } -void common_hal_digitalio_digitalinout_switch_to_input( +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { - self->output = false; // This also sets direction to input. - common_hal_digitalio_digitalinout_set_pull(self, pull); + return common_hal_digitalio_digitalinout_set_pull(self, pull); } digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( digitalio_digitalinout_obj_t *self, bool value, digitalio_drive_mode_t drive_mode) { + + #if CIRCUITPY_CYW43 + if (IS_CYW(self)) { + if (drive_mode != DRIVE_MODE_PUSH_PULL) { + return DIGITALINOUT_INVALID_DRIVE_MODE; + } + cyw43_arch_gpio_put(self->pin->number, value); + self->output = true; + self->open_drain = false; + return DIGITALINOUT_OK; + } + #endif const uint8_t pin = self->pin->number; gpio_disable_pulls(pin); @@ -99,6 +127,12 @@ digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( void common_hal_digitalio_digitalinout_set_value( digitalio_digitalinout_obj_t *self, bool value) { const uint8_t pin = self->pin->number; + #if CIRCUITPY_CYW43 + if (IS_CYW(self)) { + cyw43_arch_gpio_put(pin, value); + return; + } + #endif if (self->open_drain && value) { // If true and open-drain, set the direction -before- setting // the pin value, to to avoid a high glitch on the pin before @@ -116,13 +150,24 @@ void common_hal_digitalio_digitalinout_set_value( bool common_hal_digitalio_digitalinout_get_value( digitalio_digitalinout_obj_t *self) { + #if CIRCUITPY_CYW43 + if (IS_CYW(self)) { + return cyw43_arch_gpio_get(self->pin->number); + } + #endif return gpio_get(self->pin->number); } digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode( digitalio_digitalinout_obj_t *self, digitalio_drive_mode_t drive_mode) { - const uint8_t pin = self->pin->number; + #if CIRCUITPY_CYW43 + if (IS_CYW(self)) { + if (drive_mode != DRIVE_MODE_PUSH_PULL) { + return DIGITALINOUT_INVALID_DRIVE_MODE; + } + } + #endif bool value = common_hal_digitalio_digitalinout_get_value(self); self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; // True is implemented differently between modes so reset the value to make @@ -142,11 +187,23 @@ digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( } } -void common_hal_digitalio_digitalinout_set_pull( +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + #if CIRCUITPY_CYW43 + if (IS_CYW(self)) { + if (pull != PULL_NONE) { + return DIGITALINOUT_INVALID_PULL; + } + cyw43_arch_gpio_get(self->pin->number); + self->output = false; + return DIGITALINOUT_OK; + } + #endif const uint8_t pin = self->pin->number; gpio_set_pulls(pin, pull == PULL_UP, pull == PULL_DOWN); gpio_set_dir(pin, GPIO_IN); + self->output = false; + return DIGITALINOUT_OK; } digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( @@ -170,6 +227,11 @@ bool common_hal_digitalio_has_reg_op(digitalinout_reg_op_t op) { } volatile uint32_t *common_hal_digitalio_digitalinout_get_reg(digitalio_digitalinout_obj_t *self, digitalinout_reg_op_t op, uint32_t *mask) { + #if CIRCUITPY_CYW43 + if (IS_CYW(self)) { + return NULL; + } + #endif const uint8_t pin = self->pin->number; *mask = 1u << pin; diff --git a/ports/raspberrypi/common-hal/hashlib/Hash.c b/ports/raspberrypi/common-hal/hashlib/Hash.c new file mode 100644 index 0000000000..046bd3f096 --- /dev/null +++ b/ports/raspberrypi/common-hal/hashlib/Hash.c @@ -0,0 +1,57 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/hashlib/Hash.h" + +#include "mbedtls/ssl.h" + +void common_hal_hashlib_hash_update(hashlib_hash_obj_t *self, const uint8_t *data, size_t datalen) { + if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) { + mbedtls_sha1_update_ret(&self->sha1, data, datalen); + return; + } +} + +void common_hal_hashlib_hash_digest(hashlib_hash_obj_t *self, uint8_t *data, size_t datalen) { + if (datalen < common_hal_hashlib_hash_get_digest_size(self)) { + return; + } + if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) { + // We copy the sha1 state so we can continue to update if needed or get + // the digest a second time. + mbedtls_sha1_context copy; + mbedtls_sha1_clone(©, &self->sha1); + mbedtls_sha1_finish_ret(&self->sha1, data); + mbedtls_sha1_clone(&self->sha1, ©); + } +} + +size_t common_hal_hashlib_hash_get_digest_size(hashlib_hash_obj_t *self) { + if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) { + return 20; + } + return 0; +} diff --git a/ports/raspberrypi/common-hal/hashlib/Hash.h b/ports/raspberrypi/common-hal/hashlib/Hash.h new file mode 100644 index 0000000000..9792538e0a --- /dev/null +++ b/ports/raspberrypi/common-hal/hashlib/Hash.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "mbedtls/sha1.h" + +typedef struct { + mp_obj_base_t base; + union { + mbedtls_sha1_context sha1; + }; + // Of MBEDTLS_SSL_HASH_* + uint8_t hash_type; +} hashlib_hash_obj_t; diff --git a/ports/raspberrypi/common-hal/hashlib/__init__.c b/ports/raspberrypi/common-hal/hashlib/__init__.c new file mode 100644 index 0000000000..1ad116ea6c --- /dev/null +++ b/ports/raspberrypi/common-hal/hashlib/__init__.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/hashlib/__init__.h" + +#include "mbedtls/ssl.h" + + +bool common_hal_hashlib_new(hashlib_hash_obj_t *self, const char *algorithm) { + if (strcmp(algorithm, "sha1") == 0) { + self->hash_type = MBEDTLS_SSL_HASH_SHA1; + mbedtls_sha1_init(&self->sha1); + mbedtls_sha1_starts_ret(&self->sha1); + return true; + } + return false; +} diff --git a/ports/raspberrypi/common-hal/hashlib/__init__.h b/ports/raspberrypi/common-hal/hashlib/__init__.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c b/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c new file mode 100644 index 0000000000..fc9bf55327 --- /dev/null +++ b/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c @@ -0,0 +1,152 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Mark Komus, Ken Stillson, im-redactd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/i2ctarget/I2CTarget.h" + +#include "common-hal/busio/I2C.h" + +#include "py/mperrno.h" +#include "py/mphal.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "py/runtime.h" + +#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" + +STATIC i2c_inst_t *i2c[2] = {i2c0, i2c1}; + +#define NO_PIN 0xff + +void common_hal_i2ctarget_i2c_target_construct(i2ctarget_i2c_target_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, + uint8_t *addresses, unsigned int num_addresses, bool smbus) { + self->peripheral = NULL; + + // I2C pins have a regular pattern. SCL is always odd and SDA is even. They match up in pairs + // so we can divide by two to get the instance. This pattern repeats. + size_t scl_instance = (scl->number / 2) % 2; + size_t sda_instance = (sda->number / 2) % 2; + if (scl->number % 2 == 1 && sda->number % 2 == 0 && scl_instance == sda_instance) { + self->peripheral = i2c[sda_instance]; + } + + if (self->peripheral == NULL) { + raise_ValueError_invalid_pins(); + } + + if ((i2c_get_hw(self->peripheral)->enable & I2C_IC_ENABLE_ENABLE_BITS) != 0) { + mp_raise_ValueError(translate("I2C peripheral in use")); + } + + if (num_addresses > 1) { + mp_raise_ValueError(translate("Only one address is allowed")); + } + + self->addresses = addresses; + self->num_addresses = num_addresses; + self->scl_pin = scl->number; + self->sda_pin = sda->number; + + // Have to specify a baudrate even if the i2c target does not use it + const uint32_t frequency = 400000; + i2c_init(self->peripheral, frequency); + + gpio_set_function(sda->number, GPIO_FUNC_I2C); + gpio_set_function(scl->number, GPIO_FUNC_I2C); + + gpio_set_pulls(sda->number, true, false); + gpio_set_pulls(scl->number, true, false); + + self->peripheral->hw->intr_mask |= I2C_IC_INTR_MASK_M_RESTART_DET_BITS; + i2c_set_slave_mode(self->peripheral, true, self->addresses[0]); + + return; +} + +bool common_hal_i2ctarget_i2c_target_deinited(i2ctarget_i2c_target_obj_t *self) { + return self->sda_pin == NO_PIN; +} + +void common_hal_i2ctarget_i2c_target_deinit(i2ctarget_i2c_target_obj_t *self) { + if (common_hal_i2ctarget_i2c_target_deinited(self)) { + return; + } + + i2c_deinit(self->peripheral); + + reset_pin_number(self->sda_pin); + reset_pin_number(self->scl_pin); + self->sda_pin = NO_PIN; + self->scl_pin = NO_PIN; + + return; +} + +int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart) { + if (!((self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS) || (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RD_REQ_BITS))) { + return 0; + } + + *address = self->peripheral->hw->sar; + *is_read = !(self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS); + *is_restart = ((self->peripheral->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_RD_REQ_RESET) != 0); + + common_hal_i2ctarget_i2c_target_ack(self, true); + return 1; +} + +int common_hal_i2ctarget_i2c_target_read_byte(i2ctarget_i2c_target_obj_t *self, uint8_t *data) { + if (self->peripheral->hw->status & I2C_IC_STATUS_RFNE_BITS) { + *data = (uint8_t)self->peripheral->hw->data_cmd; + return 1; + } else { + return 0; + } +} + +int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self, uint8_t data) { + if (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_TX_ABRT_BITS) { + self->peripheral->hw->clr_tx_abrt; + } + + const size_t IC_TX_BUFFER_DEPTH = 16; + size_t space = IC_TX_BUFFER_DEPTH - self->peripheral->hw->txflr; + + if (space > 0) { + self->peripheral->hw->data_cmd = data; + self->peripheral->hw->clr_rd_req; + return 1; + } else { + return 0; + } +} + +void common_hal_i2ctarget_i2c_target_ack(i2ctarget_i2c_target_obj_t *self, bool ack) { + return; +} + +void common_hal_i2ctarget_i2c_target_close(i2ctarget_i2c_target_obj_t *self) { + return; +} diff --git a/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.h b/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.h new file mode 100644 index 0000000000..b47c51fbbb --- /dev/null +++ b/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Mark Komus, Ken Stillson, im-redactd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_RPI_COMMON_HAL_I2C_TARGET_H +#define MICROPY_INCLUDED_RPI_COMMON_HAL_I2C_TARGET_H + +#include "py/obj.h" +#include "common-hal/microcontroller/Pin.h" +#include "src/rp2_common/hardware_i2c/include/hardware/i2c.h" + +typedef struct { + mp_obj_base_t base; + + uint8_t *addresses; + unsigned int num_addresses; + + i2c_inst_t *peripheral; + + uint8_t scl_pin; + uint8_t sda_pin; +} i2ctarget_i2c_target_obj_t; + +#endif MICROPY_INCLUDED_RPI_COMMON_HAL_BUSIO_I2C_TARGET_H diff --git a/ports/raspberrypi/common-hal/i2ctarget/__init__.c b/ports/raspberrypi/common-hal/i2ctarget/__init__.c new file mode 100644 index 0000000000..4ec26465ad --- /dev/null +++ b/ports/raspberrypi/common-hal/i2ctarget/__init__.c @@ -0,0 +1 @@ +// No i2ctarget module functions. diff --git a/ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c b/ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c index 3c5c57eea5..7ad6acbaff 100644 --- a/ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c +++ b/ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c @@ -120,11 +120,6 @@ void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_paralle true, 32, true, // in settings false, // Not user-interruptible. 2, 5); // wrap settings - - - PIO pio = self->state_machine.pio; - uint8_t pio_index = pio_get_index(pio); - uint sm = self->state_machine.state_machine; } void common_hal_imagecapture_parallelimagecapture_deinit(imagecapture_parallelimagecapture_obj_t *self) { diff --git a/ports/raspberrypi/common-hal/mdns/RemoteService.c b/ports/raspberrypi/common-hal/mdns/RemoteService.c new file mode 100644 index 0000000000..071a9c1648 --- /dev/null +++ b/ports/raspberrypi/common-hal/mdns/RemoteService.c @@ -0,0 +1,64 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/mdns/RemoteService.h" + +#include "shared-bindings/ipaddress/IPv4Address.h" + +const char *common_hal_mdns_remoteservice_get_service_type(mdns_remoteservice_obj_t *self) { + return self->service_name; +} + +const char *common_hal_mdns_remoteservice_get_protocol(mdns_remoteservice_obj_t *self) { + return self->protocol; +} + +const char *common_hal_mdns_remoteservice_get_instance_name(mdns_remoteservice_obj_t *self) { + return self->instance_name; +} + +const char *common_hal_mdns_remoteservice_get_hostname(mdns_remoteservice_obj_t *self) { + return self->hostname; +} + +mp_int_t common_hal_mdns_remoteservice_get_port(mdns_remoteservice_obj_t *self) { + return self->port; +} + +uint32_t mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self) { + return self->ipv4_address; +} + +mp_obj_t common_hal_mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self) { + uint32_t addr = mdns_remoteservice_get_ipv4_address(self); + if (addr == 0) { + return mp_const_none; + } + return common_hal_ipaddress_new_ipv4address(addr); +} + +void common_hal_mdns_remoteservice_deinit(mdns_remoteservice_obj_t *self) { +} diff --git a/ports/raspberrypi/common-hal/mdns/RemoteService.h b/ports/raspberrypi/common-hal/mdns/RemoteService.h new file mode 100644 index 0000000000..06814f0fbb --- /dev/null +++ b/ports/raspberrypi/common-hal/mdns/RemoteService.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "lwip/apps/mdns.h" + +typedef struct { + mp_obj_base_t base; + uint32_t ipv4_address; + uint16_t port; + char protocol[5]; // RFC 6763 Section 7.2 - 4 bytes + 1 for NUL + char service_name[17]; // RFC 6763 Section 7.2 - 16 bytes + 1 for NUL + char instance_name[64]; // RFC 6763 Section 7.2 - 63 bytes + 1 for NUL + char hostname[64]; // RFC 6762 Appendix A - 63 bytes for label + 1 for NUL + mp_obj_t next; +} mdns_remoteservice_obj_t; diff --git a/ports/raspberrypi/common-hal/mdns/Server.c b/ports/raspberrypi/common-hal/mdns/Server.c new file mode 100644 index 0000000000..ab0a7079af --- /dev/null +++ b/ports/raspberrypi/common-hal/mdns/Server.c @@ -0,0 +1,322 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/mdns/Server.h" + +#include "py/gc.h" +#include "py/runtime.h" +#include "shared/runtime/interrupt_char.h" +#include "shared-bindings/mdns/RemoteService.h" +#include "shared-bindings/wifi/__init__.h" +#include "supervisor/shared/tick.h" + +#include "lwip/apps/mdns.h" +#include "lwip/prot/dns.h" + +// Track if we've inited the LWIP MDNS at all. It expects to only init once. +// Subsequent times, we restart it. +STATIC bool inited = false; +// Track if we are globally inited. This essentially forces one inited MDNS +// object at a time. (But ignores MDNS objects that are deinited.) +STATIC bool object_inited = false; + +#define NETIF_STA (&cyw43_state.netif[CYW43_ITF_STA]) +#define NETIF_AP (&cyw43_state.netif[CYW43_ITF_AP]) + +void mdns_server_construct(mdns_server_obj_t *self, bool workflow) { + if (object_inited) { + // Mark the object as deinit since another is already using MDNS. + self->inited = false; + return; + } + + if (!inited) { + mdns_resp_init(); + inited = true; + } else { + mdns_resp_restart(NETIF_STA); + } + self->inited = true; + + uint8_t mac[6]; + wifi_radio_get_mac_address(&common_hal_wifi_radio_obj, mac); + snprintf(self->default_hostname, sizeof(self->default_hostname), "cpy-%02x%02x%02x", mac[3], mac[4], mac[5]); + common_hal_mdns_server_set_hostname(self, self->default_hostname); + + if (workflow) { + // Add a second host entry to respond to "circuitpython.local" queries as well. + + #if MDNS_MAX_SECONDARY_HOSTNAMES > 0 + mdns_resp_add_secondary_hostname(NETIF_STA, "circuitpython"); + #endif + } +} + +void common_hal_mdns_server_construct(mdns_server_obj_t *self, mp_obj_t network_interface) { + if (network_interface != MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj)) { + mp_raise_ValueError(translate("mDNS only works with built-in WiFi")); + return; + } + if (object_inited) { + mp_raise_RuntimeError(translate("mDNS already initialized")); + } + mdns_server_construct(self, false); +} + +void common_hal_mdns_server_deinit(mdns_server_obj_t *self) { + if (common_hal_mdns_server_deinited(self)) { + return; + } + self->inited = false; + object_inited = false; + mdns_resp_remove_netif(NETIF_STA); +} + +bool common_hal_mdns_server_deinited(mdns_server_obj_t *self) { + return !self->inited; +} + +const char *common_hal_mdns_server_get_hostname(mdns_server_obj_t *self) { + return self->hostname; +} + +void common_hal_mdns_server_set_hostname(mdns_server_obj_t *self, const char *hostname) { + if (mdns_resp_netif_active(NETIF_STA)) { + mdns_resp_rename_netif(NETIF_STA, hostname); + } else { + mdns_resp_add_netif(NETIF_STA, hostname); + } + + self->hostname = hostname; +} + +const char *common_hal_mdns_server_get_instance_name(mdns_server_obj_t *self) { + return self->instance_name; +} + +void common_hal_mdns_server_set_instance_name(mdns_server_obj_t *self, const char *instance_name) { + self->instance_name = instance_name; +} + +typedef struct { + uint8_t request_id; + size_t i; + mdns_remoteservice_obj_t *out; + size_t out_len; +} nonalloc_search_state_t; + +STATIC void copy_data_into_remote_service(struct mdns_answer *answer, const char *varpart, int varlen, mdns_remoteservice_obj_t *out) { + if (varlen > 0) { + if (answer->info.type == DNS_RRTYPE_A) { + char *hostname = out->hostname; + size_t len = MIN(63, answer->info.domain.name[0]); + memcpy(hostname, answer->info.domain.name + 1, len); + hostname[len] = '\0'; + out->ipv4_address = varpart[0] | varpart[1] << 8 | varpart[2] << 16 | varpart[3] << 24; + } + if (answer->info.type == DNS_RRTYPE_SRV) { + // This isn't a null terminated string. Its length encoded. + uint8_t *domain = answer->info.domain.name; + char *instance_name = out->instance_name; + size_t offset = 0; + uint8_t iname_len = domain[offset++]; + size_t len = MIN(63, iname_len); + memcpy(instance_name, domain + offset, len); + offset += iname_len; + instance_name[len] = '\0'; + + uint8_t sn_len = domain[offset++]; + char *service_name = out->service_name; + len = MIN(16, sn_len); + memcpy(service_name, domain + offset, len); + offset += sn_len; + service_name[len] = '\0'; + + uint8_t proto_len = domain[offset++]; + char *protocol = out->protocol; + len = MIN(4, proto_len); + memcpy(protocol, domain + offset, len); + offset += proto_len; + protocol[len] = '\0'; + + out->port = varpart[4] << 8 | varpart[5]; + } + } +} + +STATIC void search_result_cb(struct mdns_answer *answer, const char *varpart, int varlen, int flags, void *arg) { + nonalloc_search_state_t *state = arg; + state->out[state->i].base.type = &mdns_remoteservice_type; + + copy_data_into_remote_service(answer, varpart, varlen, &state->out[state->i]); + + if ((flags & MDNS_SEARCH_RESULT_LAST) != 0) { + state->i += 1; + } + + if (state->i == state->out_len) { + mdns_search_stop(state->request_id); + state->request_id = MDNS_MAX_REQUESTS; + } +} + +size_t mdns_server_find(mdns_server_obj_t *self, const char *service_type, const char *protocol, + mp_float_t timeout, mdns_remoteservice_obj_t *out, size_t out_len) { + + enum mdns_sd_proto proto = DNSSD_PROTO_UDP; + if (strcmp(protocol, "_tcp") == 0) { + proto = DNSSD_PROTO_TCP; + } + + nonalloc_search_state_t state; + state.i = 0; + state.out = out; + state.out_len = out_len; + + err_t err = mdns_search_service(NULL, service_type, proto, + NETIF_STA, &search_result_cb, &state, + &state.request_id); + if (err != ERR_OK) { + return 0; + } + + uint64_t start_ticks = supervisor_ticks_ms64(); + uint64_t timeout_ms = timeout * 1000; + + while (state.request_id < MDNS_MAX_REQUESTS && + !mp_hal_is_interrupted() && + supervisor_ticks_ms64() - start_ticks < timeout_ms) { + RUN_BACKGROUND_TASKS; + } + if (state.request_id < MDNS_MAX_REQUESTS) { + mdns_search_stop(state.request_id); + state.request_id = MDNS_MAX_REQUESTS; + } + + return state.i; +} + +typedef struct { + uint8_t request_id; + mdns_remoteservice_obj_t *head; + size_t count; +} alloc_search_state_t; + +STATIC void alloc_search_result_cb(struct mdns_answer *answer, const char *varpart, int varlen, int flags, void *arg) { + alloc_search_state_t *state = arg; + + if ((flags & MDNS_SEARCH_RESULT_FIRST) != 0) { + // first + mdns_remoteservice_obj_t *service = gc_alloc(sizeof(mdns_remoteservice_obj_t), 0, false); + if (service == NULL) { + // alloc fails + mdns_search_stop(state->request_id); + state->request_id = MDNS_MAX_REQUESTS; + if (state->count == 0) { + m_malloc_fail(sizeof(mdns_remoteservice_obj_t)); + } + return; + } + service->base.type = &mdns_remoteservice_type; + state->count++; + service->next = state->head; + state->head = service; + } + + copy_data_into_remote_service(answer, varpart, varlen, state->head); +} + +mp_obj_t common_hal_mdns_server_find(mdns_server_obj_t *self, const char *service_type, const char *protocol, mp_float_t timeout) { + enum mdns_sd_proto proto = DNSSD_PROTO_UDP; + if (strcmp(protocol, "_tcp") == 0) { + proto = DNSSD_PROTO_TCP; + } + + alloc_search_state_t state; + state.count = 0; + state.head = NULL; + + err_t err = mdns_search_service(NULL, service_type, proto, + NETIF_STA, &alloc_search_result_cb, &state, + &state.request_id); + if (err != ERR_OK) { + mp_raise_RuntimeError(translate("Unable to start mDNS query")); + } + + uint64_t start_ticks = supervisor_ticks_ms64(); + uint64_t timeout_ms = timeout * 1000; + + while (state.request_id < MDNS_MAX_REQUESTS && + !mp_hal_is_interrupted() && + supervisor_ticks_ms64() - start_ticks < timeout_ms) { + RUN_BACKGROUND_TASKS; + } + if (state.request_id < MDNS_MAX_REQUESTS) { + mdns_search_stop(state.request_id); + state.request_id = MDNS_MAX_REQUESTS; + } + + mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(state.count, NULL)); + mdns_remoteservice_obj_t *next = state.head; + uint8_t added = 0; + while (next != NULL) { + mdns_remoteservice_obj_t *cur = next; + tuple->items[added] = MP_OBJ_FROM_PTR(cur); + next = cur->next; + // Set next back to NULL so that each service object is independently + // tracked for GC. + cur->next = NULL; + added++; + } + + return MP_OBJ_FROM_PTR(tuple); +} + +void common_hal_mdns_server_advertise_service(mdns_server_obj_t *self, const char *service_type, const char *protocol, mp_int_t port) { + enum mdns_sd_proto proto = DNSSD_PROTO_UDP; + if (strcmp(protocol, "_tcp") == 0) { + proto = DNSSD_PROTO_TCP; + } + // Remove the existing service if it was already added. + int8_t existing_slot = MDNS_MAX_SERVICES; + for (int i = 0; i < MDNS_MAX_SERVICES; i++) { + if (self->service_type[i] != NULL && + (service_type == self->service_type[i] || + strcmp(service_type, self->service_type[i]) == 0)) { + existing_slot = i; + break; + } + } + if (existing_slot < MDNS_MAX_SERVICES) { + mdns_resp_del_service(NETIF_STA, existing_slot); + } + int8_t slot = mdns_resp_add_service(NETIF_STA, self->instance_name, service_type, proto, port, NULL, NULL); + if (slot < 0) { + mp_raise_RuntimeError(translate("Out of MDNS service slots")); + return; + } + self->service_type[slot] = service_type; +} diff --git a/shared-bindings/dotenv/__init__.h b/ports/raspberrypi/common-hal/mdns/Server.h similarity index 77% rename from shared-bindings/dotenv/__init__.h rename to ports/raspberrypi/common-hal/mdns/Server.h index 18a6c280dd..a4dab8aa06 100644 --- a/shared-bindings/dotenv/__init__.h +++ b/ports/raspberrypi/common-hal/mdns/Server.h @@ -24,16 +24,18 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DOTENV___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_DOTENV___INIT___H +#pragma once -#include -#include +#include "py/obj.h" -#include "py/objtuple.h" +#include "lwip/apps/mdns_opts.h" -#include "shared-module/dotenv/__init__.h" - -mp_obj_t common_hal_dotenv_get_key(const char *path, const char *key); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DOTENV___INIT___H +typedef struct { + mp_obj_base_t base; + const char *hostname; + const char *instance_name; + char default_hostname[sizeof("cpy-XXXXXX")]; + const char *service_type[MDNS_MAX_SERVICES]; + // Track if this object owns access to the underlying MDNS service. + bool inited; +} mdns_server_obj_t; diff --git a/ports/raspberrypi/common-hal/mdns/__init__.c b/ports/raspberrypi/common-hal/mdns/__init__.c new file mode 100644 index 0000000000..57740777c8 --- /dev/null +++ b/ports/raspberrypi/common-hal/mdns/__init__.c @@ -0,0 +1 @@ +// No mdns module functions. diff --git a/ports/raspberrypi/common-hal/microcontroller/Pin.c b/ports/raspberrypi/common-hal/microcontroller/Pin.c index d40c1f43b5..f0a9a7c29c 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Pin.c +++ b/ports/raspberrypi/common-hal/microcontroller/Pin.c @@ -31,19 +31,40 @@ #include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#if CIRCUITPY_CYW43 +#include "bindings/cyw43/__init__.h" +#include "pico/cyw43_arch.h" + +bool cyw_ever_init; +static uint32_t cyw_pin_claimed; + +void reset_pin_number_cyw(uint8_t pin_no) { + cyw_pin_claimed &= ~(1 << pin_no); +} +#endif + STATIC uint32_t never_reset_pins; void reset_all_pins(void) { - for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) { + for (size_t i = 0; i < NUM_BANK0_GPIOS; i++) { if ((never_reset_pins & (1 << i)) != 0) { continue; } reset_pin_number(i); } + #if CIRCUITPY_CYW43 + if (cyw_ever_init) { + // reset LED and SMPS_MODE to Low; don't touch VBUS_SENSE + // otherwise it is switched to output mode forever! + cyw43_arch_gpio_put(0, 0); + cyw43_arch_gpio_put(1, 0); + } + cyw_pin_claimed = 0; + #endif } void never_reset_pin_number(uint8_t pin_number) { - if (pin_number >= TOTAL_GPIO_COUNT) { + if (pin_number >= NUM_BANK0_GPIOS) { return; } @@ -51,7 +72,7 @@ void never_reset_pin_number(uint8_t pin_number) { } void reset_pin_number(uint8_t pin_number) { - if (pin_number >= TOTAL_GPIO_COUNT) { + if (pin_number >= NUM_BANK0_GPIOS) { return; } @@ -71,15 +92,26 @@ void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) { } void common_hal_reset_pin(const mcu_pin_obj_t *pin) { + #if CIRCUITPY_CYW43 + if (pin->base.type == &cyw43_pin_type) { + reset_pin_number_cyw(pin->number); + return; + } + #endif reset_pin_number(pin->number); } void claim_pin(const mcu_pin_obj_t *pin) { + #if CIRCUITPY_CYW43 + if (pin->base.type == &cyw43_pin_type) { + cyw_pin_claimed |= (1 << pin->number); + } + #endif // Nothing to do because all changes will set the GPIO settings. } bool pin_number_is_free(uint8_t pin_number) { - if (pin_number >= TOTAL_GPIO_COUNT) { + if (pin_number >= NUM_BANK0_GPIOS) { return false; } @@ -89,6 +121,11 @@ bool pin_number_is_free(uint8_t pin_number) { } bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { + #if CIRCUITPY_CYW43 + if (pin->base.type == &cyw43_pin_type) { + return !(cyw_pin_claimed & (1 << pin->number)); + } + #endif return pin_number_is_free(pin->number); } diff --git a/ports/raspberrypi/common-hal/microcontroller/Pin.h b/ports/raspberrypi/common-hal/microcontroller/Pin.h index 3e2287dc5d..1c400fe48e 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Pin.h +++ b/ports/raspberrypi/common-hal/microcontroller/Pin.h @@ -42,4 +42,9 @@ void never_reset_pin_number(uint8_t pin_number); void claim_pin(const mcu_pin_obj_t *pin); bool pin_number_is_free(uint8_t pin_number); +#if CIRCUITPY_CYW43 +extern bool cyw_ever_init; +void reset_pin_number_cyw(uint8_t pin_number); +#endif + #endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/raspberrypi/common-hal/microcontroller/Processor.c b/ports/raspberrypi/common-hal/microcontroller/Processor.c index 8c5bc7ba75..b22d385eec 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Processor.c +++ b/ports/raspberrypi/common-hal/microcontroller/Processor.c @@ -34,6 +34,7 @@ #include "src/rp2_common/hardware_adc/include/hardware/adc.h" #include "src/rp2_common/hardware_clocks/include/hardware/clocks.h" +#include "src/rp2_common/hardware_watchdog/include/hardware/watchdog.h" #include "src/rp2040/hardware_regs/include/hardware/regs/vreg_and_chip_reset.h" #include "src/rp2040/hardware_regs/include/hardware/regs/watchdog.h" @@ -68,7 +69,6 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { mcu_reset_reason_t reason = RESET_REASON_UNKNOWN; - uint32_t watchdog_reset_reg = watchdog_hw->reason; uint32_t chip_reset_reg = vreg_and_chip_reset_hw->chip_reset; if (chip_reset_reg & VREG_AND_CHIP_RESET_CHIP_RESET_HAD_PSM_RESTART_BITS) { @@ -86,13 +86,14 @@ mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { // Check watchdog after chip reset since watchdog doesn't clear chip_reset, while chip_reset clears the watchdog - if (watchdog_reset_reg & WATCHDOG_REASON_TIMER_BITS) { - // This bit can also be set during a software reset because the pico-sdk performs a software reset by setting an extremely low timeout on the watchdog, rather than triggering a watchdog reset manually - reason = RESET_REASON_WATCHDOG; + // The watchdog is used for software reboots such as resetting after copying a UF2 via the bootloader. + if (watchdog_caused_reboot()) { + reason = RESET_REASON_SOFTWARE; } - if (watchdog_reset_reg & WATCHDOG_REASON_FORCE_BITS) { - reason = RESET_REASON_SOFTWARE; + // Actual watchdog usage will set a special value that this function detects. + if (watchdog_enable_caused_reboot()) { + reason = RESET_REASON_WATCHDOG; } return reason; diff --git a/ports/raspberrypi/common-hal/microcontroller/__init__.c b/ports/raspberrypi/common-hal/microcontroller/__init__.c index 3b656edc07..6d9b3d7fa0 100644 --- a/ports/raspberrypi/common-hal/microcontroller/__init__.c +++ b/ports/raspberrypi/common-hal/microcontroller/__init__.c @@ -60,7 +60,7 @@ void common_hal_mcu_disable_interrupts(void) { void common_hal_mcu_enable_interrupts(void) { if (nesting_count == 0) { - // reset_into_safe_mode(LOCKING_ERROR); + // reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); } nesting_count--; if (nesting_count > 0) { @@ -79,7 +79,7 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { next_reset_to_bootloader = true; break; case RUNMODE_SAFE_MODE: - safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE); + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); break; default: break; @@ -149,7 +149,7 @@ watchdog_watchdogtimer_obj_t common_hal_mcu_watchdogtimer_obj = { #endif // This maps MCU pin names to pin objects. -const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = { +const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) }, { MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_GPIO1) }, { MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) }, @@ -173,12 +173,33 @@ const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = { { MP_ROM_QSTR(MP_QSTR_GPIO20), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_GPIO21), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_GPIO22), MP_ROM_PTR(&pin_GPIO22) }, + #if !defined(IGNORE_GPIO23) { MP_ROM_QSTR(MP_QSTR_GPIO23), MP_ROM_PTR(&pin_GPIO23) }, + #endif + #if !defined(IGNORE_GPIO24) { MP_ROM_QSTR(MP_QSTR_GPIO24), MP_ROM_PTR(&pin_GPIO24) }, + #endif + #if !defined(IGNORE_GPIO25) { MP_ROM_QSTR(MP_QSTR_GPIO25), MP_ROM_PTR(&pin_GPIO25) }, + #endif { MP_ROM_QSTR(MP_QSTR_GPIO26), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_GPIO27), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_GPIO28), MP_ROM_PTR(&pin_GPIO28) }, { MP_ROM_QSTR(MP_QSTR_GPIO29), MP_ROM_PTR(&pin_GPIO29) }, + #if CIRCUITPY_CYW43 + { MP_ROM_QSTR(MP_QSTR_CYW0), MP_ROM_PTR(&pin_CYW0) }, + { MP_ROM_QSTR(MP_QSTR_CYW1), MP_ROM_PTR(&pin_CYW1) }, + { MP_ROM_QSTR(MP_QSTR_CYW2), MP_ROM_PTR(&pin_CYW2) }, + #endif }; MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table); + +const mcu_pin_obj_t *mcu_get_pin_by_number(int number) { + for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_pin_global_dict_table); i++) { + mcu_pin_obj_t *obj = MP_OBJ_TO_PTR(mcu_pin_global_dict_table[i].value); + if (obj->base.type == &mcu_pin_type && obj->number == number) { + return obj; + } + } + return NULL; +} diff --git a/ports/raspberrypi/common-hal/microcontroller/__init__.h b/ports/raspberrypi/common-hal/microcontroller/__init__.h index cc509b6b12..1154bf5e35 100644 --- a/ports/raspberrypi/common-hal/microcontroller/__init__.h +++ b/ports/raspberrypi/common-hal/microcontroller/__init__.h @@ -28,9 +28,8 @@ #define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER___INIT___H #include "src/rp2040/hardware_regs/include/hardware/platform_defs.h" +#include "peripherals/pins.h" -#define TOTAL_GPIO_COUNT NUM_BANK0_GPIOS - -extern const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT]; +const mcu_pin_obj_t *mcu_get_pin_by_number(int); #endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER___INIT___H diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c index e6f88f8894..7925a734fb 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.c +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.c @@ -89,20 +89,12 @@ void pwmout_never_reset(uint8_t slice, uint8_t ab_channel) { never_reset_channel |= _mask(slice, ab_channel); } -void pwmout_reset_ok(uint8_t slice, uint8_t ab_channel) { - never_reset_channel &= ~_mask(slice, ab_channel); -} - void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { pwmout_never_reset(self->slice, self->ab_channel); never_reset_pin_number(self->pin->number); } -void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { - pwmout_reset_ok(self->slice, self->ab_channel); -} - void pwmout_reset(void) { // Reset all slices for (size_t slice = 0; slice < NUM_PWM_SLICES; slice++) { @@ -236,14 +228,6 @@ extern void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t *self, uin } // compare_count is the CC register value, which should be TOP+1 for 100% duty cycle. pwm_set_chan_level(self->slice, self->ab_channel, compare_count); - // Wait for wrap so that we know our new cc value has been applied. Clear - // the internal interrupt and then wait for it to be set. Worst case, we - // wait a full cycle. - pwm_hw->intr = 1 << self->slice; - while ((pwm_hw->en & (1 << self->slice)) != 0 && - (pwm_hw->intr & (1 << self->slice)) == 0 && - !mp_hal_is_interrupted()) { - } } uint16_t common_hal_pwmio_pwmout_get_duty_cycle(pwmio_pwmout_obj_t *self) { diff --git a/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c b/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c index 0da12e5923..7cb4c84382 100644 --- a/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c @@ -61,12 +61,13 @@ STATIC void incrementalencoder_interrupt_handler(void *self_in); void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { - mp_obj_t pins[] = {MP_OBJ_FROM_PTR(pin_a), MP_OBJ_FROM_PTR(pin_b)}; + const mcu_pin_obj_t *pins[] = { pin_a, pin_b }; + // Start out with swapped to match behavior with other ports. self->swapped = true; if (!common_hal_rp2pio_pins_are_sequential(2, pins)) { - pins[0] = MP_OBJ_FROM_PTR(pin_b); - pins[1] = MP_OBJ_FROM_PTR(pin_a); + pins[0] = pin_b; + pins[1] = pin_a; self->swapped = false; if (!common_hal_rp2pio_pins_are_sequential(2, pins)) { mp_raise_RuntimeError(translate("Pins must be sequential GPIO pins")); diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c index 9e8d5feebc..e9cb3d34bb 100644 --- a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c +++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -48,7 +48,7 @@ #define NO_DMA_CHANNEL (-1) // Count how many state machines are using each pin. -STATIC uint8_t _pin_reference_count[TOTAL_GPIO_COUNT]; +STATIC uint8_t _pin_reference_count[NUM_BANK0_GPIOS]; STATIC uint32_t _current_program_id[NUM_PIOS][NUM_PIO_STATE_MACHINES]; STATIC uint8_t _current_program_offset[NUM_PIOS][NUM_PIO_STATE_MACHINES]; STATIC uint8_t _current_program_len[NUM_PIOS][NUM_PIO_STATE_MACHINES]; @@ -71,7 +71,7 @@ STATIC void *_interrupt_arg[NUM_PIOS][NUM_PIO_STATE_MACHINES]; STATIC void rp2pio_statemachine_interrupt_handler(void); static void rp2pio_statemachine_set_pull(uint32_t pull_pin_up, uint32_t pull_pin_down, uint32_t pins_we_use) { - for (int i = 0; i < TOTAL_GPIO_COUNT; i++) { + for (size_t i = 0; i < NUM_BANK0_GPIOS; i++) { bool used = pins_we_use & (1 << i); if (used) { bool pull_up = pull_pin_up & (1 << i); @@ -120,7 +120,7 @@ STATIC void _reset_statemachine(PIO pio, uint8_t sm, bool leave_pins) { } uint32_t pins = _current_sm_pins[pio_index][sm]; - for (size_t pin_number = 0; pin_number < TOTAL_GPIO_COUNT; pin_number++) { + for (size_t pin_number = 0; pin_number < NUM_BANK0_GPIOS; pin_number++) { if ((pins & (1 << pin_number)) == 0) { continue; } @@ -161,10 +161,14 @@ STATIC uint32_t _check_pins_free(const mcu_pin_obj_t *first_pin, uint8_t pin_cou if (first_pin != NULL) { for (size_t i = 0; i < pin_count; i++) { uint8_t pin_number = first_pin->number + i; - if (pin_number >= TOTAL_GPIO_COUNT) { + if (pin_number >= NUM_BANK0_GPIOS) { mp_raise_ValueError(translate("Pin count too large")); } - const mcu_pin_obj_t *pin = mcu_pin_global_dict_table[pin_number].value; + const mcu_pin_obj_t *pin = mcu_get_pin_by_number(pin_number); + if (!pin) { + mp_raise_ValueError_varg(translate("%q in use"), MP_QSTR_Pin); + } + if (exclusive_pin_use || _pin_reference_count[pin_number] == 0) { assert_pin_free(pin); } @@ -231,7 +235,7 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, program_offset = 32; } - int state_machine = -1; + size_t state_machine = NUM_PIO_STATE_MACHINES; if (pio_index < NUM_PIOS) { PIO pio = pio_instances[pio_index]; for (size_t i = 0; i < NUM_PIOS; i++) { @@ -269,12 +273,15 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, self->pull_pin_up = pull_pin_up; self->pull_pin_down = pull_pin_down; - for (size_t pin_number = 0; pin_number < TOTAL_GPIO_COUNT; pin_number++) { + for (size_t pin_number = 0; pin_number < NUM_BANK0_GPIOS; pin_number++) { if ((pins_we_use & (1 << pin_number)) == 0) { continue; } + const mcu_pin_obj_t *pin = mcu_get_pin_by_number(pin_number); + if (!pin) { + return false; + } _pin_reference_count[pin_number]++; - const mcu_pin_obj_t *pin = mcu_pin_global_dict_table[pin_number].value; // Also claim the pin at the top level when we're the first to grab it. if (_pin_reference_count[pin_number] == 1) { if (claim_pins) { @@ -282,6 +289,11 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, } pio_gpio_init(self->pio, pin_number); } + + // Use lowest drive level for all State Machine outputs. (#7515 + // workaround). Remove if/when Pin objects get a drive_strength + // property and use that value instead. + gpio_set_drive_strength(pin_number, GPIO_DRIVE_STRENGTH_2MA); } pio_sm_config c = {0, 0, 0}; @@ -369,6 +381,9 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, } static uint32_t mask_and_rotate(const mcu_pin_obj_t *first_pin, uint32_t bit_count, uint32_t value) { + if (!first_pin) { + return 0; + } value = value & ((1 << bit_count) - 1); uint32_t shift = first_pin->number; return value << shift | value >> (32 - shift); @@ -868,7 +883,7 @@ bool common_hal_rp2pio_statemachine_get_txstall(rp2pio_statemachine_obj_t *self) } void common_hal_rp2pio_statemachine_clear_txstall(rp2pio_statemachine_obj_t *self) { - uint8_t level = pio_sm_get_rx_fifo_level(self->pio, self->state_machine); + (void)pio_sm_get_rx_fifo_level(self->pio, self->state_machine); uint32_t stall_mask = 1 << (PIO_FDEBUG_TXSTALL_LSB + self->state_machine); self->pio->fdebug = stall_mask; } diff --git a/ports/raspberrypi/common-hal/rp2pio/__init__.c b/ports/raspberrypi/common-hal/rp2pio/__init__.c index 8b8101fbe5..7634001c98 100644 --- a/ports/raspberrypi/common-hal/rp2pio/__init__.c +++ b/ports/raspberrypi/common-hal/rp2pio/__init__.c @@ -28,13 +28,13 @@ #include "shared-bindings/microcontroller/Pin.h" #include "bindings/rp2pio/__init__.h" -bool common_hal_rp2pio_pins_are_sequential(size_t len, mp_obj_t *items) { +bool common_hal_rp2pio_pins_are_sequential(size_t len, const mcu_pin_obj_t **pins) { if (len == 0) { return true; } - const mcu_pin_obj_t *last_pin = validate_obj_is_pin(items[0]); - for (int i = 1; i < len; i++) { - const mcu_pin_obj_t *pin = validate_obj_is_pin(items[i]); + const mcu_pin_obj_t *last_pin = pins[0]; + for (size_t i = 1; i < len; i++) { + const mcu_pin_obj_t *pin = pins[i]; if (pin->number != last_pin->number + 1) { return false; } diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.c b/ports/raspberrypi/common-hal/socketpool/Socket.c new file mode 100644 index 0000000000..e2b82264ba --- /dev/null +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -0,0 +1,1269 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2019 Damien P. George + * Copyright (c) 2015 Galen Hazelwood + * Copyright (c) 2015-2017 Paul Sokolovsky + * Copyright (c) 2020 Lucian Copeland for Adafruit Industries + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/socketpool/Socket.h" + +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "shared-bindings/socketpool/SocketPool.h" +#include "shared/runtime/interrupt_char.h" +#include "shared/netutils/netutils.h" +#include "supervisor/port.h" +#include "supervisor/shared/tick.h" +#include "supervisor/workflow.h" + +#include "lwip/dns.h" +#include "lwip/err.h" +#include "lwip/igmp.h" +#include "lwip/init.h" +#include "lwip/netdb.h" +#include "lwip/priv/tcp_priv.h" +#include "lwip/raw.h" +#include "lwip/sys.h" +#include "lwip/tcp.h" +#include "lwip/timeouts.h" +#include "lwip/udp.h" + +#define MICROPY_PY_LWIP_SOCK_RAW (1) + +#if 0 // print debugging info +#define DEBUG_printf DEBUG_printf +#else // don't print debugging info +#define DEBUG_printf(...) (void)0 +#endif + +// Timeout between closing a TCP socket and doing a tcp_abort on that +// socket, if the connection isn't closed cleanly in that time. +#define MICROPY_PY_LWIP_TCP_CLOSE_TIMEOUT_MS (10000) + +// All socket options should be globally distinct, +// because we ignore option levels for efficiency. +#define IP_ADD_MEMBERSHIP 0x400 +#define IP_DROP_MEMBERSHIP 0x401 + +/******************************************************************************/ +// Table to convert lwIP err_t codes to socket errno codes, from the lwIP +// socket API. + +// Extension to lwIP error codes +// Matches lwIP 2.0.3 +#undef _ERR_BADF +#define _ERR_BADF -17 +static const int error_lookup_table[] = { + 0, /* ERR_OK 0 No error, everything OK */ + MP_ENOMEM, /* ERR_MEM -1 Out of memory error */ + MP_ENOBUFS, /* ERR_BUF -2 Buffer error */ + MP_EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ + MP_EHOSTUNREACH, /* ERR_RTE -4 Routing problem */ + MP_EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ + MP_EINVAL, /* ERR_VAL -6 Illegal value */ + MP_EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block */ + MP_EADDRINUSE, /* ERR_USE -8 Address in use */ + MP_EALREADY, /* ERR_ALREADY -9 Already connecting */ + MP_EALREADY, /* ERR_ISCONN -10 Conn already established */ + MP_ENOTCONN, /* ERR_CONN -11 Not connected */ + -1, /* ERR_IF -12 Low-level netif error */ + MP_ECONNABORTED, /* ERR_ABRT -13 Connection aborted */ + MP_ECONNRESET, /* ERR_RST -14 Connection reset */ + MP_ENOTCONN, /* ERR_CLSD -15 Connection closed */ + MP_EIO, /* ERR_ARG -16 Illegal argument. */ + MP_EBADF, /* _ERR_BADF -17 Closed socket (null pcb) */ +}; + +/*******************************************************************************/ +// The socket object provided by lwip.socket. + +#define MOD_NETWORK_AF_INET (SOCKETPOOL_AF_INET) +#define MOD_NETWORK_AF_INET6 (SOCKETPOOL_AF_INET6) + +#define MOD_NETWORK_SOCK_STREAM (SOCKETPOOL_SOCK_STREAM) +#define MOD_NETWORK_SOCK_DGRAM (SOCKETPOOL_SOCK_DGRAM) +#define MOD_NETWORK_SOCK_RAW (SOCKETPOOL_SOCK_RAW) + +#define MAX_SOCKETS (8) + +static inline void poll_sockets(void) { + #ifdef MICROPY_EVENT_POLL_HOOK + MICROPY_EVENT_POLL_HOOK; + #else + RUN_BACKGROUND_TASKS; + if (MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL) { + mp_handle_pending(true); + } + mp_hal_delay_ms(1); + #endif +} + +STATIC struct tcp_pcb *volatile *lwip_socket_incoming_array(socketpool_socket_obj_t *socket) { + if (socket->incoming.connection.alloc == 0) { + return &socket->incoming.connection.tcp.item; + } else { + return &socket->incoming.connection.tcp.array[0]; + } +} + +STATIC void lwip_socket_free_incoming(socketpool_socket_obj_t *socket) { + bool socket_is_listener = + socket->type == MOD_NETWORK_SOCK_STREAM + && socket->pcb.tcp->state == LISTEN; + + if (!socket_is_listener) { + if (socket->incoming.pbuf != NULL) { + pbuf_free(socket->incoming.pbuf); + socket->incoming.pbuf = NULL; + } + } else { + uint8_t alloc = socket->incoming.connection.alloc; + struct tcp_pcb *volatile *tcp_array = lwip_socket_incoming_array(socket); + for (uint8_t i = 0; i < alloc; ++i) { + // Deregister callback and abort + if (tcp_array[i] != NULL) { + tcp_poll(tcp_array[i], NULL, 0); + tcp_abort(tcp_array[i]); + tcp_array[i] = NULL; + } + } + } +} + +/*******************************************************************************/ +// Callback functions for the lwIP raw API. + +static inline void exec_user_callback(socketpool_socket_obj_t *socket) { + #if 0 + if (socket->callback != MP_OBJ_NULL) { + // Schedule the user callback to execute outside the lwIP context + mp_sched_schedule(socket->callback, MP_OBJ_FROM_PTR(socket)); + } + #endif + supervisor_workflow_request_background(); +} + +#if MICROPY_PY_LWIP_SOCK_RAW +// Callback for incoming raw packets. +#if LWIP_VERSION_MAJOR < 2 +STATIC u8_t _lwip_raw_incoming(void *arg, struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *addr) +#else +STATIC u8_t _lwip_raw_incoming(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) +#endif +{ + socketpool_socket_obj_t *socket = (socketpool_socket_obj_t *)arg; + + if (socket->incoming.pbuf != NULL) { + pbuf_free(p); + } else { + socket->incoming.pbuf = p; + memcpy(&socket->peer, addr, sizeof(socket->peer)); + } + return 1; // we ate the packet +} +#endif + +// Callback for incoming UDP packets. We simply stash the packet and the source address, +// in case we need it for recvfrom. +#if LWIP_VERSION_MAJOR < 2 +STATIC void _lwip_udp_incoming(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +#else +STATIC void _lwip_udp_incoming(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +#endif +{ + socketpool_socket_obj_t *socket = (socketpool_socket_obj_t *)arg; + + if (socket->incoming.pbuf != NULL) { + // That's why they call it "unreliable". No room in the inn, drop the packet. + pbuf_free(p); + } else { + socket->incoming.pbuf = p; + socket->peer_port = (mp_uint_t)port; + memcpy(&socket->peer, addr, sizeof(socket->peer)); + } +} + +// Callback for general tcp errors. +STATIC void _lwip_tcp_error(void *arg, err_t err) { + socketpool_socket_obj_t *socket = (socketpool_socket_obj_t *)arg; + + // Free any incoming buffers or connections that are stored + lwip_socket_free_incoming(socket); + // Pass the error code back via the connection variable. + socket->state = err; + // If we got here, the lwIP stack either has deallocated or will deallocate the pcb. + socket->pcb.tcp = NULL; +} + +// Callback for tcp connection requests. Error code err is unused. (See tcp.h) +STATIC err_t _lwip_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t err) { + socketpool_socket_obj_t *socket = (socketpool_socket_obj_t *)arg; + + socket->state = STATE_CONNECTED; + return ERR_OK; +} + +// Handle errors (eg connection aborted) on TCP PCBs that have been put on the +// accept queue but are not yet actually accepted. +STATIC void _lwip_tcp_err_unaccepted(void *arg, err_t err) { + struct tcp_pcb *pcb = (struct tcp_pcb *)arg; + + // The ->connected entry is repurposed to store the parent socket; this is safe + // because it's only ever used by lwIP if tcp_connect is called on the TCP PCB. + socketpool_socket_obj_t *socket = (socketpool_socket_obj_t *)pcb->connected; + + // Array is not volatile because thiss callback is executed within the lwIP context + uint8_t alloc = socket->incoming.connection.alloc; + struct tcp_pcb **tcp_array = (struct tcp_pcb **)lwip_socket_incoming_array(socket); + + // Search for PCB on the accept queue of the parent socket + struct tcp_pcb **shift_down = NULL; + uint8_t i = socket->incoming.connection.iget; + do { + if (shift_down == NULL) { + if (tcp_array[i] == pcb) { + shift_down = &tcp_array[i]; + } + } else { + *shift_down = tcp_array[i]; + shift_down = &tcp_array[i]; + } + if (++i >= alloc) { + i = 0; + } + } while (i != socket->incoming.connection.iput); + + // PCB found in queue, remove it + if (shift_down != NULL) { + *shift_down = NULL; + socket->incoming.connection.iput = shift_down - tcp_array; + } +} + +// By default, a child socket of listen socket is created with recv +// handler which discards incoming pbuf's. We don't want to do that, +// so set this handler which requests lwIP to keep pbuf's and deliver +// them later. We cannot cache pbufs in child socket on Python side, +// until it is created in accept(). +STATIC err_t _lwip_tcp_recv_unaccepted(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { + return ERR_BUF; +} + +// Callback for incoming tcp connections. +STATIC err_t _lwip_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { + // err can be ERR_MEM to notify us that there was no memory for an incoming connection + if (err != ERR_OK) { + return ERR_OK; + } + + socketpool_socket_obj_t *socket = (socketpool_socket_obj_t *)arg; + tcp_recv(newpcb, _lwip_tcp_recv_unaccepted); + + // Search for an empty slot to store the new connection + struct tcp_pcb *volatile *slot = &lwip_socket_incoming_array(socket)[socket->incoming.connection.iput]; + if (*slot == NULL) { + // Have an empty slot to store waiting connection + *slot = newpcb; + if (++socket->incoming.connection.iput >= socket->incoming.connection.alloc) { + socket->incoming.connection.iput = 0; + } + + // Schedule user accept callback + exec_user_callback(socket); + + // Set the error callback to handle the case of a dropped connection before we + // have a chance to take it off the accept queue. + // The ->connected entry is repurposed to store the parent socket; this is safe + // because it's only ever used by lwIP if tcp_connect is called on the TCP PCB. + newpcb->connected = (void *)socket; + tcp_arg(newpcb, newpcb); + tcp_err(newpcb, _lwip_tcp_err_unaccepted); + + return ERR_OK; + } + + DEBUG_printf("_lwip_tcp_accept: No room to queue pcb waiting for accept\n"); + return ERR_BUF; +} + +// Callback for inbound tcp packets. +STATIC err_t _lwip_tcp_recv(void *arg, struct tcp_pcb *tcpb, struct pbuf *p, err_t err) { + socketpool_socket_obj_t *socket = (socketpool_socket_obj_t *)arg; + + if (p == NULL) { + // Other side has closed connection. + DEBUG_printf("_lwip_tcp_recv[%p]: other side closed connection\n", socket); + socket->state = STATE_PEER_CLOSED; + exec_user_callback(socket); + return ERR_OK; + } + + if (socket->incoming.pbuf == NULL) { + socket->incoming.pbuf = p; + } else { + #ifdef SOCKET_SINGLE_PBUF + return ERR_BUF; + #else + pbuf_cat(socket->incoming.pbuf, p); + #endif + } + + exec_user_callback(socket); + + return ERR_OK; +} + +/*******************************************************************************/ +// Functions for socket send/receive operations. Socket send/recv and friends call +// these to do the work. + +// Helper function for send/sendto to handle raw/UDP packets. +STATIC mp_uint_t lwip_raw_udp_send(socketpool_socket_obj_t *socket, const byte *buf, mp_uint_t len, ip_addr_t *dest, uint32_t port, int *_errno) { + if (len > 0xffff) { + // Any packet that big is probably going to fail the pbuf_alloc anyway, but may as well try + len = 0xffff; + } + + MICROPY_PY_LWIP_ENTER + + struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (p == NULL) { + MICROPY_PY_LWIP_EXIT + *_errno = MP_ENOMEM; + return -1; + } + + memcpy(p->payload, buf, len); + + err_t err; + if (dest == NULL) { + #if MICROPY_PY_LWIP_SOCK_RAW + if (socket->type == MOD_NETWORK_SOCK_RAW) { + err = raw_send(socket->pcb.raw, p); + } else + #endif + { + err = udp_send(socket->pcb.udp, p); + } + } else { + #if MICROPY_PY_LWIP_SOCK_RAW + if (socket->type == MOD_NETWORK_SOCK_RAW) { + err = raw_sendto(socket->pcb.raw, p, dest); + } else + #endif + { + err = udp_sendto(socket->pcb.udp, p, dest, port); + } + } + + pbuf_free(p); + + MICROPY_PY_LWIP_EXIT + + // udp_sendto can return 1 on occasion for ESP8266 port. It's not known why + // but it seems that the send actually goes through without error in this case. + // So we treat such cases as a success until further investigation. + if (err != ERR_OK && err != 1) { + *_errno = error_lookup_table[-err]; + return -1; + } + + return len; +} + +// Helper function for recv/recvfrom to handle raw/UDP packets +STATIC mp_uint_t lwip_raw_udp_receive(socketpool_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, uint32_t *port, int *_errno) { + + if (socket->incoming.pbuf == NULL) { + if (socket->timeout == 0) { + // Non-blocking socket. + *_errno = MP_EAGAIN; + return -1; + } + + // Wait for data to arrive on UDP socket. + mp_uint_t start = mp_hal_ticks_ms(); + while (socket->incoming.pbuf == NULL) { + if (socket->timeout != (unsigned)-1 && mp_hal_ticks_ms() - start > socket->timeout) { + *_errno = MP_ETIMEDOUT; + return -1; + } + poll_sockets(); + } + } + + if (ip != NULL) { + memcpy(ip, &socket->peer, sizeof(socket->peer)); + *port = socket->peer_port; + } + + struct pbuf *p = socket->incoming.pbuf; + + MICROPY_PY_LWIP_ENTER + + u16_t result = pbuf_copy_partial(p, buf, ((p->tot_len > len) ? len : p->tot_len), 0); + pbuf_free(p); + socket->incoming.pbuf = NULL; + + MICROPY_PY_LWIP_EXIT + + return (mp_uint_t)result; +} + +// For use in stream virtual methods +#define STREAM_ERROR_CHECK(socket) \ + if (socket->state < 0) { \ + *_errno = error_lookup_table[-socket->state]; \ + return MP_STREAM_ERROR; \ + } \ + assert(socket->pcb.tcp); + +// Version of above for use when lock is held +#define STREAM_ERROR_CHECK_WITH_LOCK(socket) \ + if (socket->state < 0) { \ + *_errno = error_lookup_table[-socket->state]; \ + MICROPY_PY_LWIP_EXIT \ + return MP_STREAM_ERROR; \ + } \ + assert(socket->pcb.tcp); + + +// Helper function for send/sendto to handle TCP packets +STATIC mp_uint_t lwip_tcp_send(socketpool_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) { + // Check for any pending errors + STREAM_ERROR_CHECK(socket); + + MICROPY_PY_LWIP_ENTER + + u16_t available = tcp_sndbuf(socket->pcb.tcp); + + if (available == 0) { + // Non-blocking socket + if (socket->timeout == 0) { + MICROPY_PY_LWIP_EXIT + *_errno = MP_EAGAIN; + return MP_STREAM_ERROR; + } + + mp_uint_t start = mp_hal_ticks_ms(); + // Assume that STATE_PEER_CLOSED may mean half-closed connection, where peer closed it + // sending direction, but not receiving. Consequently, check for both STATE_CONNECTED + // and STATE_PEER_CLOSED as normal conditions and still waiting for buffers to be sent. + // If peer fully closed socket, we would have socket->state set to ERR_RST (connection + // reset) by error callback. + // Avoid sending too small packets, so wait until at least 16 bytes available + while (socket->state >= STATE_CONNECTED && (available = tcp_sndbuf(socket->pcb.tcp)) < 16) { + MICROPY_PY_LWIP_EXIT + if (socket->timeout != (unsigned)-1 && mp_hal_ticks_ms() - start > socket->timeout) { + *_errno = MP_ETIMEDOUT; + return MP_STREAM_ERROR; + } + poll_sockets(); + MICROPY_PY_LWIP_REENTER + } + + // While we waited, something could happen + STREAM_ERROR_CHECK_WITH_LOCK(socket); + } + + u16_t write_len = MIN(available, len); + + // If tcp_write returns ERR_MEM then there's currently not enough memory to + // queue the write, so wait and keep trying until it succeeds (with 10s limit). + // Note: if the socket is non-blocking then this code will actually block until + // there's enough memory to do the write, but by this stage we have already + // committed to being able to write the data. + err_t err; + for (int i = 0; i < 200; ++i) { + err = tcp_write(socket->pcb.tcp, buf, write_len, TCP_WRITE_FLAG_COPY); + if (err != ERR_MEM) { + break; + } + if (err == ERR_MEM && write_len > TCP_MSS) { + // Decreasing the amount sent to the next lower number of MSS + write_len = (write_len - 1) / TCP_MSS * TCP_MSS; + continue; + } + err = tcp_output(socket->pcb.tcp); + if (err != ERR_OK) { + break; + } + MICROPY_PY_LWIP_EXIT + mp_hal_delay_ms(50); + MICROPY_PY_LWIP_REENTER + } + + // If the output buffer is getting full then send the data to the lower layers + if (err == ERR_OK && tcp_sndbuf(socket->pcb.tcp) < TCP_SND_BUF / 4) { + err = tcp_output(socket->pcb.tcp); + } + + MICROPY_PY_LWIP_EXIT + + if (err != ERR_OK) { + *_errno = error_lookup_table[-err]; + return MP_STREAM_ERROR; + } + + return write_len; +} + +// Helper function for recv/recvfrom to handle TCP packets +STATIC mp_uint_t lwip_tcp_receive(socketpool_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) { + // Check for any pending errors + STREAM_ERROR_CHECK(socket); + + if (socket->incoming.pbuf == NULL) { + + // Non-blocking socket + if (socket->timeout == 0) { + if (socket->state == STATE_PEER_CLOSED) { + return 0; + } + *_errno = MP_EAGAIN; + return -1; + } + + mp_uint_t start = mp_hal_ticks_ms(); + while (socket->state == STATE_CONNECTED && socket->incoming.pbuf == NULL) { + if (socket->timeout != (unsigned)-1 && mp_hal_ticks_ms() - start > socket->timeout) { + *_errno = MP_ETIMEDOUT; + return -1; + } + poll_sockets(); + } + + if (socket->state == STATE_PEER_CLOSED) { + if (socket->incoming.pbuf == NULL) { + // socket closed and no data left in buffer + return 0; + } + } else if (socket->state != STATE_CONNECTED) { + if (socket->state >= STATE_NEW) { + *_errno = MP_ENOTCONN; + } else { + *_errno = error_lookup_table[-socket->state]; + } + return -1; + } + } + + MICROPY_PY_LWIP_ENTER + + assert(socket->pcb.tcp != NULL); + + struct pbuf *p = socket->incoming.pbuf; + + mp_uint_t remaining = p->len - socket->recv_offset; + if (len > remaining) { + len = remaining; + } + + memcpy(buf, (byte *)p->payload + socket->recv_offset, len); + + remaining -= len; + if (remaining == 0) { + socket->incoming.pbuf = p->next; + // If we don't ref here, free() will free the entire chain, + // if we ref, it does what we need: frees 1st buf, and decrements + // next buf's refcount back to 1. + pbuf_ref(p->next); + pbuf_free(p); + socket->recv_offset = 0; + } else { + socket->recv_offset += len; + } + tcp_recved(socket->pcb.tcp, len); + + MICROPY_PY_LWIP_EXIT + + return len; +} + + +STATIC socketpool_socket_obj_t *open_socket_objs[MAX_SOCKETS]; +STATIC bool user_socket[MAX_SOCKETS]; + +void socket_user_reset(void) { + for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_objs); i++) { + if (open_socket_objs[i] && user_socket[i]) { + socketpool_socket_close(open_socket_objs[i]); + open_socket_objs[i] = NULL; + user_socket[i] = false; + } + } +} + +// The writes below send an event to the socket select task so that it redoes the +// select with the new open socket set. + +STATIC bool register_open_socket(socketpool_socket_obj_t *obj) { + for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_objs); i++) { + if (!open_socket_objs[i]) { + open_socket_objs[i] = obj; + DEBUG_printf("register_open_socket(%p) -> %d\n", obj, i); + user_socket[i] = false; + return true; + } + } + DEBUG_printf("register_open_socket(%p) fails due to full table\n", obj); + return false; +} + +STATIC void unregister_open_socket(socketpool_socket_obj_t *obj) { + for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_objs); i++) { + if (open_socket_objs[i] == obj) { + DEBUG_printf("unregister_open_socket(%p) clears %d\n", obj, i); + open_socket_objs[i] = NULL; + user_socket[i] = false; + return; + } + } + DEBUG_printf("unregister_open_socket(%p) fails due to missing entry\n", obj); +} + +STATIC void mark_user_socket(socketpool_socket_obj_t *obj) { + for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_objs); i++) { + if (open_socket_objs[i] == obj) { + DEBUG_printf("mark_user_socket(%p) -> %d\n", obj, i); + user_socket[i] = true; + return; + } + } + DEBUG_printf("mark_user_socket(%p) fails due to missing entry\n", obj); +} + +bool socketpool_socket(socketpool_socketpool_obj_t *self, + socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type, + socketpool_socket_obj_t *socket) { + + if (!register_open_socket(socket)) { + DEBUG_printf("collecting garbage to open socket\n"); + gc_collect(); + if (!register_open_socket(socket)) { + return false; + } + } + + socket->timeout = -1; + socket->recv_offset = 0; + socket->domain = SOCKETPOOL_AF_INET; + socket->type = type; + socket->callback = MP_OBJ_NULL; + socket->state = STATE_NEW; + + switch (socket->type) { + case SOCKETPOOL_SOCK_STREAM: + socket->pcb.tcp = tcp_new(); + socket->incoming.connection.alloc = 0; + socket->incoming.connection.tcp.item = NULL; + break; + case SOCKETPOOL_SOCK_DGRAM: + socket->pcb.udp = udp_new(); + socket->incoming.pbuf = NULL; + break; + #if MICROPY_PY_LWIP_SOCK_RAW + case SOCKETPOOL_SOCK_RAW: { + socket->pcb.raw = raw_new(0); + break; + } + #endif + default: + return false; + } + + if (socket->pcb.tcp == NULL) { + return false; + } + + switch (socket->type) { + case MOD_NETWORK_SOCK_STREAM: { + // Register the socket object as our callback argument. + tcp_arg(socket->pcb.tcp, (void *)socket); + // Register our error callback. + tcp_err(socket->pcb.tcp, _lwip_tcp_error); + break; + } + case MOD_NETWORK_SOCK_DGRAM: { + socket->state = STATE_ACTIVE_UDP; + // Register our receive callback now. Since UDP sockets don't require binding or connection + // before use, there's no other good time to do it. + udp_recv(socket->pcb.udp, _lwip_udp_incoming, (void *)socket); + break; + } + #if MICROPY_PY_LWIP_SOCK_RAW + case MOD_NETWORK_SOCK_RAW: { + // Register our receive callback now. Since raw sockets don't require binding or connection + // before use, there's no other good time to do it. + raw_recv(socket->pcb.raw, _lwip_raw_incoming, (void *)socket); + break; + } + #endif + } + return true; +} + +socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_t *self, + socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type) { + if (family != SOCKETPOOL_AF_INET) { + mp_raise_NotImplementedError(translate("Only IPv4 sockets supported")); + } + + // we must allocate sockets long-lived because we depend on their object-identity + socketpool_socket_obj_t *socket = m_new_ll_obj_with_finaliser(socketpool_socket_obj_t); + socket->base.type = &socketpool_socket_type; + + if (!socketpool_socket(self, family, type, socket)) { + mp_raise_RuntimeError(translate("Out of sockets")); + } + mark_user_socket(socket); + return socket; +} + +int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port, socketpool_socket_obj_t *accepted) { + if (self->type != MOD_NETWORK_SOCK_STREAM) { + return -MP_EOPNOTSUPP; + } + + if (common_hal_socketpool_socket_get_closed(self)) { + return -MP_EBADF; + } + + MICROPY_PY_LWIP_ENTER + + if (self->pcb.tcp == NULL) { + MICROPY_PY_LWIP_EXIT + return -MP_EBADF; + } + + // I need to do this because "tcp_accepted", later, is a macro. + struct tcp_pcb *listener = self->pcb.tcp; + if (listener->state != LISTEN) { + MICROPY_PY_LWIP_EXIT + return -MP_EINVAL; + } + + // accept incoming connection + struct tcp_pcb *volatile *incoming_connection = &lwip_socket_incoming_array(self)[self->incoming.connection.iget]; + if (*incoming_connection == NULL) { + if (self->timeout == 0) { + MICROPY_PY_LWIP_EXIT + return -MP_EAGAIN; + } else if (self->timeout != (unsigned)-1) { + mp_uint_t retries = self->timeout / 100; + while (*incoming_connection == NULL && !mp_hal_is_interrupted()) { + MICROPY_PY_LWIP_EXIT + if (retries-- == 0) { + return -MP_ETIMEDOUT; + } + mp_hal_delay_ms(100); + MICROPY_PY_LWIP_REENTER + } + } else { + while (*incoming_connection == NULL && !mp_hal_is_interrupted()) { + MICROPY_PY_LWIP_EXIT + poll_sockets(); + MICROPY_PY_LWIP_REENTER + } + } + } + + if (*incoming_connection == NULL) { + // We were interrupted. + return 0; + } + + // Close the accepted socket because we have another we accepted. + if (!common_hal_socketpool_socket_get_closed(accepted)) { + common_hal_socketpool_socket_close(accepted); + } + + // We get a new pcb handle... + accepted->pcb.tcp = *incoming_connection; + if (++self->incoming.connection.iget >= self->incoming.connection.alloc) { + self->incoming.connection.iget = 0; + } + *incoming_connection = NULL; + + // ...and set up the new socket for it. + accepted->domain = MOD_NETWORK_AF_INET; + accepted->type = MOD_NETWORK_SOCK_STREAM; + accepted->incoming.pbuf = NULL; + accepted->timeout = self->timeout; + accepted->state = STATE_CONNECTED; + accepted->recv_offset = 0; + accepted->callback = MP_OBJ_NULL; + tcp_arg(accepted->pcb.tcp, (void *)accepted); + tcp_err(accepted->pcb.tcp, _lwip_tcp_error); + tcp_recv(accepted->pcb.tcp, _lwip_tcp_recv); + + tcp_accepted(listener); + + MICROPY_PY_LWIP_EXIT + + // output values + memcpy(ip, &(accepted->pcb.tcp->remote_ip), NETUTILS_IPV4ADDR_BUFSIZE); + *port = (mp_uint_t)accepted->pcb.tcp->remote_port; + + return 1; +} + +socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *socket, + uint8_t *ip, uint32_t *port) { + // Create new socket object, do it here because we must not raise an out-of-memory + // exception when the LWIP concurrency lock is held + socketpool_socket_obj_t *accepted = m_new_ll_obj_with_finaliser(socketpool_socket_obj_t); + socketpool_socket_reset(accepted); + + int ret = socketpool_socket_accept(socket, ip, port, accepted); + + if (ret <= 0) { + m_del_obj(socketpool_socket_obj_t, accepted); + if (ret == 0) { + // Interrupted. + return mp_const_none; + } + mp_raise_OSError(-ret); + } + + DEBUG_printf("registering socket in socketpool_socket_accept()\n"); + if (!register_open_socket(accepted)) { + DEBUG_printf("collecting garbage to open socket\n"); + gc_collect(); + if (!register_open_socket(accepted)) { + mp_raise_RuntimeError(translate("Out of sockets")); + } + } + mark_user_socket(accepted); + + return MP_OBJ_FROM_PTR(accepted); +} + +bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *socket, + const char *host, size_t hostlen, uint32_t port) { + + // get address + ip_addr_t bind_addr; + const ip_addr_t *bind_addr_ptr = &bind_addr; + if (hostlen > 0) { + socketpool_resolve_host_raise(socket->pool, host, &bind_addr); + } else { + bind_addr_ptr = IP_ANY_TYPE; + } + ip_set_option(socket->pcb.ip, SOF_REUSEADDR); + + err_t err = ERR_ARG; + switch (socket->type) { + case MOD_NETWORK_SOCK_STREAM: { + err = tcp_bind(socket->pcb.tcp, bind_addr_ptr, port); + break; + } + case MOD_NETWORK_SOCK_DGRAM: { + err = udp_bind(socket->pcb.udp, bind_addr_ptr, port); + break; + } + } + + if (err != ERR_OK) { + mp_raise_OSError(error_lookup_table[-err]); + } + + return mp_const_none; +} + +STATIC err_t _lwip_tcp_close_poll(void *arg, struct tcp_pcb *pcb) { + // Connection has not been cleanly closed so just abort it to free up memory + tcp_poll(pcb, NULL, 0); + tcp_abort(pcb); + return ERR_OK; +} + +void socketpool_socket_close(socketpool_socket_obj_t *socket) { + unregister_open_socket(socket); + MICROPY_PY_LWIP_ENTER + if (socket->pcb.tcp == NULL) { // already closed + MICROPY_PY_LWIP_EXIT + return; + } + lwip_socket_free_incoming(socket); + switch (socket->type) { + case SOCKETPOOL_SOCK_STREAM: { + // Deregister callback (pcb.tcp is set to NULL below so must deregister now) + tcp_arg(socket->pcb.tcp, NULL); + tcp_err(socket->pcb.tcp, NULL); + tcp_recv(socket->pcb.tcp, NULL); + + if (socket->pcb.tcp->state != LISTEN) { + // Schedule a callback to abort the connection if it's not cleanly closed after + // the given timeout. The callback must be set before calling tcp_close since + // the latter may free the pcb; if it doesn't then the callback will be active. + tcp_poll(socket->pcb.tcp, _lwip_tcp_close_poll, MICROPY_PY_LWIP_TCP_CLOSE_TIMEOUT_MS / 500); + } + if (tcp_close(socket->pcb.tcp) != ERR_OK) { + DEBUG_printf("lwip_close: had to call tcp_abort()\n"); + tcp_abort(socket->pcb.tcp); + } + break; + } + case SOCKETPOOL_SOCK_DGRAM: + udp_recv(socket->pcb.udp, NULL, NULL); + udp_remove(socket->pcb.udp); + break; + #if MICROPY_PY_LWIP_SOCK_RAW + case SOCKETPOOL_SOCK_RAW: + raw_recv(socket->pcb.raw, NULL, NULL); + raw_remove(socket->pcb.raw); + break; + #endif + } + + socket->pcb.tcp = NULL; + socket->state = _ERR_BADF; + MICROPY_PY_LWIP_EXIT +} + +void common_hal_socketpool_socket_close(socketpool_socket_obj_t *socket) { + socketpool_socket_close(socket); +} + +void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *socket, + const char *host, size_t hostlen, uint32_t port) { + + if (socket->pcb.tcp == NULL) { + mp_raise_OSError(MP_EBADF); + } + + // get address + ip_addr_t dest; + socketpool_resolve_host_raise(socket->pool, host, &dest); + + err_t err = ERR_ARG; + switch (socket->type) { + case MOD_NETWORK_SOCK_STREAM: { + if (socket->state != STATE_NEW) { + if (socket->state == STATE_CONNECTED) { + mp_raise_OSError(MP_EISCONN); + } else { + mp_raise_OSError(MP_EALREADY); + } + } + + // Register our receive callback. + MICROPY_PY_LWIP_ENTER + tcp_recv(socket->pcb.tcp, _lwip_tcp_recv); + socket->state = STATE_CONNECTING; + err = tcp_connect(socket->pcb.tcp, &dest, port, _lwip_tcp_connected); + if (err != ERR_OK) { + MICROPY_PY_LWIP_EXIT + socket->state = STATE_NEW; + mp_raise_OSError(error_lookup_table[-err]); + } + socket->peer_port = (mp_uint_t)port; + memcpy(socket->peer, &dest, sizeof(socket->peer)); + MICROPY_PY_LWIP_EXIT + + // And now we wait... + if (socket->timeout != (unsigned)-1) { + for (mp_uint_t retries = socket->timeout / 100; retries--;) { + mp_hal_delay_ms(100); + if (socket->state != STATE_CONNECTING) { + break; + } + } + if (socket->state == STATE_CONNECTING) { + mp_raise_OSError(MP_EINPROGRESS); + } + } else { + while (socket->state == STATE_CONNECTING) { + poll_sockets(); + } + } + if (socket->state == STATE_CONNECTED) { + err = ERR_OK; + } else { + err = socket->state; + } + break; + } + case MOD_NETWORK_SOCK_DGRAM: { + err = udp_connect(socket->pcb.udp, &dest, port); + break; + } + #if MICROPY_PY_LWIP_SOCK_RAW + case MOD_NETWORK_SOCK_RAW: { + err = raw_connect(socket->pcb.raw, &dest); + break; + } + #endif + } + + if (err != ERR_OK) { + mp_raise_OSError(error_lookup_table[-err]); + } +} + +bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t *socket) { + return !socket->pcb.tcp; +} + +bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t *socket) { + return socket->state == STATE_CONNECTED; +} + +bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *socket, int backlog) { + if (socket->type != MOD_NETWORK_SOCK_STREAM) { + mp_raise_OSError(MP_EOPNOTSUPP); + } + + struct tcp_pcb *new_pcb = tcp_listen_with_backlog(socket->pcb.tcp, (u8_t)backlog); + if (new_pcb == NULL) { + mp_raise_OSError(MP_ENOMEM); + } + socket->pcb.tcp = new_pcb; + + // Allocate memory for the backlog of connections + if (backlog <= 1) { + socket->incoming.connection.alloc = 0; + socket->incoming.connection.tcp.item = NULL; + } else { + socket->incoming.connection.alloc = backlog; + socket->incoming.connection.tcp.array = m_new0(struct tcp_pcb *, backlog); + } + socket->incoming.connection.iget = 0; + socket->incoming.connection.iput = 0; + + tcp_accept(new_pcb, _lwip_tcp_accept); + + // Socket is no longer considered "new" for purposes of polling + socket->state = STATE_LISTENING; + + return mp_const_none; +} + +mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *socket, + uint8_t *buf, uint32_t len, uint8_t *ip, uint32_t *port) { + int _errno; + + mp_uint_t ret = 0; + switch (socket->type) { + case SOCKETPOOL_SOCK_STREAM: { + memcpy(ip, &socket->peer, sizeof(socket->peer)); + *port = (mp_uint_t)socket->peer_port; + ret = lwip_tcp_receive(socket, (byte *)buf, len, &_errno); + break; + } + case SOCKETPOOL_SOCK_DGRAM: + #if MICROPY_PY_LWIP_SOCK_RAW + case SOCKETPOOL_SOCK_RAW: + #endif + ret = lwip_raw_udp_receive(socket, (byte *)buf, len, ip, port, &_errno); + break; + } + if (ret == (unsigned)-1) { + mp_raise_OSError(_errno); + } + + return ret; +} + +int socketpool_socket_recv_into(socketpool_socket_obj_t *socket, + const uint8_t *buf, uint32_t len) { + mp_uint_t ret = 0; + int _errno = 0; + switch (socket->type) { + case SOCKETPOOL_SOCK_STREAM: { + ret = lwip_tcp_receive(socket, (byte *)buf, len, &_errno); + break; + } + case SOCKETPOOL_SOCK_DGRAM: + #if MICROPY_PY_LWIP_SOCK_RAW + case SOCKETPOOL_SOCK_RAW: + #endif + ret = lwip_raw_udp_receive(socket, (byte *)buf, len, NULL, NULL, &_errno); + break; + } + if (ret == (unsigned)-1) { + mp_raise_OSError(_errno); + } + return ret; +} + +mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) { + int received = socketpool_socket_recv_into(self, buf, len); + if (received < 0) { + mp_raise_OSError(-received); + } + return received; +} + +int socketpool_socket_send(socketpool_socket_obj_t *socket, const uint8_t *buf, uint32_t len) { + mp_uint_t ret = 0; + int _errno = 0; + switch (socket->type) { + case SOCKETPOOL_SOCK_STREAM: { + ret = lwip_tcp_send(socket, buf, len, &_errno); + break; + } + case SOCKETPOOL_SOCK_DGRAM: + #if MICROPY_PY_LWIP_SOCK_RAW + case SOCKETPOOL_SOCK_RAW: + #endif + ret = lwip_raw_udp_send(socket, buf, len, NULL, 0, &_errno); + break; + } + if (ret == (unsigned)-1) { + return -_errno; + } + return ret; +} + +mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) { + int sent = socketpool_socket_send(self, buf, len); + + if (sent < 0) { + mp_raise_OSError(-sent); + } + return sent; +} + +mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t *socket, + const char *host, size_t hostlen, uint32_t port, const uint8_t *buf, uint32_t len) { + int _errno; + ip_addr_t ip; + socketpool_resolve_host_raise(socket->pool, host, &ip); + + mp_uint_t ret = 0; + switch (socket->type) { + case SOCKETPOOL_SOCK_STREAM: { + ret = lwip_tcp_send(socket, buf, len, &_errno); + break; + } + case SOCKETPOOL_SOCK_DGRAM: + #if MICROPY_PY_LWIP_SOCK_RAW + case SOCKETPOOL_SOCK_RAW: + #endif + ret = lwip_raw_udp_send(socket, buf, len, &ip, port, &_errno); + break; + } + if (ret == (unsigned)-1) { + mp_raise_OSError(_errno); + } + + return ret; +} + +void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint32_t timeout_ms) { + self->timeout = timeout_ms; +} + +int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen) { + if (level == SOCKETPOOL_IPPROTO_TCP && optname == SOCKETPOOL_TCP_NODELAY) { + int one = 1; + bool enable = optlen == sizeof(&one) && memcmp(value, &one, optlen); + if (enable) { + tcp_set_flags(self->pcb.tcp, TF_NODELAY); + } else { + tcp_clear_flags(self->pcb.tcp, TF_NODELAY); + } + return 0; + } + return -MP_EOPNOTSUPP; +} + +bool common_hal_socketpool_readable(socketpool_socket_obj_t *self) { + + MICROPY_PY_LWIP_ENTER; + + bool result = self->incoming.pbuf != NULL; + + if (self->state == STATE_PEER_CLOSED) { + result = true; + } + + if (self->type == SOCKETPOOL_SOCK_STREAM && self->pcb.tcp->state == LISTEN) { + struct tcp_pcb *volatile *incoming_connection = &lwip_socket_incoming_array(self)[self->incoming.connection.iget]; + result = (incoming_connection != NULL); + } + + MICROPY_PY_LWIP_EXIT; + + return result; +} + +bool common_hal_socketpool_writable(socketpool_socket_obj_t *self) { + bool result = false; + + MICROPY_PY_LWIP_ENTER; + + switch (self->type) { + case SOCKETPOOL_SOCK_STREAM: { + result = tcp_sndbuf(self->pcb.tcp) != 0; + break; + } + case SOCKETPOOL_SOCK_DGRAM: + #if MICROPY_PY_LWIP_SOCK_RAW + case SOCKETPOOL_SOCK_RAW: + #endif + result = true; + break; + } + + MICROPY_PY_LWIP_EXIT; + + return result; +} + +void socketpool_socket_move(socketpool_socket_obj_t *self, socketpool_socket_obj_t *sock) { + *sock = *self; + self->state = _ERR_BADF; + + // Reregister the callbacks with the new socket copy. + MICROPY_PY_LWIP_ENTER; + + tcp_arg(self->pcb.tcp, NULL); + tcp_err(self->pcb.tcp, NULL); + tcp_recv(self->pcb.tcp, NULL); + + self->pcb.tcp = NULL; + + tcp_arg(sock->pcb.tcp, (void *)sock); + tcp_err(sock->pcb.tcp, _lwip_tcp_error); + tcp_recv(sock->pcb.tcp, _lwip_tcp_recv); + + MICROPY_PY_LWIP_EXIT; +} + +void socketpool_socket_reset(socketpool_socket_obj_t *self) { + if (self->base.type == &socketpool_socket_type) { + return; + } + self->base.type = &socketpool_socket_type; + self->pcb.tcp = NULL; + self->state = _ERR_BADF; +} diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.h b/ports/raspberrypi/common-hal/socketpool/Socket.h new file mode 100644 index 0000000000..6e26087674 --- /dev/null +++ b/ports/raspberrypi/common-hal/socketpool/Socket.h @@ -0,0 +1,78 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2019 Damien P. George + * Copyright (c) 2015 Galen Hazelwood + * Copyright (c) 2015-2017 Paul Sokolovsky + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/obj.h" + +#include "common-hal/socketpool/SocketPool.h" + +typedef struct _lwip_socket_obj_t { + mp_obj_base_t base; + + volatile union { + struct tcp_pcb *ip; + struct tcp_pcb *tcp; + struct udp_pcb *udp; + struct raw_pcb *raw; + } pcb; + volatile union { + struct pbuf *pbuf; + struct { + uint8_t alloc; + uint8_t iget; + uint8_t iput; + union { + struct tcp_pcb *item; // if alloc == 0 + struct tcp_pcb **array; // if alloc != 0 + } tcp; + } connection; + } incoming; + mp_obj_t callback; + byte peer[4]; + mp_uint_t peer_port; + mp_uint_t timeout; + uint16_t recv_offset; + + uint8_t domain; + uint8_t type; + + #define STATE_NEW 0 + #define STATE_LISTENING 1 + #define STATE_CONNECTING 2 + #define STATE_CONNECTED 3 + #define STATE_PEER_CLOSED 4 + #define STATE_ACTIVE_UDP 5 + // Negative value is lwIP error + int8_t state; + + socketpool_socketpool_obj_t *pool; +} socketpool_socket_obj_t; + +void socket_user_reset(void); diff --git a/ports/raspberrypi/common-hal/socketpool/SocketPool.c b/ports/raspberrypi/common-hal/socketpool/SocketPool.c new file mode 100644 index 0000000000..e562314d69 --- /dev/null +++ b/ports/raspberrypi/common-hal/socketpool/SocketPool.c @@ -0,0 +1,119 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/socketpool/SocketPool.h" +#include "common-hal/socketpool/Socket.h" +#include "shared/runtime/interrupt_char.h" +#include "py/runtime.h" +#include "shared-bindings/wifi/__init__.h" + +#include "lwip/dns.h" +#include "lwip/inet.h" + +void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *self, mp_obj_t radio) { + if (radio != MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj)) { + mp_raise_ValueError(translate("SocketPool can only be used with wifi.radio")); + } +} + +// common_hal_socketpool_socket is in socketpool/Socket.c to centralize open socket tracking. + +typedef struct _getaddrinfo_state_t { + volatile int status; + volatile ip_addr_t ipaddr; +} getaddrinfo_state_t; + +STATIC void lwip_getaddrinfo_cb(const char *name, const ip_addr_t *ipaddr, void *arg) { + getaddrinfo_state_t *state = arg; + if (ipaddr != NULL) { + state->status = 1; + state->ipaddr = *ipaddr; + } else { + // error + state->status = -2; + } +} + +STATIC int socketpool_resolve_host(socketpool_socketpool_obj_t *self, const char *host, ip_addr_t *addr) { + + getaddrinfo_state_t state; + state.status = 0; + + MICROPY_PY_LWIP_ENTER + err_t ret = dns_gethostbyname(host, (ip_addr_t *)&state.ipaddr, lwip_getaddrinfo_cb, &state); + MICROPY_PY_LWIP_EXIT + + switch (ret) { + case ERR_OK: + // cached + state.status = 1; + break; + case ERR_INPROGRESS: + while (state.status == 0) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + break; + } + } + break; + default: + state.status = ret; + } + + if (state.status < 0) { + return state.status; + // TODO: CPython raises gaierror, we raise with native lwIP negative error + // values, to differentiate from normal errno's at least in such way. + mp_raise_OSError(state.status); + } + + *addr = state.ipaddr; + return 0; +} + +void socketpool_resolve_host_raise(socketpool_socketpool_obj_t *self, const char *host, ip_addr_t *addr) { + int result = socketpool_resolve_host(self, host, addr); + if (result < 0) { + printf("socket_resolve_host() returned %d\n", result); + common_hal_socketpool_socketpool_raise_gaierror_noname(); + mp_raise_OSError(-result); + } +} + +mp_obj_t common_hal_socketpool_socketpool_gethostbyname(socketpool_socketpool_obj_t *self, const char *host) { + + ip_addr_t addr; + socketpool_resolve_host_raise(self, host, &addr); + + char ip_str[IP4ADDR_STRLEN_MAX]; + inet_ntoa_r(addr, ip_str, IP4ADDR_STRLEN_MAX); + mp_obj_t ip_obj = mp_obj_new_str(ip_str, strlen(ip_str)); + return ip_obj; +} + +mp_obj_t common_hal_socketpool_socketpool_gethostbyname_raise(socketpool_socketpool_obj_t *self, const char *host) { + return common_hal_socketpool_socketpool_gethostbyname(self, host); +} diff --git a/ports/raspberrypi/common-hal/socketpool/SocketPool.h b/ports/raspberrypi/common-hal/socketpool/SocketPool.h new file mode 100644 index 0000000000..a7ad36b92f --- /dev/null +++ b/ports/raspberrypi/common-hal/socketpool/SocketPool.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} socketpool_socketpool_obj_t; + +void socketpool_resolve_host_raise(socketpool_socketpool_obj_t *self, const char *host, ip_addr_t *addr); diff --git a/ports/litex/fatfs_port.c b/ports/raspberrypi/common-hal/socketpool/__init__.c similarity index 79% rename from ports/litex/fatfs_port.c rename to ports/raspberrypi/common-hal/socketpool/__init__.c index 631f7f0982..595977d24f 100644 --- a/ports/litex/fatfs_port.c +++ b/ports/raspberrypi/common-hal/socketpool/__init__.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,10 +24,10 @@ * THE SOFTWARE. */ -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" +#include "shared-bindings/socketpool/__init__.h" -DWORD get_fattime(void) { - // TODO: Implement this function. For now, fake it. - return ((2016 - 1980) << 25) | ((12) << 21) | ((4) << 16) | ((00) << 11) | ((18) << 5) | (23 / 2); +#include "common-hal/socketpool/Socket.h" + +void socketpool_user_reset(void) { + socket_user_reset(); } diff --git a/ports/raspberrypi/common-hal/socketpool/__init__.h b/ports/raspberrypi/common-hal/socketpool/__init__.h new file mode 100644 index 0000000000..32f1fe1dcb --- /dev/null +++ b/ports/raspberrypi/common-hal/socketpool/__init__.h @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once diff --git a/ports/raspberrypi/common-hal/ssl/SSLContext.c b/ports/raspberrypi/common-hal/ssl/SSLContext.c new file mode 100644 index 0000000000..67287128b0 --- /dev/null +++ b/ports/raspberrypi/common-hal/ssl/SSLContext.c @@ -0,0 +1,66 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/ssl/SSLContext.h" +#include "shared-bindings/ssl/SSLSocket.h" +#include "shared-bindings/socketpool/SocketPool.h" + +#include "py/runtime.h" +#include "py/stream.h" + +#include "mbedtls/crt_bundle.h" + +void common_hal_ssl_sslcontext_construct(ssl_sslcontext_obj_t *self) { + common_hal_ssl_sslcontext_set_default_verify_paths(self); +} + +void common_hal_ssl_sslcontext_load_verify_locations(ssl_sslcontext_obj_t *self, + const char *cadata) { + self->crt_bundle_attach = NULL; + self->use_global_ca_store = false; + self->cacert_buf = (const unsigned char *)cadata; + self->cacert_bytes = *cadata ? strlen(cadata) + 1 : 0; +} + +void common_hal_ssl_sslcontext_set_default_verify_paths(ssl_sslcontext_obj_t *self) { + self->crt_bundle_attach = crt_bundle_attach; + self->use_global_ca_store = true; + self->cacert_buf = NULL; + self->cacert_bytes = 0; +} + +bool common_hal_ssl_sslcontext_get_check_hostname(ssl_sslcontext_obj_t *self) { + return self->check_name; +} + +void common_hal_ssl_sslcontext_set_check_hostname(ssl_sslcontext_obj_t *self, bool value) { + self->check_name = value; +} + +void common_hal_ssl_sslcontext_load_cert_chain(ssl_sslcontext_obj_t *self, mp_buffer_info_t *cert_buf, mp_buffer_info_t *key_buf) { + self->cert_buf = *cert_buf; + self->key_buf = *key_buf; +} diff --git a/ports/raspberrypi/common-hal/ssl/SSLContext.h b/ports/raspberrypi/common-hal/ssl/SSLContext.h new file mode 100644 index 0000000000..40840deeec --- /dev/null +++ b/ports/raspberrypi/common-hal/ssl/SSLContext.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/obj.h" +#include "mbedtls/ssl.h" + +typedef struct { + mp_obj_base_t base; + bool check_name, use_global_ca_store; + const unsigned char *cacert_buf; + size_t cacert_bytes; + int (*crt_bundle_attach)(mbedtls_ssl_config *conf); + mp_buffer_info_t cert_buf, key_buf; +} ssl_sslcontext_obj_t; diff --git a/ports/raspberrypi/common-hal/ssl/SSLSocket.c b/ports/raspberrypi/common-hal/ssl/SSLSocket.c new file mode 100644 index 0000000000..67508f16c8 --- /dev/null +++ b/ports/raspberrypi/common-hal/ssl/SSLSocket.c @@ -0,0 +1,364 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Linaro Ltd. + * Copyright (c) 2019 Paul Sokolovsky + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/ssl/SSLSocket.h" +#include "shared-bindings/socketpool/Socket.h" +#include "shared-bindings/ssl/SSLContext.h" +#include "shared-bindings/socketpool/SocketPool.h" +#include "shared-bindings/socketpool/Socket.h" + +#include "shared/runtime/interrupt_char.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/tick.h" + +#if defined(MBEDTLS_ERROR_C) +#include "../../lib/mbedtls_errors/mp_mbedtls_errors.c" +#endif + +#ifdef MBEDTLS_DEBUG_C +#include "mbedtls/debug.h" +STATIC void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) { + (void)ctx; + (void)level; + mp_printf(&mp_plat_print, "DBG:%s:%04d: %s\n", file, line, str); +} +#define DEBUG(fmt, ...) mp_printf(&mp_plat_print, "DBG:%s:%04d: " fmt "\n", __FILE__, __LINE__,##__VA_ARGS__) +#else +#define DEBUG(...) do {} while (0) +#endif + +STATIC NORETURN void mbedtls_raise_error(int err) { + // _mbedtls_ssl_send and _mbedtls_ssl_recv (below) turn positive error codes from the + // underlying socket into negative codes to pass them through mbedtls. Here we turn them + // positive again so they get interpreted as the OSError they really are. The + // cut-off of -256 is a bit hacky, sigh. + if (err < 0 && err > -256) { + mp_raise_OSError(-err); + } + + #if defined(MBEDTLS_ERROR_C) + // Including mbedtls_strerror takes about 1.5KB due to the error strings. + // MBEDTLS_ERROR_C is the define used by mbedtls to conditionally include mbedtls_strerror. + // It is set/unset in the MBEDTLS_CONFIG_FILE which is defined in the Makefile. + + // Try to allocate memory for the message + #define ERR_STR_MAX 80 // mbedtls_strerror truncates if it doesn't fit + mp_obj_str_t *o_str = m_new_obj_maybe(mp_obj_str_t); + byte *o_str_buf = m_new_maybe(byte, ERR_STR_MAX); + if (o_str == NULL || o_str_buf == NULL) { + mp_raise_OSError(err); + } + + // print the error message into the allocated buffer + mbedtls_strerror(err, (char *)o_str_buf, ERR_STR_MAX); + size_t len = strlen((char *)o_str_buf); + + // Put the exception object together + o_str->base.type = &mp_type_str; + o_str->data = o_str_buf; + o_str->len = len; + o_str->hash = qstr_compute_hash(o_str->data, o_str->len); + // raise + mp_obj_t args[2] = { MP_OBJ_NEW_SMALL_INT(err), MP_OBJ_FROM_PTR(o_str)}; + nlr_raise(mp_obj_exception_make_new(&mp_type_OSError, 2, 0, args)); + #else + // mbedtls is compiled without error strings so we simply return the err number + mp_raise_OSError(err); // err is typically a large negative number + #endif +} + +STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) { + mp_obj_t sock = *(mp_obj_t *)ctx; + + // mp_uint_t out_sz = sock_stream->write(sock, buf, len, &err); + mp_int_t out_sz = socketpool_socket_send(sock, buf, len); + DEBUG("socket_send() -> %d", out_sz); + if (out_sz < 0) { + int err = -out_sz; + DEBUG("sock_stream->write() -> %d nonblocking? %d", out_sz, mp_is_nonblocking_error(err)); + if (mp_is_nonblocking_error(err)) { + return MBEDTLS_ERR_SSL_WANT_WRITE; + } + return -err; // convert an MP_ERRNO to something mbedtls passes through as error + } else { + return out_sz; + } +} + +// _mbedtls_ssl_recv is called by mbedtls to receive bytes from the underlying socket +STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { + mp_obj_t sock = *(mp_obj_t *)ctx; + + mp_int_t out_sz = socketpool_socket_recv_into(sock, buf, len); + DEBUG("socket_recv() -> %d", out_sz); + if (out_sz < 0) { + int err = -out_sz; + if (mp_is_nonblocking_error(err)) { + return MBEDTLS_ERR_SSL_WANT_READ; + } + return -err; + } else { + return out_sz; + } +} + + + +ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t *self, + socketpool_socket_obj_t *socket, bool server_side, const char *server_hostname) { + + if (socket->type != SOCKETPOOL_SOCK_STREAM) { + mp_raise_RuntimeError(translate("Invalid socket for TLS")); + } + + ssl_sslsocket_obj_t *o = m_new_obj_with_finaliser(ssl_sslsocket_obj_t); + o->base.type = &ssl_sslsocket_type; + o->ssl_context = self; + o->sock = socket; + + mbedtls_ssl_init(&o->ssl); + mbedtls_ssl_config_init(&o->conf); + mbedtls_x509_crt_init(&o->cacert); + mbedtls_x509_crt_init(&o->cert); + mbedtls_pk_init(&o->pkey); + mbedtls_ctr_drbg_init(&o->ctr_drbg); + #ifdef MBEDTLS_DEBUG_C + // Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose + mbedtls_debug_set_threshold(4); + #endif + + mbedtls_entropy_init(&o->entropy); + const byte seed[] = "upy"; + int ret = mbedtls_ctr_drbg_seed(&o->ctr_drbg, mbedtls_entropy_func, &o->entropy, seed, sizeof(seed)); + if (ret != 0) { + goto cleanup; + } + + ret = mbedtls_ssl_config_defaults(&o->conf, + server_side ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT); + if (ret != 0) { + goto cleanup; + } + + if (self->crt_bundle_attach != NULL) { + mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_REQUIRED); + self->crt_bundle_attach(&o->conf); + } else if (self->cacert_buf && self->cacert_bytes) { + ret = mbedtls_x509_crt_parse(&o->cacert, self->cacert_buf, self->cacert_bytes); + if (ret != 0) { + goto cleanup; + } + mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_REQUIRED); + mbedtls_ssl_conf_ca_chain(&o->conf, &o->cacert, NULL); + + } else { + mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_NONE); + } + mbedtls_ssl_conf_rng(&o->conf, mbedtls_ctr_drbg_random, &o->ctr_drbg); + #ifdef MBEDTLS_DEBUG_C + mbedtls_ssl_conf_dbg(&o->conf, mbedtls_debug, NULL); + #endif + + ret = mbedtls_ssl_setup(&o->ssl, &o->conf); + if (ret != 0) { + goto cleanup; + } + + if (server_hostname != NULL) { + ret = mbedtls_ssl_set_hostname(&o->ssl, server_hostname); + if (ret != 0) { + goto cleanup; + } + } + + mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL); + + if (self->cert_buf.buf != NULL) { + ret = mbedtls_pk_parse_key(&o->pkey, self->key_buf.buf, self->key_buf.len + 1, NULL, 0); + if (ret != 0) { + goto cleanup; + } + ret = mbedtls_x509_crt_parse(&o->cert, self->cert_buf.buf, self->cert_buf.len + 1); + if (ret != 0) { + goto cleanup; + } + + ret = mbedtls_ssl_conf_own_cert(&o->conf, &o->cert, &o->pkey); + if (ret != 0) { + goto cleanup; + } + } + return o; +cleanup: + mbedtls_pk_free(&o->pkey); + mbedtls_x509_crt_free(&o->cert); + mbedtls_x509_crt_free(&o->cacert); + mbedtls_ssl_free(&o->ssl); + mbedtls_ssl_config_free(&o->conf); + mbedtls_ctr_drbg_free(&o->ctr_drbg); + mbedtls_entropy_free(&o->entropy); + + if (ret == MBEDTLS_ERR_SSL_ALLOC_FAILED) { + mp_raise_type(&mp_type_MemoryError); + } else if (ret == MBEDTLS_ERR_PK_BAD_INPUT_DATA) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid key")); + } else if (ret == MBEDTLS_ERR_X509_BAD_INPUT_DATA) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid cert")); + } else { + mbedtls_raise_error(ret); + } +} + +mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t *self, uint8_t *buf, uint32_t len) { + int ret = mbedtls_ssl_read(&self->ssl, buf, len); + DEBUG("recv_into mbedtls_ssl_read() -> %d\n", ret); + if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { + DEBUG("returning %d\n", 0); + // end of stream + return 0; + } + if (ret >= 0) { + DEBUG("returning %d\n", ret); + return ret; + } + if (ret == MBEDTLS_ERR_SSL_WANT_READ) { + ret = MP_EWOULDBLOCK; + } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + // If handshake is not finished, read attempt may end up in protocol + // wanting to write next handshake message. The same may happen with + // renegotation. + ret = MP_EWOULDBLOCK; + } + DEBUG("raising errno [error case] %d\n", ret); + mp_raise_OSError(ret); +} + +mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t *buf, uint32_t len) { + int ret = mbedtls_ssl_write(&self->ssl, buf, len); + DEBUG("send mbedtls_ssl_write() -> %d\n", ret); + if (ret >= 0) { + DEBUG("returning %d\n", ret); + return ret; + } + if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + ret = MP_EWOULDBLOCK; + } else if (ret == MBEDTLS_ERR_SSL_WANT_READ) { + // If handshake is not finished, write attempt may end up in protocol + // wanting to read next handshake message. The same may happen with + // renegotation. + ret = MP_EWOULDBLOCK; + } + DEBUG("raising errno [error case] %d\n", ret); + mp_raise_OSError(ret); +} + +bool common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port) { + return common_hal_socketpool_socket_bind(self->sock, host, hostlen, port); +} + +void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self) { + self->closed = true; + common_hal_socketpool_socket_close(self->sock); + mbedtls_pk_free(&self->pkey); + mbedtls_x509_crt_free(&self->cert); + mbedtls_x509_crt_free(&self->cacert); + mbedtls_ssl_free(&self->ssl); + mbedtls_ssl_config_free(&self->conf); + mbedtls_ctr_drbg_free(&self->ctr_drbg); + mbedtls_entropy_free(&self->entropy); +} + +STATIC void do_handshake(ssl_sslsocket_obj_t *self) { + int ret; + while ((ret = mbedtls_ssl_handshake(&self->ssl)) != 0) { + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + goto cleanup; + } + RUN_BACKGROUND_TASKS; + if (MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL) { + mp_handle_pending(true); + } + mp_hal_delay_ms(1); + } + + return; + +cleanup: + self->closed = true; + mbedtls_pk_free(&self->pkey); + mbedtls_x509_crt_free(&self->cert); + mbedtls_x509_crt_free(&self->cacert); + mbedtls_ssl_free(&self->ssl); + mbedtls_ssl_config_free(&self->conf); + mbedtls_ctr_drbg_free(&self->ctr_drbg); + mbedtls_entropy_free(&self->entropy); + + if (ret == MBEDTLS_ERR_SSL_ALLOC_FAILED) { + mp_raise_type(&mp_type_MemoryError); + } else if (ret == MBEDTLS_ERR_PK_BAD_INPUT_DATA) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid key")); + } else if (ret == MBEDTLS_ERR_X509_BAD_INPUT_DATA) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid cert")); + } else { + mbedtls_raise_error(ret); + } +} + +void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port) { + common_hal_socketpool_socket_connect(self->sock, host, hostlen, port); + do_handshake(self); +} + +bool common_hal_ssl_sslsocket_get_closed(ssl_sslsocket_obj_t *self) { + return self->closed; +} + +bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t *self) { + return !self->closed; +} + +bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog) { + return common_hal_socketpool_socket_listen(self->sock, backlog); +} + +ssl_sslsocket_obj_t *common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self, uint8_t *ip, uint32_t *port) { + socketpool_socket_obj_t *sock = common_hal_socketpool_socket_accept(self->sock, ip, port); + ssl_sslsocket_obj_t *sslsock = common_hal_ssl_sslcontext_wrap_socket(self->ssl_context, sock, true, NULL); + do_handshake(sslsock); + return sslsock; +} + +void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, uint32_t timeout_ms) { + self->sock->timeout = timeout_ms; +} diff --git a/ports/raspberrypi/common-hal/ssl/SSLSocket.h b/ports/raspberrypi/common-hal/ssl/SSLSocket.h new file mode 100644 index 0000000000..ad4f0f7092 --- /dev/null +++ b/ports/raspberrypi/common-hal/ssl/SSLSocket.h @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland for Adafruit Industries + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/obj.h" + +#include "common-hal/ssl/SSLContext.h" +#include "common-hal/socketpool/Socket.h" + +#include "mbedtls/platform.h" +#include "mbedtls/ssl.h" +#include "mbedtls/x509_crt.h" +#include "mbedtls/pk.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" + +typedef struct { + mp_obj_base_t base; + socketpool_socket_obj_t *sock; + ssl_sslcontext_obj_t *ssl_context; + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ssl_context ssl; + mbedtls_ssl_config conf; + mbedtls_x509_crt cacert; + mbedtls_x509_crt cert; + mbedtls_pk_context pkey; + bool closed; +} ssl_sslsocket_obj_t; diff --git a/ports/raspberrypi/common-hal/ssl/__init__.c b/ports/raspberrypi/common-hal/ssl/__init__.c new file mode 100644 index 0000000000..a59898b957 --- /dev/null +++ b/ports/raspberrypi/common-hal/ssl/__init__.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/ssl/__init__.h" +#include "shared-bindings/ssl/__init__.h" +#include "shared-bindings/ssl/SSLContext.h" +#include "mbedtls/crt_bundle.h" + +void common_hal_ssl_create_default_context(ssl_sslcontext_obj_t *self) { + common_hal_ssl_sslcontext_construct(self); +} + +void ssl_reset(void) { + crt_bundle_detach(NULL); +} diff --git a/ports/raspberrypi/common-hal/ssl/__init__.h b/ports/raspberrypi/common-hal/ssl/__init__.h new file mode 100644 index 0000000000..6f1757ee47 --- /dev/null +++ b/ports/raspberrypi/common-hal/ssl/__init__.h @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +void ssl_reset(void); diff --git a/ports/raspberrypi/common-hal/wifi/Monitor.c b/ports/raspberrypi/common-hal/wifi/Monitor.c new file mode 100644 index 0000000000..f288cd1ea1 --- /dev/null +++ b/ports/raspberrypi/common-hal/wifi/Monitor.c @@ -0,0 +1,74 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/mpstate.h" +#include "py/runtime.h" + +#include "shared-bindings/wifi/Monitor.h" +#include "shared-bindings/wifi/Packet.h" + + +#define MONITOR_PAYLOAD_FCS_LEN (4) +#define MONITOR_QUEUE_TIMEOUT_TICK (0) + +typedef struct { +} monitor_packet_t; + +void common_hal_wifi_monitor_construct(wifi_monitor_obj_t *self, uint8_t channel, size_t queue) { + mp_raise_NotImplementedError(translate("wifi.Monitor not available")); +} + +bool common_hal_wifi_monitor_deinited(void) { + return true; +} + +void common_hal_wifi_monitor_deinit(wifi_monitor_obj_t *self) { +} + +void common_hal_wifi_monitor_set_channel(wifi_monitor_obj_t *self, uint8_t channel) { +} + +mp_obj_t common_hal_wifi_monitor_get_channel(wifi_monitor_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(0); +} + +mp_obj_t common_hal_wifi_monitor_get_queue(wifi_monitor_obj_t *self) { + return mp_obj_new_int_from_uint(0); +} + +mp_obj_t common_hal_wifi_monitor_get_lost(wifi_monitor_obj_t *self) { + return mp_obj_new_int_from_uint(0); +} + +mp_obj_t common_hal_wifi_monitor_get_queued(wifi_monitor_obj_t *self) { + return mp_obj_new_int_from_uint(0); +} + +mp_obj_t common_hal_wifi_monitor_get_packet(wifi_monitor_obj_t *self) { + return mp_const_none; +} diff --git a/ports/raspberrypi/common-hal/wifi/Monitor.h b/ports/raspberrypi/common-hal/wifi/Monitor.h new file mode 100644 index 0000000000..14ee685bbd --- /dev/null +++ b/ports/raspberrypi/common-hal/wifi/Monitor.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_WIFI_MONITOR_H +#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_WIFI_MONITOR_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t channel; + size_t lost; + size_t queue_length; +} wifi_monitor_obj_t; + +#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_WIFI_MONITOR_H diff --git a/ports/raspberrypi/common-hal/wifi/Network.c b/ports/raspberrypi/common-hal/wifi/Network.c new file mode 100644 index 0000000000..ef81247712 --- /dev/null +++ b/ports/raspberrypi/common-hal/wifi/Network.c @@ -0,0 +1,81 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "shared-bindings/wifi/Network.h" +#include "shared-bindings/wifi/AuthMode.h" + +mp_obj_t common_hal_wifi_network_get_ssid(wifi_network_obj_t *self) { + const char *cstr = (const char *)self->record.ssid; + return mp_obj_new_str(cstr, self->record.ssid_len); +} + +#define MAC_ADDRESS_LENGTH 6 + +mp_obj_t common_hal_wifi_network_get_bssid(wifi_network_obj_t *self) { + return mp_obj_new_bytes(self->record.bssid, MAC_ADDRESS_LENGTH); +} + +mp_obj_t common_hal_wifi_network_get_rssi(wifi_network_obj_t *self) { + return mp_obj_new_int(self->record.rssi); +} + +mp_obj_t common_hal_wifi_network_get_channel(wifi_network_obj_t *self) { + return mp_obj_new_int(self->record.channel); +} + +mp_obj_t common_hal_wifi_network_get_country(wifi_network_obj_t *self) { + return (mp_obj_t)MP_QSTR_; +} + +mp_obj_t common_hal_wifi_network_get_authmode(wifi_network_obj_t *self) { + uint32_t authmode_mask = 0; + if (self->record.auth_mode == 0) { + authmode_mask = AUTHMODE_OPEN; + } + if (self->record.auth_mode & 1) { + authmode_mask |= AUTHMODE_PSK; + } + ; + if (self->record.auth_mode & 2) { + authmode_mask |= AUTHMODE_WPA; + } + ; + if (self->record.auth_mode & 4) { + authmode_mask |= AUTHMODE_WPA2; + } + ; + mp_obj_t authmode_list = mp_obj_new_list(0, NULL); + if (authmode_mask != 0) { + for (uint32_t i = 0; i < 32; i++) { + if ((authmode_mask >> i) & 1) { + mp_obj_list_append(authmode_list, cp_enum_find(&wifi_authmode_type, 1 << i)); + } + } + } + return authmode_list; +} diff --git a/ports/raspberrypi/common-hal/wifi/Network.h b/ports/raspberrypi/common-hal/wifi/Network.h new file mode 100644 index 0000000000..8e4e7bd310 --- /dev/null +++ b/ports/raspberrypi/common-hal/wifi/Network.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/obj.h" + +#include "pico/cyw43_arch.h" + +typedef struct { + mp_obj_base_t base; + cyw43_ev_scan_result_t record; +} wifi_network_obj_t; diff --git a/ports/raspberrypi/common-hal/wifi/Radio.c b/ports/raspberrypi/common-hal/wifi/Radio.c new file mode 100644 index 0000000000..ae14d29ade --- /dev/null +++ b/ports/raspberrypi/common-hal/wifi/Radio.c @@ -0,0 +1,438 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/port.h" +#include "shared-bindings/wifi/Radio.h" +#include "shared-bindings/wifi/Network.h" + +#include +#include + +#include "common-hal/wifi/__init__.h" +#include "shared/runtime/interrupt_char.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "bindings/cyw43/__init__.h" +#include "shared-bindings/ipaddress/IPv4Address.h" +#include "shared-bindings/wifi/ScannedNetworks.h" +#include "shared-bindings/wifi/AuthMode.h" +#include "shared-bindings/time/__init__.h" +#include "shared-module/ipaddress/__init__.h" + +#include "lwip/sys.h" +#include "lwip/dns.h" +#include "lwip/icmp.h" +#include "lwip/raw.h" +#include "lwip_src/ping.h" + +#define MAC_ADDRESS_LENGTH 6 + +#define NETIF_STA (&cyw43_state.netif[CYW43_ITF_STA]) +#define NETIF_AP (&cyw43_state.netif[CYW43_ITF_AP]) + +static inline uint32_t nw_get_le32(const uint8_t *buf) { + return buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24; +} + +static inline void nw_put_le32(uint8_t *buf, uint32_t x) { + buf[0] = x; + buf[1] = x >> 8; + buf[2] = x >> 16; + buf[3] = x >> 24; +} + +NORETURN static void ro_attribute(qstr attr) { + mp_raise_NotImplementedError_varg(translate("%q is read-only for this board"), attr); +} + +bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self) { + return self->enabled; +} + +void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) { + self->enabled = enabled; + // TODO: Actually enable and disable the WiFi module at this point. +} + +mp_obj_t common_hal_wifi_radio_get_hostname(wifi_radio_obj_t *self) { + if (!NETIF_STA->hostname) { + return mp_const_none; + } + return mp_obj_new_str(NETIF_STA->hostname, strlen(NETIF_STA->hostname)); +} + +void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *hostname) { + assert(strlen(hostname) < MP_ARRAY_SIZE(self->hostname)); + memcpy(self->hostname, hostname, strlen(hostname)); + netif_set_hostname(NETIF_STA, self->hostname); + netif_set_hostname(NETIF_AP, self->hostname); +} + +void wifi_radio_get_mac_address(wifi_radio_obj_t *self, uint8_t *mac) { + memcpy(mac, cyw43_state.mac, MAC_ADDRESS_LENGTH); +} + +mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) { + return mp_obj_new_bytes(cyw43_state.mac, MAC_ADDRESS_LENGTH); +} + +void common_hal_wifi_radio_set_mac_address(wifi_radio_obj_t *self, const uint8_t *mac) { + ro_attribute(MP_QSTR_mac_address); +} + +mp_float_t common_hal_wifi_radio_get_tx_power(wifi_radio_obj_t *self) { + uint8_t buf[13]; + memcpy(buf, "qtxpower\x00\x00\x00\x00\x00", 13); + cyw43_ioctl(&cyw43_state, CYW43_IOCTL_GET_VAR, 13, buf, CYW43_ITF_STA); + return nw_get_le32(buf) * MICROPY_FLOAT_CONST(0.25); +} + +void common_hal_wifi_radio_set_tx_power(wifi_radio_obj_t *self, const mp_float_t tx_power) { + mp_int_t dbm_times_four = (int)(4 * tx_power); + uint8_t buf[9 + 4]; + memcpy(buf, "qtxpower\x00", 9); + nw_put_le32(buf + 9, dbm_times_four); + cyw43_ioctl(&cyw43_state, CYW43_IOCTL_SET_VAR, 9 + 4, buf, CYW43_ITF_STA); + cyw43_ioctl(&cyw43_state, CYW43_IOCTL_SET_VAR, 9 + 4, buf, CYW43_ITF_AP); +} + +mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self) { + return common_hal_wifi_radio_get_mac_address(self); +} + +void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, const uint8_t *mac) { + ro_attribute(MP_QSTR_mac_address_ap); +} + +mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, uint8_t start_channel, uint8_t stop_channel) { + // channel bounds are ignored; not implemented in driver + if (self->current_scan) { + mp_raise_RuntimeError(translate("Already scanning for wifi networks")); + } + if (!common_hal_wifi_radio_get_enabled(self)) { + mp_raise_RuntimeError(translate("Wifi is not enabled")); + } + wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t); + scan->base.type = &wifi_scannednetworks_type; + mp_obj_t args[] = { mp_const_empty_tuple, MP_OBJ_NEW_SMALL_INT(16) }; + scan->results = mp_type_deque.make_new(&mp_type_deque, 2, 0, args); + self->current_scan = scan; + wifi_scannednetworks_start_scan(scan); + return scan; +} + +void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self) { + self->current_scan = NULL; +} + +void common_hal_wifi_radio_start_station(wifi_radio_obj_t *self) { + cyw43_arch_enable_sta_mode(); + bindings_cyw43_wifi_enforce_pm(); +} + +void common_hal_wifi_radio_stop_station(wifi_radio_obj_t *self) { + + cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA); + // This is wrong, but without this call the state of ITF_STA is still + // reported as CYW43_LINK_JOIN (by wifi_link_status) and CYW43_LINK_UP + // (by tcpip_link_status). However since ap disconnection isn't working + // either, this is not an issue. + cyw43_wifi_leave(&cyw43_state, CYW43_ITF_AP); + + bindings_cyw43_wifi_enforce_pm(); +} + +void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint32_t authmodes, uint8_t max_connections) { + if (!common_hal_wifi_radio_get_enabled(self)) { + mp_raise_RuntimeError(translate("Wifi is not enabled")); + } + + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_DOWN) { + mp_raise_RuntimeError(translate("Wifi is in station mode.")); + } + + common_hal_wifi_radio_stop_ap(self); + + // Channel can only be changed after inital powerup and config of ap. + // Defaults to 1 if not set or invalid (i.e. 13) + cyw43_wifi_ap_set_channel(&cyw43_state, (const uint32_t)channel); + + cyw43_arch_enable_ap_mode((const char *)ssid, (const char *)password, CYW43_AUTH_WPA2_AES_PSK); + + // TODO: Implement authmode check like in espressif + bindings_cyw43_wifi_enforce_pm(); +} + +void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self) { + if (!common_hal_wifi_radio_get_enabled(self)) { + mp_raise_RuntimeError(translate("wifi is not enabled")); + } + + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_AP) != CYW43_LINK_DOWN) { + mp_raise_NotImplementedError(translate("Stopping AP is not supported.")); + } + + /* + * AP cannot be disconnected. cyw43_wifi_leave is broken. + * This code snippet should work, but doesn't. + * + * cyw43_wifi_leave(&cyw43_state, CYW43_ITF_AP); + * cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA); + * + * bindings_cyw43_wifi_enforce_pm(); + */ +} + +static bool connection_unchanged(wifi_radio_obj_t *self, const uint8_t *ssid, size_t ssid_len) { + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP) { + return false; + } + if (ssid_len != self->connected_ssid_len) { + return false; + } + if (memcmp(ssid, self->connected_ssid, self->connected_ssid_len)) { + return false; + } + return true; +} + +wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, mp_float_t timeout, uint8_t *bssid, size_t bssid_len) { + if (!common_hal_wifi_radio_get_enabled(self)) { + mp_raise_RuntimeError(translate("Wifi is not enabled")); + } + + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_AP) != CYW43_LINK_DOWN) { + mp_raise_RuntimeError(translate("Wifi is in access point mode.")); + } + + if (ssid_len > 32) { + return WIFI_RADIO_ERROR_CONNECTION_FAIL; + } + + size_t timeout_ms = timeout <= 0 ? 8000 : (size_t)MICROPY_FLOAT_C_FUN(ceil)(timeout * 1000); + uint64_t start = port_get_raw_ticks(NULL); + uint64_t deadline = start + timeout_ms; + + if (connection_unchanged(self, ssid, ssid_len)) { + return WIFI_RADIO_ERROR_NONE; + } + + // disconnect + common_hal_wifi_radio_stop_station(self); + + // connect + int auth_mode = password_len ? CYW43_AUTH_WPA2_AES_PSK : CYW43_AUTH_OPEN; + cyw43_arch_wifi_connect_async((const char *)ssid, (const char *)password, auth_mode); + // TODO: Implement authmode check like in espressif + + while (port_get_raw_ticks(NULL) < deadline) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + break; + } + + int result = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA); + + switch (result) { + case CYW43_LINK_UP: + memcpy(self->connected_ssid, ssid, ssid_len); + self->connected_ssid_len = ssid_len; + bindings_cyw43_wifi_enforce_pm(); + return WIFI_RADIO_ERROR_NONE; + case CYW43_LINK_FAIL: + return WIFI_RADIO_ERROR_CONNECTION_FAIL; + case CYW43_LINK_NONET: + return WIFI_RADIO_ERROR_NO_AP_FOUND; + case CYW43_LINK_BADAUTH: + return WIFI_RADIO_ERROR_AUTH_FAIL; + } + } + + // Being here means we either timed out or got interrupted. + return WIFI_RADIO_ERROR_UNSPECIFIED; +} + +mp_obj_t common_hal_wifi_radio_get_ap_info(wifi_radio_obj_t *self) { + mp_raise_NotImplementedError(NULL); +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_gateway(wifi_radio_obj_t *self) { + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP) { + return mp_const_none; + } + return common_hal_ipaddress_new_ipv4address(NETIF_STA->gw.addr); +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_gateway_ap(wifi_radio_obj_t *self) { + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_AP) != CYW43_LINK_UP) { + return mp_const_none; + } + return common_hal_ipaddress_new_ipv4address(NETIF_AP->gw.addr); +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_subnet(wifi_radio_obj_t *self) { + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP) { + return mp_const_none; + } + return common_hal_ipaddress_new_ipv4address(NETIF_STA->netmask.addr); +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_subnet_ap(wifi_radio_obj_t *self) { + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_AP) != CYW43_LINK_UP) { + return mp_const_none; + } + return common_hal_ipaddress_new_ipv4address(NETIF_AP->netmask.addr); +} + +uint32_t wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) { + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP) { + return 0; + } + return NETIF_STA->ip_addr.addr; +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) { + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP) { + return mp_const_none; + } + return common_hal_ipaddress_new_ipv4address(NETIF_STA->ip_addr.addr); +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_address_ap(wifi_radio_obj_t *self) { + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_AP) != CYW43_LINK_UP) { + return mp_const_none; + } + return common_hal_ipaddress_new_ipv4address(NETIF_AP->ip_addr.addr); +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_dns(wifi_radio_obj_t *self) { + uint32_t addr = dns_getserver(0)->addr; + if (cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP || addr == 0) { + return mp_const_none; + } + return common_hal_ipaddress_new_ipv4address(addr); +} + +void common_hal_wifi_radio_set_ipv4_dns(wifi_radio_obj_t *self, mp_obj_t ipv4_dns_addr) { + ip4_addr_t addr; + ipaddress_ipaddress_to_lwip(ipv4_dns_addr, &addr); + dns_setserver(0, &addr); +} + +void common_hal_wifi_radio_start_dhcp_client(wifi_radio_obj_t *self) { + dhcp_start(NETIF_STA); +} + +void common_hal_wifi_radio_stop_dhcp_client(wifi_radio_obj_t *self) { + dhcp_stop(NETIF_STA); +} + +void common_hal_wifi_radio_set_ipv4_address(wifi_radio_obj_t *self, mp_obj_t ipv4, mp_obj_t netmask, mp_obj_t gateway, mp_obj_t ipv4_dns) { + common_hal_wifi_radio_stop_dhcp_client(self); + + ip4_addr_t ipv4_addr, netmask_addr, gateway_addr; + ipaddress_ipaddress_to_lwip(ipv4, &ipv4_addr); + ipaddress_ipaddress_to_lwip(netmask, &netmask_addr); + ipaddress_ipaddress_to_lwip(gateway, &gateway_addr); + netif_set_addr(NETIF_STA, &ipv4_addr, &netmask_addr, &gateway_addr); + if (ipv4_dns != MP_OBJ_NULL) { + common_hal_wifi_radio_set_ipv4_dns(self, ipv4_dns); + } +} + +volatile bool ping_received; +uint32_t ping_time; + +static u8_t +ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) { + struct icmp_echo_hdr *iecho; + LWIP_ASSERT("p != NULL", p != NULL); + + if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) && + pbuf_remove_header(p, PBUF_IP_HLEN) == 0) { + + iecho = (struct icmp_echo_hdr *)p->payload; + + if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) { + LWIP_DEBUGF(PING_DEBUG, ("ping: recv ")); + ip_addr_debug_print(PING_DEBUG, addr); + LWIP_DEBUGF(PING_DEBUG, (" %"U32_F " ms\n", (sys_now() - ping_time))); + + /* do some ping result processing */ + ping_received = true; + pbuf_free(p); + return 1; /* eat the packet */ + } + /* not eaten, restore original packet */ + pbuf_add_header(p, PBUF_IP_HLEN); + } + return 0; /* don't eat the packet */ +} + +mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address, mp_float_t timeout) { + ping_time = sys_now(); + ip_addr_t ping_addr; + ipaddress_ipaddress_to_lwip(ip_address, &ping_addr); + + struct raw_pcb *ping_pcb; + MICROPY_PY_LWIP_ENTER + ping_pcb = raw_new(IP_PROTO_ICMP); + if (!ping_pcb) { + MICROPY_PY_LWIP_EXIT + return -1; + } + raw_recv(ping_pcb, ping_recv, NULL); + raw_bind(ping_pcb, IP_ADDR_ANY); + MICROPY_PY_LWIP_EXIT + + ping_received = false; + ping_send(ping_pcb, &ping_addr); + size_t timeout_ms = (size_t)MICROPY_FLOAT_C_FUN(ceil)(timeout * 1000); + uint64_t start = port_get_raw_ticks(NULL); + uint64_t deadline = start + timeout_ms; + while (port_get_raw_ticks(NULL) < deadline && !ping_received) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + break; + } + } + mp_int_t result = -1; + if (ping_received) { + uint64_t now = port_get_raw_ticks(NULL); + result = now - start; + } + + MICROPY_PY_LWIP_ENTER; + raw_remove(ping_pcb); + MICROPY_PY_LWIP_EXIT; + + return result; +} + +void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self) { + // Only bother to scan the actual object references. + gc_collect_ptr(self->current_scan); +} diff --git a/shared-bindings/multiterminal/__init__.h b/ports/raspberrypi/common-hal/wifi/Radio.h similarity index 70% rename from shared-bindings/multiterminal/__init__.h rename to ports/raspberrypi/common-hal/wifi/Radio.h index 7c28842630..a4125fe7ba 100644 --- a/shared-bindings/multiterminal/__init__.h +++ b/ports/raspberrypi/common-hal/wifi/Radio.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2022 Jeff Epler for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,14 +24,20 @@ * THE SOFTWARE. */ -#ifndef SHARED_BINDINGS_MULTITERMINAL___INIT___H -#define SHARED_BINDINGS_MULTITERMINAL___INIT___H +#pragma once #include "py/obj.h" -void common_hal_multiterminal_schedule_secondary_terminal_read(mp_obj_t socket); -mp_obj_t common_hal_multiterminal_get_secondary_terminal(); -void common_hal_multiterminal_set_secondary_terminal(mp_obj_t secondary_terminal); -void common_hal_multiterminal_clear_secondary_terminal(); +#include "shared-bindings/wifi/ScannedNetworks.h" +#include "shared-bindings/wifi/Network.h" -#endif // SHARED_BINDINGS_MULTITERMINAL___INIT___H +typedef struct { + mp_obj_base_t base; + char hostname[254]; // hostname max is 253 chars, + 1 for trailing NUL + wifi_scannednetworks_obj_t *current_scan; + uint8_t connected_ssid[32]; + uint8_t connected_ssid_len; + bool enabled; +} wifi_radio_obj_t; + +extern void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self); diff --git a/ports/raspberrypi/common-hal/wifi/ScannedNetworks.c b/ports/raspberrypi/common-hal/wifi/ScannedNetworks.c new file mode 100644 index 0000000000..97299e2f74 --- /dev/null +++ b/ports/raspberrypi/common-hal/wifi/ScannedNetworks.c @@ -0,0 +1,115 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "shared/runtime/interrupt_char.h" +#include "py/gc.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "common-hal/wifi/__init__.h" +#include "shared-bindings/wifi/__init__.h" +#include "shared-bindings/wifi/Network.h" +#include "shared-bindings/wifi/Radio.h" +#include "shared-bindings/wifi/ScannedNetworks.h" + +#define NUM_SCAN (16) +static cyw43_ev_scan_result_t scan_results[NUM_SCAN]; +static uint8_t scan_put, scan_get; +static bool scan_full; + + +static void scan_result_put(const cyw43_ev_scan_result_t *result) { + if (!scan_full) { + scan_results[scan_put] = *result; + scan_put = (scan_put + 1) % NUM_SCAN; + scan_full = (scan_put == scan_get); + } +} + +static bool scan_result_available(void) { + return scan_full || (scan_get != scan_put); +} + +static cyw43_ev_scan_result_t *scan_result_get(cyw43_ev_scan_result_t *result) { + if (!scan_result_available()) { + return NULL; + } + + *result = scan_results[scan_get]; + scan_get = (scan_get + 1) % NUM_SCAN; + scan_full = false; + return result; +} + +// Note: It's not OK to allocate memory in here, we can be called at a bad time +// which messes up the gc allocator +static int scan_result(void *env, const cyw43_ev_scan_result_t *result) { + wifi_scannednetworks_obj_t *self = common_hal_wifi_radio_obj.current_scan; + // scan ended or something + if (!self) { + return 0; + } + + scan_result_put(result); + + return 0; +} + +mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) { + // no results available, wait for some + while (!scan_result_available() && cyw43_wifi_scan_active(&cyw43_state)) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + return mp_const_none; + } + cyw43_arch_poll(); + } + + if (!scan_result_available()) { + common_hal_wifi_radio_obj.current_scan = NULL; + return mp_const_none; + } + + + wifi_network_obj_t *entry = m_new_obj(wifi_network_obj_t); + entry->base.type = &wifi_network_type; + scan_result_get(&entry->record); + + return MP_OBJ_FROM_PTR(entry); +} + +void wifi_scannednetworks_deinit(wifi_scannednetworks_obj_t *self) { + // there's actually no way to stop an ongoing scan in cyw43! + common_hal_wifi_radio_obj.current_scan = NULL; +} + +void wifi_scannednetworks_start_scan(wifi_scannednetworks_obj_t *self) { + cyw43_wifi_scan_options_t scan_options = {0}; + CHECK_CYW_RESULT(cyw43_wifi_scan(&cyw43_state, &scan_options, NULL, scan_result)); +} diff --git a/shared-module/multiterminal/__init__.h b/ports/raspberrypi/common-hal/wifi/ScannedNetworks.h similarity index 74% rename from shared-module/multiterminal/__init__.h rename to ports/raspberrypi/common-hal/wifi/ScannedNetworks.h index 30044da065..eae783ca4e 100644 --- a/shared-module/multiterminal/__init__.h +++ b/ports/raspberrypi/common-hal/wifi/ScannedNetworks.h @@ -3,7 +3,8 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Dan Halbert for Adafruit Industries + * Copyright (c) 2018 Artur Pacholec * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,11 +25,18 @@ * THE SOFTWARE. */ -#ifndef SHARED_MODULE_MULTITERMINAL___INIT___H -#define SHARED_MODULE_MULTITERMINAL___INIT___H +#pragma once -mp_obj_t shared_module_multiterminal_get_secondary_terminal(); -void shared_module_multiterminal_set_secondary_terminal(mp_obj_t secondary_terminal); -void shared_module_multiterminal_clear_secondary_terminal(); +#include -#endif // SHARED_MODULE_MULTITERMINAL___INIT___H +#include "py/obj.h" +#include "cyw43.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t results; + bool done; +} wifi_scannednetworks_obj_t; + +void wifi_scannednetworks_deinit(wifi_scannednetworks_obj_t *self); +void wifi_scannednetworks_start_scan(wifi_scannednetworks_obj_t *self); diff --git a/ports/raspberrypi/common-hal/wifi/__init__.c b/ports/raspberrypi/common-hal/wifi/__init__.c new file mode 100644 index 0000000000..e5a646f88f --- /dev/null +++ b/ports/raspberrypi/common-hal/wifi/__init__.c @@ -0,0 +1,124 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/wifi/__init__.h" +#include "shared-bindings/wifi/__init__.h" + +#include "shared-bindings/ipaddress/IPv4Address.h" +#include "shared-bindings/wifi/Monitor.h" +#include "shared-bindings/wifi/Radio.h" + +#include "py/mperrno.h" +#include "py/mpstate.h" +#include "py/runtime.h" + +wifi_radio_obj_t common_hal_wifi_radio_obj; + +#include "supervisor/port.h" +#include "supervisor/shared/status_bar.h" +#include "supervisor/workflow.h" + +static bool wifi_inited; +static bool wifi_ever_inited; +static bool wifi_user_initiated; + +void common_hal_wifi_init(bool user_initiated) { + wifi_radio_obj_t *self = &common_hal_wifi_radio_obj; + + if (wifi_inited) { + if (user_initiated && !wifi_user_initiated) { + common_hal_wifi_radio_set_enabled(self, true); + } + return; + } + wifi_inited = true; + wifi_user_initiated = user_initiated; + common_hal_wifi_radio_obj.base.type = &wifi_radio_type; + common_hal_wifi_radio_obj.current_scan = NULL; + + if (!wifi_ever_inited) { + } + wifi_ever_inited = true; + + // set station mode to avoid the default SoftAP + common_hal_wifi_radio_start_station(self); + // start wifi + common_hal_wifi_radio_set_enabled(self, true); +} + +void wifi_user_reset(void) { + if (wifi_user_initiated) { + // wifi_reset(); + wifi_user_initiated = false; + } +} + +void wifi_reset(void) { + if (!wifi_inited) { + return; + } + // the cyw43 wifi chip is not reset due to https://github.com/raspberrypi/pico-sdk/issues/980 + common_hal_wifi_monitor_deinit(MP_STATE_VM(wifi_monitor_singleton)); + common_hal_wifi_radio_obj.current_scan = NULL; + // common_hal_wifi_radio_set_enabled(radio, false); + supervisor_workflow_request_background(); +} + +void common_hal_wifi_gc_collect(void) { + common_hal_wifi_radio_gc_collect(&common_hal_wifi_radio_obj); +} + +void raise_cyw_error(int err) { + int mp_errno; + switch (err) { + case -CYW43_EIO: + mp_errno = MP_EIO; + break; + case -CYW43_EPERM: + mp_errno = MP_EPERM; + break; + case -CYW43_EINVAL: + mp_errno = MP_EINVAL; + break; + case -CYW43_ETIMEDOUT: + mp_errno = MP_ETIMEDOUT; + break; + default: + mp_raise_OSError_msg_varg(translate("Unkown error code %d"), err); + } + mp_raise_OSError(mp_errno); +} + +void ipaddress_ipaddress_to_lwip(mp_obj_t ip_address, ip_addr_t *lwip_ip_address) { + if (!mp_obj_is_type(ip_address, &ipaddress_ipv4address_type)) { + mp_raise_ValueError(translate("Only IPv4 addresses supported")); + } + mp_obj_t packed = common_hal_ipaddress_ipv4address_get_packed(ip_address); + size_t len; + const char *bytes = mp_obj_str_get_data(packed, &len); + + IP_ADDR4(lwip_ip_address, bytes[0], bytes[1], bytes[2], bytes[3]); +} diff --git a/ports/raspberrypi/common-hal/wifi/__init__.h b/ports/raspberrypi/common-hal/wifi/__init__.h new file mode 100644 index 0000000000..d34d631089 --- /dev/null +++ b/ports/raspberrypi/common-hal/wifi/__init__.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/obj.h" +#include "py/mpconfig.h" +#include "lwip/ip_addr.h" + +void wifi_reset(void); +NORETURN void raise_cyw_error(int err); +#define CHECK_CYW_RESULT(x) do { int res = (x); if (res != 0) raise_cyw_error(res); } while (0) + +void ipaddress_ipaddress_to_lwip(mp_obj_t ip_address, ip_addr_t *lwip_ip_address); diff --git a/ports/raspberrypi/lib/cyw43-driver b/ports/raspberrypi/lib/cyw43-driver new file mode 160000 index 0000000000..e52dd14a15 --- /dev/null +++ b/ports/raspberrypi/lib/cyw43-driver @@ -0,0 +1 @@ +Subproject commit e52dd14a15e6a53e6263840704470246aa77c5ce diff --git a/ports/raspberrypi/lib/lwip b/ports/raspberrypi/lib/lwip new file mode 160000 index 0000000000..d26459c32c --- /dev/null +++ b/ports/raspberrypi/lib/lwip @@ -0,0 +1 @@ +Subproject commit d26459c32c83aa14a6d4e30237d91cee36e0adbd diff --git a/ports/raspberrypi/link.ld b/ports/raspberrypi/link.ld index c9480f84db..982c5e3a0c 100644 --- a/ports/raspberrypi/link.ld +++ b/ports/raspberrypi/link.ld @@ -24,6 +24,7 @@ MEMORY { FLASH_FIRMWARE (rx) : ORIGIN = 0x10000000, LENGTH = 1020k + /* Followed by: 4kB of NVRAM and at least 1024kB of CIRCUITPY */ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256k SCRATCH_X (rwx) : ORIGIN = 0x20040000, LENGTH = 4k SCRATCH_Y (rwx) : ORIGIN = 0x20041000, LENGTH = 4k diff --git a/ports/raspberrypi/lwip_inc/arch/sys_arch.h b/ports/raspberrypi/lwip_inc/arch/sys_arch.h new file mode 100644 index 0000000000..8b1a393741 --- /dev/null +++ b/ports/raspberrypi/lwip_inc/arch/sys_arch.h @@ -0,0 +1 @@ +// empty diff --git a/ports/raspberrypi/lwip_inc/lwipopts.h b/ports/raspberrypi/lwip_inc/lwipopts.h new file mode 100644 index 0000000000..06df7f1318 --- /dev/null +++ b/ports/raspberrypi/lwip_inc/lwipopts.h @@ -0,0 +1,115 @@ +#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H +#define _LWIPOPTS_EXAMPLE_COMMONH_H + + +// Common settings used in most of the pico_w examples +// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details) + +// allow override in some examples +#ifndef NO_SYS +#define NO_SYS 1 +#endif +// allow override in some examples +#ifndef LWIP_SOCKET +#define LWIP_SOCKET 0 +#endif +#if PICO_CYW43_ARCH_POLL +#define MEM_LIBC_MALLOC 1 +#else +// MEM_LIBC_MALLOC is incompatible with non polling versions +#define MEM_LIBC_MALLOC 0 +#endif +#define MEM_ALIGNMENT 4 +#define MEM_SIZE 4000 +#define MEMP_NUM_TCP_SEG 32 +#define MEMP_NUM_ARP_QUEUE 10 +#define PBUF_POOL_SIZE 24 +#define LWIP_ARP 1 +#define LWIP_ETHERNET 1 +#define LWIP_ICMP 1 +#define LWIP_RAW 1 +#define TCP_WND (8 * TCP_MSS) +#define TCP_MSS 1460 +#define TCP_SND_BUF (8 * TCP_MSS) +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS)) +#define LWIP_NETIF_STATUS_CALLBACK 1 +#define LWIP_NETIF_LINK_CALLBACK 1 +#define LWIP_NETIF_HOSTNAME 1 +#define LWIP_NETCONN 0 +#define MEM_STATS 0 +#define SYS_STATS 0 +#define MEMP_STATS 0 +#define LINK_STATS 0 +// #define ETH_PAD_SIZE 2 +#define LWIP_CHKSUM_ALGORITHM 3 +#define LWIP_DHCP 1 +#define LWIP_IPV4 1 +#define LWIP_TCP 1 +#define LWIP_UDP 1 +#define LWIP_DNS 1 +#define LWIP_DNS_SUPPORT_MDNS_QUERIES 1 +#define LWIP_TCP_KEEPALIVE 1 +#define LWIP_NETIF_TX_SINGLE_PBUF 1 +#define DHCP_DOES_ARP_CHECK 0 +#define LWIP_DHCP_DOES_ACD_CHECK 0 +#define SO_REUSE 1 + +#if CIRCUITPY_MDNS +#define LWIP_IGMP 1 +#define LWIP_MDNS_RESPONDER 1 +#define LWIP_NUM_NETIF_CLIENT_DATA 1 +#define LWIP_NETIF_EXT_STATUS_CALLBACK 1 +#define MDNS_MAX_SECONDARY_HOSTNAMES 1 +#define MEMP_NUM_SYS_TIMEOUT (8 + 3 * (LWIP_IPV4 + LWIP_IPV6)) +#endif + +#ifndef NDEBUG +#define LWIP_DEBUG 1 +#define LWIP_STATS 1 +#define LWIP_STATS_DISPLAY 1 +#endif + +#define ETHARP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define INET_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define SYS_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define PPP_DEBUG LWIP_DBG_OFF +#define SLIP_DEBUG LWIP_DBG_OFF +#define DHCP_DEBUG LWIP_DBG_OFF +#define MDNS_DEBUG LWIP_DBG_OFF + +#define LWIP_TIMEVAL_PRIVATE 0 + +#define LWIP_NO_CTYPE_H 1 + +#define X8_F "02x" +#define U16_F "u" +#define U32_F "lu" +#define S32_F "ld" +#define X32_F "lx" + +#define S16_F "d" +#define X16_F "x" +#define SZT_F "u" +#endif /* __LWIPOPTS_H__ */ diff --git a/ports/raspberrypi/lwip_src/ping.c b/ports/raspberrypi/lwip_src/ping.c new file mode 100644 index 0000000000..e59b4d6662 --- /dev/null +++ b/ports/raspberrypi/lwip_src/ping.c @@ -0,0 +1,384 @@ +/** + * @file + * Ping sender module + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +/** + * This is an example of a "ping" sender (with raw API and socket API). + * It can be used as a start point to maintain opened a network connection, or + * like a network "watchdog" for your device. + * + */ + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "ping.h" + +#include "lwip/mem.h" +#include "lwip/raw.h" +#include "lwip/icmp.h" +#include "lwip/netif.h" +#include "lwip/sys.h" +#include "lwip/timeouts.h" +#include "lwip/inet_chksum.h" +#include "lwip/prot/ip4.h" + +#if PING_USE_SOCKETS +#include "lwip/sockets.h" +#include "lwip/inet.h" +#include +#endif /* PING_USE_SOCKETS */ + + +/** + * PING_DEBUG: Enable debugging for PING. + */ +#ifndef PING_DEBUG +#define PING_DEBUG LWIP_DBG_ON +#endif + +/** ping receive timeout - in milliseconds */ +#ifndef PING_RCV_TIMEO +#define PING_RCV_TIMEO 1000 +#endif + +/** ping delay - in milliseconds */ +#ifndef PING_DELAY +#define PING_DELAY 1000 +#endif + +/** ping identifier - must fit on a u16_t */ +#ifndef PING_ID +#define PING_ID 0xAFAF +#endif + +/** ping additional data size to include in the packet */ +#ifndef PING_DATA_SIZE +#define PING_DATA_SIZE 32 +#endif + +/** ping result action - no default action */ +#ifndef PING_RESULT +#define PING_RESULT(ping_ok) +#endif + +/* ping variables */ +static const ip_addr_t *ping_target; +u16_t ping_seq_num; +#ifdef LWIP_DEBUG +static u32_t ping_time; +#endif /* LWIP_DEBUG */ +#if !PING_USE_SOCKETS +static struct raw_pcb *ping_pcb; +#endif /* PING_USE_SOCKETS */ + +/** Prepare a echo ICMP request */ +void +ping_prepare_echo(struct icmp_echo_hdr *iecho, u16_t len) { + size_t i; + size_t data_len = len - sizeof(struct icmp_echo_hdr); + + ICMPH_TYPE_SET(iecho, ICMP_ECHO); + ICMPH_CODE_SET(iecho, 0); + iecho->chksum = 0; + iecho->id = PING_ID; + iecho->seqno = lwip_htons(++ping_seq_num); + + /* fill the additional data buffer with some data */ + for (i = 0; i < data_len; i++) { + ((char *)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i; + } + + iecho->chksum = inet_chksum(iecho, len); +} + +#if PING_USE_SOCKETS + +/* Ping using the socket ip */ +err_t +ping_send(int s, const ip_addr_t *addr) { + int err; + struct icmp_echo_hdr *iecho; + struct sockaddr_storage to; + size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff); + + #if LWIP_IPV6 + if (IP_IS_V6(addr) && !ip6_addr_isipv4mappedipv6(ip_2_ip6(addr))) { + /* todo: support ICMP6 echo */ + return ERR_VAL; + } + #endif /* LWIP_IPV6 */ + + iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size); + if (!iecho) { + return ERR_MEM; + } + + ping_prepare_echo(iecho, (u16_t)ping_size); + + #if LWIP_IPV4 + if (IP_IS_V4(addr)) { + struct sockaddr_in *to4 = (struct sockaddr_in *)&to; + to4->sin_len = sizeof(*to4); + to4->sin_family = AF_INET; + inet_addr_from_ip4addr(&to4->sin_addr, ip_2_ip4(addr)); + } + #endif /* LWIP_IPV4 */ + + #if LWIP_IPV6 + if (IP_IS_V6(addr)) { + struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&to; + to6->sin6_len = sizeof(*to6); + to6->sin6_family = AF_INET6; + inet6_addr_from_ip6addr(&to6->sin6_addr, ip_2_ip6(addr)); + } + #endif /* LWIP_IPV6 */ + + err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr *)&to, sizeof(to)); + + mem_free(iecho); + + return err ? ERR_OK : ERR_VAL; +} + +static void +ping_recv(int s) { + char buf[64]; + int len; + struct sockaddr_storage from; + int fromlen = sizeof(from); + + while ((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, (socklen_t *)&fromlen)) > 0) { + if (len >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr))) { + ip_addr_t fromaddr; + memset(&fromaddr, 0, sizeof(fromaddr)); + + #if LWIP_IPV4 + if (from.ss_family == AF_INET) { + struct sockaddr_in *from4 = (struct sockaddr_in *)&from; + inet_addr_to_ip4addr(ip_2_ip4(&fromaddr), &from4->sin_addr); + IP_SET_TYPE_VAL(fromaddr, IPADDR_TYPE_V4); + } + #endif /* LWIP_IPV4 */ + + #if LWIP_IPV6 + if (from.ss_family == AF_INET6) { + struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from; + inet6_addr_to_ip6addr(ip_2_ip6(&fromaddr), &from6->sin6_addr); + IP_SET_TYPE_VAL(fromaddr, IPADDR_TYPE_V6); + } + #endif /* LWIP_IPV6 */ + + LWIP_DEBUGF(PING_DEBUG, ("ping: recv ")); + ip_addr_debug_print_val(PING_DEBUG, fromaddr); + LWIP_DEBUGF(PING_DEBUG, (" %"U32_F " ms\n", (sys_now() - ping_time))); + + /* todo: support ICMP6 echo */ + #if LWIP_IPV4 + if (IP_IS_V4_VAL(fromaddr)) { + struct ip_hdr *iphdr; + struct icmp_echo_hdr *iecho; + + iphdr = (struct ip_hdr *)buf; + iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4)); + if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) { + /* do some ping result processing */ + PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER)); + return; + } else { + LWIP_DEBUGF(PING_DEBUG, ("ping: drop\n")); + } + } + #endif /* LWIP_IPV4 */ + } + fromlen = sizeof(from); + } + + if (len == 0) { + LWIP_DEBUGF(PING_DEBUG, ("ping: recv - %"U32_F " ms - timeout\n", (sys_now() - ping_time))); + } + + /* do some ping result processing */ + PING_RESULT(0); +} + +static void +ping_thread(void *arg) { + int s; + int ret; + + #if LWIP_SO_SNDRCVTIMEO_NONSTANDARD + int timeout = PING_RCV_TIMEO; + #else + struct timeval timeout; + timeout.tv_sec = PING_RCV_TIMEO / 1000; + timeout.tv_usec = (PING_RCV_TIMEO % 1000) * 1000; + #endif + LWIP_UNUSED_ARG(arg); + + #if LWIP_IPV6 + if (IP_IS_V4(ping_target) || ip6_addr_isipv4mappedipv6(ip_2_ip6(ping_target))) { + s = lwip_socket(AF_INET6, SOCK_RAW, IP_PROTO_ICMP); + } else { + s = lwip_socket(AF_INET6, SOCK_RAW, IP6_NEXTH_ICMP6); + } + #else + s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP); + #endif + if (s < 0) { + return; + } + + ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + LWIP_ASSERT("setting receive timeout failed", ret == 0); + LWIP_UNUSED_ARG(ret); + + while (1) { + if (ping_send(s, ping_target) == ERR_OK) { + LWIP_DEBUGF(PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, ping_target); + LWIP_DEBUGF(PING_DEBUG, ("\n")); + + #ifdef LWIP_DEBUG + ping_time = sys_now(); + #endif /* LWIP_DEBUG */ + ping_recv(s); + } else { + LWIP_DEBUGF(PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, ping_target); + LWIP_DEBUGF(PING_DEBUG, (" - error\n")); + } + sys_msleep(PING_DELAY); + } +} + +#else /* PING_USE_SOCKETS */ + +/* Ping using the raw ip */ +static u8_t +ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) { + struct icmp_echo_hdr *iecho; + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_ASSERT("p != NULL", p != NULL); + + if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) && + pbuf_remove_header(p, PBUF_IP_HLEN) == 0) { + iecho = (struct icmp_echo_hdr *)p->payload; + + if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) { + LWIP_DEBUGF(PING_DEBUG, ("ping: recv ")); + ip_addr_debug_print(PING_DEBUG, addr); + LWIP_DEBUGF(PING_DEBUG, (" %"U32_F " ms\n", (sys_now() - ping_time))); + + /* do some ping result processing */ + PING_RESULT(1); + pbuf_free(p); + return 1; /* eat the packet */ + } + /* not eaten, restore original packet */ + pbuf_add_header(p, PBUF_IP_HLEN); + } + + return 0; /* don't eat the packet */ +} + +int +ping_send(struct raw_pcb *raw, const ip_addr_t *addr) { + struct pbuf *p; + struct icmp_echo_hdr *iecho; + size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + + LWIP_DEBUGF(PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, addr); + LWIP_DEBUGF(PING_DEBUG, ("\n")); + LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff); + + p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM); + if (!p) { + return 0; + } + if ((p->len == p->tot_len) && (p->next == NULL)) { + iecho = (struct icmp_echo_hdr *)p->payload; + + ping_prepare_echo(iecho, (u16_t)ping_size); + + raw_sendto(raw, p, addr); + #ifdef LWIP_DEBUG + ping_time = sys_now(); + #endif /* LWIP_DEBUG */ + } + pbuf_free(p); + return 1; +} + +static void +ping_timeout(void *arg) { + struct raw_pcb *pcb = (struct raw_pcb *)arg; + + LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL); + + ping_send(pcb, ping_target); + + sys_timeout(PING_DELAY, ping_timeout, pcb); +} + +static void +ping_raw_init(void) { + if (ping_pcb) { + return; + } + ping_pcb = raw_new(IP_PROTO_ICMP); + LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL); + + raw_recv(ping_pcb, ping_recv, NULL); + raw_bind(ping_pcb, IP_ADDR_ANY); + sys_timeout(PING_DELAY, ping_timeout, ping_pcb); +} + +#endif /* PING_USE_SOCKETS */ + +void +ping_init(const ip_addr_t *ping_addr) { + ping_target = ping_addr; + + #if PING_USE_SOCKETS + sys_thread_new("ping_thread", ping_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); + #else /* PING_USE_SOCKETS */ + ping_raw_init(); + #endif /* PING_USE_SOCKETS */ +} + +#endif /* LWIP_RAW */ diff --git a/ports/raspberrypi/lwip_src/ping.h b/ports/raspberrypi/lwip_src/ping.h new file mode 100644 index 0000000000..1a02e2450c --- /dev/null +++ b/ports/raspberrypi/lwip_src/ping.h @@ -0,0 +1,33 @@ +#ifndef LWIP_PING_H +#define LWIP_PING_H + +#include "lwip/raw.h" +#include "lwip/ip_addr.h" +#include "lwip/prot/icmp.h" + +/** + * PING_USE_SOCKETS: Set to 1 to use sockets, otherwise the raw api is used + */ +#ifndef PING_USE_SOCKETS +#define PING_USE_SOCKETS LWIP_SOCKET +#endif + +#ifndef PING_ID +#define PING_ID 0xAFAF +#endif + +#ifndef PING_DEBUG +#define PING_DEBUG LWIP_DBG_ON +#endif + +void ping_init(const ip_addr_t *ping_addr); +void ping_prepare_echo(struct icmp_echo_hdr *iecho, u16_t len); + +extern u16_t ping_seq_num; +#if !PING_USE_SOCKETS +void ping_set_target(const ip_addr_t *ping_addr); +int ping_send(struct raw_pcb *raw, const ip_addr_t *addr); +// u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr); +#endif /* !PING_USE_SOCKETS */ + +#endif /* LWIP_PING_H */ diff --git a/ports/raspberrypi/mbedtls/crt_bundle.c b/ports/raspberrypi/mbedtls/crt_bundle.c new file mode 100644 index 0000000000..7fce35872b --- /dev/null +++ b/ports/raspberrypi/mbedtls/crt_bundle.c @@ -0,0 +1,255 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// Copyright 2022 Jeff Epler for Adafruit Industries +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#define BUNDLE_MAX_CERTS (200) + +#include + +#include "py/runtime.h" +#include "py/mperrno.h" +#include "mbedtls/x509_crt.h" +#include "mbedtls/crt_bundle.h" + +#define BUNDLE_HEADER_OFFSET 2 +#define CRT_HEADER_OFFSET 4 + +/* a dummy certificate so that + * cacert_ptr passes non-NULL check during handshake */ +static mbedtls_x509_crt s_dummy_crt; + +#define TAG "x509-crt-bundle" + +#define LOGE(tag, fmt, ...) mp_printf(&mp_plat_print, tag ":" fmt "\n",##__VA_ARGS__) +#if 0 +#define LOGI(tag, fmt, ...) mp_printf(&mp_plat_print, tag ":" fmt "\n",##__VA_ARGS__) +#define LOGD(tag, fmt, ...) mp_printf(&mp_plat_print, tag ":" fmt "\n",##__VA_ARGS__) +#else +#define LOGI(tag, fmt, ...) do {} while (0) +#define LOGD(tag, fmt, ...) do {} while (0) +#endif + +extern const uint8_t x509_crt_imported_bundle_bin_start[] asm ("_binary_x509_crt_bundle_start"); +extern const uint8_t x509_crt_imported_bundle_bin_end[] asm ("_binary_x509_crt_bundle_end"); + + +typedef struct crt_bundle_t { + const uint8_t **crts; + uint16_t num_certs; + size_t x509_crt_bundle_len; +} crt_bundle_t; + +static crt_bundle_t s_crt_bundle; + +static int crt_check_signature(mbedtls_x509_crt *child, const uint8_t *pub_key_buf, size_t pub_key_len); + + +static int crt_check_signature(mbedtls_x509_crt *child, const uint8_t *pub_key_buf, size_t pub_key_len) { + int ret = 0; + mbedtls_x509_crt parent; + const mbedtls_md_info_t *md_info; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + + mbedtls_x509_crt_init(&parent); + + if ((ret = mbedtls_pk_parse_public_key(&parent.pk, pub_key_buf, pub_key_len)) != 0) { + LOGE(TAG, "PK parse failed with error %X", ret); + goto cleanup; + } + + + // Fast check to avoid expensive computations when not necessary + if (!mbedtls_pk_can_do(&parent.pk, child->sig_pk)) { + LOGE(TAG, "Simple compare failed"); + ret = -1; + goto cleanup; + } + + md_info = mbedtls_md_info_from_type(child->sig_md); + if ((ret = mbedtls_md(md_info, child->tbs.p, child->tbs.len, hash)) != 0) { + LOGE(TAG, "Internal mbedTLS error %X", ret); + goto cleanup; + } + + if ((ret = mbedtls_pk_verify_ext(child->sig_pk, child->sig_opts, &parent.pk, + child->sig_md, hash, mbedtls_md_get_size(md_info), + child->sig.p, child->sig.len)) != 0) { + + LOGE(TAG, "PK verify failed with error %X", ret); + goto cleanup; + } +cleanup: + mbedtls_x509_crt_free(&parent); + + return ret; +} + + +/* This callback is called for every certificate in the chain. If the chain + * is proper each intermediate certificate is validated through its parent + * in the x509_crt_verify_chain() function. So this callback should + * only verify the first untrusted link in the chain is signed by the + * root certificate in the trusted bundle +*/ +static int crt_verify_callback(void *buf, mbedtls_x509_crt *crt, int depth, uint32_t *flags) { + mbedtls_x509_crt *child = crt; + + /* It's OK for a trusted cert to have a weak signature hash alg. + as we already trust this certificate */ + uint32_t flags_filtered = *flags & ~(MBEDTLS_X509_BADCERT_BAD_MD); + + if (flags_filtered != MBEDTLS_X509_BADCERT_NOT_TRUSTED) { + return 0; + } + + + if (s_crt_bundle.crts == NULL) { + LOGE(TAG, "No certificates in bundle"); + return MBEDTLS_ERR_X509_FATAL_ERROR; + } + + LOGD(TAG, "%d certificates in bundle", s_crt_bundle.num_certs); + + size_t name_len = 0; + const uint8_t *crt_name; + + bool crt_found = false; + int start = 0; + int end = s_crt_bundle.num_certs - 1; + int middle = (end - start) / 2; + + /* Look for the certificate using binary search on subject name */ + while (start <= end) { + name_len = s_crt_bundle.crts[middle][0] << 8 | s_crt_bundle.crts[middle][1]; + crt_name = s_crt_bundle.crts[middle] + CRT_HEADER_OFFSET; + + int cmp_res = memcmp(child->issuer_raw.p, crt_name, name_len); + if (cmp_res == 0) { + crt_found = true; + break; + } else if (cmp_res < 0) { + end = middle - 1; + } else { + start = middle + 1; + } + middle = (start + end) / 2; + } + + int ret = MBEDTLS_ERR_X509_FATAL_ERROR; + if (crt_found) { + size_t key_len = s_crt_bundle.crts[middle][2] << 8 | s_crt_bundle.crts[middle][3]; + ret = crt_check_signature(child, s_crt_bundle.crts[middle] + CRT_HEADER_OFFSET + name_len, key_len); + } + + if (ret == 0) { + LOGI(TAG, "Certificate validated"); + *flags = 0; + return 0; + } + + LOGE(TAG, "Failed to verify certificate"); + return MBEDTLS_ERR_X509_FATAL_ERROR; +} + + +/* Initialize the bundle into an array so we can do binary search for certs, + the bundle generated by the python utility is already presorted by subject name + */ +static err_t crt_bundle_init(const uint8_t *x509_bundle, size_t bundle_size) { + if (bundle_size < BUNDLE_HEADER_OFFSET + CRT_HEADER_OFFSET) { + LOGE(TAG, "Invalid certificate bundle"); + return -MP_EINVAL; + } + + uint16_t num_certs = (x509_bundle[0] << 8) | x509_bundle[1]; + if (num_certs > BUNDLE_MAX_CERTS) { + // No. of certs in the certificate bundle = %d exceeds\n" + // Max allowed certificates in the certificate bundle = %d\n" + // Please update the menuconfig option with appropriate value", num_certs, BUNDLE_MAX_CERTS + return -MP_E2BIG; + } + + const uint8_t **crts = m_tracked_calloc(num_certs, sizeof(x509_bundle)); + if (crts == NULL) { + LOGE(TAG, "Unable to allocate memory for bundle"); + return -MP_ENOMEM; + } + + const uint8_t *cur_crt; + /* This is the maximum region that is allowed to access */ + const uint8_t *bundle_end = x509_bundle + bundle_size; + cur_crt = x509_bundle + BUNDLE_HEADER_OFFSET; + + for (int i = 0; i < num_certs; i++) { + crts[i] = cur_crt; + if (cur_crt + CRT_HEADER_OFFSET > bundle_end) { + LOGE(TAG, "Invalid certificate bundle"); + m_tracked_free(crts); + return -MP_EINVAL; + } + size_t name_len = cur_crt[0] << 8 | cur_crt[1]; + size_t key_len = cur_crt[2] << 8 | cur_crt[3]; + cur_crt = cur_crt + CRT_HEADER_OFFSET + name_len + key_len; + } + + if (cur_crt > bundle_end) { + LOGE(TAG, "Invalid certificate bundle"); + m_tracked_free(crts); + return -MP_EINVAL; + } + + /* The previous crt bundle is only updated when initialization of the + * current crt_bundle is successful */ + /* Free previous crt_bundle */ + m_tracked_free(s_crt_bundle.crts); + s_crt_bundle.num_certs = num_certs; + s_crt_bundle.crts = crts; + return 0; +} + +int crt_bundle_attach(mbedtls_ssl_config *ssl_conf) { + int ret = 0; + // If no bundle has been set by the user then use the bundle embedded in the binary + if (s_crt_bundle.crts == NULL) { + ret = crt_bundle_init(x509_crt_imported_bundle_bin_start, x509_crt_imported_bundle_bin_end - x509_crt_imported_bundle_bin_start); + } + + if (ret != 0) { + return ret; + } + + if (ssl_conf) { + /* point to a dummy certificate + * This is only required so that the + * cacert_ptr passes non-NULL check during handshake + */ + mbedtls_x509_crt_init(&s_dummy_crt); + mbedtls_ssl_conf_ca_chain(ssl_conf, &s_dummy_crt, NULL); + mbedtls_ssl_conf_verify(ssl_conf, crt_verify_callback, NULL); + } + + return ret; +} + +void crt_bundle_detach(mbedtls_ssl_config *conf) { + m_tracked_free(s_crt_bundle.crts); + s_crt_bundle.crts = NULL; + if (conf) { + mbedtls_ssl_conf_verify(conf, NULL, NULL); + } +} + +int crt_bundle_set(const uint8_t *x509_bundle, size_t bundle_size) { + return crt_bundle_init(x509_bundle, bundle_size); +} diff --git a/ports/raspberrypi/mbedtls/crt_bundle.h b/ports/raspberrypi/mbedtls/crt_bundle.h new file mode 100644 index 0000000000..b265ae4abe --- /dev/null +++ b/ports/raspberrypi/mbedtls/crt_bundle.h @@ -0,0 +1,21 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// Copyright 2022 Jeff Epler for Adafruit Industries +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once +#include "mbedtls/ssl.h" + +int crt_bundle_attach(mbedtls_ssl_config *conf); +void crt_bundle_detach(mbedtls_ssl_config *conf); +int crt_bundle_set(const uint8_t *x509_bundle, size_t bundle_size); diff --git a/ports/raspberrypi/mbedtls/mbedtls_config.h b/ports/raspberrypi/mbedtls/mbedtls_config.h new file mode 100644 index 0000000000..3791924a13 --- /dev/null +++ b/ports/raspberrypi/mbedtls/mbedtls_config.h @@ -0,0 +1,128 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018-2019 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. + */ +#ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_H +#define MICROPY_INCLUDED_MBEDTLS_CONFIG_H + +// If you want to debug MBEDTLS uncomment the following and +// Pass 3 to mbedtls_debug_set_threshold in socket_new +// #define MBEDTLS_DEBUG_C + +// Set mbedtls configuration +#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS +#define MBEDTLS_DEPRECATED_REMOVED +#define MBEDTLS_ENTROPY_HARDWARE_ALT +#define MBEDTLS_AES_ROM_TABLES +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +#define MBEDTLS_ECP_DP_BP256R1_ENABLED +#define MBEDTLS_ECP_DP_BP384R1_ENABLED +#define MBEDTLS_ECP_DP_BP512R1_ENABLED +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +#define MBEDTLS_ECP_NIST_OPTIM +#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED +#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED +#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED +#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_PKCS1_V15 +#define MBEDTLS_SHA256_SMALLER +#define MBEDTLS_SSL_PROTO_TLS1 +#define MBEDTLS_SSL_PROTO_TLS1_1 +#define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_SERVER_NAME_INDICATION + +// Use a smaller output buffer to reduce size of SSL context +#define MBEDTLS_SSL_MAX_CONTENT_LEN (16384) +#define MBEDTLS_SSL_IN_CONTENT_LEN (MBEDTLS_SSL_MAX_CONTENT_LEN) +#define MBEDTLS_SSL_OUT_CONTENT_LEN (4096) + +// Enable mbedtls modules +#define MBEDTLS_AES_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_BASE64_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_CTR_DRBG_C +#define MBEDTLS_ECDH_C +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECP_C +#define MBEDTLS_ENTROPY_C +#define MBEDTLS_ERROR_C +#define MBEDTLS_GCM_C +#define MBEDTLS_MD_C +#define MBEDTLS_MD5_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS5_C +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_RSA_C +#define MBEDTLS_SHA1_C +#define MBEDTLS_SHA256_C +#define MBEDTLS_SHA512_C +#define MBEDTLS_SSL_CLI_C +#define MBEDTLS_SSL_SRV_C +#define MBEDTLS_SSL_TLS_C +#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_USE_C +#define MBEDTLS_HAVE_TIME +#define MBEDTLS_DHM_C // needed by DHE_PSK +#undef MBEDTLS_HAVE_TIME_DATE + +// Memory allocation hooks +#include +#include +void *m_tracked_calloc(size_t nmemb, size_t size); +void m_tracked_free(void *ptr); +#define MBEDTLS_PLATFORM_STD_CALLOC m_tracked_calloc +#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free +#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf + +// Time hook +#include +time_t rp2_rtctime_seconds(time_t *timer); +#define MBEDTLS_PLATFORM_TIME_MACRO rp2_rtctime_seconds + +#include "mbedtls/check_config.h" + +#endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */ diff --git a/ports/cxd56/fatfs_port.c b/ports/raspberrypi/mbedtls/mbedtls_port.c similarity index 64% rename from ports/cxd56/fatfs_port.c rename to ports/raspberrypi/mbedtls/mbedtls_port.c index e672b095b7..596d08ccd9 100644 --- a/ports/cxd56/fatfs_port.c +++ b/ports/raspberrypi/mbedtls/mbedtls_port.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright 2019 Sony Semiconductor Solutions Corporation + * Copyright (c) 2019 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 @@ -23,24 +23,29 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include -#include "py/mphal.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ -#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ +#if CIRCUITPY_SSL_MBEDTLS + +#include "mbedtls_config.h" +#include "mbedtls/entropy_poll.h" + +#include "hardware/rtc.h" #include "shared/timeutils/timeutils.h" +#include "shared-bindings/os/__init__.h" -#if CIRCUITPY_RTC -#include "shared-bindings/rtc/RTC.h" -#endif +extern uint8_t rosc_random_u8(size_t cycles); -DWORD get_fattime(void) { - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif +int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen) { + *olen = len; + common_hal_os_urandom(data, len); + return 0; } + +time_t rp2_rtctime_seconds(time_t *timer) { + datetime_t t; + rtc_get_datetime(&t); + return timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.min, t.sec); +} + +#endif diff --git a/ports/raspberrypi/mpconfigport.h b/ports/raspberrypi/mpconfigport.h index fd09d8a9ac..a2eb9a15ef 100644 --- a/ports/raspberrypi/mpconfigport.h +++ b/ports/raspberrypi/mpconfigport.h @@ -31,9 +31,17 @@ #define MICROPY_PY_SYS_PLATFORM "RP2040" -#define CIRCUITPY_INTERNAL_NVM_SIZE (4 * 1024) -#define CIRCUITPY_INTERNAL_NVM_START_ADDR (0x100FF000) +// Setting a non-default value also requires a non-default link.ld +#ifndef CIRCUITPY_FIRMWARE_SIZE +#define CIRCUITPY_FIRMWARE_SIZE (1020 * 1024) +#endif +#define CIRCUITPY_INTERNAL_NVM_SIZE (4 * 1024) +// This is the XIP address +#define CIRCUITPY_INTERNAL_NVM_START_ADDR (0x10000000 + CIRCUITPY_FIRMWARE_SIZE) + +// This is the flash linear address +#define CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR (CIRCUITPY_FIRMWARE_SIZE + CIRCUITPY_INTERNAL_NVM_SIZE) #define CIRCUITPY_DEFAULT_STACK_SIZE (24 * 1024) #define MICROPY_USE_INTERNAL_PRINTF (1) @@ -49,4 +57,11 @@ mp_obj_t background_pio[NUM_DMA_CHANNELS]; \ CIRCUITPY_COMMON_ROOT_POINTERS; +#if CIRCUITPY_CYW43 +#include "pico/cyw43_arch.h" +#define MICROPY_PY_LWIP_ENTER cyw43_arch_lwip_begin(); +#define MICROPY_PY_LWIP_REENTER MICROPY_PY_LWIP_ENTER +#define MICROPY_PY_LWIP_EXIT cyw43_arch_lwip_end(); +#endif + #endif // __INCLUDED_MPCONFIGPORT_H diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index 32666ed9ea..c5de2a439d 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -2,6 +2,9 @@ LONGINT_IMPL = MPZ CIRCUITPY_OPTIMIZE_PROPERTY_FLASH_SIZE ?= 1 +# CYW43 support does not provide settable MAC addresses for station or AP. +CIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS = 0 + CIRCUITPY_ALARM ?= 1 CIRCUITPY_RP2PIO ?= 1 @@ -20,12 +23,15 @@ CIRCUITPY_ROTARYIO_SOFTENCODER = 1 # Things that need to be implemented. # Use PWM interally CIRCUITPY_FREQUENCYIO = 0 -CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_I2CTARGET = 1 CIRCUITPY_NVM = 1 # Use PIO interally CIRCUITPY_PULSEIO ?= 1 CIRCUITPY_WATCHDOG ?= 1 +# Use of analogbufio +CIRCUITPY_ANALOGBUFIO = 1 + # Audio via PWM CIRCUITPY_AUDIOIO = 0 CIRCUITPY_AUDIOBUSIO ?= 1 @@ -36,6 +42,8 @@ CIRCUITPY_AUDIOMIXER = 1 INTERNAL_LIBM = 1 +CIRCUITPY_BUILD_EXTENSIONS ?= uf2 + # Number of USB endpoint pairs. USB_NUM_ENDPOINT_PAIRS = 8 diff --git a/ports/raspberrypi/peripherals/pins.c b/ports/raspberrypi/peripherals/pins.c index 1b5fe91cac..3b21d3f08c 100644 --- a/ports/raspberrypi/peripherals/pins.c +++ b/ports/raspberrypi/peripherals/pins.c @@ -27,6 +27,7 @@ #include "pins.h" #include "shared-bindings/microcontroller/Pin.h" +#include "bindings/cyw43/__init__.h" // This macro is used to simplify pin definition in boards//pins.c #define PIN(p_number) \ @@ -34,6 +35,11 @@ { &mcu_pin_type }, \ .number = p_number \ } +#define CYW_PIN(p_number) \ + const mcu_pin_obj_t pin_CYW##p_number = { \ + { &cyw43_pin_type }, \ + .number = p_number \ + } PIN(0); PIN(1); @@ -58,10 +64,21 @@ PIN(19); PIN(20); PIN(21); PIN(22); +#if !defined(IGNORE_GPIO23) PIN(23); +#endif +#if !defined(IGNORE_GPIO24) PIN(24); +#endif +#if !defined(IGNORE_GPIO25) PIN(25); +#endif PIN(26); PIN(27); PIN(28); PIN(29); +#if CIRCUITPY_CYW43 +CYW_PIN(0); +CYW_PIN(1); +CYW_PIN(2); +#endif diff --git a/ports/raspberrypi/peripherals/pins.h b/ports/raspberrypi/peripherals/pins.h index 99ab9cfe48..9ec74ed262 100644 --- a/ports/raspberrypi/peripherals/pins.h +++ b/ports/raspberrypi/peripherals/pins.h @@ -62,10 +62,18 @@ extern const mcu_pin_obj_t pin_GPIO21; extern const mcu_pin_obj_t pin_GPIO22; extern const mcu_pin_obj_t pin_GPIO23; extern const mcu_pin_obj_t pin_GPIO24; +#if !defined(IGNORE_GPIO25) extern const mcu_pin_obj_t pin_GPIO25; +#endif extern const mcu_pin_obj_t pin_GPIO26; extern const mcu_pin_obj_t pin_GPIO27; extern const mcu_pin_obj_t pin_GPIO28; extern const mcu_pin_obj_t pin_GPIO29; +#if CIRCUITPY_CYW43 +extern const mcu_pin_obj_t pin_CYW0; +extern const mcu_pin_obj_t pin_CYW1; +extern const mcu_pin_obj_t pin_CYW2; +#endif + #endif // MICROPY_INCLUDED_RASPBERRYPI_PERIPHERALS_PINS_H diff --git a/ports/raspberrypi/pioasm/CMakeLists.txt b/ports/raspberrypi/pioasm/CMakeLists.txt new file mode 100644 index 0000000000..1923068bae --- /dev/null +++ b/ports/raspberrypi/pioasm/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.12) +project(pioasm) +set(PICO_TINYUSB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/tinyusb) +include(../sdk/pico_sdk_init.cmake) +pico_sdk_init() + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PICO_SDK_PATH}/tools) +find_package(Pioasm REQUIRED) diff --git a/ports/raspberrypi/sdk b/ports/raspberrypi/sdk index 426e46126b..2ccab115de 160000 --- a/ports/raspberrypi/sdk +++ b/ports/raspberrypi/sdk @@ -1 +1 @@ -Subproject commit 426e46126b5a1efaea4544cdb71ab81b61983034 +Subproject commit 2ccab115de0d42d31d6611cca19ef0cd0d2ccaa7 diff --git a/ports/raspberrypi/supervisor/internal_flash.c b/ports/raspberrypi/supervisor/internal_flash.c index c128cb74b2..010528559d 100644 --- a/ports/raspberrypi/supervisor/internal_flash.c +++ b/ports/raspberrypi/supervisor/internal_flash.c @@ -46,7 +46,9 @@ #include "src/rp2_common/hardware_flash/include/hardware/flash.h" #include "src/common/pico_binary_info/include/pico/binary_info.h" -#define RESERVED_FLASH (1 * 1024 * 1024) +#if !defined(TOTAL_FLASH_MINIMUM) +#define TOTAL_FLASH_MINIMUM (2 * 1024 * 1024) +#endif // TODO: Split the caching out of supervisor/shared/external_flash so we can use it. #define SECTOR_SIZE 4096 @@ -59,8 +61,8 @@ void supervisor_flash_init(void) { bi_decl_if_func_used(bi_block_device( BINARY_INFO_MAKE_TAG('C', 'P'), "CircuitPython", - RESERVED_FLASH, - (1 * 1024 * 1024), // This is a minimum. We can't set it dynamically. + CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR, + TOTAL_FLASH_MINIMUM - CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR, // This is a minimum. We can't set it dynamically. NULL, BINARY_INFO_BLOCK_DEV_FLAG_READ | BINARY_INFO_BLOCK_DEV_FLAG_WRITE | @@ -86,7 +88,7 @@ uint32_t supervisor_flash_get_block_size(void) { } uint32_t supervisor_flash_get_block_count(void) { - return (_flash_size - RESERVED_FLASH) / FILESYSTEM_BLOCK_SIZE; + return (_flash_size - CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR) / FILESYSTEM_BLOCK_SIZE; } void port_internal_flash_flush(void) { @@ -94,15 +96,15 @@ void port_internal_flash_flush(void) { return; } common_hal_mcu_disable_interrupts(); - flash_range_erase(RESERVED_FLASH + _cache_lba, SECTOR_SIZE); - flash_range_program(RESERVED_FLASH + _cache_lba, _cache, SECTOR_SIZE); + flash_range_erase(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba, SECTOR_SIZE); + flash_range_program(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba, _cache, SECTOR_SIZE); common_hal_mcu_enable_interrupts(); _cache_lba = NO_CACHE; } mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { memcpy(dest, - (void *)(XIP_BASE + RESERVED_FLASH + block * FILESYSTEM_BLOCK_SIZE), + (void *)(XIP_BASE + CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + block * FILESYSTEM_BLOCK_SIZE), num_blocks * FILESYSTEM_BLOCK_SIZE); return 0; } @@ -117,7 +119,7 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32 if (_cache_lba != block_address) { memcpy(_cache, - (void *)(XIP_BASE + RESERVED_FLASH + sector_offset), + (void *)(XIP_BASE + CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + sector_offset), SECTOR_SIZE); _cache_lba = sector_offset; } @@ -133,8 +135,8 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32 } // Make sure we don't have an interrupt while we do flash operations. common_hal_mcu_disable_interrupts(); - flash_range_erase(RESERVED_FLASH + sector_offset, SECTOR_SIZE); - flash_range_program(RESERVED_FLASH + sector_offset, _cache, SECTOR_SIZE); + flash_range_erase(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + sector_offset, SECTOR_SIZE); + flash_range_program(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + sector_offset, _cache, SECTOR_SIZE); common_hal_mcu_enable_interrupts(); } diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index 5041250c0a..f3da71cbd7 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -41,6 +41,14 @@ #include "shared-bindings/rtc/__init__.h" #include "shared-bindings/pwmio/PWMOut.h" +#if CIRCUITPY_SSL +#include "common-hal/ssl/__init__.h" +#endif + +#if CIRCUITPY_WIFI +#include "common-hal/wifi/__init__.h" +#endif + #include "common-hal/rtc/RTC.h" #include "common-hal/busio/UART.h" @@ -53,12 +61,21 @@ #include "src/rp2_common/hardware_uart/include/hardware/uart.h" #include "src/rp2_common/hardware_sync/include/hardware/sync.h" #include "src/rp2_common/hardware_timer/include/hardware/timer.h" +#if CIRCUITPY_CYW43 +#include "py/mphal.h" +#include "pico/cyw43_arch.h" +#endif #include "src/common/pico_time/include/pico/time.h" #include "src/common/pico_binary_info/include/pico/binary_info.h" #include "pico/bootrom.h" #include "hardware/watchdog.h" +#include "supervisor/serial.h" + +#include "tusb.h" +#include + extern volatile bool mp_msc_enabled; STATIC void _tick_callback(uint alarm_num); @@ -110,6 +127,13 @@ safe_mode_t port_init(void) { (&_ld_dtcm_bss_start)[i] = 0; } + #if CIRCUITPY_CYW43 + never_reset_pin_number(23); + never_reset_pin_number(24); + never_reset_pin_number(25); + never_reset_pin_number(29); + #endif + // Reset everything into a known state before board_init. reset_port(); @@ -122,11 +146,25 @@ safe_mode_t port_init(void) { // Check brownout. + #if CIRCUITPY_CYW43 + // A small number of samples of pico w need an additional delay before + // initializing the cyw43 chip. Delays inside cyw43_arch_init_with_country + // are intended to meet the power on timing requirements, but apparently + // are inadequate. We'll back off this long delay based on future testing. + mp_hal_delay_ms(1000); + // Change this as a placeholder as to how to init with country code. + // Default country code is CYW43_COUNTRY_WORLDWIDE) + if (cyw43_arch_init_with_country(PICO_CYW43_ARCH_DEFAULT_COUNTRY_CODE)) { + serial_write("WiFi init failed\n"); + } else { + cyw_ever_init = true; + } + #endif if (board_requests_safe_mode()) { - return USER_SAFE_MODE; + return SAFE_MODE_USER; } - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } void reset_port(void) { @@ -159,6 +197,14 @@ void reset_port(void) { audio_dma_reset(); #endif + #if CIRCUITPY_SSL + ssl_reset(); + #endif + + #if CIRCUITPY_WIFI + wifi_reset(); + #endif + reset_all_pins(); } @@ -209,38 +255,48 @@ uint32_t port_get_saved_word(void) { return __scratch_x_start__; } +static volatile bool ticks_enabled; + uint64_t port_get_raw_ticks(uint8_t *subticks) { uint64_t microseconds = time_us_64(); return 1024 * (microseconds / 1000000) + (microseconds % 1000000) / 977; } STATIC void _tick_callback(uint alarm_num) { - supervisor_tick(); - hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), 977)); + if (ticks_enabled) { + supervisor_tick(); + hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), 977)); + } } // Enable 1/1024 second tick. void port_enable_tick(void) { + ticks_enabled = true; hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), 977)); } // Disable 1/1024 second tick. void port_disable_tick(void) { - // hardware_alarm_cancel(0); + // One additional _tick_callback may occur, but it will just return + // whenever !ticks_enabled. Cancel is not called just in case + // it could nuke a timeout set by port_interrupt_after_ticks. + ticks_enabled = false; } // This is called by sleep, we ignore it when our ticks are enabled because // they'll wake us up earlier. If we don't, we'll mess up ticks by overwriting // the next RTC wake up time. void port_interrupt_after_ticks(uint32_t ticks) { + if (!ticks_enabled) { + hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), ticks * 977)); + } } void port_idle_until_interrupt(void) { common_hal_mcu_disable_interrupts(); - if (!background_callback_pending()) { - // TODO: Does not work when board is power-cycled. - // asm volatile ("dsb 0xF" ::: "memory"); - // __wfi(); + if (!background_callback_pending() && !tud_task_event_ready()) { + __DSB(); + __WFI(); } common_hal_mcu_enable_interrupts(); } @@ -256,8 +312,24 @@ __attribute__((used)) void HardFault_Handler(void) { REG_MTB_MASTER = 0x00000000 + 6; #endif - reset_into_safe_mode(HARD_CRASH); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } + +void port_yield() { + #if CIRCUITPY_CYW43 + cyw43_arch_poll(); + #endif +} + +void port_boot_info(void) { + #if CIRCUITPY_CYW43 + mp_printf(&mp_plat_print, "MAC"); + for (int i = 0; i < 6; i++) { + mp_printf(&mp_plat_print, ":%02X", cyw43_state.mac[i]); + } + mp_printf(&mp_plat_print, "\n"); + #endif +} diff --git a/ports/stm/.gitignore b/ports/stm/.gitignore index 5d645392ca..ade7a0d09d 100644 --- a/ports/stm/.gitignore +++ b/ports/stm/.gitignore @@ -1,9 +1,3 @@ -# Build files -##################### -build-*/ - # Reference files ##################### ref/ - -.gdb_history diff --git a/ports/stm/Makefile b/ports/stm/Makefile index afde51bdc0..325b13b1bc 100755 --- a/ports/stm/Makefile +++ b/ports/stm/Makefile @@ -23,37 +23,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Select the board to build for. -ifeq ($(BOARD),) -$(error You must provide a BOARD parameter) -else -ifeq ($(wildcard boards/$(BOARD)/.),) -$(error Invalid BOARD specified) -endif -endif - -# If the build directory is not given, make it reflect the board name. -BUILD ?= build-$(BOARD) - -include ../../py/mkenv.mk -# Board-specific -include boards/$(BOARD)/mpconfigboard.mk -# Port-specific -include mpconfigport.mk - -# CircuitPython-specific -include $(TOP)/py/circuitpy_mpconfig.mk - -# qstr definitions (must come before including py.mk) -QSTR_DEFS = qstrdefsport.h - -# include py core make definitions -include $(TOP)/py/py.mk - -include $(TOP)/supervisor/supervisor.mk - -# Include make rules and variables common across CircuitPython builds. -include $(TOP)/py/circuitpy_defns.mk +include ../../py/circuitpy_mkenv.mk CROSS_COMPILE = arm-none-eabi- @@ -221,7 +191,6 @@ SRC_STM32 += boards/system_stm32$(MCU_SERIES_LOWER)xx.c SRC_C += \ background.c \ - fatfs_port.c \ mphalport.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ @@ -234,6 +203,17 @@ SRC_C += \ peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/periph.c \ packages/$(MCU_PACKAGE).c +ifneq ($(CIRCUITPY_AUDIOBUSIO_PDMIN),0) + SRC_C += \ + common-hal/audiobusio/MEMS_Audio.c \ + common-hal/audiobusio/MEMS_Audio_ll_stm32l4.c \ + common-hal/audiobusio/OpenPDMFilter.c + + SRC_STM32 += \ + $(HAL_DIR)/Src/stm32$(MCU_SERIES_LOWER)xx_hal_sai.c + +endif + ifneq ($(CIRCUITPY_USB),0) SRC_C += lib/tinyusb/src/portable/st/synopsys/dcd_synopsys.c endif @@ -288,7 +268,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(STEPECHO) "LINK $@" $(Q)echo $^ > $(BUILD)/firmware.objs $(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--start-group $(LIBS) -Wl,--end-group - $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LD_FILE) + $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LD_FILE) $(BUILD) $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(STEPECHO) "Create $@" diff --git a/ports/stm/background.c b/ports/stm/background.c index dbf5ccee2b..68703a5233 100644 --- a/ports/stm/background.c +++ b/ports/stm/background.c @@ -35,6 +35,8 @@ void port_background_task(void) { } +void port_background_tick(void) { +} void port_start_background_task(void) { } void port_finish_background_task(void) { diff --git a/ports/stm/boards/STM32F446_fs.ld b/ports/stm/boards/STM32F446_fs.ld new file mode 100644 index 0000000000..76735cbdc2 --- /dev/null +++ b/ports/stm/boards/STM32F446_fs.ld @@ -0,0 +1,26 @@ +/* + GNU linker script for STM32F446 with filesystem +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K /* entire flash */ + FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */ + FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 48K /* sectors 1,2,3 are 16K */ + FLASH_FIRMWARE (rx) : ORIGIN = 0x08010000, LENGTH = 448K /* sector 4 is 64K, sectors 5,6,7 are 128K */ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 24K; +_minimum_heap_size = 16K; + +/* Define tho top end of the stack. The stack is full descending so begins just + above last byte of RAM. Note that EABI requires the stack to be 8-byte + aligned for a call. */ +_estack = ORIGIN(RAM) + LENGTH(RAM); + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); diff --git a/ports/stm/boards/espruino_pico/board.c b/ports/stm/boards/espruino_pico/board.c index 4286717446..fb1ce4fb83 100644 --- a/ports/stm/boards/espruino_pico/board.c +++ b/ports/stm/boards/espruino_pico/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/espruino_wifi/board.c b/ports/stm/boards/espruino_wifi/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/espruino_wifi/board.c +++ b/ports/stm/boards/espruino_wifi/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/feather_stm32f405_express/board.c b/ports/stm/boards/feather_stm32f405_express/board.c index 4286717446..fb1ce4fb83 100644 --- a/ports/stm/boards/feather_stm32f405_express/board.c +++ b/ports/stm/boards/feather_stm32f405_express/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/meowbit_v121/board.c b/ports/stm/boards/meowbit_v121/board.c index 95d9139998..e4d362bbfa 100644 --- a/ports/stm/boards/meowbit_v121/board.c +++ b/ports/stm/boards/meowbit_v121/board.c @@ -104,8 +104,7 @@ void board_init(void) { sizeof(display_init_sequence), &pin_PB03, NO_BRIGHTNESS_COMMAND, - 1.0f, // brightness (ignored) - false, // auto_brightness + 1.0f, // brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh @@ -120,13 +119,4 @@ void board_init(void) { never_reset_pin_number(pin_PB08.port, pin_PB08.number); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/meowbit_v121/mpconfigboard.mk b/ports/stm/boards/meowbit_v121/mpconfigboard.mk index 77b046ada7..3bbfb7eec8 100644 --- a/ports/stm/boards/meowbit_v121/mpconfigboard.mk +++ b/ports/stm/boards/meowbit_v121/mpconfigboard.mk @@ -13,6 +13,8 @@ MCU_SERIES = F4 MCU_VARIANT = STM32F401xE MCU_PACKAGE = LQFP64 +CIRCUITPY_BUILD_EXTENSIONS = uf2 + OPTIMIZATION_FLAGS = -Os LD_COMMON = boards/common_default.ld diff --git a/ports/stm/boards/nucleo_f446re/board.c b/ports/stm/boards/nucleo_f446re/board.c new file mode 100644 index 0000000000..b75dda3061 --- /dev/null +++ b/ports/stm/boards/nucleo_f446re/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 flom84 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/nucleo_f446re/mpconfigboard.h b/ports/stm/boards/nucleo_f446re/mpconfigboard.h new file mode 100644 index 0000000000..f0155f4624 --- /dev/null +++ b/ports/stm/boards/nucleo_f446re/mpconfigboard.h @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 flom84 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "NUCLEO F446RE" +#define MICROPY_HW_MCU_NAME "STM32F446xx" + +#define FLASH_SIZE (0x80000u) // 512K +#define FLASH_PAGE_SIZE (0x4000u) // 16K + +#define HSE_VALUE ((uint32_t)8000000u) +#define BOARD_HSE_SOURCE (RCC_HSE_ON) +// The schematic has a 32k crystal that isn't fitted. Uncommented the line below if you add it. +// #define BOARD_HAS_LOW_SPEED_CRYSTAL (1) +// #define LSE_VALUE ((uint32_t)32000U) +#define BOARD_HAS_LOW_SPEED_CRYSTAL (0) + +// USART3 + USB FTDI +// #define CIRCUITPY_CONSOLE_UART_TX (&pin_PC10) +// #define CIRCUITPY_CONSOLE_UART_RX (&pin_PC11) + +// USART2 + ST link +// #define CIRCUITPY_CONSOLE_UART_TX (&pin_PA02) +// #define CIRCUITPY_CONSOLE_UART_RX (&pin_PA03) + +// Status LEDs +#define MICROPY_HW_LED_STATUS (&pin_PA05) + +#define MICROPY_FATFS_EXFAT 0 + +#define BOARD_NO_VBUS_SENSE (1) diff --git a/ports/stm/boards/nucleo_f446re/mpconfigboard.mk b/ports/stm/boards/nucleo_f446re/mpconfigboard.mk new file mode 100644 index 0000000000..0887578166 --- /dev/null +++ b/ports/stm/boards/nucleo_f446re/mpconfigboard.mk @@ -0,0 +1,35 @@ +USB_VID = 0x0483 +USB_PID = 0x572A +USB_PRODUCT = "NUCLEO-F446RE - CPy" +USB_MANUFACTURER = "STMicroelectronics" + +INTERNAL_FLASH_FILESYSTEM = 1 + +MCU_SERIES = F4 +MCU_VARIANT = STM32F446xx +MCU_PACKAGE = LQFP64 + +LD_COMMON = boards/common_default.ld +LD_FILE = boards/STM32F446_fs.ld + +# Too big for the flash +CIRCUITPY_AUDIOCORE = 0 +CIRCUITPY_AUDIOPWMIO = 0 +CIRCUITPY_BITMAPTOOLS = 0 +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_VECTORIO = 0 +CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_RAINBOWIO = 0 +CIRCUITPY_USB_HID = 0 +CIRCUITPY_USB_MIDI = 0 +CIRCUITPY_JSON = 0 +# Requires neopixel_write or SPI (dotstar) +CIRCUITPY_PIXELBUF = 0 +# No requirements, but takes extra flash +CIRCUITPY_ULAB = 0 +CIRCUITPY_GAMEPADSHIFT = 0 +CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_SDCARDIO = 0 +CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_KEYPAD = 0 diff --git a/ports/stm/boards/nucleo_f446re/pins.c b/ports/stm/boards/nucleo_f446re/pins.c new file mode 100644 index 0000000000..ac5a457d07 --- /dev/null +++ b/ports/stm/boards/nucleo_f446re/pins.c @@ -0,0 +1,78 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + {MP_ROM_QSTR(MP_QSTR_ID), MP_ROM_PTR(&board_module_id_obj)}, + {MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA03)}, + {MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA02)}, + {MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA10)}, + {MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB03)}, + {MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB05)}, + {MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB04)}, + {MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB10)}, + {MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA08)}, + {MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA09)}, + {MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PC07)}, + {MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB06)}, + {MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA07)}, + {MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA06)}, + {MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA05)}, + {MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB09)}, + {MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PB08)}, + {MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA00)}, + {MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA01)}, + {MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04)}, + {MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB00)}, + {MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PC01)}, + {MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PC00)}, + {MP_ROM_QSTR(MP_QSTR_PA0), MP_ROM_PTR(&pin_PA00)}, + {MP_ROM_QSTR(MP_QSTR_PA1), MP_ROM_PTR(&pin_PA01)}, + {MP_ROM_QSTR(MP_QSTR_PA2), MP_ROM_PTR(&pin_PA02)}, + {MP_ROM_QSTR(MP_QSTR_PA3), MP_ROM_PTR(&pin_PA03)}, + {MP_ROM_QSTR(MP_QSTR_PA4), MP_ROM_PTR(&pin_PA04)}, + {MP_ROM_QSTR(MP_QSTR_PA5), MP_ROM_PTR(&pin_PA05)}, + {MP_ROM_QSTR(MP_QSTR_PA6), MP_ROM_PTR(&pin_PA06)}, + {MP_ROM_QSTR(MP_QSTR_PA7), MP_ROM_PTR(&pin_PA07)}, + {MP_ROM_QSTR(MP_QSTR_PA8), MP_ROM_PTR(&pin_PA08)}, + {MP_ROM_QSTR(MP_QSTR_PA9), MP_ROM_PTR(&pin_PA09)}, + {MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10)}, + {MP_ROM_QSTR(MP_QSTR_PA11), MP_ROM_PTR(&pin_PA11)}, + {MP_ROM_QSTR(MP_QSTR_PA12), MP_ROM_PTR(&pin_PA12)}, + {MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15)}, + {MP_ROM_QSTR(MP_QSTR_PB0), MP_ROM_PTR(&pin_PB00)}, + {MP_ROM_QSTR(MP_QSTR_PB1), MP_ROM_PTR(&pin_PB01)}, + {MP_ROM_QSTR(MP_QSTR_PB2), MP_ROM_PTR(&pin_PB02)}, + {MP_ROM_QSTR(MP_QSTR_PB3), MP_ROM_PTR(&pin_PB03)}, + {MP_ROM_QSTR(MP_QSTR_PB4), MP_ROM_PTR(&pin_PB04)}, + {MP_ROM_QSTR(MP_QSTR_PB5), MP_ROM_PTR(&pin_PB05)}, + {MP_ROM_QSTR(MP_QSTR_PB6), MP_ROM_PTR(&pin_PB06)}, + {MP_ROM_QSTR(MP_QSTR_PB7), MP_ROM_PTR(&pin_PB07)}, + {MP_ROM_QSTR(MP_QSTR_PB8), MP_ROM_PTR(&pin_PB08)}, + {MP_ROM_QSTR(MP_QSTR_PB9), MP_ROM_PTR(&pin_PB09)}, + {MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10)}, + {MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12)}, + {MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13)}, + {MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14)}, + {MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15)}, + {MP_ROM_QSTR(MP_QSTR_PC0), MP_ROM_PTR(&pin_PC00)}, + {MP_ROM_QSTR(MP_QSTR_PC1), MP_ROM_PTR(&pin_PC01)}, + {MP_ROM_QSTR(MP_QSTR_PC2), MP_ROM_PTR(&pin_PC02)}, + {MP_ROM_QSTR(MP_QSTR_PC3), MP_ROM_PTR(&pin_PC03)}, + {MP_ROM_QSTR(MP_QSTR_PC4), MP_ROM_PTR(&pin_PC04)}, + {MP_ROM_QSTR(MP_QSTR_PC5), MP_ROM_PTR(&pin_PC05)}, + {MP_ROM_QSTR(MP_QSTR_PC6), MP_ROM_PTR(&pin_PC06)}, + {MP_ROM_QSTR(MP_QSTR_PC7), MP_ROM_PTR(&pin_PC07)}, + {MP_ROM_QSTR(MP_QSTR_PC8), MP_ROM_PTR(&pin_PC08)}, + {MP_ROM_QSTR(MP_QSTR_PC9), MP_ROM_PTR(&pin_PC09)}, + {MP_ROM_QSTR(MP_QSTR_PC10), MP_ROM_PTR(&pin_PC10)}, + {MP_ROM_QSTR(MP_QSTR_PC11), MP_ROM_PTR(&pin_PC11)}, + {MP_ROM_QSTR(MP_QSTR_PC12), MP_ROM_PTR(&pin_PC12)}, + {MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13)}, + {MP_ROM_QSTR(MP_QSTR_PC14), MP_ROM_PTR(&pin_PC14)}, + {MP_ROM_QSTR(MP_QSTR_PC15), MP_ROM_PTR(&pin_PC15)}, + {MP_ROM_QSTR(MP_QSTR_PD2), MP_ROM_PTR(&pin_PD02)}, + {MP_ROM_QSTR(MP_QSTR_PH0), MP_ROM_PTR(&pin_PH00)}, + {MP_ROM_QSTR(MP_QSTR_PH1), MP_ROM_PTR(&pin_PH01)}, + {MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA05)}, + {MP_ROM_QSTR(MP_QSTR_SW), MP_ROM_PTR(&pin_PC13)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/stm/boards/nucleo_f746zg/board.c b/ports/stm/boards/nucleo_f746zg/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/nucleo_f746zg/board.c +++ b/ports/stm/boards/nucleo_f746zg/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/nucleo_f767zi/board.c b/ports/stm/boards/nucleo_f767zi/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/nucleo_f767zi/board.c +++ b/ports/stm/boards/nucleo_f767zi/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/nucleo_h743zi_2/board.c b/ports/stm/boards/nucleo_h743zi_2/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/nucleo_h743zi_2/board.c +++ b/ports/stm/boards/nucleo_h743zi_2/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/openmv_h7/board.c b/ports/stm/boards/openmv_h7/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/openmv_h7/board.c +++ b/ports/stm/boards/openmv_h7/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/pyb_nano_v2/board.c b/ports/stm/boards/pyb_nano_v2/board.c index 4286717446..fb1ce4fb83 100644 --- a/ports/stm/boards/pyb_nano_v2/board.c +++ b/ports/stm/boards/pyb_nano_v2/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/pyb_nano_v2/mpconfigboard.mk b/ports/stm/boards/pyb_nano_v2/mpconfigboard.mk index 3ba45e0c5b..c8b548c50f 100644 --- a/ports/stm/boards/pyb_nano_v2/mpconfigboard.mk +++ b/ports/stm/boards/pyb_nano_v2/mpconfigboard.mk @@ -16,10 +16,4 @@ LD_FILE = boards/STM32F411_fs.ld # Too big for the flash CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_AUDIOPWMIO = 0 -CIRCUITPY_BITMAPTOOLS = 0 CIRCUITPY_BLEIO_HCI = 0 -CIRCUITPY_BUSDEVICE = 0 -CIRCUITPY_GIFIO = 0 -CIRCUITPY_KEYPAD = 0 -CIRCUITPY_MSGPACK = 0 -CIRCUITPY_ONEWIREIO = 0 diff --git a/ports/stm/boards/pyboard_v11/board.c b/ports/stm/boards/pyboard_v11/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/pyboard_v11/board.c +++ b/ports/stm/boards/pyboard_v11/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/sparkfun_stm32_thing_plus/mpconfigboard.mk b/ports/stm/boards/sparkfun_stm32_thing_plus/mpconfigboard.mk index 62d0136be5..24505eb23d 100644 --- a/ports/stm/boards/sparkfun_stm32_thing_plus/mpconfigboard.mk +++ b/ports/stm/boards/sparkfun_stm32_thing_plus/mpconfigboard.mk @@ -19,3 +19,5 @@ LD_BOOT = boards/STM32F405_boot.ld UF2_OFFSET = 0x8010000 CIRCUITPY_RGBMATRIX ?= 1 + +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 diff --git a/ports/stm/boards/sparkfun_stm32f405_micromod/board.c b/ports/stm/boards/sparkfun_stm32f405_micromod/board.c index 4286717446..f081e7fa90 100644 --- a/ports/stm/boards/sparkfun_stm32f405_micromod/board.c +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/board.c @@ -27,16 +27,4 @@ #include "supervisor/board.h" #include "mpconfigboard.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/stm32f411ce_blackpill/board.c b/ports/stm/boards/stm32f411ce_blackpill/board.c index 4286717446..fb1ce4fb83 100644 --- a/ports/stm/boards/stm32f411ce_blackpill/board.c +++ b/ports/stm/boards/stm32f411ce_blackpill/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/stm32f411ce_blackpill_with_flash/board.c b/ports/stm/boards/stm32f411ce_blackpill_with_flash/board.c index 4286717446..fb1ce4fb83 100644 --- a/ports/stm/boards/stm32f411ce_blackpill_with_flash/board.c +++ b/ports/stm/boards/stm32f411ce_blackpill_with_flash/board.c @@ -25,18 +25,5 @@ */ #include "supervisor/board.h" -#include "mpconfigboard.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/stm32f411ve_discovery/board.c b/ports/stm/boards/stm32f411ve_discovery/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/stm32f411ve_discovery/board.c +++ b/ports/stm/boards/stm32f411ve_discovery/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/stm32f412zg_discovery/board.c b/ports/stm/boards/stm32f412zg_discovery/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/stm32f412zg_discovery/board.c +++ b/ports/stm/boards/stm32f412zg_discovery/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/stm32f4_discovery/board.c b/ports/stm/boards/stm32f4_discovery/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/stm32f4_discovery/board.c +++ b/ports/stm/boards/stm32f4_discovery/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/stm32f746g_discovery/board.c b/ports/stm/boards/stm32f746g_discovery/board.c index 8f35532627..56c90bd8c6 100644 --- a/ports/stm/boards/stm32f746g_discovery/board.c +++ b/ports/stm/boards/stm32f746g_discovery/board.c @@ -48,13 +48,4 @@ void board_init(void) { never_reset_pin_number(10, 3); } -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/swan_r5/board.c b/ports/stm/boards/swan_r5/board.c index 4f29be35f8..602fd87537 100644 --- a/ports/stm/boards/swan_r5/board.c +++ b/ports/stm/boards/swan_r5/board.c @@ -88,13 +88,8 @@ void board_init(void) { HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET); } -bool board_requests_safe_mode(void) { - return false; -} - void reset_board(void) { initialize_discharge_pin(); } -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/swan_r5/mpconfigboard.h b/ports/stm/boards/swan_r5/mpconfigboard.h index 94cc58ff9d..8c6949201e 100644 --- a/ports/stm/boards/swan_r5/mpconfigboard.h +++ b/ports/stm/boards/swan_r5/mpconfigboard.h @@ -45,6 +45,9 @@ #define BOARD_HAS_LOW_SPEED_CRYSTAL (1) #define BOARD_HAS_HIGH_SPEED_CRYSTAL (0) +// Increase drive strength of 32kHz external crystal, in line with calculations specified in ST AN2867 sections 3.3, 3.4, and STM32L4 datasheet DS12023 Table 58. LSE oscillator characteristics. +// The drive strength RCC_LSEDRIVE_LOW is marginal for the 32kHz crystal oscillator stability, and RCC_LSEDRIVE_MEDIUMLOW meets the calculated drive strength with a small margin for parasitic capacitance. +#define BOARD_LSE_DRIVE_LEVEL RCC_LSEDRIVE_MEDIUMLOW // Bootloader only #ifdef UF2_BOOTLOADER_ENABLED diff --git a/ports/stm/boards/swan_r5/mpconfigboard.mk b/ports/stm/boards/swan_r5/mpconfigboard.mk index 5d51c9406b..ea4125e02b 100644 --- a/ports/stm/boards/swan_r5/mpconfigboard.mk +++ b/ports/stm/boards/swan_r5/mpconfigboard.mk @@ -15,59 +15,42 @@ LD_DEFAULT = boards/STM32L4R5_default.ld LD_BOOT = boards/STM32L4R5_boot.ld UF2_OFFSET = 0x8010000 UF2_BOOTLOADER ?= 1 +CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 -# Turn all of the below off while trying to get the thing to run -# These modules are implemented in ports//common-hal: - -# Typically the first module to create -CIRCUITPY_MICROCONTROLLER = 1 CIRCUITPY_ALARM = 1 - -# Typically the second module to create -CIRCUITPY_DIGITALIO = 1 -# Other modules: - -CIRCUITPY_OS = 1 -CIRCUITPY_STORAGE = 1 -CIRCUITPY_USB_MSC = 1 -CIRCUITPY_UDB_CDC = 1 -CIRCUITPY_USB_VENDOR = 1 -CIRCUITPY_NVM = 0 - CIRCUITPY_ANALOGIO = 1 +CIRCUITPY_AUDIOBUSIO = 1 +CIRCUITPY_AUDIOBUSIO_I2SOUT = 0 +CIRCUITPY_AUDIOBUSIO_PDMIN = 1 +CIRCUITPY_AUDIOPWMIO = 1 +CIRCUITPY_BITBANGIO = 1 +CIRCUITPY_BLEIO = 0 +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_BUSIO = 1 +CIRCUITPY_CANIO = 0 +CIRCUITPY_DIGITALIO = 1 +CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_ENABLE_MPY_NATIVE = 1 +CIRCUITPY_I2CTARGET = 0 +CIRCUITPY_KEYPAD = 1 +CIRCUITPY_MICROCONTROLLER = 1 CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_NVM = 0 +CIRCUITPY_OS = 1 +CIRCUITPY_PIXELBUF = 0 CIRCUITPY_PULSEIO = 1 CIRCUITPY_PWMIO = 1 -CIRCUITPY_AUDIOPWMIO = 1 -CIRCUITPY_CANIO = 0 -CIRCUITPY_AUDIOBUSIO = 0 -CIRCUITPY_I2CPERIPHERAL = 0 -# Requires SPI, PulseIO (stub ok): -CIRCUITPY_DISPLAYIO = 0 - -# These modules are implemented in shared-module/ - they can be included in -# any port once their prerequisites in common-hal are complete. -# Requires DigitalIO: -CIRCUITPY_BITBANGIO = 1 -# Requires neopixel_write or SPI (dotstar) -CIRCUITPY_PIXELBUF = 0 -# Requires OS CIRCUITPY_RANDOM = 1 -# Requires Microcontroller -CIRCUITPY_TOUCHIO = 1 -# Requires USB -CIRCUITPY_USB_HID = 0 -CIRCUITPY_USB_MIDI = 0 -# Does nothing without I2C CIRCUITPY_REQUIRE_I2C_PULLUPS = 0 -# No requirements, but takes extra flash -CIRCUITPY_ULAB = 1 -# requires SPI -CIRCUITPY_SDCARDIO = 0 -CIRCUITPY_BLEIO_HCI = 0 -CIRCUITPY_BLEIO = 0 -CIRCUITPY_BUSDEVICE = 0 -CIRCUITPY_KEYPAD = 1 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_RTC = 1 +CIRCUITPY_SDCARDIO = 0 +CIRCUITPY_STORAGE = 1 +CIRCUITPY_TOUCHIO = 1 +CIRCUITPY_UDB_CDC = 1 +CIRCUITPY_ULAB = 1 +CIRCUITPY_USB_HID = 0 +CIRCUITPY_USB_MIDI = 0 +CIRCUITPY_USB_MSC = 1 +CIRCUITPY_USB_VENDOR = 1 diff --git a/ports/stm/boards/swan_r5/pins.c b/ports/stm/boards/swan_r5/pins.c index cf97c3587a..dc273cb6d4 100644 --- a/ports/stm/boards/swan_r5/pins.c +++ b/ports/stm/boards/swan_r5/pins.c @@ -129,5 +129,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_PC03) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/stm/boards/swan_r5/tests/board_voltage.py b/ports/stm/boards/swan_r5/tests/board_voltage.py index 6191067fde..2cb0ad4cc0 100644 --- a/ports/stm/boards/swan_r5/tests/board_voltage.py +++ b/ports/stm/boards/swan_r5/tests/board_voltage.py @@ -44,6 +44,7 @@ PASS = "PASS" FAIL = "FAIL" NA = "N/A" + # Determine if given value is a number def _is_number(val): try: @@ -61,7 +62,6 @@ def _deinit_pins(gpios): # Toggle IO pins while waiting for answer def _toggle_wait(pin_gpios): - timestamp = time.monotonic() led_state = False failed = [] @@ -96,7 +96,6 @@ def buildPin(pin): def run_test(pins): - """ Toggles all available GPIO on and off repeatedly. @@ -114,7 +113,6 @@ def run_test(pins): gpio_pins = analog_pins + digital_pins if gpio_pins: - # Print out the LEDs found print("GPIO pins found:", end=" ") for pin in gpio_pins: diff --git a/ports/stm/boards/thunderpack_v11/board.c b/ports/stm/boards/thunderpack_v11/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/thunderpack_v11/board.c +++ b/ports/stm/boards/thunderpack_v11/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/thunderpack_v12/board.c b/ports/stm/boards/thunderpack_v12/board.c index b4070e72dc..fb1ce4fb83 100644 --- a/ports/stm/boards/thunderpack_v12/board.c +++ b/ports/stm/boards/thunderpack_v12/board.c @@ -26,16 +26,4 @@ #include "supervisor/board.h" -void board_init(void) { -} - -bool board_requests_safe_mode(void) { - return false; -} - -void reset_board(void) { - -} - -void board_deinit(void) { -} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/thunderpack_v12/mpconfigboard.mk b/ports/stm/boards/thunderpack_v12/mpconfigboard.mk index f7905f6945..526415ca30 100644 --- a/ports/stm/boards/thunderpack_v12/mpconfigboard.mk +++ b/ports/stm/boards/thunderpack_v12/mpconfigboard.mk @@ -14,7 +14,6 @@ EXTERNAL_FLASH_DEVICES = GD25Q16C CIRCUITPY_NVM = 1 CIRCUITPY_BITMAPTOOLS = 0 CIRCUITPY_BLEIO_HCI = 0 -CIRCUITPY_ONEWIREIO = 0 CIRCUITPY_ZLIB = 0 MCU_SERIES = F4 diff --git a/ports/stm/common-hal/alarm/SleepMemory.h b/ports/stm/common-hal/alarm/SleepMemory.h index 0e9fc54904..14848cd5a0 100644 --- a/ports/stm/common-hal/alarm/SleepMemory.h +++ b/ports/stm/common-hal/alarm/SleepMemory.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_SLEEPMEMORY_H -#define MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_SLEEPMEMORY_H +#pragma once #include "py/obj.h" @@ -34,5 +33,3 @@ typedef struct { } alarm_sleep_memory_obj_t; extern void alarm_sleep_memory_reset(void); - -#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_SLEEPMEMORY_H diff --git a/ports/stm/common-hal/alarm/__init__.c b/ports/stm/common-hal/alarm/__init__.c index 466c2d5199..78d50b41a8 100644 --- a/ports/stm/common-hal/alarm/__init__.c +++ b/ports/stm/common-hal/alarm/__init__.c @@ -47,6 +47,10 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = { }, }; +// Non-heap alarm object recording alarm (if any) that woke up CircuitPython after light or deep sleep. +// This object lives across VM instantiations, so none of these objects can contain references to the heap. +alarm_wake_alarm_union_t alarm_wake_alarm; + STATIC stm_sleep_source_t true_deep_wake_reason; void alarm_reset(void) { @@ -81,16 +85,16 @@ bool common_hal_alarm_woken_from_sleep(void) { return alarm_get_wakeup_cause() != STM_WAKEUP_UNDEF; } -mp_obj_t common_hal_alarm_create_wake_alarm(void) { +mp_obj_t common_hal_alarm_record_wake_alarm(void) { // If woken from deep sleep, create a copy alarm similar to what would have // been passed in originally. Otherwise, just return none stm_sleep_source_t cause = alarm_get_wakeup_cause(); switch (cause) { case STM_WAKEUP_RTC: { - return alarm_time_timealarm_create_wakeup_alarm(); + return alarm_time_timealarm_record_wake_alarm(); } case STM_WAKEUP_GPIO: { - return alarm_pin_pinalarm_create_wakeup_alarm(); + return alarm_pin_pinalarm_record_wake_alarm(); } case STM_WAKEUP_UNDEF: default: @@ -144,7 +148,10 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj return wake_alarm; } -void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { +void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t **preserve_dios) { + if (n_dios > 0) { + mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_preserve_dios); + } _setup_sleep_alarms(true, n_alarms, alarms); } diff --git a/ports/stm/common-hal/alarm/__init__.h b/ports/stm/common-hal/alarm/__init__.h index 6c72364fc3..c87cb3b1eb 100644 --- a/ports/stm/common-hal/alarm/__init__.h +++ b/ports/stm/common-hal/alarm/__init__.h @@ -24,10 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM__INIT__H -#define MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM__INIT__H +#pragma once #include "common-hal/alarm/SleepMemory.h" +#include "common-hal/alarm/pin/PinAlarm.h" +#include "common-hal/alarm/time/TimeAlarm.h" extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; @@ -37,10 +38,15 @@ typedef enum { STM_WAKEUP_RTC } stm_sleep_source_t; +typedef union { + alarm_pin_pinalarm_obj_t pin_alarm; + alarm_time_timealarm_obj_t time_alarm; +} alarm_wake_alarm_union_t; + +extern alarm_wake_alarm_union_t alarm_wake_alarm; + #define STM_ALARM_FLAG (RTC->BKP0R) extern void alarm_set_wakeup_reason(stm_sleep_source_t reason); -stm_sleep_source_t alarm_get_wakeup_cause(void); +extern stm_sleep_source_t alarm_get_wakeup_cause(void); extern void alarm_reset(void); - -#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM__INIT__H diff --git a/ports/stm/common-hal/alarm/coproc/CoprocAlarm.c b/ports/stm/common-hal/alarm/coproc/CoprocAlarm.c new file mode 100644 index 0000000000..4bd8276f34 --- /dev/null +++ b/ports/stm/common-hal/alarm/coproc/CoprocAlarm.c @@ -0,0 +1 @@ +// empty file diff --git a/ports/stm/common-hal/alarm/coproc/CoprocAlarm.h b/ports/stm/common-hal/alarm/coproc/CoprocAlarm.h new file mode 100644 index 0000000000..4bd8276f34 --- /dev/null +++ b/ports/stm/common-hal/alarm/coproc/CoprocAlarm.h @@ -0,0 +1 @@ +// empty file diff --git a/ports/stm/common-hal/alarm/pin/PinAlarm.c b/ports/stm/common-hal/alarm/pin/PinAlarm.c index 799922ae8f..161bd9fea6 100644 --- a/ports/stm/common-hal/alarm/pin/PinAlarm.c +++ b/ports/stm/common-hal/alarm/pin/PinAlarm.c @@ -26,9 +26,8 @@ #include "py/runtime.h" +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/microcontroller/Pin.h" #include "peripherals/exti.h" @@ -102,8 +101,9 @@ mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t return mp_const_none; } -mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) { - alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t); +mp_obj_t alarm_pin_pinalarm_record_wake_alarm(void) { + alarm_pin_pinalarm_obj_t *const alarm = &alarm_wake_alarm.pin_alarm; + alarm->base.type = &alarm_pin_pinalarm_type; // TODO: replace this if/when other WKUP pins are supported alarm->pin = &pin_PA00; diff --git a/ports/stm/common-hal/alarm/pin/PinAlarm.h b/ports/stm/common-hal/alarm/pin/PinAlarm.h index bc52849a53..77e0c6143e 100644 --- a/ports/stm/common-hal/alarm/pin/PinAlarm.h +++ b/ports/stm/common-hal/alarm/pin/PinAlarm.h @@ -24,12 +24,13 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_PINALARM_H -#define MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_PINALARM_H +#pragma once #include "py/obj.h" #include "py/objtuple.h" +#include "shared-bindings/microcontroller/Pin.h" + typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *pin; @@ -38,11 +39,9 @@ typedef struct { } alarm_pin_pinalarm_obj_t; mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void); +mp_obj_t alarm_pin_pinalarm_record_wake_alarm(void); void alarm_pin_pinalarm_reset(void); void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); void alarm_pin_pinalarm_prepare_for_deep_sleep(void); bool alarm_pin_pinalarm_woke_this_cycle(void); - -#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_PINALARM_H diff --git a/ports/stm/common-hal/alarm/time/TimeAlarm.c b/ports/stm/common-hal/alarm/time/TimeAlarm.c index 2eb8ee4a81..9ba6ed7658 100644 --- a/ports/stm/common-hal/alarm/time/TimeAlarm.c +++ b/ports/stm/common-hal/alarm/time/TimeAlarm.c @@ -26,9 +26,9 @@ #include "py/runtime.h" +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/time/__init__.h" -#include "supervisor/port.h" #include "peripherals/rtc.h" #include STM32_HAL_H @@ -54,12 +54,13 @@ mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj return mp_const_none; } -mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) { - alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t); - timer->base.type = &alarm_time_timealarm_type; +mp_obj_t alarm_time_timealarm_record_wake_alarm(void) { + alarm_time_timealarm_obj_t *const alarm = &alarm_wake_alarm.time_alarm; + + alarm->base.type = &alarm_time_timealarm_type; // TODO: Set monotonic_time based on the RTC state. - timer->monotonic_time = 0.0f; - return timer; + alarm->monotonic_time = 0.0f; + return alarm; } // This is run in the timer task. We use it to wake the main CircuitPython task. diff --git a/ports/stm/common-hal/alarm/time/TimeAlarm.h b/ports/stm/common-hal/alarm/time/TimeAlarm.h index 48531ebdf6..e3b9caadcd 100644 --- a/ports/stm/common-hal/alarm/time/TimeAlarm.h +++ b/ports/stm/common-hal/alarm/time/TimeAlarm.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_TIMEALARM_H -#define MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_TIMEALARM_H +#pragma once #include "py/obj.h" @@ -35,12 +34,10 @@ typedef struct { } alarm_time_timealarm_obj_t; mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); -mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void); +mp_obj_t alarm_time_timealarm_record_wake_alarm(void); bool alarm_time_timealarm_woke_this_cycle(void); void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); void alarm_time_timealarm_reset(void); void alarm_time_timealarm_prepare_for_deep_sleep(void); - -#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_TIMEALARM_H diff --git a/ports/stm/common-hal/alarm/touch/TouchAlarm.h b/ports/stm/common-hal/alarm/touch/TouchAlarm.h index 6c89353f93..59f202c69d 100644 --- a/ports/stm/common-hal/alarm/touch/TouchAlarm.h +++ b/ports/stm/common-hal/alarm/touch/TouchAlarm.h @@ -24,12 +24,9 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_TOUCHALARM_H -#define MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_TOUCHALARM_H +#pragma once typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *pin; } alarm_touch_touchalarm_obj_t; - -#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_TOUCHALARM_H diff --git a/ports/stm/common-hal/analogio/AnalogOut.c b/ports/stm/common-hal/analogio/AnalogOut.c index 3c2860c9ad..4dd8783545 100644 --- a/ports/stm/common-hal/analogio/AnalogOut.c +++ b/ports/stm/common-hal/analogio/AnalogOut.c @@ -28,9 +28,12 @@ #include #include + #include "py/mperrno.h" #include "py/runtime.h" + + #include "shared-bindings/analogio/AnalogOut.h" #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/shared/translate/translate.h" diff --git a/ports/stm/common-hal/audiobusio/I2SOut.c b/ports/stm/common-hal/audiobusio/I2SOut.c new file mode 100644 index 0000000000..b63c3e7b22 --- /dev/null +++ b/ports/stm/common-hal/audiobusio/I2SOut.c @@ -0,0 +1 @@ +// Although IS2Out is not enabled on the STM32L4 family, this file is still required for the build to pass diff --git a/ports/stm/common-hal/audiobusio/I2SOut.h b/ports/stm/common-hal/audiobusio/I2SOut.h new file mode 100644 index 0000000000..b63c3e7b22 --- /dev/null +++ b/ports/stm/common-hal/audiobusio/I2SOut.h @@ -0,0 +1 @@ +// Although IS2Out is not enabled on the STM32L4 family, this file is still required for the build to pass diff --git a/ports/stm/common-hal/audiobusio/MEMS_Audio.c b/ports/stm/common-hal/audiobusio/MEMS_Audio.c new file mode 100644 index 0000000000..624ffc92b0 --- /dev/null +++ b/ports/stm/common-hal/audiobusio/MEMS_Audio.c @@ -0,0 +1,96 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Matthew McGowan for Blues Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "MEMS_Audio.h" +#include "MEMS_Audio_ll.h" + +static void default_pcm_data_available(MemsAudio *audio, pcm_sample_t *pcmSamples, size_t pcmLength) { +} + + + +/** + * @brief Initializes the MemsAudio instance. Only one instance can be initialized and used at a given time. + * + * @param audio + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_init(MemsAudio *audio) { + if (!audio->pcm_data_available) { + audio->pcm_data_available = default_pcm_data_available; + } + return mems_audio_ll_init(audio); +} + +/** + * @brief Uninitializes the MemsAudio instance. + * + * @param audio + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_uninit(MemsAudio *audio) { + return mems_audio_ll_uninit(audio); +} + +/** + * @brief Asynchronously records audio. + * + * @param audio + * @param pdmBuffer + * @param pdmBufferLength + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_record(MemsAudio *audio) { + return mems_audio_ll_record(audio); +} + +/** + * @brief Pause recording audio. + */ +mems_audio_err_t mems_audio_pause(MemsAudio *audio) { + return mems_audio_ll_pause(audio); +} + +/** + * @brief Resume recording audio. + * + * @param audio + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_resume(MemsAudio *audio) { + return mems_audio_ll_resume(audio); +} + +/** + * @brief Stop recording audio and + * + * @param audio + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_stop(MemsAudio *audio) { + return mems_audio_ll_stop(audio); +} diff --git a/ports/stm/common-hal/audiobusio/MEMS_Audio.h b/ports/stm/common-hal/audiobusio/MEMS_Audio.h new file mode 100644 index 0000000000..2f670c8505 --- /dev/null +++ b/ports/stm/common-hal/audiobusio/MEMS_Audio.h @@ -0,0 +1,156 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Matthew McGowan for Blues Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _MEMS_AUDIO_H_ +#define _MEMS_AUDIO_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief How many milliseconds of audio can fit in the audio buffer(s). + * Interrupts for recieved data fire at half this duration / twice the frequency. + */ +#ifndef MEMS_AUDIO_MS_BUFFER +#define MEMS_AUDIO_MS_BUFFER (1) +#endif + + +/** + * @brief The number of bits per sample of the PCM output + */ +#define PCM_OUT_RESOLUTION 16 + +/** + * @brief The output frequency of PCM samples in Hz. + */ +#define PCM_OUT_SAMPLING_FREQUENCY 16000 + +/** + * @brief type for describing error conditions. + */ +typedef int32_t mems_audio_err_t; + +/** + * @brief The datatype that holds an output PCM sample. + */ +typedef int16_t pcm_sample_t; +_Static_assert(PCM_OUT_RESOLUTION==16, "Output PCM resolution must be 16-bits"); + + +typedef enum { + MEMS_AUDIO_OK = 0, + MEMS_AUDIO_ERROR_ALREADY_INITIALIZED = -1, + MEMS_AUDIO_ERROR_NOT_INITIALIZED = -2 +} mems_audio_err_enum_t; + +#define IS_MEMS_AUDIO_ERROR(e) (e) +#define CHECK_MEMS_AUDIO_ERROR(e) { if (IS_MEMS_AUDIO_ERROR(e)) return e; } +#define CHECK_MEMS_AUDIO_INITIALIZED(x) { if (!x) return MEMS_AUDIO_ERROR_NOT_INITIALIZED; } + +typedef struct MemsAudio_t MemsAudio; + +/** + * @brief Callback informing that PCM samples are available for processing. + */ +typedef void (*pcm_data_available_t)(MemsAudio* audio, pcm_sample_t* pcmSamples, size_t pcmLength); + +/** + * @brief MemsAudio manages the filter, buffers and callbacks used to capture PDM audio samples and convert to PCM. + * + */ +typedef struct MemsAudio_t { + + /** + * @brief The buffer to store PCM audio samples + */ + volatile pcm_sample_t* volatile pcmOutputBuffer; + + /** + * @brief The length of the PCM buffer. SHould be at least MEMS_AUDIO_PCM_BUFFER_LENGTH + */ + volatile size_t pcmOutputBufferLength; + + /** + * @brief Optional callback for when PCM data is available. + */ + pcm_data_available_t pcm_data_available; + + void* audioImpl; + void* userData; +} MemsAudio; + + +mems_audio_err_t mems_audio_init(MemsAudio* audio); + +/** + * @brief Uninitializes the MemsAudio instance. + * + * @param audio + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_uninit(MemsAudio* audio); + +/** + * @brief Asynchronously records audio. + * + * @param audio + * @param pdmBuffer + * @param pdmBufferLength + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_record(MemsAudio* audio); + +/** + * @brief Pause recording audio. + */ +mems_audio_err_t mems_audio_pause(MemsAudio* audio); + +/** + * @brief Resume recording audio. + * + * @param audio + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_resume(MemsAudio* audio); + +/** + * @brief Stop recording audio and + * + * @param audio + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_stop(MemsAudio* audio); + +#ifdef __cplusplus +} +#endif + + +#endif // _MEMS_AUDIO_H_ diff --git a/ports/raspberrypi/fatfs_port.c b/ports/stm/common-hal/audiobusio/MEMS_Audio_ll.h similarity index 55% rename from ports/raspberrypi/fatfs_port.c rename to ports/stm/common-hal/audiobusio/MEMS_Audio_ll.h index 58a0ef0d72..13d218fd5d 100644 --- a/ports/raspberrypi/fatfs_port.c +++ b/ports/stm/common-hal/audiobusio/MEMS_Audio_ll.h @@ -1,9 +1,7 @@ /* - * This file is part of the MicroPython project, http://micropython.org/ - * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2022 Matthew McGowan for Blues Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,25 +22,54 @@ * THE SOFTWARE. */ -#include "py/mphal.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" /* FatFs lower layer API */ -#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */ -#include "shared/timeutils/timeutils.h" -#if CIRCUITPY_RTC -#include "shared-bindings/rtc/RTC.h" +#ifndef _MEMS_AUDIO_LL_H_ +#define _MEMS_AUDIO_LL_H_ + +#include "MEMS_Audio.h" + +#ifdef __cplusplus +extern "C" { #endif -DWORD get_fattime(void) { - #if CIRCUITPY_RTC - timeutils_struct_time_t tm; - common_hal_rtc_get_time(&tm); - return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) | - (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); - #else - return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2); - #endif +mems_audio_err_t mems_audio_ll_init(MemsAudio *audio); +mems_audio_err_t mems_audio_ll_uninit(MemsAudio *audio); +/** + * @brief Asynchronously records audio. + * + * @param audio + * @param pdmBuffer + * @param pdmBufferLength + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_ll_record(MemsAudio *audio); + +/** + * @brief Pause recording audio. + */ +mems_audio_err_t mems_audio_ll_pause(MemsAudio *audio); + +/** + * @brief Resume recording audio. + * + * @param audio + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_ll_resume(MemsAudio *audio); + +/** + * @brief Stop recording audio and + * + * @param audio + * @return mems_audio_err_t + */ +mems_audio_err_t mems_audio_ll_stop(MemsAudio *audio); + +#ifdef __cplusplus } +#endif + + +#endif // _MEMS_AUDIO_LL_H_ diff --git a/ports/stm/common-hal/audiobusio/MEMS_Audio_ll_stm32l4.c b/ports/stm/common-hal/audiobusio/MEMS_Audio_ll_stm32l4.c new file mode 100644 index 0000000000..d10cdcd23e --- /dev/null +++ b/ports/stm/common-hal/audiobusio/MEMS_Audio_ll_stm32l4.c @@ -0,0 +1,386 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Matthew McGowan for Blues Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include +#include "MEMS_Audio_ll_stm32l4.h" +#include "MEMS_Audio.h" + +/** + * @brief The implementation is a singleton. + * + */ +MemsAudio_STM32L4SAIPDM* volatile audioImpl; + +static mems_audio_err_t MX_DMA_Init(void); +static mems_audio_err_t MX_DMA_Uninit(void); +static mems_audio_err_t MX_SAI1_Init(void); + +#define CHECK_HAL_ERROR(x, e) \ + { \ + if ((x) != HAL_OK) \ + return e; \ + } + +/** + * @brief Checks the HAL return code and returns from a void function on error. The + * error is saved to lastError. + */ +#define CHECK_HAL_ERROR_VOID(x, e) \ + { \ + if ((x) != HAL_OK) { \ + audioImpl->lastError = e; \ + return; \ + } \ + } + +#define CHECK_MEMS_AUDIO_ERROR_LAST() \ + { \ + if (audioImpl->lastError != MEMS_AUDIO_OK) \ + return audioImpl->lastError; \ + } + +static bool default_pdm_data_available(MemsAudio_STM32L4SAIPDM* audio, pdm_sample_t* pdmSamples, size_t count) +{ + return true; +} + +int filter_pdm(MemsAudio_STM32L4SAIPDM* impl, pdm_sample_t* input, pcm_sample_t* output) +{ + if (impl->filter.Decimation==64) { + Open_PDM_Filter_64(input, output, 1, &impl->filter); + } + else { + Open_PDM_Filter_128(input, output, 1, &impl->filter); + } + return impl->filter.nSamples; +} + +static void mems_audio_init_filter(MemsAudio_STM32L4SAIPDM *impl) +{ + TPDMFilter_InitStruct* filter = &impl->filter; + filter->Fs = PCM_OUT_SAMPLING_FREQUENCY; + filter->nSamples = MEMS_AUDIO_PCM_BUFFER_LENGTH; + filter->LP_HZ = PCM_OUT_SAMPLING_FREQUENCY / 2; // The Nyquist frequency + filter->HP_HZ = 10; // high pass to remove DC offset + filter->In_MicChannels = 1; + filter->Out_MicChannels = 1; + filter->Decimation = PDM_IN_DECIMATION_FACTOR; + Open_PDM_Filter_Init(filter); +} +volatile unsigned ignore_dma_count; + +/** + * @brief Converts PDM samples + * + * @param pdmBuffer The buffer holding the PDM samples + * @param pdmBufferLength The number of samples available + */ +void pdm2pcm(uint8_t *pdmBuffer, size_t pdmBufferLength) +{ + MemsAudio_STM32L4SAIPDM *impl = audioImpl; + if (impl) + { + bool convert = impl->discard_dma || impl->pdm_data_available(impl, pdmBuffer, pdmBufferLength); + if (convert) + { + MemsAudio* audio = impl->audio; + filter_pdm(impl, pdmBuffer, (pcm_sample_t*)audio->pcmOutputBuffer); + if (!impl->discard_dma) + audio->pcm_data_available(audio, (pcm_sample_t*)audio->pcmOutputBuffer, impl->filter.nSamples); + else + impl->discard_dma--; + } + } +} + +/** + * @brief Initialize the PDM interface ready to begin capture. + * @retval + */ +mems_audio_err_t mems_audio_ll_init(MemsAudio *audio) +{ + mems_audio_init_filter(audioImpl); + if (!audioImpl->pdm_data_available) { + audioImpl->pdm_data_available = &default_pdm_data_available; + } + + CHECK_MEMS_AUDIO_ERROR(MX_DMA_Init()); + CHECK_MEMS_AUDIO_ERROR(MX_SAI1_Init()); + return MEMS_AUDIO_OK; +} + +mems_audio_err_t uninit(void) { + if (audioImpl) { + MemsAudio_STM32L4SAIPDM* impl = audioImpl; + audioImpl = NULL; + mems_audio_ll_stop(impl->audio); + CHECK_HAL_ERROR(HAL_SAI_DeInit(&impl->hSAI_BlockA1), MEMS_AUDIO_ERROR_SAI_DEINIT); + CHECK_MEMS_AUDIO_ERROR(MX_DMA_Uninit()); + } + return MEMS_AUDIO_OK; +} + +/** + * @brief Uninitialize low level PDM capture + */ +mems_audio_err_t mems_audio_ll_uninit(MemsAudio *audio) +{ + if (audioImpl->audio == audio) { + uninit(); + } + return MEMS_AUDIO_OK; +} + +mems_audio_err_t mems_audio_ll_record(MemsAudio *audio) +{ + audioImpl->discard_dma = (100/MEMS_AUDIO_MS_BUFFER)+1; + CHECK_HAL_ERROR(HAL_SAI_Receive_DMA(&audioImpl->hSAI_BlockA1, audioImpl->pdmBuffer, audioImpl->pdmBufferLength), + MEMS_AUDIO_ERROR_DMA_START); + return MEMS_AUDIO_OK; +} + +mems_audio_err_t mems_audio_ll_stop(MemsAudio *audio) +{ + CHECK_HAL_ERROR(HAL_SAI_DMAStop(&audioImpl->hSAI_BlockA1), MEMS_AUDIO_ERROR_DMA_STOP); + return MEMS_AUDIO_OK; +} + +mems_audio_err_t mems_audio_ll_pause(MemsAudio *audio) +{ + CHECK_HAL_ERROR(HAL_SAI_DMAPause(&audioImpl->hSAI_BlockA1), MEMS_AUDIO_ERROR_DMA_PAUSE); + return MEMS_AUDIO_OK; +} + +mems_audio_err_t mems_audio_ll_resume(MemsAudio *audio) +{ + CHECK_HAL_ERROR(HAL_SAI_DMAResume(&audioImpl->hSAI_BlockA1), MEMS_AUDIO_ERROR_DMA_RESUME); + return MEMS_AUDIO_OK; +} + +/** + * @brief SAI1 Initialization Function + * @param None + * @retval None + */ +static mems_audio_err_t MX_SAI1_Init(void) +{ + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + + SAI_HandleTypeDef hSAI_BlockA1 = {0}; + MemsAudio_STM32L4SAIPDM* impl = audioImpl; + CHECK_MEMS_AUDIO_INITIALIZED(impl); + hSAI_BlockA1.Instance = SAI1_Block_A; + hSAI_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL; + hSAI_BlockA1.Init.AudioMode = SAI_MODEMASTER_RX; + /* The PDM interface provides 8 1-bit samples at a time */ + hSAI_BlockA1.Init.DataSize = SAI_DATASIZE_8; + hSAI_BlockA1.Init.FirstBit = SAI_FIRSTBIT_MSB; + + hSAI_BlockA1.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; + hSAI_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS; /* asynchronous - not chained to other SAI blocks */ + hSAI_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE; /* Not driving the primary SAI clock */ + hSAI_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_DISABLE; + hSAI_BlockA1.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE; + hSAI_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_FULL; + hSAI_BlockA1.Init.MonoStereoMode = SAI_MONOMODE; /* PDM is intrinsicly stereo, sampling on */ + hSAI_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING; + hSAI_BlockA1.Init.PdmInit.Activation = ENABLE; /* Enable PDM interface in the SAI */ + hSAI_BlockA1.Init.PdmInit.MicPairsNbr = 1; /* 1 pair - 2 mics */ + hSAI_BlockA1.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE; + hSAI_BlockA1.FrameInit.FrameLength = 16; + hSAI_BlockA1.FrameInit.ActiveFrameLength = 1; + hSAI_BlockA1.FrameInit.FSDefinition = SAI_FS_STARTFRAME; /* FS is not really used */ + hSAI_BlockA1.FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH; + hSAI_BlockA1.FrameInit.FSOffset = SAI_FS_FIRSTBIT; + hSAI_BlockA1.SlotInit.FirstBitOffset = 0; + hSAI_BlockA1.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE; + hSAI_BlockA1.SlotInit.SlotNumber = 2; + hSAI_BlockA1.SlotInit.SlotActive = 0x0001; + impl->hSAI_BlockA1 = hSAI_BlockA1; + CHECK_HAL_ERROR(HAL_SAI_Init(&impl->hSAI_BlockA1), MEMS_AUDIO_ERROR_SAI_INIT); + CHECK_MEMS_AUDIO_ERROR_LAST(); + return MEMS_AUDIO_OK; +} + +#define MEMS_AUDIO_DMA_IRQn DMA1_Channel6_IRQn +#define MEMS_AUDIO_DMA_CHANNEL DMA1_Channel6 +#define MEMS_AUDIO_DMA_PRIORITY 6 +#define DMA_HANDLER DMA1_Channel6_IRQHandler + +void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + /* SAI1 */ + MemsAudio_STM32L4SAIPDM* impl = audioImpl; + if (hsai->Instance == SAI1_Block_A && impl) + { + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI1; + PeriphClkInit.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; + PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI; + PeriphClkInit.PLLSAI1.PLLSAI1M = MEMS_AUDIO_CLOCK_PLLM; + PeriphClkInit.PLLSAI1.PLLSAI1N = MEMS_AUDIO_CLOCK_PLLN; + PeriphClkInit.PLLSAI1.PLLSAI1P = MEMS_AUDIO_CLOCK_PLLP; + PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2; + PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2; + PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK; + CHECK_HAL_ERROR_VOID(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit), MEMS_AUDIO_ERROR_SAI_CLOCK); + + if (impl->SAI1_client == 0) + { + __HAL_RCC_SAI1_CLK_ENABLE(); + } + impl->SAI1_client++; + + /**SAI1_A_Block_A GPIO Configuration + PC3 ------> SAI1_D1 + PA3 ------> SAI1_CK1 + */ + GPIO_InitStruct.Pin = GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF3_SAI1; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF3_SAI1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral DMA init*/ + DMA_HandleTypeDef hdma_sai1_a = {0}; + hdma_sai1_a.Instance = MEMS_AUDIO_DMA_CHANNEL; + hdma_sai1_a.Init.Request = DMA_REQUEST_SAI1_A; + hdma_sai1_a.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_sai1_a.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_sai1_a.Init.MemInc = DMA_MINC_ENABLE; + hdma_sai1_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_sai1_a.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_sai1_a.Init.Mode = DMA_CIRCULAR; + hdma_sai1_a.Init.Priority = DMA_PRIORITY_HIGH; + impl->hdma_sai1_a = hdma_sai1_a; + CHECK_HAL_ERROR_VOID(HAL_DMA_Init(&impl->hdma_sai1_a), MEMS_AUDIO_ERROR_SAI_DMA_INIT); + + /* Several peripheral DMA handle pointers point to the same DMA handle. + Be aware that there is only one channel to perform all the requested DMAs. */ + __HAL_LINKDMA(hsai, hdmarx, impl->hdma_sai1_a); + + __HAL_LINKDMA(hsai, hdmatx, impl->hdma_sai1_a); + } +} + +void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai) +{ + /* SAI1 */ + MemsAudio_STM32L4SAIPDM* impl = audioImpl; + if (hsai->Instance == SAI1_Block_A && impl) + { + impl->SAI1_client--; + if (impl->SAI1_client == 0) + { + /* Peripheral clock disable */ + __HAL_RCC_SAI1_CLK_DISABLE(); + } + + /**SAI1_A_Block_A GPIO Configuration + PC3 ------> SAI1_D1 + PA3 ------> SAI1_CK1 + */ + HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3); + + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3); + + /* SAI1 DMA Deinit */ + HAL_DMA_DeInit(hsai->hdmarx); + HAL_DMA_DeInit(hsai->hdmatx); + } +} + +/** + * @brief Initialize the DMA peripheral + * + */ +static mems_audio_err_t MX_DMA_Init(void) +{ + + /* DMA controller clock enable */ + __HAL_RCC_DMAMUX1_CLK_ENABLE(); + __HAL_RCC_DMA1_CLK_ENABLE(); + + /* DMA interrupt init */ + /* DMA1_Channel1_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(MEMS_AUDIO_DMA_IRQn, MEMS_AUDIO_DMA_PRIORITY, 0); + HAL_NVIC_EnableIRQ(MEMS_AUDIO_DMA_IRQn); + return MEMS_AUDIO_OK; +} + +static mems_audio_err_t MX_DMA_Uninit(void) +{ + HAL_NVIC_DisableIRQ(MEMS_AUDIO_DMA_IRQn); + return MEMS_AUDIO_OK; +} + +/** + * @brief Global handler for the DMA interrupt. Forwards to the HAL for further processing. + * + */ +void DMA_HANDLER(void) +{ + HAL_DMA_IRQHandler(&audioImpl->hdma_sai1_a); +} + +/** + * @brief Converts PDM samples in the upper half of the PDM buffer. + * + * @param hSai + */ +void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hSai) +{ + (void)hSai; + pdm2pcm(audioImpl->pdmBuffer, audioImpl->pdmBufferLength>>1); +} + +/** + * @brief Converts PDM samples in the upper half of the PDM buffer. + * + * @param hSai + */ +void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hSai) +{ + (void)hSai; + pdm2pcm(audioImpl->pdmBuffer+(audioImpl->pdmBufferLength>>1), audioImpl->pdmBufferLength>>1); +} + +mems_audio_err_t mems_audio_init_stm32l4_sai_pdm(MemsAudio* audio, MemsAudio_STM32L4SAIPDM* impl) +{ + uninit(); + audioImpl = impl; + impl->audio = audio; + return mems_audio_init(audio); +} diff --git a/ports/stm/common-hal/audiobusio/MEMS_Audio_ll_stm32l4.h b/ports/stm/common-hal/audiobusio/MEMS_Audio_ll_stm32l4.h new file mode 100644 index 0000000000..ce2c397d47 --- /dev/null +++ b/ports/stm/common-hal/audiobusio/MEMS_Audio_ll_stm32l4.h @@ -0,0 +1,209 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Matthew McGowan for Blues Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _MEMS_AUDIO_LL_STM32L4_H_ +#define _MEMS_AUDIO_LL_STM32L4_H_ + +#include +#include +#include +#include "OpenPDMFilter.h" +#include "MEMS_Audio.h" +#include "MEMS_Audio_ll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The SAI PDM interface captures 8 bits from the PDM signal. + */ +typedef uint8_t pdm_sample_t; + +/** + * @brief The PDM sample frequency in kHz. (Bit samples per millisecond.) + */ +#define PDM_IN_FREQUENCY_KHZ 1024 + +#define PDM_IN_FREQUENCY (PDM_IN_FREQUENCY_KHZ * 1000) + +/** + * @brief The number of channels of audio captured + */ +#define PDM_IN_CHANNELS 1 + +/** + * @brief The decimation of the PDM bit stream to produce PCM samples at the desired output rate. + */ +#define PDM_IN_DECIMATION_FACTOR 64 + +/** + * @brief The number of pdm samples captured per millisecond from the PDM interface. + */ +#define MEMS_AUDIO_PDM_SAMPLES_PER_MS ((PDM_IN_FREQUENCY_KHZ / (sizeof(pdm_sample_t) * 8)) * PDM_IN_CHANNELS) + +/** + * @brief The size of the buffer used to hold PDM samples prior to conversion to PCM. + * Each half of the buffer generates an interrupt. + */ +#define MEMS_AUDIO_PDM_BUFFER_LENGTH (MEMS_AUDIO_PDM_SAMPLES_PER_MS * MEMS_AUDIO_MS_BUFFER * 2) + +/** + * @brief The length of the PCM buffer required to hold converted samples. + */ +#define MEMS_AUDIO_PCM_BUFFER_LENGTH (PCM_OUT_SAMPLING_FREQUENCY * MEMS_AUDIO_MS_BUFFER / 1000) + + +/** + * Presently the internal PDM parameters and output PCM parameters are fixed for the values given here. + */ + + +/** + * @brief 128 point decimation did not work with the OpenPDMFilter and just produced PCM output + * approaching a square wave. + */ +_Static_assert(PDM_IN_DECIMATION_FACTOR == 64 || PDM_IN_DECIMATION_FACTOR == 128, "A decomation factor of 64 or 128 is supported at present."); + + +/** + * @brief The PDM bitstream frequency divided by the decimation factor should be the same as the desired output PCM frequency. + */ +_Static_assert(PDM_IN_FREQUENCY / PDM_IN_DECIMATION_FACTOR == PCM_OUT_SAMPLING_FREQUENCY, "PDM output frequency should equal the input frequency divided by the decimation factor."); + +// +// SAI PDM interface clock configuration +// + +#define MEMS_AUDIO_MSI_FREQUENCY (48 * 1000 * 1000) +#define MEMS_AUDIO_CLOCK_PLLM (15) +#define MEMS_AUDIO_CLOCK_PLLN (16) +#define MEMS_AUDIO_CLOCK_PLLP (RCC_PLLP_DIV25) + +/** + * @brief The SAI PDM clock should be twice the desired PDM bitstream frequency + */ +_Static_assert((MEMS_AUDIO_MSI_FREQUENCY / MEMS_AUDIO_CLOCK_PLLM * MEMS_AUDIO_CLOCK_PLLN / MEMS_AUDIO_CLOCK_PLLP) == (PDM_IN_FREQUENCY_KHZ * 1000 * 2), "PDM clock should be twice the PDM sample frequency."); + +typedef struct MemsAudio_STM32L4SAIPDM_t MemsAudio_STM32L4SAIPDM; + +/** + * @brief Callback informing that PDM samples are available for processing. + * @param audio The MemsAudio instance + * @return `false` to skip conversion of PDM to PCM. `true` to convert the PDM samples to PCM. + */ +typedef bool (*pdm_data_available_t)(MemsAudio_STM32L4SAIPDM *audio, pdm_sample_t *pdmSamples, size_t pdmLength); + +/** + * @brief Implementation details for the STM32 SAI PDM implementation. + * + */ +/** + * @brief Audio capture from a MEMS microphone on the STM32L4 using the SAI PDM interface. + */ +typedef struct MemsAudio_STM32L4SAIPDM_t { + + MemsAudio *audio; + + /** + * @brief The last error that happened in a void function (e.g. HAL callback) + */ + mems_audio_err_t lastError; + + /** + * @brief The buffer to store PDM audio samples + */ + pdm_sample_t *pdmBuffer; + + /** + * @brief The length of the PDM buffer. Should be at least MEMS_AUDIO_PDM_BUFFER_LENGTH + */ + size_t pdmBufferLength; + + /** + * @brief Optional callback for when PDM data is available. + */ + pdm_data_available_t pdm_data_available; + + /** + * @brief A cound of the number of PDM clients in use. + */ + uint32_t SAI1_client; + + /** + * @brief The SAI peripheral handle being used for SAI A subclock 1. + */ + SAI_HandleTypeDef hSAI_BlockA1; + + /** + * @brief The DMA handle to transfer SAI data from the peripheral to memory. + */ + DMA_HandleTypeDef hdma_sai1_a; + + /** + * @brief An instance of the PDM filter that performs decimation, and high and low pass filtering. + * Unlike the DFSDM peripheral, the SAI PDM interface doesn't perform these operations in hardware. + */ + TPDMFilter_InitStruct filter; + + /** + * @brief The number of DMA transfers to ignore after starting recording. + */ + volatile uint16_t discard_dma; + +} MemsAudio_STM32L4SAIPDM; + +/** + * @brief Creates a MemsAudio instance that retrieves PDM samples from SAI A block 1 via the PDM interface, + * decimates and filters these in software to produce the PCM output stream. + * + * @param audio + * @param implementation + * @return meems_audio_error_t + */ +mems_audio_err_t mems_audio_init_stm32l4_sai_pdm(MemsAudio *audio, MemsAudio_STM32L4SAIPDM *implementation); + +/** + * @brief Implementation-specific error codes. + * + */ +typedef enum mems_audio_err_stm32l4_t { + MEMS_AUDIO_ERROR_SAI_DMA_INIT = 1, + MEMS_AUDIO_ERROR_SAI_CLOCK = 2, + MEMS_AUDIO_ERROR_SAI_INIT = 3, + MEMS_AUDIO_ERROR_SAI_DEINIT = 4, + MEMS_AUDIO_ERROR_DMA_START = 5, + MEMS_AUDIO_ERROR_DMA_STOP = 6, + MEMS_AUDIO_ERROR_DMA_PAUSE = 7, + MEMS_AUDIO_ERROR_DMA_RESUME = 8 +} mems_audio_err_stm32l4_t; + + +#ifdef __cplusplus +} +#endif + + +#endif // _MEMS_AUDIO_LL_STM32L4_H_ diff --git a/ports/stm/common-hal/audiobusio/OpenPDMFilter.c b/ports/stm/common-hal/audiobusio/OpenPDMFilter.c new file mode 100644 index 0000000000..c65353b146 --- /dev/null +++ b/ports/stm/common-hal/audiobusio/OpenPDMFilter.c @@ -0,0 +1,302 @@ +/** + ******************************************************************************* + * @file OpenPDMFilter.c + * @author CL + * @version V1.0.0 + * @date 9-September-2015 + * @brief Open PDM audio software decoding Library. + * This Library is used to decode and reconstruct the audio signal + * produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx). + ******************************************************************************* + * @attention + * + *

© COPYRIGHT 2018 STMicroelectronics

+ * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************* + */ + + +/* Includes ------------------------------------------------------------------*/ + +#include "OpenPDMFilter.h" + + + +/* Functions -----------------------------------------------------------------*/ + +#ifdef USE_LUT +int32_t filter_table_mono_64(lut_t lut, uint8_t *data, uint8_t sincn) { + return (int32_t) + lut[data[0]][0][sincn] + + lut[data[1]][1][sincn] + + lut[data[2]][2][sincn] + + lut[data[3]][3][sincn] + + lut[data[4]][4][sincn] + + lut[data[5]][5][sincn] + + lut[data[6]][6][sincn] + + lut[data[7]][7][sincn]; +} +int32_t filter_table_stereo_64(lut_t lut, uint8_t *data, uint8_t sincn) { + return (int32_t) + lut[data[0]][0][sincn] + + lut[data[2]][1][sincn] + + lut[data[4]][2][sincn] + + lut[data[6]][3][sincn] + + lut[data[8]][4][sincn] + + lut[data[10]][5][sincn] + + lut[data[12]][6][sincn] + + lut[data[14]][7][sincn]; +} +#if DECIMATION_MAX == 128 +int32_t filter_table_mono_128(lut_t lut, uint8_t *data, uint8_t sincn) { + return (int32_t) + lut[data[0]][0][sincn] + + lut[data[1]][1][sincn] + + lut[data[2]][2][sincn] + + lut[data[3]][3][sincn] + + lut[data[4]][4][sincn] + + lut[data[5]][5][sincn] + + lut[data[6]][6][sincn] + + lut[data[7]][7][sincn] + + lut[data[8]][8][sincn] + + lut[data[9]][9][sincn] + + lut[data[10]][10][sincn] + + lut[data[11]][11][sincn] + + lut[data[12]][12][sincn] + + lut[data[13]][13][sincn] + + lut[data[14]][14][sincn] + + lut[data[15]][15][sincn]; +} +int32_t filter_table_stereo_128(lut_t lut, uint8_t *data, uint8_t sincn) { + return (int32_t) + lut[data[0]][0][sincn] + + lut[data[2]][1][sincn] + + lut[data[4]][2][sincn] + + lut[data[6]][3][sincn] + + lut[data[8]][4][sincn] + + lut[data[10]][5][sincn] + + lut[data[12]][6][sincn] + + lut[data[14]][7][sincn] + + lut[data[16]][8][sincn] + + lut[data[18]][9][sincn] + + lut[data[20]][10][sincn] + + lut[data[22]][11][sincn] + + lut[data[24]][12][sincn] + + lut[data[26]][13][sincn] + + lut[data[28]][14][sincn] + + lut[data[30]][15][sincn]; +} +#endif +int32_t (*filter_tables_64[2])(lut_t lut, uint8_t *data, uint8_t sincn) = {filter_table_mono_64, filter_table_stereo_64}; +#if DECIMATION_MAX == 128 +int32_t (*filter_tables_128[2])(lut_t lut, uint8_t *data, uint8_t sincn) = {filter_table_mono_128, filter_table_stereo_128}; +#endif +#else +int32_t filter_table(uint8_t *data, uint8_t sincn, TPDMFilter_InitStruct *param) { + uint8_t c, i; + uint16_t data_index = 0; + uint32_t *coef_p = ¶m->coef[sincn][0]; + int32_t F = 0; + uint8_t decimation = param->Decimation; + uint8_t channels = param->In_MicChannels; + + for (i = 0; i < decimation; i += 8) { + c = data[data_index]; + F += ((c >> 7)) * coef_p[i ] + + ((c >> 6) & 0x01) * coef_p[i + 1] + + ((c >> 5) & 0x01) * coef_p[i + 2] + + ((c >> 4) & 0x01) * coef_p[i + 3] + + ((c >> 3) & 0x01) * coef_p[i + 4] + + ((c >> 2) & 0x01) * coef_p[i + 5] + + ((c >> 1) & 0x01) * coef_p[i + 6] + + ((c) & 0x01) * coef_p[i + 7]; + data_index += channels; + } + return F; +} +#endif + +void convolve(uint32_t Signal[] /* SignalLen */, unsigned short SignalLen, + uint32_t Kernel[] /* KernelLen */, unsigned short KernelLen, + uint32_t Result[] /* SignalLen + KernelLen - 1 */) { + uint16_t n; + + for (n = 0; n < SignalLen + KernelLen - 1; n++) + { + unsigned short kmin, kmax, k; + + Result[n] = 0; + + kmin = (n >= KernelLen - 1) ? n - (KernelLen - 1) : 0; + kmax = (n < SignalLen - 1) ? n : SignalLen - 1; + + for (k = kmin; k <= kmax; k++) { + Result[n] += Signal[k] * Kernel[n - k]; + } + } +} + +void Open_PDM_Filter_Init(TPDMFilter_InitStruct *Param) { + uint16_t i, j; + int64_t sum = 0; + + uint8_t decimation = Param->Decimation; + + for (i = 0; i < SINCN; i++) { + Param->Coef[i] = 0; + Param->bit[i] = 0; + } + for (i = 0; i < decimation; i++) { + Param->sinc1[i] = 1; + } + + Param->OldOut = Param->OldIn = Param->OldZ = 0; + Param->LP_ALFA = (Param->LP_HZ != 0 ? (uint16_t)((float)Param->LP_HZ * 256 / (Param->LP_HZ + Param->Fs / (2 * 3.14159))) : 0); + Param->HP_ALFA = (Param->HP_HZ != 0 ? (uint16_t)((float)Param->Fs * 256 / (2 * 3.14159 * Param->HP_HZ + Param->Fs)) : 0); + + Param->FilterLen = decimation * SINCN; + Param->sinc[0] = 0; + Param->sinc[decimation * SINCN - 1] = 0; + convolve(Param->sinc1, decimation, Param->sinc1, decimation, Param->sinc2); + convolve(Param->sinc2, (decimation << 1) - 1, Param->sinc1, decimation, &Param->sinc[1]); + for (j = 0; j < SINCN; j++) { + for (i = 0; i < decimation; i++) { + Param->coef[j][i] = Param->sinc[j * decimation + i]; + sum += Param->sinc[j * decimation + i]; + } + } + + Param->sub_const = sum >> 1; + uint32_t div_const = Param->sub_const * Param->MaxVolume / 32768 / FILTER_GAIN; + Param->div_const = (div_const == 0 ? 1 : div_const); + + #ifdef USE_LUT + /* Look-Up Table. */ + uint16_t c, d, s; + for (s = 0; s < SINCN; s++) + { + uint32_t *coef_p = &Param->coef[s][0]; + for (c = 0; c < 256; c++) { + for (d = 0; d < decimation / 8; d++) { + Param->lut[c][d][s] = ((c >> 7)) * coef_p[d * 8 ] + + ((c >> 6) & 0x01) * coef_p[d * 8 + 1] + + ((c >> 5) & 0x01) * coef_p[d * 8 + 2] + + ((c >> 4) & 0x01) * coef_p[d * 8 + 3] + + ((c >> 3) & 0x01) * coef_p[d * 8 + 4] + + ((c >> 2) & 0x01) * coef_p[d * 8 + 5] + + ((c >> 1) & 0x01) * coef_p[d * 8 + 6] + + ((c) & 0x01) * coef_p[d * 8 + 7]; + } + } + } + #endif +} + +int Open_PDM_Filter_64(uint8_t *data, int16_t *dataOut, uint16_t volume, TPDMFilter_InitStruct *Param) { + uint8_t i, data_out_index; + uint8_t channels = Param->In_MicChannels; + uint8_t data_inc = ((DECIMATION_MAX >> 4) * channels); + int64_t Z, Z0, Z1, Z2; + int64_t OldOut, OldIn, OldZ; + + OldOut = Param->OldOut; + OldIn = Param->OldIn; + OldZ = Param->OldZ; + + #ifdef USE_LUT + uint8_t j = channels - 1; + #endif + + for (i = 0, data_out_index = 0; i < Param->nSamples; i++, data_out_index += channels) { + #ifdef USE_LUT + Z0 = filter_tables_64[j](Param->lut, data, 0); + Z1 = filter_tables_64[j](Param->lut, data, 1); + Z2 = filter_tables_64[j](Param->lut, data, 2); + #else + Z0 = filter_table(data, 0, Param); + Z1 = filter_table(data, 1, Param); + Z2 = filter_table(data, 2, Param); + #endif + + Z = Param->Coef[1] + Z2 - Param->sub_const; + Param->Coef[1] = Param->Coef[0] + Z1; + Param->Coef[0] = Z0; + + OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8; + OldIn = Z; + OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * OldOut) >> 8; + + Z = OldZ * volume; + Z = RoundDiv(Z, (Param->div_const)); + Z = SaturaLH(Z, -32700, 32700); + + dataOut[data_out_index] = Z; + data += data_inc; + } + + Param->OldOut = OldOut; + Param->OldIn = OldIn; + Param->OldZ = OldZ; + return data_out_index; +} + +#if DECIMATION_MAX == 128 +int Open_PDM_Filter_128(uint8_t *data, int16_t *dataOut, uint16_t volume, TPDMFilter_InitStruct *Param) { + uint8_t i, data_out_index; + uint8_t channels = Param->In_MicChannels; + uint8_t data_inc = ((DECIMATION_MAX >> 3) * channels); + int64_t Z, Z0, Z1, Z2; + int64_t OldOut, OldIn, OldZ; + + OldOut = Param->OldOut; + OldIn = Param->OldIn; + OldZ = Param->OldZ; + + #ifdef USE_LUT + uint8_t j = channels - 1; + #endif + + for (i = 0, data_out_index = 0; i < Param->nSamples; i++, data_out_index += channels) { + #ifdef USE_LUT + Z0 = filter_tables_128[j](Param->lut, data, 0); + Z1 = filter_tables_128[j](Param->lut, data, 1); + Z2 = filter_tables_128[j](Param->lut, data, 2); + #else + Z0 = filter_table(data, 0, Param); + Z1 = filter_table(data, 1, Param); + Z2 = filter_table(data, 2, Param); + #endif + + Z = Param->Coef[1] + Z2 - Param->sub_const; + Param->Coef[1] = Param->Coef[0] + Z1; + Param->Coef[0] = Z0; + + OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8; + OldIn = Z; + OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * OldOut) >> 8; + + Z = OldZ * volume; + Z = RoundDiv(Z, (Param->div_const)); + Z = SaturaLH(Z, -32700, 32700); + + dataOut[data_out_index] = Z; + data += data_inc; + } + + Param->OldOut = OldOut; + Param->OldIn = OldIn; + Param->OldZ = OldZ; + return data_out_index; +} +#endif diff --git a/ports/stm/common-hal/audiobusio/OpenPDMFilter.h b/ports/stm/common-hal/audiobusio/OpenPDMFilter.h new file mode 100644 index 0000000000..a6e4a8c063 --- /dev/null +++ b/ports/stm/common-hal/audiobusio/OpenPDMFilter.h @@ -0,0 +1,112 @@ +/** + ******************************************************************************* + * @file OpenPDMFilter.h + * @author CL + * @version V1.0.0 + * @date 9-September-2015 + * @brief Header file for Open PDM audio software decoding Library. + * This Library is used to decode and reconstruct the audio signal + * produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx). + ******************************************************************************* + * @attention + * + *

© COPYRIGHT 2018 STMicroelectronics

+ * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __OPENPDMFILTER_H +#define __OPENPDMFILTER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +#include + +/* Definitions ---------------------------------------------------------------*/ + +/* + * Enable to use a Look-Up Table to improve performances while using more FLASH + * and RAM memory. + * Note: Without Look-Up Table up to stereo@16KHz configuration is supported. + */ +#define USE_LUT + +#define SINCN 3 +#define DECIMATION_MAX 128 // can be 128 but this didn't work for me +#define FILTER_GAIN 16 + +#define HTONS(A) ((((uint16_t)(A) & 0xff00) >> 8) | \ + (((uint16_t)(A) & 0x00ff) << 8)) + +#define RoundDiv(a, b) (((a) > 0) ? (((a) + (b) / 2) / (b)) : (((a) - (b) / 2) / (b))) + +#define SaturaLH(N, L, H) (((N) < (L)) ? (L) : (((N) > (H)) ? (H) : (N))) + +/* Types ---------------------------------------------------------------------*/ + +typedef int32_t lut_t[256][DECIMATION_MAX / 8][SINCN]; + + +typedef struct +{ + /* Public */ + uint16_t LP_HZ; + uint16_t HP_HZ; + uint16_t Fs; + unsigned int nSamples; + uint8_t In_MicChannels; + uint8_t Out_MicChannels; + uint8_t Decimation; + uint8_t MaxVolume; + /* Private */ + uint32_t Coef[SINCN]; + uint16_t FilterLen; + int64_t OldOut, OldIn, OldZ; + uint16_t LP_ALFA; + uint16_t HP_ALFA; + uint16_t bit[5]; + uint16_t byte; + uint32_t div_const; + int64_t sub_const; + uint32_t sinc[DECIMATION_MAX * SINCN]; + uint32_t sinc1[DECIMATION_MAX]; + uint32_t sinc2[DECIMATION_MAX * 2]; + uint32_t coef[SINCN][DECIMATION_MAX]; + #ifdef USE_LUT + lut_t lut; + #endif +} TPDMFilter_InitStruct; + +/* Exported functions ------------------------------------------------------- */ + +void Open_PDM_Filter_Init(TPDMFilter_InitStruct *init_struct); +int Open_PDM_Filter_64(uint8_t *data, int16_t *data_out, uint16_t mic_gain, TPDMFilter_InitStruct *init_struct); + +#if DECIMATION_MAX == 128 +int Open_PDM_Filter_128(uint8_t *data, int16_t *data_out, uint16_t mic_gain, TPDMFilter_InitStruct *init_struct); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // __OPENPDMFILTER_H + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/ports/stm/common-hal/audiobusio/PDMIn.c b/ports/stm/common-hal/audiobusio/PDMIn.c new file mode 100644 index 0000000000..5deb785371 --- /dev/null +++ b/ports/stm/common-hal/audiobusio/PDMIn.c @@ -0,0 +1,199 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Matthew McGowan for Blues Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "common-hal/audiobusio/PDMIn.h" +#include "shared-bindings/audiobusio/PDMIn.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "py/runtime.h" +#include "supervisor/memory.h" +#include "MEMS_Audio_ll_stm32l4.h" + + +MemsAudio memsAudio; +MemsAudio_STM32L4SAIPDM memsAudioImpl; +pdm_sample_t pdmBuffer[MEMS_AUDIO_PDM_BUFFER_LENGTH]; +audiobusio_pdmin_obj_t *instance; + +static bool pdm_data_available(MemsAudio_STM32L4SAIPDM *impl, uint8_t *pdmBuffer, size_t pdmBufferLength); + +// Caller validates that pins are free. +void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self, + const mcu_pin_obj_t *clock_pin, + const mcu_pin_obj_t *data_pin, + uint32_t sample_rate, + uint8_t bit_depth, + bool mono, + uint8_t oversample) { + self->sample_rate = sample_rate; + self->mono = mono; + self->oversample = oversample; + self->recording_complete = true; + + + if (!mono) { + mp_raise_ValueError(translate("only mono is supported")); + } + if (sample_rate != 16000) { + mp_raise_ValueError(translate("only sample_rate=16000 is supported")); + } + if (bit_depth != 16) { + mp_raise_ValueError(translate("only bit_depth=16 is supported")); + } + if (oversample != 64) { + mp_raise_ValueError(translate("only oversample=64 is supported")); + } + + // wait for the previous instance to finish. + if (instance) { + common_hal_audiobusio_pdmin_deinit(instance); + } + instance = self; + + memset(&memsAudio, 0, sizeof(memsAudio)); + memset(&memsAudioImpl, 0, sizeof(memsAudioImpl)); + + common_hal_mcu_pin_claim(clock_pin); + self->clock_pin = clock_pin; + common_hal_mcu_pin_claim(data_pin); + self->data_pin = data_pin; + + self->audio = &memsAudio; + self->audio_impl = &memsAudioImpl; + self->audio_impl->pdmBuffer = pdmBuffer; + self->audio_impl->pdmBufferLength = sizeof(pdmBuffer) / sizeof(pdmBuffer[0]); + self->audio_impl->pdm_data_available = pdm_data_available; + + mems_audio_init_stm32l4_sai_pdm(self->audio, self->audio_impl); + mems_audio_record(self->audio); + mems_audio_pause(self->audio); +} + +bool common_hal_audiobusio_pdmin_deinited(audiobusio_pdmin_obj_t *self) { + return self->clock_pin == NULL; +} + +void wait_dma_complete(audiobusio_pdmin_obj_t *self) { + while (!self->recording_complete) { + MICROPY_VM_HOOK_LOOP; + } +} + +void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t *self) { + if (instance != self) { + return; + } + instance = NULL; + if (self->audio) { + wait_dma_complete(self); + mems_audio_stop(self->audio); + mems_audio_uninit(self->audio); + self->audio = NULL; + self->audio_impl = NULL; + } + + if (self->data_pin) { + common_hal_reset_pin(self->data_pin); + self->data_pin = NULL; + } + if (self->clock_pin) { + common_hal_reset_pin(self->clock_pin); + self->clock_pin = NULL; + } + + +} + +uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t *self) { + return 16; +} + +uint32_t common_hal_audiobusio_pdmin_get_sample_rate(audiobusio_pdmin_obj_t *self) { + return 16000; +} + +static bool pdm_data_available(MemsAudio_STM32L4SAIPDM *impl, uint8_t *pdmBuffer, size_t pdmBufferLength) { + // update the filter with the correct number of samples + + audiobusio_pdmin_obj_t *pdmIn = (audiobusio_pdmin_obj_t *)(impl->audio->userData); + MemsAudio *audio = impl->audio; + + uint32_t pcmSamplesAvailable = pdmBufferLength * 8 / PDM_IN_DECIMATION_FACTOR; + if (pcmSamplesAvailable > audio->pcmOutputBufferLength) { + pcmSamplesAvailable = audio->pcmOutputBufferLength; + } + + // ensure the filter doesn't try to produce more samples than available + pdmIn->audio_impl->filter.nSamples = pcmSamplesAvailable; + + return pcmSamplesAvailable > 0; +} + +static void pcm_data_available(MemsAudio *audio, int16_t *pcmBuffer, size_t pcmBufferLength) { + // data is already in the output buffer + audiobusio_pdmin_obj_t *pdmIn = (audiobusio_pdmin_obj_t *)(audio->userData); + + // if DMA copies more data than will fit into the output buffer, crop the length to what will fit + if (audio->pcmOutputBufferLength < pcmBufferLength) { + pcmBufferLength = audio->pcmOutputBufferLength; + } + + audio->pcmOutputBuffer += pcmBufferLength; + audio->pcmOutputBufferLength -= pcmBufferLength; + if (audio->pcmOutputBufferLength == 0) { + pdmIn->recording_complete = true; + mems_audio_pause(audio); + } +} + +uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t *self, + uint16_t *output_buffer, uint32_t output_buffer_length) { + + MemsAudio *audio = self->audio; + + wait_dma_complete(self); + + audio->pcmOutputBuffer = (int16_t *)output_buffer; + audio->pcmOutputBufferLength = output_buffer_length; + audio->pcm_data_available = pcm_data_available; + audio->userData = self; /// reference back to the PDMIn instance + self->recording_complete = false; + + mems_audio_err_t err = mems_audio_resume(audio); + if (!IS_MEMS_AUDIO_ERROR(err)) { + wait_dma_complete(self); + } + + mems_audio_pause(audio); + int samples_output = (int)(output_buffer_length) - audio->pcmOutputBufferLength; + + // convert from signed to unsigned (min-point moves from 0 to 32k) + for (int i = 0; i < samples_output; i++) { + output_buffer[i] += 0x8000; + } + + return samples_output; +} diff --git a/ports/stm/common-hal/audiobusio/PDMIn.h b/ports/stm/common-hal/audiobusio/PDMIn.h new file mode 100644 index 0000000000..64c0d2b167 --- /dev/null +++ b/ports/stm/common-hal/audiobusio/PDMIn.h @@ -0,0 +1,56 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Matthew McGowan for Blues Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_STM_COMMON_HAL_AUDIOBUSIO_AUDIOOUT_H +#define MICROPY_INCLUDED_STM_COMMON_HAL_AUDIOBUSIO_AUDIOOUT_H + +#include +#include "py/obj.h" +#include "peripherals/pins.h" +#include "supervisor/memory.h" + +typedef struct MemsAudio_t MemsAudio; +typedef struct MemsAudio_STM32L4SAIPDM_t MemsAudio_STM32L4SAIPDM; + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *clock_pin; + const mcu_pin_obj_t *data_pin; + uint32_t sample_rate; + uint8_t bit_depth; + bool mono; + uint8_t oversample; + supervisor_allocation *audio_allocation; + MemsAudio *audio; + MemsAudio_STM32L4SAIPDM *audio_impl; + /** + * @brief Flag to indicate from the ISR that recording is complete. + */ + volatile bool recording_complete; +} audiobusio_pdmin_obj_t; + + +#endif diff --git a/ports/stm/common-hal/audiobusio/__init__.c b/ports/stm/common-hal/audiobusio/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ports/stm/common-hal/busio/I2C.c b/ports/stm/common-hal/busio/I2C.c index 4faa5ca2ef..259d678f2b 100644 --- a/ports/stm/common-hal/busio/I2C.c +++ b/ports/stm/common-hal/busio/I2C.c @@ -30,7 +30,6 @@ #include "py/mperrno.h" #include "py/runtime.h" -#include "shared-bindings/microcontroller/__init__.h" #include "supervisor/shared/translate/translate.h" #include "shared-bindings/microcontroller/Pin.h" diff --git a/ports/stm/common-hal/busio/SPI.c b/ports/stm/common-hal/busio/SPI.c index 7886e18a0c..89ec4b7cdc 100644 --- a/ports/stm/common-hal/busio/SPI.c +++ b/ports/stm/common-hal/busio/SPI.c @@ -28,11 +28,8 @@ #include #include "shared-bindings/busio/SPI.h" -#include "py/mperrno.h" #include "py/runtime.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "supervisor/board.h" #include "supervisor/shared/translate/translate.h" #include "shared-bindings/microcontroller/Pin.h" diff --git a/ports/stm/common-hal/busio/UART.c b/ports/stm/common-hal/busio/UART.c index 171e915dd9..cdace31639 100644 --- a/ports/stm/common-hal/busio/UART.c +++ b/ports/stm/common-hal/busio/UART.c @@ -85,7 +85,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, bool sigint_enabled) { // match pins to UART objects - USART_TypeDef *USARTx; + USART_TypeDef *USARTx = NULL; uint8_t tx_len = MP_ARRAY_SIZE(mcu_uart_tx_list); uint8_t rx_len = MP_ARRAY_SIZE(mcu_uart_rx_list); @@ -159,8 +159,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, USARTx = assign_uart_or_throw(self, (self->tx != NULL), periph_index, uart_taken); } else { - // both pins cannot be empty - mp_raise_ValueError(translate("Supply at least one UART pin")); + // TX and RX are both None. But this is already handled in shared-bindings, so + // we won't get here. } // Other errors @@ -214,9 +214,16 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // Init buffer for rx and claim pins if (self->rx != NULL) { + // Use the provided buffer when given. if (receiver_buffer != NULL) { - self->ringbuf = (ringbuf_t) { receiver_buffer, receiver_buffer_size }; + ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); } else { + // Initially allocate the UART's buffer in the long-lived part of the + // heap. UARTs are generally long-lived objects, but the "make long- + // lived" machinery is incapable of moving internal pointers like + // self->buffer, so do it manually. (However, as long as internal + // pointers like this are NOT moved, allocating the buffer + // in the long-lived pool is not strictly necessary) if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { m_malloc_fail(receiver_buffer_size); } @@ -281,7 +288,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { self->rx = NULL; } - ringbuf_free(&self->ringbuf); + ringbuf_deinit(&self->ringbuf); } size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { diff --git a/ports/stm/common-hal/canio/Listener.c b/ports/stm/common-hal/canio/Listener.c index 69c196b78d..0def8192f9 100644 --- a/ports/stm/common-hal/canio/Listener.c +++ b/ports/stm/common-hal/canio/Listener.c @@ -105,8 +105,7 @@ STATIC int next_filter(canio_can_obj_t *can) { return i; } } - reset_into_safe_mode(MICROPY_FATAL_ERROR); - return -1; + mp_raise_msg_varg(&mp_type_RuntimeError, translate("%q"), MP_QSTR_Listener); } // IDE = "extended ID" flag of packet header. We always add this bit to the diff --git a/ports/stm/common-hal/digitalio/DigitalInOut.c b/ports/stm/common-hal/digitalio/DigitalInOut.c index 3a0e27943b..51b05907f7 100644 --- a/ports/stm/common-hal/digitalio/DigitalInOut.c +++ b/ports/stm/common-hal/digitalio/DigitalInOut.c @@ -27,8 +27,6 @@ #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/microcontroller/Pin.h" -#include "py/runtime.h" -#include "supervisor/shared/translate/translate.h" // The HAL is sparse on obtaining register information, so we use the LLs here. #if (CPY_STM32H7) @@ -77,7 +75,7 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self self->pin = NULL; } -void common_hal_digitalio_digitalinout_switch_to_input( +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { GPIO_InitTypeDef GPIO_InitStruct = {0}; @@ -88,6 +86,7 @@ void common_hal_digitalio_digitalinout_switch_to_input( HAL_GPIO_Init(pin_port(self->pin->port), &GPIO_InitStruct); common_hal_digitalio_digitalinout_set_pull(self, pull); + return DIGITALINOUT_OK; } digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( @@ -138,7 +137,7 @@ digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( == LL_GPIO_OUTPUT_OPENDRAIN ? DRIVE_MODE_OPEN_DRAIN : DRIVE_MODE_PUSH_PULL; } -void common_hal_digitalio_digitalinout_set_pull( +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { switch (pull) { @@ -154,6 +153,7 @@ void common_hal_digitalio_digitalinout_set_pull( default: break; } + return DIGITALINOUT_OK; } digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( diff --git a/ports/stm/common-hal/microcontroller/Pin.c b/ports/stm/common-hal/microcontroller/Pin.c index 9d6c8ec71a..7c4f4511e7 100644 --- a/ports/stm/common-hal/microcontroller/Pin.c +++ b/ports/stm/common-hal/microcontroller/Pin.c @@ -26,9 +26,7 @@ */ #include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/digitalio/DigitalInOut.h" -#include "py/mphal.h" #include "pins.h" #if defined(TFBGA216) diff --git a/ports/stm/common-hal/microcontroller/__init__.c b/ports/stm/common-hal/microcontroller/__init__.c index 3bb850f5d3..dc2e125a68 100644 --- a/ports/stm/common-hal/microcontroller/__init__.c +++ b/ports/stm/common-hal/microcontroller/__init__.c @@ -36,7 +36,7 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Processor.h" - +#include "supervisor/port.h" #include "supervisor/filesystem.h" #include "supervisor/shared/safe_mode.h" @@ -61,9 +61,8 @@ void common_hal_mcu_disable_interrupts(void) { void common_hal_mcu_enable_interrupts(void) { if (nesting_count == 0) { - // This is very very bad because it means there was mismatched disable/enables so we - // "HardFault". - asm ("bkpt"); + // This is very very bad because it means there was mismatched disable/enables. + reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); } nesting_count--; if (nesting_count > 0) { @@ -73,15 +72,25 @@ void common_hal_mcu_enable_interrupts(void) { __enable_irq(); } +static bool next_reset_to_bootloader = false; + void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { if (runmode == RUNMODE_SAFE_MODE) { - safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE); + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); + } + if (runmode == RUNMODE_BOOTLOADER) { + next_reset_to_bootloader = true; } } void common_hal_mcu_reset(void) { filesystem_flush(); // TODO: implement as part of flash improvements - NVIC_SystemReset(); + + if (next_reset_to_bootloader) { + reset_to_bootloader(); + } else { + NVIC_SystemReset(); + } } // The singleton microcontroller.Processor object, bound to microcontroller.cpu diff --git a/ports/stm/common-hal/pulseio/PulseIn.c b/ports/stm/common-hal/pulseio/PulseIn.c index 1c323ad711..5b7602d9bf 100644 --- a/ports/stm/common-hal/pulseio/PulseIn.c +++ b/ports/stm/common-hal/pulseio/PulseIn.c @@ -28,7 +28,6 @@ #include #include #include "py/mpconfig.h" -#include "py/gc.h" #include "py/runtime.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" @@ -107,7 +106,8 @@ void pulsein_reset(void) { memset(callback_obj_ref, 0, sizeof(callback_obj_ref)); HAL_TIM_Base_DeInit(&tim_handle); - tim_clock_disable(stm_peripherals_timer_get_index(tim_handle.Instance)); + // tim_clock_disable() takes a bitmask of timers. + tim_clock_disable(1 << stm_peripherals_timer_get_index(tim_handle.Instance)); memset(&tim_handle, 0, sizeof(tim_handle)); refcount = 0; } diff --git a/ports/stm/common-hal/pulseio/PulseOut.c b/ports/stm/common-hal/pulseio/PulseOut.c index 7725d8cdde..f558c8f776 100644 --- a/ports/stm/common-hal/pulseio/PulseOut.c +++ b/ports/stm/common-hal/pulseio/PulseOut.c @@ -29,14 +29,10 @@ #include #include "py/mpconfig.h" -#include "py/gc.h" -#include "py/runtime.h" #include "shared-bindings/pulseio/PulseOut.h" #include "shared-bindings/pwmio/PWMOut.h" -#include "supervisor/shared/translate/translate.h" #include STM32_HAL_H -#include "shared-bindings/microcontroller/Pin.h" #include "timers.h" // A single timer is shared amongst all PulseOut objects under the assumption that diff --git a/ports/stm/common-hal/pwmio/PWMOut.c b/ports/stm/common-hal/pwmio/PWMOut.c index 45f00b901b..a983718ff2 100644 --- a/ports/stm/common-hal/pwmio/PWMOut.c +++ b/ports/stm/common-hal/pwmio/PWMOut.c @@ -31,29 +31,30 @@ #include "shared-bindings/pwmio/PWMOut.h" #include "supervisor/shared/translate/translate.h" -#include "shared-bindings/microcontroller/__init__.h" #include STM32_HAL_H #include "shared-bindings/microcontroller/Pin.h" #include "timers.h" -#define ALL_CLOCKS 0xFFFF - -STATIC uint8_t reserved_tim[TIM_BANK_ARRAY_LEN]; +// Bitmask of channels taken. +STATIC uint8_t tim_channels_taken[TIM_BANK_ARRAY_LEN]; +// Initial frequency timer is set to. STATIC uint32_t tim_frequencies[TIM_BANK_ARRAY_LEN]; -STATIC bool never_reset_tim[TIM_BANK_ARRAY_LEN]; +STATIC uint8_t never_reset_tim[TIM_BANK_ARRAY_LEN]; +STATIC TIM_HandleTypeDef *active_handles[TIM_BANK_ARRAY_LEN]; STATIC uint32_t timer_get_internal_duty(uint16_t duty, uint32_t period) { // duty cycle is duty/0xFFFF fraction x (number of pulses per period) - return (duty * period) / ((1 << 16) - 1); + return (duty * period) / 0xffff; } STATIC bool timer_get_optimal_divisors(uint32_t *period, uint32_t *prescaler, uint32_t frequency, uint32_t source_freq) { // Find the largest possible period supported by this frequency - for (int i = 0; i < (1 << 16); i++) { + *prescaler = 0; + for (uint32_t i = 1; i <= 0xffff; i++) { *period = source_freq / (i * frequency); - if (*period < (1 << 16) && *period >= 2) { + if (*period <= 0xffff && *period >= 2) { *prescaler = i; break; } @@ -63,14 +64,26 @@ STATIC bool timer_get_optimal_divisors(uint32_t *period, uint32_t *prescaler, } void pwmout_reset(void) { - uint16_t never_reset_mask = 0x00; for (int i = 0; i < TIM_BANK_ARRAY_LEN; i++) { - if (!never_reset_tim[i]) { - reserved_tim[i] = 0x00; - tim_frequencies[i] = 0x00; - } else { - never_reset_mask |= 1 << i; + if (active_handles[i] == NULL) { + continue; } + for (int c = 0; c < 8; c++) { + if ((never_reset_tim[i] & (1 << c)) != 0 || + (tim_channels_taken[i] & (1 << c)) == 0) { + continue; + } + HAL_TIM_PWM_Stop(active_handles[i], c); + } + // TODO: Actually shut down individual channels and PWM. + if (never_reset_tim[i] != 0) { + continue; + } + tim_channels_taken[i] = 0x00; + tim_frequencies[i] = 0; + stm_peripherals_timer_free(mcu_tim_banks[i]); + HAL_TIM_PWM_DeInit(active_handles[i]); + active_handles[i] = NULL; } } @@ -79,73 +92,69 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, uint16_t duty, uint32_t frequency, bool variable_frequency) { - TIM_TypeDef *TIMx; - uint8_t tim_num = MP_ARRAY_SIZE(mcu_tim_pin_list); - bool tim_taken_internal = false; - bool tim_chan_taken = false; - bool tim_taken_f_mismatch = false; - bool var_freq_mismatch = false; + // Default error is no timer at all on pin. + pwmout_result_t last_failure = PWMOUT_INVALID_PIN; bool first_time_setup = true; - for (uint i = 0; i < tim_num; i++) { - const mcu_tim_pin_obj_t *l_tim = &mcu_tim_pin_list[i]; - uint8_t l_tim_index = l_tim->tim_index; - uint8_t l_tim_channel = l_tim->channel_index; + uint8_t tim_index; + uint8_t tim_channel_index; + + self->tim = NULL; + for (uint i = 0; i < MP_ARRAY_SIZE(mcu_tim_pin_list); i++) { + const mcu_tim_pin_obj_t *tim = &mcu_tim_pin_list[i]; + tim_index = tim->tim_index; + tim_channel_index = tim->channel_index; // if pin is same - if (l_tim->pin == pin) { + if (tim->pin == pin) { // check if the timer has a channel active, or is reserved by main timer system - if (l_tim_index < TIM_BANK_ARRAY_LEN && reserved_tim[l_tim_index] != 0) { + if (tim_index < TIM_BANK_ARRAY_LEN && tim_channels_taken[tim_index] != 0) { // Timer has already been reserved by an internal module - if (stm_peripherals_timer_is_reserved(mcu_tim_banks[l_tim_index])) { - tim_taken_internal = true; + if (stm_peripherals_timer_is_reserved(mcu_tim_banks[tim_index])) { + last_failure = PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; continue; // keep looking } // is it the same channel? (or all channels reserved by a var-freq) - if (reserved_tim[l_tim_index] & 1 << (l_tim_channel)) { - tim_chan_taken = true; + if (tim_channels_taken[tim_index] & (1 << tim_channel_index)) { + last_failure = PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; continue; // keep looking, might be another viable option } // If the frequencies are the same it's ok - if (tim_frequencies[l_tim_index] != frequency) { - tim_taken_f_mismatch = true; + if (tim_frequencies[tim_index] != frequency) { + last_failure = PWMOUT_INVALID_FREQUENCY_ON_PIN; continue; // keep looking } // you can't put a variable frequency on a partially reserved timer if (variable_frequency) { - var_freq_mismatch = true; + last_failure = PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE; continue; // keep looking } first_time_setup = false; // skip setting up the timer } // No problems taken, so set it up - self->tim = l_tim; + self->tim = tim; break; } } + TIM_TypeDef *TIMx; + // handle valid/invalid timer instance if (self->tim != NULL) { // create instance - TIMx = mcu_tim_banks[self->tim->tim_index]; + TIMx = mcu_tim_banks[tim_index]; // reserve timer/channel if (variable_frequency) { - reserved_tim[self->tim->tim_index] = 0x0F; + // Take all the channels. + tim_channels_taken[tim_index] = 0x0F; } else { - reserved_tim[self->tim->tim_index] |= 1 << self->tim->channel_index; + tim_channels_taken[tim_index] |= 1 << tim_channel_index; } - tim_frequencies[self->tim->tim_index] = frequency; + tim_frequencies[tim_index] = frequency; stm_peripherals_timer_reserve(TIMx); - } else { // no match found - if (tim_chan_taken || tim_taken_internal) { - return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; - } else if (tim_taken_f_mismatch) { - return PWMOUT_INVALID_FREQUENCY_ON_PIN; - } else if (var_freq_mismatch) { - return PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE; - } else { - return PWMOUT_INVALID_PIN; - } + } else { + // no match found + return last_failure; } uint32_t prescaler = 0; // prescaler is 15 bit @@ -164,10 +173,10 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, HAL_GPIO_Init(pin_port(pin->port), &GPIO_InitStruct); self->pin = pin; - tim_clock_enable(1 << (self->tim->tim_index)); + tim_clock_enable(1 << tim_index); - // translate channel into handle value - self->channel = 4 * self->tim->channel_index; + // translate channel into handle value: TIM_CHANNEL_1, _2, _3, _4. + self->channel = 4 * tim_channel_index; // Timer init self->handle.Instance = TIMx; @@ -176,12 +185,14 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, self->handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; self->handle.Init.CounterMode = TIM_COUNTERMODE_UP; self->handle.Init.RepetitionCounter = 0; + self->handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; // only run init if this is the first instance of this timer if (first_time_setup) { if (HAL_TIM_PWM_Init(&self->handle) != HAL_OK) { return PWMOUT_INITIALIZATION_ERROR; } + active_handles[tim_index] = &self->handle; } // Channel/PWM init @@ -214,15 +225,6 @@ void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { } } -void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { - for (size_t i = 0; i < TIM_BANK_ARRAY_LEN; i++) { - if (mcu_tim_banks[i] == self->handle.Instance) { - never_reset_tim[i] = false; - break; - } - } -} - bool common_hal_pwmio_pwmout_deinited(pwmio_pwmout_obj_t *self) { return self->tim == NULL; } @@ -233,16 +235,20 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { } // var freq shuts down entire timer, others just their channel if (self->variable_frequency) { - reserved_tim[self->tim->tim_index] = 0x00; + tim_channels_taken[self->tim->tim_index] = 0x00; } else { - reserved_tim[self->tim->tim_index] &= ~(1 << self->tim->channel_index); + tim_channels_taken[self->tim->tim_index] &= ~(1 << self->tim->channel_index); HAL_TIM_PWM_Stop(&self->handle, self->channel); } common_hal_reset_pin(self->pin); + never_reset_tim[self->tim->tim_index] &= ~(1 << self->tim->channel_index); + // if reserved timer has no active channels, we can disable it - if (reserved_tim[self->tim->tim_index] == 0) { + if (tim_channels_taken[self->tim->tim_index] == 0) { tim_frequencies[self->tim->tim_index] = 0x00; + HAL_TIM_PWM_DeInit(&self->handle); + active_handles[self->tim->tim_index] = NULL; stm_peripherals_timer_free(self->handle.Instance); } diff --git a/ports/stm/common-hal/pwmio/PWMOut.h b/ports/stm/common-hal/pwmio/PWMOut.h index de3a304721..9a8b897c6c 100644 --- a/ports/stm/common-hal/pwmio/PWMOut.h +++ b/ports/stm/common-hal/pwmio/PWMOut.h @@ -39,12 +39,12 @@ typedef struct { TIM_HandleTypeDef handle; TIM_OC_InitTypeDef chan_handle; const mcu_tim_pin_obj_t *tim; - uint8_t channel : 7; - bool variable_frequency : 1; - uint16_t duty_cycle; uint32_t frequency; uint32_t period; const mcu_pin_obj_t *pin; + uint16_t duty_cycle; + uint8_t channel; + bool variable_frequency; } pwmio_pwmout_obj_t; void pwmout_reset(void); diff --git a/ports/stm/common-hal/rtc/RTC.c b/ports/stm/common-hal/rtc/RTC.c index 48c47fda8c..c9dc50d769 100644 --- a/ports/stm/common-hal/rtc/RTC.c +++ b/ports/stm/common-hal/rtc/RTC.c @@ -26,13 +26,9 @@ #include -#include "py/obj.h" #include "py/runtime.h" #include "shared/timeutils/timeutils.h" -#include "shared-bindings/rtc/__init__.h" -#include "common-hal/rtc/RTC.h" #include "shared-bindings/rtc/RTC.h" -#include "supervisor/port.h" #include "supervisor/shared/translate/translate.h" #include "peripherals/rtc.h" diff --git a/ports/stm/mpconfigport.mk b/ports/stm/mpconfigport.mk index dd83e0d7bc..cb578e76e2 100644 --- a/ports/stm/mpconfigport.mk +++ b/ports/stm/mpconfigport.mk @@ -24,7 +24,7 @@ ifeq ($(MCU_SERIES),F4) CIRCUITPY_AUDIOBUSIO ?= 0 CIRCUITPY_COUNTIO ?= 0 CIRCUITPY_FREQUENCYIO ?= 0 - CIRCUITPY_I2CPERIPHERAL ?= 0 + CIRCUITPY_I2CTARGET ?= 0 CIRCUITPY_NVM ?= 0 CIRCUITPY_ROTARYIO ?= 0 CIRCUITPY_RTC ?= 1 @@ -39,7 +39,7 @@ ifeq ($(MCU_SERIES),H7) CIRCUITPY_AUDIOIO ?= 0 CIRCUITPY_COUNTIO ?= 0 CIRCUITPY_FREQUENCYIO ?= 0 - CIRCUITPY_I2CPERIPHERAL ?= 0 + CIRCUITPY_I2CTARGET ?= 0 CIRCUITPY_NEOPIXEL_WRITE ?= 0 CIRCUITPY_NVM ?= 0 CIRCUITPY_PULSEIO ?= 0 @@ -58,7 +58,7 @@ ifeq ($(MCU_SERIES),F7) CIRCUITPY_AUDIOIO ?= 0 CIRCUITPY_COUNTIO ?= 0 CIRCUITPY_FREQUENCYIO ?= 0 - CIRCUITPY_I2CPERIPHERAL ?= 0 + CIRCUITPY_I2CTARGET ?= 0 CIRCUITPY_NEOPIXEL_WRITE ?= 0 CIRCUITPY_NVM ?= 0 CIRCUITPY_ROTARYIO ?= 0 @@ -75,7 +75,7 @@ ifeq ($(MCU_SERIES),L4) CIRCUITPY_AUDIOIO ?= 0 CIRCUITPY_COUNTIO ?= 0 CIRCUITPY_FREQUENCYIO ?= 0 - CIRCUITPY_I2CPERIPHERAL ?= 0 + CIRCUITPY_I2CTARGET ?= 0 CIRCUITPY_NEOPIXEL_WRITE ?= 0 CIRCUITPY_NVM ?= 0 CIRCUITPY_ROTARYIO ?= 0 @@ -88,3 +88,4 @@ ifeq ($(MCU_SERIES),L4) endif CIRCUITPY_PARALLELDISPLAY := 0 +CIRCUITPY_BUILD_EXTENSIONS ?= bin diff --git a/ports/stm/mphalport.c b/ports/stm/mphalport.c index bb62b07987..647798f6d5 100644 --- a/ports/stm/mphalport.c +++ b/ports/stm/mphalport.c @@ -28,11 +28,8 @@ #include #include "py/mphal.h" -#include "py/mpstate.h" -#include "py/gc.h" #include "shared-bindings/microcontroller/__init__.h" -#include "supervisor/shared/tick.h" void mp_hal_delay_us(mp_uint_t delay) { common_hal_mcu_delay_us(delay); diff --git a/ports/stm/peripherals/exti.c b/ports/stm/peripherals/exti.c index a161898491..861e5de0a6 100644 --- a/ports/stm/peripherals/exti.c +++ b/ports/stm/peripherals/exti.c @@ -26,9 +26,7 @@ #include #include "py/mpconfig.h" -#include "py/gc.h" -#include "py/obj.h" -#include "py/runtime.h" +#include "py/misc.h" #include "peripherals/exti.h" diff --git a/ports/stm/peripherals/periph.h b/ports/stm/peripherals/periph.h index caf4ca1324..1049aeb084 100644 --- a/ports/stm/peripherals/periph.h +++ b/ports/stm/peripherals/periph.h @@ -119,6 +119,13 @@ typedef struct { #include "stm32f4/stm32f407xx/periph.h" #endif +#ifdef STM32F446xx +#define HAS_DAC 0 +#define HAS_TRNG 0 +#define HAS_BASIC_TIM 0 +#include "stm32f4/stm32f446xx/periph.h" +#endif + // F7 Series #ifdef STM32F746xx diff --git a/ports/stm/peripherals/pins.h b/ports/stm/peripherals/pins.h index 37aa2d8feb..a53b05aa1d 100644 --- a/ports/stm/peripherals/pins.h +++ b/ports/stm/peripherals/pins.h @@ -97,6 +97,9 @@ extern const mp_obj_type_t mcu_pin_type; #ifdef STM32F407xx #include "stm32f4/stm32f407xx/pins.h" #endif +#ifdef STM32F446xx +#include "stm32f4/stm32f446xx/pins.h" +#endif // F7 Series #ifdef STM32F746xx diff --git a/ports/stm/peripherals/rtc.c b/ports/stm/peripherals/rtc.c index bd65ccbf17..15f82ba78d 100644 --- a/ports/stm/peripherals/rtc.c +++ b/ports/stm/peripherals/rtc.c @@ -29,9 +29,6 @@ #include STM32_HAL_H #include "py/mpconfig.h" -#include "py/gc.h" -#include "py/obj.h" -#include "py/runtime.h" #include "shared/timeutils/timeutils.h" // Default period for ticks is 1/1024 second diff --git a/ports/stm/peripherals/stm32f4/clocks.c b/ports/stm/peripherals/stm32f4/clocks.c index f3434a944b..a2f8344901 100644 --- a/ports/stm/peripherals/stm32f4/clocks.c +++ b/ports/stm/peripherals/stm32f4/clocks.c @@ -47,11 +47,14 @@ #ifdef STM32F407xx #include "stm32f4/stm32f407xx/clocks.h" #endif +#ifdef STM32F446xx +#include "stm32f4/stm32f446xx/clocks.h" +#endif void stm32_peripherals_clocks_init(void) { - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; // Set voltage scaling in accordance with system clock speed __HAL_RCC_PWR_CLK_ENABLE(); diff --git a/ports/stm/peripherals/stm32f4/stm32f446xx/clocks.h b/ports/stm/peripherals/stm32f4/stm32f446xx/clocks.h new file mode 100644 index 0000000000..2cd4b59c75 --- /dev/null +++ b/ports/stm/peripherals/stm32f4/stm32f446xx/clocks.h @@ -0,0 +1,66 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 flom84 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "stm32f4xx_hal.h" + +// Chip: STM32F446xC/xV +// Line Type: Access Line +// Speed: 168MHz (max 180MHz) + +// Defaults: +#ifndef CPY_CLK_VSCALE +#define CPY_CLK_VSCALE (PWR_REGULATOR_VOLTAGE_SCALE1) +#endif +#ifndef CPY_CLK_PLLM +#define CPY_CLK_PLLM (8) +#endif +#ifndef CPY_CLK_PLLN +#define CPY_CLK_PLLN (336) +#endif +#ifndef CPY_CLK_PLLP +#define CPY_CLK_PLLP (RCC_PLLP_DIV2) +#endif +#ifndef CPY_CLK_PLLQ +#define CPY_CLK_PLLQ (7) +#endif +#ifndef CPY_CLK_AHBDIV +#define CPY_CLK_AHBDIV (RCC_SYSCLK_DIV1) +#endif +#ifndef CPY_CLK_APB1DIV +#define CPY_CLK_APB1DIV (RCC_HCLK_DIV4) +#endif +#ifndef CPY_CLK_APB2DIV +#define CPY_CLK_APB2DIV (RCC_HCLK_DIV2) +#endif +#ifndef CPY_CLK_FLASH_LATENCY +#define CPY_CLK_FLASH_LATENCY (FLASH_LATENCY_5) +#endif +#ifndef CPY_CLK_USB_USES_AUDIOPLL +#define CPY_CLK_USB_USES_AUDIOPLL (0) +#endif +#ifndef BOARD_HSE_SOURCE +#define BOARD_HSE_SOURCE (RCC_HSE_ON) +#endif diff --git a/ports/stm/peripherals/stm32f4/stm32f446xx/gpio.c b/ports/stm/peripherals/stm32f4/stm32f446xx/gpio.c new file mode 100644 index 0000000000..624eb319f4 --- /dev/null +++ b/ports/stm/peripherals/stm32f4/stm32f446xx/gpio.c @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 flom84 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "peripherals/gpio.h" +#include "stm32f4xx_hal.h" +#include "common-hal/microcontroller/Pin.h" + +void stm32_peripherals_gpio_init(void) { + // * GPIO Ports Clock Enable */ + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + // Never reset pins + never_reset_pin_number(2, 13); // PC13 anti tamp + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK +} + +void stm32f4_peripherals_status_led(uint8_t led, uint8_t state) { +} diff --git a/ports/stm/peripherals/stm32f4/stm32f446xx/periph.c b/ports/stm/peripherals/stm32f4/stm32f446xx/periph.c new file mode 100644 index 0000000000..5287a8bdf0 --- /dev/null +++ b/ports/stm/peripherals/stm32f4/stm32f446xx/periph.c @@ -0,0 +1,129 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 flom84 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/mphal.h" +#include "peripherals/pins.h" +#include "peripherals/periph.h" + +// I2C +I2C_TypeDef *mcu_i2c_banks[3] = {I2C1, I2C2, I2C3}; + +const mcu_periph_obj_t mcu_i2c_sda_list[3] = { + PERIPH(1, 4, &pin_PB07), + PERIPH(2, 4, &pin_PB03), + PERIPH(3, 4, &pin_PB04), +}; + +const mcu_periph_obj_t mcu_i2c_scl_list[3] = { + PERIPH(1, 4, &pin_PB06), + PERIPH(2, 4, &pin_PB10), + PERIPH(3, 4, &pin_PA08), +}; + +// SPI +SPI_TypeDef *mcu_spi_banks[3] = {SPI1, SPI2, SPI3}; + +const mcu_periph_obj_t mcu_spi_sck_list[3] = { + PERIPH(1, 5, &pin_PA05), + PERIPH(2, 5, &pin_PB13), + PERIPH(3, 6, &pin_PB03), +}; + +const mcu_periph_obj_t mcu_spi_mosi_list[3] = { + PERIPH(1, 5, &pin_PA07), + PERIPH(2, 5, &pin_PB15), + PERIPH(3, 6, &pin_PB05), + +}; + +const mcu_periph_obj_t mcu_spi_miso_list[3] = { + PERIPH(1, 5, &pin_PA06), + PERIPH(2, 5, &pin_PB14), + PERIPH(3, 6, &pin_PB04), +}; + +const mcu_periph_obj_t mcu_spi_nss_list[3] = { + PERIPH(1, 5, &pin_PA04), + PERIPH(2, 5, &pin_PB12), + PERIPH(3, 6, &pin_PA15), +}; + +USART_TypeDef *mcu_uart_banks[MAX_UART] = {USART1, USART2, USART3, NULL, NULL, NULL}; +bool mcu_uart_has_usart[MAX_UART] = {false, false, false, true, true, false}; + +const mcu_periph_obj_t mcu_uart_tx_list[3] = { + PERIPH(1, 7, &pin_PB06), + PERIPH(2, 7, &pin_PA02), + PERIPH(3, 7, &pin_PC10), + +}; + +const mcu_periph_obj_t mcu_uart_rx_list[3] = { + PERIPH(1, 7, &pin_PB07), + PERIPH(2, 7, &pin_PA03), + PERIPH(3, 7, &pin_PC11), +}; + +// Timers +TIM_TypeDef *mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, NULL, TIM9, TIM10, + TIM11, NULL, NULL, NULL}; + +const mcu_tim_pin_obj_t mcu_tim_pin_list[34] = { + TIM(2, 1, 1, &pin_PA00), + TIM(5, 2, 1, &pin_PA00), + TIM(2, 1, 2, &pin_PA01), + TIM(5, 2, 2, &pin_PA01), + TIM(2, 1, 3, &pin_PA02), + TIM(5, 2, 3, &pin_PA02), + TIM(2, 1, 4, &pin_PA03), + TIM(5, 2, 4, &pin_PA03), + TIM(9, 3, 1, &pin_PA02), + TIM(9, 3, 2, &pin_PA03), + TIM(3, 2, 1, &pin_PA06), + TIM(3, 2, 2, &pin_PA07), + TIM(1, 1, 1, &pin_PA08), + TIM(1, 1, 2, &pin_PA09), + TIM(1, 1, 3, &pin_PA10), + TIM(1, 1, 4, &pin_PA11), + TIM(2, 1, 1, &pin_PA15), + TIM(3, 2, 3, &pin_PB00), + TIM(3, 2, 4, &pin_PB01), + TIM(2, 1, 2, &pin_PB03), + TIM(3, 2, 1, &pin_PB04), + TIM(3, 2, 2, &pin_PB05), + TIM(4, 2, 1, &pin_PB06), + TIM(4, 2, 2, &pin_PB07), + TIM(4, 2, 3, &pin_PB08), + TIM(10, 2, 1, &pin_PB08), + TIM(4, 2, 4, &pin_PB09), + TIM(11, 2, 1, &pin_PB09), + TIM(2, 1, 3, &pin_PB10), + TIM(3, 2, 1, &pin_PC06), + TIM(3, 2, 2, &pin_PC07), + TIM(3, 2, 3, &pin_PC08), + TIM(3, 2, 4, &pin_PC09), +}; diff --git a/ports/stm/peripherals/stm32f4/stm32f446xx/periph.h b/ports/stm/peripherals/stm32f4/stm32f446xx/periph.h new file mode 100644 index 0000000000..d34be9d156 --- /dev/null +++ b/ports/stm/peripherals/stm32f4/stm32f446xx/periph.h @@ -0,0 +1,57 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 flom84 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_STM32_PERIPHERALS_STM32F446RE_PERIPH_H +#define MICROPY_INCLUDED_STM32_PERIPHERALS_STM32F446RE_PERIPH_H + +// I2C +extern I2C_TypeDef *mcu_i2c_banks[3]; + +extern const mcu_periph_obj_t mcu_i2c_sda_list[3]; +extern const mcu_periph_obj_t mcu_i2c_scl_list[3]; + +// SPI +extern SPI_TypeDef *mcu_spi_banks[3]; + +extern const mcu_periph_obj_t mcu_spi_sck_list[3]; +extern const mcu_periph_obj_t mcu_spi_mosi_list[3]; +extern const mcu_periph_obj_t mcu_spi_miso_list[3]; +extern const mcu_periph_obj_t mcu_spi_nss_list[3]; + +// UART +extern USART_TypeDef *mcu_uart_banks[MAX_UART]; +extern bool mcu_uart_has_usart[MAX_UART]; + +extern const mcu_periph_obj_t mcu_uart_tx_list[3]; +extern const mcu_periph_obj_t mcu_uart_rx_list[3]; + +// Timers +#define TIM_BANK_ARRAY_LEN 14 +#define TIM_PIN_ARRAY_LEN 34 +extern TIM_TypeDef *mcu_tim_banks[TIM_BANK_ARRAY_LEN]; +extern const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN]; + +#endif // MICROPY_INCLUDED_STM32_PERIPHERALS_STM32F446RE_PERIPH_H diff --git a/ports/stm/peripherals/stm32f4/stm32f446xx/pins.c b/ports/stm/peripherals/stm32f4/stm32f446xx/pins.c new file mode 100644 index 0000000000..17176ea72f --- /dev/null +++ b/ports/stm/peripherals/stm32f4/stm32f446xx/pins.c @@ -0,0 +1,88 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 flom84 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/mphal.h" +#include "peripherals/pins.h" + +const mcu_pin_obj_t pin_PC13 = PIN(2, 13, NO_ADC); // anti-tamp +const mcu_pin_obj_t pin_PC14 = PIN(2, 14, NO_ADC); // OSC32_IN +const mcu_pin_obj_t pin_PC15 = PIN(2, 15, NO_ADC); // OSC32_OUT +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1, 10)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1, 11)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1, 12)); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1, 13)); + +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1, 0)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1, 1)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1, 2)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1, 3)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1, 4)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1, 5)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1, 6)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1, 7)); + +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1, 14)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1, 15)); +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1, 8)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1, 9)); +const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); + +const mcu_pin_obj_t pin_PB10 = PIN(1, 10, NO_ADC); +const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC); +const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC); +const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC); +const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC); + +const mcu_pin_obj_t pin_PC06 = PIN(2, 6, NO_ADC); +const mcu_pin_obj_t pin_PC07 = PIN(2, 7, NO_ADC); +const mcu_pin_obj_t pin_PC08 = PIN(2, 8, NO_ADC); +const mcu_pin_obj_t pin_PC09 = PIN(2, 9, NO_ADC); +const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC); +const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC); + +const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC); +const mcu_pin_obj_t pin_PA11 = PIN(0, 11, NO_ADC); +const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC); +const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); // SWDIO +const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); // SWCLK +const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); // JTDI +const mcu_pin_obj_t pin_PC10 = PIN(2, 10, NO_ADC); +const mcu_pin_obj_t pin_PC11 = PIN(2, 11, NO_ADC); +const mcu_pin_obj_t pin_PC12 = PIN(2, 12, NO_ADC); + +const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC); +const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC); +const mcu_pin_obj_t pin_PB05 = PIN(1, 5, NO_ADC); +const mcu_pin_obj_t pin_PB06 = PIN(1, 6, NO_ADC); + +const mcu_pin_obj_t pin_PB07 = PIN(1, 7, NO_ADC); +const mcu_pin_obj_t pin_PB08 = PIN(1, 8, NO_ADC); +const mcu_pin_obj_t pin_PB09 = PIN(1, 9, NO_ADC); +const mcu_pin_obj_t pin_PD02 = PIN(5, 2, NO_ADC); + +const mcu_pin_obj_t pin_PH00 = PIN(7, 0, NO_ADC); +const mcu_pin_obj_t pin_PH01 = PIN(7, 1, NO_ADC); diff --git a/ports/stm/peripherals/stm32f4/stm32f446xx/pins.h b/ports/stm/peripherals/stm32f4/stm32f446xx/pins.h new file mode 100644 index 0000000000..c56412a258 --- /dev/null +++ b/ports/stm/peripherals/stm32f4/stm32f446xx/pins.h @@ -0,0 +1,90 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 flom84 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_STM32_PERIPHERALS_STM32F446RE_PINS_H +#define MICROPY_INCLUDED_STM32_PERIPHERALS_STM32F446RE_PINS_H + +// Pins in datasheet order: DocID026289 Rev 7 page 38. LQFP64 only + +extern const mcu_pin_obj_t pin_PC13; +extern const mcu_pin_obj_t pin_PC14; +extern const mcu_pin_obj_t pin_PC15; +extern const mcu_pin_obj_t pin_PC00; +extern const mcu_pin_obj_t pin_PC01; +extern const mcu_pin_obj_t pin_PC02; +extern const mcu_pin_obj_t pin_PC03; + +extern const mcu_pin_obj_t pin_PA00; +extern const mcu_pin_obj_t pin_PA01; +extern const mcu_pin_obj_t pin_PA02; +extern const mcu_pin_obj_t pin_PA03; +extern const mcu_pin_obj_t pin_PA04; +extern const mcu_pin_obj_t pin_PA05; +extern const mcu_pin_obj_t pin_PA06; +extern const mcu_pin_obj_t pin_PA07; + +extern const mcu_pin_obj_t pin_PC04; +extern const mcu_pin_obj_t pin_PC05; +extern const mcu_pin_obj_t pin_PB00; +extern const mcu_pin_obj_t pin_PB01; +extern const mcu_pin_obj_t pin_PB02; + +extern const mcu_pin_obj_t pin_PB10; +extern const mcu_pin_obj_t pin_PB12; +extern const mcu_pin_obj_t pin_PB13; +extern const mcu_pin_obj_t pin_PB14; +extern const mcu_pin_obj_t pin_PB15; + +extern const mcu_pin_obj_t pin_PC06; +extern const mcu_pin_obj_t pin_PC07; +extern const mcu_pin_obj_t pin_PC08; +extern const mcu_pin_obj_t pin_PC09; +extern const mcu_pin_obj_t pin_PA08; +extern const mcu_pin_obj_t pin_PA09; + +extern const mcu_pin_obj_t pin_PA10; +extern const mcu_pin_obj_t pin_PA11; +extern const mcu_pin_obj_t pin_PA12; +extern const mcu_pin_obj_t pin_PA13; +extern const mcu_pin_obj_t pin_PA14; +extern const mcu_pin_obj_t pin_PA15; +extern const mcu_pin_obj_t pin_PC10; +extern const mcu_pin_obj_t pin_PC11; +extern const mcu_pin_obj_t pin_PC12; + +extern const mcu_pin_obj_t pin_PB03; +extern const mcu_pin_obj_t pin_PB04; +extern const mcu_pin_obj_t pin_PB05; +extern const mcu_pin_obj_t pin_PB06; + +extern const mcu_pin_obj_t pin_PB07; +extern const mcu_pin_obj_t pin_PB08; +extern const mcu_pin_obj_t pin_PB09; +extern const mcu_pin_obj_t pin_PD02; +extern const mcu_pin_obj_t pin_PH00; +extern const mcu_pin_obj_t pin_PH01; + +#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F446RE_PINS_H diff --git a/ports/stm/peripherals/stm32l4/clocks.c b/ports/stm/peripherals/stm32l4/clocks.c index 4419f751d4..5724a74ae2 100644 --- a/ports/stm/peripherals/stm32l4/clocks.c +++ b/ports/stm/peripherals/stm32l4/clocks.c @@ -39,6 +39,8 @@ #error HSE support needs to be added for the L4 family. #elif !BOARD_HAS_LOW_SPEED_CRYSTAL #error LSE clock source required +#elif !defined(BOARD_LSE_DRIVE_LEVEL) + #error BOARD_LSE_DRIVE_LEVEL is not defined for this board. The board should define the drive strength of 32kHz external crystal in line with calculations specified in ST AN2867 sections 3.3, 3.4, and STM32L4 datasheet DS12023 Table 58, LSE oscillator characteristics. #endif void Error_Handler(void) { @@ -57,7 +59,7 @@ void stm32_peripherals_clocks_init(void) { // Configure LSE Drive HAL_PWR_EnableBkUpAccess(); - __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); + __HAL_RCC_LSEDRIVE_CONFIG(BOARD_LSE_DRIVE_LEVEL); __HAL_RCC_PWR_CLK_ENABLE(); /** Configure the main internal regulator output voltage diff --git a/ports/stm/peripherals/timers.c b/ports/stm/peripherals/timers.c index 371b8f414b..20b6bcc759 100644 --- a/ports/stm/peripherals/timers.c +++ b/ports/stm/peripherals/timers.c @@ -26,7 +26,6 @@ #include "timers.h" #include "py/mpconfig.h" -#include "py/gc.h" #include "py/obj.h" #include "py/runtime.h" #include "supervisor/shared/translate/translate.h" @@ -151,26 +150,65 @@ static size_t irq_map[] = { }; // Get the frequency (in Hz) of the source clock for the given timer. -// On STM32F405/407/415/417 there are 2 cases for how the clock freq is set. -// If the APB prescaler is 1, then the timer clock is equal to its respective -// APB clock. Otherwise (APB prescaler > 1) the timer clock is twice its -// respective APB clock. See DM00031020 Rev 4, page 115. +// +// From STM ref manual: DM00031020 Rev 19, section 7.2, page 217: +// +// The timer clock frequencies for STM32F405xx/07xx and STM32F415xx/17xx are +// automatically set by hardware. There are two cases: +// 1. If the APB prescaler is 1, the timer clock frequencies are set to the same frequency as +// that of the APB domain to which the timers are connected. +// 2. Otherwise, they are set to twice (×2) the frequency of the APB domain to which the +// timers are connected. + +// From STM ref manual: DM00031020 Rev 19, section 6.2, page 153: +// +// The timer clock frequencies for STM32F42xxx and STM32F43xxx are automatically set by +// hardware. There are two cases depending on the value of TIMPRE bit in RCC_CFGR [sic - should be RCC_DKCFGR] +// register: +// * If TIMPRE bit in RCC_DKCFGR register is reset: +// If the APB prescaler is configured to a division factor of 1, the timer clock frequencies +// (TIMxCLK) are set to PCLKx. Otherwise, the timer clock frequencies are twice the +// frequency of the APB domain to which the timers are connected: TIMxCLK = 2xPCLKx. +// * If TIMPRE bit in RCC_DKCFGR register is set: +// If the APB prescaler is configured to a division factor of 1, 2 or 4, the timer clock +// frequencies (TIMxCLK) are set to HCLK. Otherwise, the timer clock frequencies is four +// times the frequency of the APB domain to which the timers are connected: TIMxCLK = 4xPCLKx. + uint32_t stm_peripherals_timer_get_source_freq(TIM_TypeDef *timer) { - size_t tim_id = stm_peripherals_timer_get_index(timer); + // The timer index starts at 0, but the timer numbers start at TIM1. + size_t tim_id = stm_peripherals_timer_get_index(timer) + 1; uint32_t source, clk_div; if (tim_id == 1 || (8 <= tim_id && tim_id <= 11)) { // TIM{1,8,9,10,11} are on APB2 source = HAL_RCC_GetPCLK2Freq(); - clk_div = RCC->CFGR & RCC_CFGR_PPRE2; + // 0b0xx means not divided; 0b100 is divide by 2; 0b101 by 4; 0b110 by 8; 0b111 by 16. + clk_div = (RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos; } else { // TIM{2,3,4,5,6,7,12,13,14} are on APB1 source = HAL_RCC_GetPCLK1Freq(); - clk_div = RCC->CFGR & RCC_CFGR_PPRE1; + // 0b0xx means not divided; 0b100 is divide by 2; 0b101 by 4; 0b110 by 8; 0b111 by 16. + clk_div = (RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos; } - if (clk_div != 0) { - // APB prescaler for this timer is > 1 + + // Only some STM32's have TIMPRE. + #if defined(RCC_CFGR_TIMPRE) + uint32_t timpre = RCC->DCKCFGR & RCC_CFGR_TIMPRE; + if (timpre == 0) { + if (clk_div >= 0b100) { + source *= 2; + } + } else { + if (clk_div > 0b101) { + source *= 4; + } else { + source = HAL_RCC_GetHCLKFreq(); + } + } + #else + if (clk_div >= 0b100) { source *= 2; } + #endif return source; } @@ -272,6 +310,7 @@ bool stm_peripherals_timer_is_reserved(TIM_TypeDef *instance) { return stm_timer_reserved[tim_idx]; } +// Note this returns a timer index starting at zero, corresponding to TIM1. size_t stm_peripherals_timer_get_index(TIM_TypeDef *instance) { for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_tim_banks); i++) { if (instance == mcu_tim_banks[i]) { diff --git a/ports/stm/supervisor/internal_flash.c b/ports/stm/supervisor/internal_flash.c index cd693d0c66..f3f9719753 100644 --- a/ports/stm/supervisor/internal_flash.c +++ b/ports/stm/supervisor/internal_flash.c @@ -29,12 +29,7 @@ #include #include -#include "extmod/vfs.h" -#include "extmod/vfs_fat.h" -#include "py/mphal.h" #include "py/obj.h" -#include "py/runtime.h" -#include "lib/oofatfs/ff.h" #include "supervisor/flash.h" #include "supervisor/shared/safe_mode.h" @@ -220,7 +215,7 @@ void port_internal_flash_flush(void) { EraseInitStruct.NbSectors = 1; #endif if (sector_size > sizeof(_flash_cache) || sector_start_addr == 0xffffffff) { - reset_into_safe_mode(FLASH_WRITE_FAIL); + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); } // Skip if data is the same @@ -233,7 +228,7 @@ void port_internal_flash_flush(void) { if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) { // error occurred during sector erase HAL_FLASH_Lock(); // lock the flash - reset_into_safe_mode(FLASH_WRITE_FAIL); + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); } uint32_t *cache_addr = (uint32_t *)_flash_cache; @@ -245,7 +240,7 @@ void port_internal_flash_flush(void) { (uint32_t)cache_addr) != HAL_OK) { // error occurred during flash write HAL_FLASH_Lock(); // lock the flash - reset_into_safe_mode(FLASH_WRITE_FAIL); + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); } // RAM memory is by word (4 byte), but flash memory is by byte cache_addr += 8; @@ -258,7 +253,7 @@ void port_internal_flash_flush(void) { *(uint64_t *)cache_addr) != HAL_OK) { // error occurred during flash write HAL_FLASH_Lock(); // lock the flash - reset_into_safe_mode(FLASH_WRITE_FAIL); + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); } // RAM memory is by word (4 byte), but flash memory is by byte cache_addr += 2; @@ -272,7 +267,7 @@ void port_internal_flash_flush(void) { (uint64_t)*cache_addr) != HAL_OK) { // error occurred during flash write HAL_FLASH_Lock(); // lock the flash - reset_into_safe_mode(FLASH_WRITE_FAIL); + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); } // RAM memory is by word (4 byte), but flash memory is by byte cache_addr += 1; @@ -340,7 +335,7 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, // Fail for any sector outside what's supported by the cache if (sector_size > sizeof(_flash_cache)) { - reset_into_safe_mode(FLASH_WRITE_FAIL); + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); } // Find how many blocks are left in the sector diff --git a/ports/stm/supervisor/internal_flash.h b/ports/stm/supervisor/internal_flash.h index 98c55d30e8..809c263666 100644 --- a/ports/stm/supervisor/internal_flash.h +++ b/ports/stm/supervisor/internal_flash.h @@ -77,6 +77,12 @@ #define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x08004000 #endif +#ifdef STM32F446xx +#define STM32_FLASH_SIZE 0x80000 // 512KiB +#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 // 48KiB +#define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x08004000 +#endif + /* Note this applies to STM32F769xG only, STM32F746xE has 512KB */ #ifdef STM32F746xx #define STM32_FLASH_SIZE 0x100000 // 1MB diff --git a/ports/stm/supervisor/port.c b/ports/stm/supervisor/port.c index b15d81611e..1fb3f36377 100644 --- a/ports/stm/supervisor/port.c +++ b/ports/stm/supervisor/port.c @@ -29,7 +29,6 @@ #include "supervisor/background_callback.h" #include "supervisor/board.h" #include "supervisor/port.h" -#include "shared/timeutils/timeutils.h" #include "common-hal/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" @@ -212,7 +211,7 @@ safe_mode_t port_init(void) { // Turn off SysTick SysTick->CTRL = 0; - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } void HAL_Delay(uint32_t delay_ms) { @@ -244,6 +243,7 @@ void SysTick_Handler(void) { void reset_port(void) { reset_all_pins(); + #if CIRCUITPY_RTC rtc_reset(); #endif @@ -275,7 +275,48 @@ void reset_port(void) { } void reset_to_bootloader(void) { + +/* +From STM AN2606: +Before jumping to bootloader user must: +• Disable all peripheral clocks +• Disable used PLL +• Disable interrupts +• Clear pending interrupts +System memory boot mode can be exited by getting out from bootloader activation +condition and generating hardware reset or using Go command to execute user code +*/ + HAL_RCC_DeInit(); + HAL_DeInit(); + + // Disable all pending interrupts using NVIC + for (uint8_t i = 0; i < MP_ARRAY_SIZE(NVIC->ICER); ++i) { + NVIC->ICER[i] = 0xFFFFFFFF; + } + + // if it is necessary to ensure an interrupt will not be triggered after disabling it in the NVIC, + // add a DSB instruction and then an ISB instruction. (ARM Cortex™-M Programming Guide to + // Memory Barrier Instructions, 4.6 Disabling Interrupts using NVIC) + __DSB(); + __ISB(); + + // Clear all pending interrupts using NVIC + for (uint8_t i = 0; i < MP_ARRAY_SIZE(NVIC->ICPR); ++i) { + NVIC->ICPR[i] = 0xFFFFFFFF; + } + + // information about jump addresses has been taken from STM AN2606. + #if defined(STM32F4) + __set_MSP(*((uint32_t *)0x1FFF0000)); + ((void (*)(void)) * ((uint32_t *)0x1FFF0004))(); + #else + // DFU mode for STM32 variant note implemented. NVIC_SystemReset(); + #endif + + while (true) { + asm ("nop;"); + } } void reset_cpu(void) { @@ -316,28 +357,28 @@ uint32_t port_get_saved_word(void) { } __attribute__((used)) void MemManage_Handler(void) { - reset_into_safe_mode(MEM_MANAGE); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } __attribute__((used)) void BusFault_Handler(void) { - reset_into_safe_mode(MEM_MANAGE); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } __attribute__((used)) void UsageFault_Handler(void) { - reset_into_safe_mode(MEM_MANAGE); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } __attribute__((used)) void HardFault_Handler(void) { - reset_into_safe_mode(HARD_CRASH); + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } diff --git a/ports/stm/supervisor/usb.c b/ports/stm/supervisor/usb.c index 168bacc569..cafa401bd4 100644 --- a/ports/stm/supervisor/usb.c +++ b/ports/stm/supervisor/usb.c @@ -27,9 +27,7 @@ #include "supervisor/usb.h" -#include "shared/runtime/interrupt_char.h" #include "shared/readline/readline.h" -#include "lib/tinyusb/src/device/usbd.h" #include "py/mpconfig.h" diff --git a/ports/stm/tools/parse_af_csv.py b/ports/stm/tools/parse_af_csv.py index 3e48d4145d..e3188e2e24 100644 --- a/ports/stm/tools/parse_af_csv.py +++ b/ports/stm/tools/parse_af_csv.py @@ -31,6 +31,7 @@ import sys # # See examples/stm32f405.csv for example formatting. + # Most peripherals (SPI, I2C) output 3 values: # peripheral index, alt function, pin string def evaluate_periph(inper, inlist, periph, subtype, altfn, pin): diff --git a/ports/unix/.gitignore b/ports/unix/.gitignore index 6745218688..3ca8f6cb27 100644 --- a/ports/unix/.gitignore +++ b/ports/unix/.gitignore @@ -1,4 +1,3 @@ micropython micropython-* -*.py *.gcov diff --git a/ports/unix/Makefile b/ports/unix/Makefile index c0d2bdfc63..5141beff4c 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -296,9 +296,10 @@ include $(TOP)/py/mkrules.mk .PHONY: test test_full +TEST_EXTRA ?= test: $(PROG) $(TOP)/tests/run-tests.py $(eval DIRNAME=ports/$(notdir $(CURDIR))) - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py $(TEST_EXTRA) test_full: $(PROG) $(TOP)/tests/run-tests.py $(eval DIRNAME=ports/$(notdir $(CURDIR))) @@ -309,6 +310,10 @@ test_full: $(PROG) $(TOP)/tests/run-tests.py cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(PROG) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) --emit native -d basics float micropython cat $(TOP)/tests/basics/0prelim.py | ./$(PROG) | grep -q 'abc' +.PHONY: print-failures clean-failures +print-failures clean-failures: + ../../tests/run-tests.py --$@ + test_gcov: test_full gcov -o $(BUILD)/py $(TOP)/py/*.c gcov -o $(BUILD)/extmod $(TOP)/extmod/*.c diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index 179181dc83..0e4c6dbd48 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -526,7 +526,9 @@ STATIC mp_obj_t extra_coverage(void) { // ringbuf { - byte buf[100]; + #define RINGBUF_SIZE 99 + + byte buf[RINGBUF_SIZE]; ringbuf_t ringbuf; ringbuf_init(&ringbuf, &buf[0], sizeof(buf)); @@ -546,7 +548,7 @@ STATIC mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); // Two-byte put with full ringbuf. - for (int i = 0; i < 99; ++i) { + for (int i = 0; i < RINGBUF_SIZE; ++i) { ringbuf_put(&ringbuf, i); } mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); @@ -558,16 +560,15 @@ STATIC mp_obj_t extra_coverage(void) { ringbuf_get(&ringbuf); mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); mp_printf(&mp_plat_print, "%d\n", ringbuf_put16(&ringbuf, 0xcc99)); - for (int i = 0; i < 97; ++i) { + for (int i = 0; i < RINGBUF_SIZE - 2; ++i) { ringbuf_get(&ringbuf); } mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf)); mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); // Two-byte put with wrap around on first byte: - ringbuf.iput = 0; - ringbuf.iget = 0; - for (int i = 0; i < 99; ++i) { + ringbuf_clear(&ringbuf); + for (int i = 0; i < RINGBUF_SIZE; ++i) { ringbuf_put(&ringbuf, i); ringbuf_get(&ringbuf); } @@ -575,9 +576,8 @@ STATIC mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf)); // Two-byte put with wrap around on second byte: - ringbuf.iput = 0; - ringbuf.iget = 0; - for (int i = 0; i < 98; ++i) { + ringbuf_clear(&ringbuf); + for (int i = 0; i < RINGBUF_SIZE - 1; ++i) { ringbuf_put(&ringbuf, i); ringbuf_get(&ringbuf); } @@ -585,13 +585,11 @@ STATIC mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf)); // Two-byte get from empty ringbuf. - ringbuf.iput = 0; - ringbuf.iget = 0; + ringbuf_clear(&ringbuf); mp_printf(&mp_plat_print, "%d\n", ringbuf_get16(&ringbuf)); // Two-byte get from ringbuf with one byte available. - ringbuf.iput = 0; - ringbuf.iget = 0; + ringbuf_clear(&ringbuf); ringbuf_put(&ringbuf, 0xaa); mp_printf(&mp_plat_print, "%d\n", ringbuf_get16(&ringbuf)); } diff --git a/ports/unix/modos.c b/ports/unix/modos.c index 6241dfa6c3..a6365aa6a3 100644 --- a/ports/unix/modos.c +++ b/ports/unix/modos.c @@ -56,6 +56,14 @@ #endif #endif +#if defined(MICROPY_UNIX_COVERAGE) +#include "py/objstr.h" +typedef int os_getenv_err_t; +mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_); +os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t value_len); +os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value); +#endif + STATIC mp_obj_t mod_os_urandom(mp_obj_t num) { mp_int_t n = mp_obj_get_int(num); vstr_t vstr; @@ -194,6 +202,12 @@ STATIC mp_obj_t mod_os_system(mp_obj_t cmd_in) { MP_DEFINE_CONST_FUN_OBJ_1(mod_os_system_obj, mod_os_system); STATIC mp_obj_t mod_os_getenv(mp_obj_t var_in) { + #if defined(MICROPY_UNIX_COVERAGE) + mp_obj_t result = common_hal_os_getenv(mp_obj_str_get_str(var_in), mp_const_none); + if (result != mp_const_none) { + return result; + } + #endif const char *s = getenv(mp_obj_str_get_str(var_in)); if (s == NULL) { return mp_const_none; @@ -202,6 +216,28 @@ STATIC mp_obj_t mod_os_getenv(mp_obj_t var_in) { } MP_DEFINE_CONST_FUN_OBJ_1(mod_os_getenv_obj, mod_os_getenv); +#if defined(MICROPY_UNIX_COVERAGE) +STATIC mp_obj_t mod_os_getenv_int(mp_obj_t var_in) { + mp_int_t value; + os_getenv_err_t result = common_hal_os_getenv_int(mp_obj_str_get_str(var_in), &value); + if (result == 0) { + return mp_obj_new_int(value); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mod_os_getenv_int_obj, mod_os_getenv_int); + +STATIC mp_obj_t mod_os_getenv_str(mp_obj_t var_in) { + char buf[4096]; + os_getenv_err_t result = common_hal_os_getenv_str(mp_obj_str_get_str(var_in), buf, sizeof(buf)); + if (result == 0) { + return mp_obj_new_str_copy(&mp_type_str, (byte *)buf, strlen(buf)); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mod_os_getenv_str_obj, mod_os_getenv_str); +#endif + STATIC mp_obj_t mod_os_putenv(mp_obj_t key_in, mp_obj_t value_in) { const char *key = mp_obj_str_get_str(key_in); const char *value = mp_obj_str_get_str(value_in); @@ -341,6 +377,10 @@ STATIC const mp_rom_map_elem_t mp_module_os_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mod_os_rename_obj) }, { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mod_os_rmdir_obj) }, { MP_ROM_QSTR(MP_QSTR_getenv), MP_ROM_PTR(&mod_os_getenv_obj) }, + #if defined(MICROPY_UNIX_COVERAGE) + { MP_ROM_QSTR(MP_QSTR_getenv_int), MP_ROM_PTR(&mod_os_getenv_int_obj) }, + { MP_ROM_QSTR(MP_QSTR_getenv_str), MP_ROM_PTR(&mod_os_getenv_str_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mod_os_putenv_obj) }, { MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mod_os_unsetenv_obj) }, { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mod_os_mkdir_obj) }, diff --git a/ports/unix/moduos_vfs.c b/ports/unix/moduos_vfs.c index 41273bc7e2..495679290a 100644 --- a/ports/unix/moduos_vfs.c +++ b/ports/unix/moduos_vfs.c @@ -37,6 +37,10 @@ // These are defined in modos.c MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mod_os_errno_obj); MP_DECLARE_CONST_FUN_OBJ_1(mod_os_getenv_obj); +#if defined(MICROPY_UNIX_COVERAGE) +MP_DECLARE_CONST_FUN_OBJ_1(mod_os_getenv_int_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mod_os_getenv_str_obj); +#endif MP_DECLARE_CONST_FUN_OBJ_1(mod_os_putenv_obj); MP_DECLARE_CONST_FUN_OBJ_1(mod_os_unsetenv_obj); MP_DECLARE_CONST_FUN_OBJ_1(mod_os_system_obj); @@ -47,6 +51,10 @@ STATIC const mp_rom_map_elem_t uos_vfs_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mod_os_errno_obj) }, { MP_ROM_QSTR(MP_QSTR_getenv), MP_ROM_PTR(&mod_os_getenv_obj) }, + #if defined(MICROPY_UNIX_COVERAGE) + { MP_ROM_QSTR(MP_QSTR_getenv_int), MP_ROM_PTR(&mod_os_getenv_int_obj) }, + { MP_ROM_QSTR(MP_QSTR_getenv_str), MP_ROM_PTR(&mod_os_getenv_str_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mod_os_putenv_obj) }, { MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mod_os_unsetenv_obj) }, { MP_ROM_QSTR(MP_QSTR_system), MP_ROM_PTR(&mod_os_system_obj) }, diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index c54fede813..c94845229c 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -178,6 +178,9 @@ #define MICROPY_FATFS_RPATH (2) #define MICROPY_FATFS_MAX_SS (4096) #define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ +#define MICROPY_FATFS_LFN_UNICODE (2) + +#define FF_FS_CASE_INSENSITIVE_COMPARISON_ASCII_ONLY (1) // Define to MICROPY_ERROR_REPORTING_DETAILED to get function, etc. // names in exception messages (may require more RAM). diff --git a/ports/unix/variants/coverage/mpconfigvariant.h b/ports/unix/variants/coverage/mpconfigvariant.h index f6ebc2087b..ba9e941c28 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.h +++ b/ports/unix/variants/coverage/mpconfigvariant.h @@ -65,6 +65,7 @@ #define MICROPY_PY_UCRYPTOLIB (1) #define MICROPY_PY_UCRYPTOLIB_CTR (1) #define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (1) +#define MICROPY_CPYTHON_EXCEPTION_CHAIN (1) // use vfs's functions for import stat and builtin open #define mp_import_stat mp_vfs_import_stat diff --git a/ports/unix/variants/coverage/mpconfigvariant.mk b/ports/unix/variants/coverage/mpconfigvariant.mk index 3377bf20d3..fd12bbd8b5 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.mk +++ b/ports/unix/variants/coverage/mpconfigvariant.mk @@ -26,7 +26,6 @@ CFLAGS += -DCIRCUITPY_QRIO=1 $(BUILD)/lib/quirc/lib/%.o: CFLAGS += -Wno-shadow -Wno-sign-compare -include shared-module/qrio/quirc_alloc.h SRC_BITMAP := \ - $(patsubst ../../%,%,$(wildcard ../../shared-bindings/gifio/*.c ../../shared-module/gifio/*.c)) \ shared/runtime/context_manager_helpers.c \ displayio_min.c \ shared-bindings/aesio/aes.c \ @@ -44,17 +43,18 @@ SRC_BITMAP := \ shared-module/displayio/Bitmap.c \ shared-module/displayio/ColorConverter.c \ shared-module/displayio/ColorConverter.c \ + shared-module/os/getenv.c \ shared-module/rainbowio/__init__.c \ shared-module/traceback/__init__.c \ shared-module/zlib/__init__.c \ -$(info $(SRC_BITMAP)) SRC_C += $(SRC_BITMAP) CFLAGS += \ -DCIRCUITPY_AESIO=1 \ -DCIRCUITPY_BITMAPTOOLS=1 \ -DCIRCUITPY_DISPLAYIO_UNIX=1 \ + -DCIRCUITPY_OS_GETENV=1 \ -DCIRCUITPY_GIFIO=1 \ -DCIRCUITPY_RAINBOWIO=1 \ -DCIRCUITPY_TRACEBACK=1 \ diff --git a/py/argcheck.c b/py/argcheck.c index cabfaeeaae..05c2567ca2 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -145,9 +145,11 @@ void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, mp_arg_parse_all(n_pos, args, &kw_args, n_allowed, allowed, out_vals); } +#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE NORETURN void mp_arg_error_terse_mismatch(void) { mp_raise_TypeError(MP_ERROR_TEXT("argument num/types mismatch")); } +#endif #if MICROPY_CPYTHON_COMPAT NORETURN void mp_arg_error_unimpl_kw(void) { @@ -189,7 +191,7 @@ mp_float_t mp_arg_validate_obj_float_non_negative(mp_obj_t float_in, mp_float_t ? default_for_null : mp_obj_get_float(float_in); if (f <= (mp_float_t)0.0) { - mp_raise_ValueError_varg(translate("%q must be >= 0"), arg_name); + mp_raise_ValueError_varg(translate("%q must be >= %d"), arg_name, 0); } return f; } @@ -232,14 +234,28 @@ mp_int_t mp_arg_validate_index_range(mp_int_t index, mp_int_t min, mp_int_t max, mp_obj_t mp_arg_validate_type(mp_obj_t obj, const mp_obj_type_t *type, qstr arg_name) { if (!mp_obj_is_type(obj, type)) { - mp_raise_TypeError_varg(translate("%q must be of type %q"), arg_name, type->name); + mp_raise_TypeError_varg(translate("%q must be of type %q, not %q"), arg_name, type->name, mp_obj_get_type(obj)->name); + } + return obj; +} + +mp_obj_t mp_arg_validate_type_in(mp_obj_t obj, const mp_obj_type_t *type, qstr arg_name) { + if (!mp_obj_is_type(obj, type)) { + mp_raise_TypeError_varg(translate("%q in %q must be of type %q, not %q"), MP_QSTR_object, arg_name, type->name, mp_obj_get_type(obj)->name); + } + return obj; +} + +mp_obj_t mp_arg_validate_type_or_none(mp_obj_t obj, const mp_obj_type_t *type, qstr arg_name) { + if (obj != mp_const_none && !mp_obj_is_type(obj, type)) { + mp_raise_TypeError_varg(translate("%q must be of type %q or %q, not %q"), arg_name, type->name, MP_QSTR_None, mp_obj_get_type(obj)->name); } return obj; } mp_obj_t mp_arg_validate_type_string(mp_obj_t obj, qstr arg_name) { if (!mp_obj_is_str(obj)) { - mp_raise_TypeError_varg(translate("%q must be a string"), arg_name); + mp_raise_TypeError_varg(translate("%q must be of type %q, not %q"), arg_name, MP_QSTR_str, mp_obj_get_type(obj)->name); } return obj; } @@ -247,7 +263,7 @@ mp_obj_t mp_arg_validate_type_string(mp_obj_t obj, qstr arg_name) { mp_int_t mp_arg_validate_type_int(mp_obj_t obj, qstr arg_name) { mp_int_t an_int; if (!mp_obj_get_int_maybe(obj, &an_int)) { - mp_raise_TypeError_varg(translate("%q must be an int"), arg_name); + mp_raise_TypeError_varg(translate("%q must be of type %q, not %q"), arg_name, MP_QSTR_int, mp_obj_get_type(obj)->name); } return an_int; } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index af49c876ba..79769e000e 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -101,6 +101,7 @@ endif ### # Select which builtin modules to compile and include. +# Keep alphabetical. ifeq ($(CIRCUITPY_AESIO),1) SRC_PATTERNS += aesio/% @@ -108,6 +109,9 @@ endif ifeq ($(CIRCUITPY_ALARM),1) SRC_PATTERNS += alarm/% endif +ifeq ($(CIRCUITPY_ANALOGBUFIO),1) +SRC_PATTERNS += analogbufio/% +endif ifeq ($(CIRCUITPY_ANALOGIO),1) SRC_PATTERNS += analogio/% endif @@ -166,20 +170,17 @@ endif ifeq ($(CIRCUITPY_COUNTIO),1) SRC_PATTERNS += countio/% endif +ifeq ($(CIRCUITPY_CYW43),1) +SRC_PATTERNS += cyw43/% +endif ifeq ($(CIRCUITPY_DIGITALIO),1) SRC_PATTERNS += digitalio/% endif ifeq ($(CIRCUITPY_DISPLAYIO),1) SRC_PATTERNS += displayio/% endif -ifeq ($(CIRCUITPY_DOTENV),1) -SRC_PATTERNS += dotenv/% -endif -ifeq ($(CIRCUITPY_PARALLELDISPLAY),1) -SRC_PATTERNS += paralleldisplay/% -endif -ifeq ($(CIRCUITPY_VECTORIO),1) -SRC_PATTERNS += vectorio/% +ifeq ($(CIRCUITPY__EVE),1) +SRC_PATTERNS += _eve/% endif ifeq ($(CIRCUITPY_FLOPPYIO),1) SRC_PATTERNS += floppyio/% @@ -187,17 +188,12 @@ endif ifeq ($(CIRCUITPY_FRAMEBUFFERIO),1) SRC_PATTERNS += framebufferio/% endif -ifeq ($(CIRCUITPY__EVE),1) -SRC_PATTERNS += _eve/% -endif ifeq ($(CIRCUITPY_FREQUENCYIO),1) SRC_PATTERNS += frequencyio/% endif - ifeq ($(CIRCUITPY_FUTURE),1) SRC_PATTERNS += __future__/% endif - ifeq ($(CIRCUITPY_GETPASS),1) SRC_PATTERNS += getpass/% endif @@ -210,8 +206,8 @@ endif ifeq ($(CIRCUITPY_HASHLIB),1) SRC_PATTERNS += hashlib/% endif -ifeq ($(CIRCUITPY_I2CPERIPHERAL),1) -SRC_PATTERNS += i2cperipheral/% +ifeq ($(CIRCUITPY_I2CTARGET),1) +SRC_PATTERNS += i2ctarget/% endif ifeq ($(CIRCUITPY_IMAGECAPTURE),1) SRC_PATTERNS += imagecapture/% @@ -228,6 +224,9 @@ endif ifeq ($(CIRCUITPY_MATH),1) SRC_PATTERNS += math/% endif +ifeq ($(CIRCUITPY_MEMORYMAP),1) +SRC_PATTERNS += memorymap/% +endif ifeq ($(CIRCUITPY_MEMORYMONITOR),1) SRC_PATTERNS += memorymonitor/% endif @@ -237,6 +236,9 @@ endif ifeq ($(CIRCUITPY_MDNS),1) SRC_PATTERNS += mdns/% endif +ifeq ($(CIRCUITPY_MSGPACK),1) +SRC_PATTERNS += msgpack/% +endif ifeq ($(CIRCUITPY_NEOPIXEL_WRITE),1) SRC_PATTERNS += neopixel_write/% endif @@ -252,9 +254,18 @@ endif ifeq ($(CIRCUITPY_DUALBANK),1) SRC_PATTERNS += dualbank/% endif +ifeq ($(CIRCUITPY_PARALLELDISPLAY),1) +SRC_PATTERNS += paralleldisplay/% +endif +ifeq ($(CIRCUITPY_PEW),1) +SRC_PATTERNS += _pew/% +endif ifeq ($(CIRCUITPY_PIXELBUF),1) SRC_PATTERNS += adafruit_pixelbuf/% endif +ifeq ($(CIRCUITPY_PIXELMAP),1) +SRC_PATTERNS += _pixelmap/% +endif ifeq ($(CIRCUITPY_QRIO),1) SRC_PATTERNS += qrio/% endif @@ -321,6 +332,9 @@ endif ifeq ($(CIRCUITPY_TERMINALIO),1) SRC_PATTERNS += terminalio/% fontio/% endif +ifeq ($(CIRCUITPY_FONTIO),1) +SRC_PATTERNS += fontio/% +endif ifeq ($(CIRCUITPY_TIME),1) SRC_PATTERNS += time/% endif @@ -351,8 +365,8 @@ endif ifeq ($(CIRCUITPY_USTACK),1) SRC_PATTERNS += ustack/% endif -ifeq ($(CIRCUITPY_ZLIB),1) -SRC_PATTERNS += zlib/% +ifeq ($(CIRCUITPY_VECTORIO),1) +SRC_PATTERNS += vectorio/% endif ifeq ($(CIRCUITPY_VIDEOCORE),1) SRC_PATTERNS += videocore/% @@ -363,11 +377,8 @@ endif ifeq ($(CIRCUITPY_WIFI),1) SRC_PATTERNS += wifi/% endif -ifeq ($(CIRCUITPY_PEW),1) -SRC_PATTERNS += _pew/% -endif -ifeq ($(CIRCUITPY_MSGPACK),1) -SRC_PATTERNS += msgpack/% +ifeq ($(CIRCUITPY_ZLIB),1) +SRC_PATTERNS += zlib/% endif # All possible sources are listed here, and are filtered by SRC_PATTERNS in SRC_COMMON_HAL @@ -389,6 +400,8 @@ SRC_COMMON_HAL_ALL = \ alarm/pin/PinAlarm.c \ alarm/time/TimeAlarm.c \ alarm/touch/TouchAlarm.c \ + analogbufio/BufferedIn.c \ + analogbufio/__init__.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ analogio/__init__.c \ @@ -424,11 +437,13 @@ SRC_COMMON_HAL_ALL = \ gnss/SatelliteSystem.c \ hashlib/__init__.c \ hashlib/Hash.c \ - i2cperipheral/I2CPeripheral.c \ - i2cperipheral/__init__.c \ + i2ctarget/I2CTarget.c \ + i2ctarget/__init__.c \ + memorymap/__init__.c \ + memorymap/AddressRange.c \ + microcontroller/__init__.c \ microcontroller/Pin.c \ microcontroller/Processor.c \ - microcontroller/__init__.c \ mdns/__init__.c \ mdns/Server.c \ mdns/RemoteService.c \ @@ -479,7 +494,6 @@ SRC_C += \ endif - SRC_COMMON_HAL = $(filter $(SRC_PATTERNS), $(SRC_COMMON_HAL_ALL)) # These don't have corresponding files in each port but are still located in @@ -511,10 +525,16 @@ $(filter $(SRC_PATTERNS), \ qrio/PixelPolicy.c \ qrio/QRInfo.c \ supervisor/RunReason.c \ + supervisor/StatusBar.c \ wifi/AuthMode.c \ wifi/Packet.c \ ) +ifeq ($(CIRCUITPY_SAFEMODE_PY),1) +SRC_BINDINGS_ENUMS += \ + supervisor/SafeModeReason.c +endif + SRC_BINDINGS_ENUMS += \ util.c @@ -526,6 +546,8 @@ SRC_SHARED_MODULE_ALL = \ _eve/__init__.c \ adafruit_pixelbuf/PixelBuf.c \ adafruit_pixelbuf/__init__.c \ + _pixelmap/PixelMap.c \ + _pixelmap/__init__.c \ _stage/Layer.c \ _stage/Text.c \ _stage/__init__.c \ @@ -567,7 +589,6 @@ SRC_SHARED_MODULE_ALL = \ displayio/TileGrid.c \ displayio/area.c \ displayio/__init__.c \ - dotenv/__init__.c \ floppyio/__init__.c \ fontio/BuiltinFont.c \ fontio/__init__.c \ @@ -576,6 +597,7 @@ SRC_SHARED_MODULE_ALL = \ getpass/__init__.c \ gifio/__init__.c \ gifio/GifWriter.c \ + gifio/OnDiskGif.c \ imagecapture/ParallelImageCapture.c \ ipaddress/IPv4Address.c \ ipaddress/__init__.c \ @@ -611,6 +633,8 @@ SRC_SHARED_MODULE_ALL = \ socket/__init__.c \ storage/__init__.c \ struct/__init__.c \ + supervisor/__init__.c \ + supervisor/StatusBar.c \ synthio/MidiTrack.c \ synthio/__init__.c \ terminalio/Terminal.c \ @@ -679,6 +703,13 @@ SRC_MOD += $(addprefix lib/protomatter/src/, \ $(BUILD)/lib/protomatter/src/core.o: CFLAGS += -include "shared-module/rgbmatrix/allocator.h" -DCIRCUITPY -Wno-missing-braces -Wno-missing-prototypes endif +ifeq ($(CIRCUITPY_GIFIO),1) +SRC_MOD += $(addprefix lib/AnimatedGIF/, \ + gif.c \ +) +$(BUILD)/lib/AnimatedGIF/gif.o: CFLAGS += -DCIRCUITPY +endif + ifeq ($(CIRCUITPY_ZLIB),1) SRC_MOD += $(addprefix lib/uzlib/, \ tinflate.c \ @@ -694,6 +725,7 @@ endif SRC_SHARED_MODULE_INTERNAL = \ $(filter $(SRC_PATTERNS), \ displayio/display_core.c \ + os/getenv.c \ usb/utf16le.c \ ) diff --git a/py/circuitpy_mkenv.mk b/py/circuitpy_mkenv.mk new file mode 100644 index 0000000000..d776cc2fef --- /dev/null +++ b/py/circuitpy_mkenv.mk @@ -0,0 +1,70 @@ +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# SPDX-FileCopyrightText: Copyright (c) 2022 MicroDev +# +# 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. + +# Common Makefile items that can be shared across CircuitPython ports. + +# Select the board to build for. +define show_board_error +$(info Valid boards:) +$(shell printf '%s\n' $(patsubst boards/%/mpconfigboard.mk,%,$(wildcard boards/*/mpconfigboard.mk)) | column -xc $$(tput cols || echo 80) 1>&2) +$(error Rerun with $(MAKE) BOARD=) +endef + +ifeq ($(BOARD),) + $(info No BOARD specified) + $(call show_board_error) +else + ifeq ($(wildcard boards/$(BOARD)/.),) + $(info Invalid BOARD specified) + $(call show_board_error) + endif +endif + +# If the flash PORT is not given, use the default /dev/tty.SLAB_USBtoUART. +PORT ?= /dev/tty.SLAB_USBtoUART + +# If the build directory is not given, make it reflect the board name. +BUILD ?= build-$(BOARD) + +include ../../py/mkenv.mk + +# Board-specific +include boards/$(BOARD)/mpconfigboard.mk + +# Port-specific +include mpconfigport.mk + +# CircuitPython-specific +include $(TOP)/py/circuitpy_mpconfig.mk + +# qstr definitions (must come before including py.mk) +QSTR_DEFS = qstrdefsport.h + +# include py core make definitions +include $(TOP)/py/py.mk + +include $(TOP)/supervisor/supervisor.mk + +# Include make rules and variables common across CircuitPython builds. +include $(TOP)/py/circuitpy_defns.mk diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 950cf91e2e..a514b6a160 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -35,7 +35,8 @@ #include // This is CircuitPython. -#define CIRCUITPY 1 +// Always 1: defined in circuitpy_mpconfig.mk +// #define CIRCUITPY (1) // REPR_C encodes qstrs, 31-bit ints, and 30-bit floats in a single 32-bit word. #ifndef MICROPY_OBJ_REPR @@ -72,6 +73,7 @@ extern void common_hal_mcu_enable_interrupts(void); #define MICROPY_ENABLE_DOC_STRING (0) #define MICROPY_ENABLE_FINALISER (1) #define MICROPY_ENABLE_GC (1) +#define MICROPY_TRACKED_ALLOC (CIRCUITPY_SSL_MBEDTLS) #define MICROPY_ENABLE_SOURCE_LINE (1) #define MICROPY_EPOCH_IS_1970 (1) #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL) @@ -91,7 +93,7 @@ extern void common_hal_mcu_enable_interrupts(void); #define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (CIRCUITPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) #define MICROPY_PERSISTENT_CODE_LOAD (1) -#define MICROPY_PY_ARRAY (1) +#define MICROPY_PY_ARRAY (CIRCUITPY_ARRAY) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_ATTRTUPLE (1) @@ -113,27 +115,37 @@ extern void common_hal_mcu_enable_interrupts(void); #define MICROPY_PY_BUILTINS_STR_UNICODE (1) #define MICROPY_PY_CMATH (0) -#define MICROPY_PY_COLLECTIONS (1) +#define MICROPY_PY_COLLECTIONS (CIRCUITPY_COLLECTIONS) #define MICROPY_PY_DESCRIPTORS (1) #define MICROPY_PY_IO_FILEIO (1) #define MICROPY_PY_GC (1) // Supplanted by shared-bindings/math +#define MICROPY_PY_IO (CIRCUITPY_IO) #define MICROPY_PY_MATH (0) #define MICROPY_PY_MICROPYTHON_MEM_INFO (0) // Supplanted by shared-bindings/struct #define MICROPY_PY_STRUCT (0) -#define MICROPY_PY_SYS (1) +#define MICROPY_PY_SYS (CIRCUITPY_SYS) #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_STDFILES (1) +// In extmod +#define MICROPY_PY_UBINASCII (CIRCUITPY_BINASCII) +#define MICROPY_PY_UERRNO (CIRCUITPY_ERRNO) +// Uses about 80 bytes. +#define MICROPY_PY_UERRNO_ERRORCODE (CIRCUITPY_ERRNO) // Supplanted by shared-bindings/random #define MICROPY_PY_URANDOM (0) #define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) +// In extmod +#define MICROPY_PY_UJSON (CIRCUITPY_JSON) +#define MICROPY_PY_URE (CIRCUITPY_RE) #define MICROPY_PY___FILE__ (1) #define MICROPY_QSTR_BYTES_IN_HASH (1) #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_REPL_EVENT_DRIVEN (0) #define MICROPY_ENABLE_PYSTACK (1) +#define CIRCUITPY_SETTABLE_PYSTACK (1) #define MICROPY_STACK_CHECK (1) #define MICROPY_STREAMS_NON_BLOCK (1) #ifndef MICROPY_USE_INTERNAL_PRINTF @@ -213,6 +225,9 @@ typedef long mp_off_t; #ifndef MICROPY_CPYTHON_COMPAT #define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD) #endif +#ifndef MICROPY_CPYTHON_EXCEPTION_CHAIN +#define MICROPY_CPYTHON_EXCEPTION_CHAIN (CIRCUITPY_FULL_BUILD) +#endif #define MICROPY_PY_BUILTINS_POW3 (CIRCUITPY_BUILTINS_POW3) #define MICROPY_PY_FSTRINGS (1) #define MICROPY_MODULE_WEAK_LINKS (0) @@ -349,26 +364,6 @@ typedef long mp_off_t; extern const struct _mp_obj_module_t nvm_module; #endif -// Following modules are implemented in either extmod or py directory. - -#define MICROPY_PY_UBINASCII CIRCUITPY_BINASCII - -#define MICROPY_PY_UERRNO CIRCUITPY_ERRNO -// Uses about 80 bytes. -#define MICROPY_PY_UERRNO_ERRORCODE CIRCUITPY_ERRNO - -#define MICROPY_PY_URE CIRCUITPY_RE - -#if CIRCUITPY_JSON -#define MICROPY_PY_UJSON (1) -#define MICROPY_PY_IO (1) -#else -#ifndef MICROPY_PY_IO -// We don't need MICROPY_PY_IO unless someone else wants it. -#define MICROPY_PY_IO (0) -#endif -#endif - #ifndef ULAB_SUPPORTS_COMPLEX #define ULAB_SUPPORTS_COMPLEX (0) #endif @@ -564,6 +559,10 @@ void supervisor_run_background_tasks_if_tick(void); #error "CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR must be at least 1" #endif +#ifndef CIRCUITPY_PORT_NUM_SUPERVISOR_ALLOCATIONS +#define CIRCUITPY_PORT_NUM_SUPERVISOR_ALLOCATIONS (0) +#endif + #ifndef USB_MIDI_EP_NUM_OUT #define USB_MIDI_EP_NUM_OUT (0) #endif @@ -584,6 +583,22 @@ void supervisor_run_background_tasks_if_tick(void); #define MICROPY_WRAP_MP_EXECUTE_BYTECODE PLACE_IN_ITCM #endif +#ifndef CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY +#define CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY (0) +#endif + +#ifndef CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (0) +#endif + +#ifndef CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE (0) +#endif + +#define FF_FS_CASE_INSENSITIVE_COMPARISON_ASCII_ONLY (1) + +#define FF_FS_MAKE_VOLID (1) + #define MICROPY_PY_OPTIMIZE_PROPERTY_FLASH_SIZE (CIRCUITPY_OPTIMIZE_PROPERTY_FLASH_SIZE) #endif // __INCLUDED_MPCONFIG_CIRCUITPY_H diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 4d7d026aa5..43f4fb186a 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -26,6 +26,10 @@ # Boards default to all modules enabled (with exceptions) # Manually disable by overriding in #mpconfigboard.mk +# Always on. Present here to help generate documentation module support matrix for "builtins". +CIRCUITPY = 1 +CFLAGS += -DCIRCUITPY=$(CIRCUITPY) + # Smaller builds can be forced for resource constrained chips (typically SAMD21s # without external flash) by setting CIRCUITPY_FULL_BUILD=0. Avoid using this # for merely incomplete ports, as it changes settings in other files. @@ -62,9 +66,15 @@ CFLAGS += -DCIRCUITPY_AESIO=$(CIRCUITPY_AESIO) CIRCUITPY_ALARM ?= 0 CFLAGS += -DCIRCUITPY_ALARM=$(CIRCUITPY_ALARM) +CIRCUITPY_ANALOGBUFIO ?= 0 +CFLAGS += -DCIRCUITPY_ANALOGBUFIO=$(CIRCUITPY_ANALOGBUFIO) + CIRCUITPY_ANALOGIO ?= 1 CFLAGS += -DCIRCUITPY_ANALOGIO=$(CIRCUITPY_ANALOGIO) +CIRCUITPY_ARRAY ?= 1 +CFLAGS += -DCIRCUITPY_ARRAY=$(CIRCUITPY_ARRAY) + CIRCUITPY_ATEXIT ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_ATEXIT=$(CIRCUITPY_ATEXIT) @@ -156,17 +166,20 @@ CFLAGS += -DCIRCUITPY_CAMERA=$(CIRCUITPY_CAMERA) CIRCUITPY_CANIO ?= 0 CFLAGS += -DCIRCUITPY_CANIO=$(CIRCUITPY_CANIO) -CIRCUITPY_DIGITALIO ?= 1 -CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO) +CIRCUITPY_COLLECTIONS ?= 1 +CFLAGS += -DCIRCUITPY_COLLECTIONS=$(CIRCUITPY_COLLECTIONS) CIRCUITPY_COMPUTED_GOTO_SAVE_SPACE ?= 0 CFLAGS += -DCIRCUITPY_COMPUTED_GOTO_SAVE_SPACE=$(CIRCUITPY_COMPUTED_GOTO_SAVE_SPACE) -CIRCUITPY_OPT_LOAD_ATTR_FAST_PATH ?= 1 -CFLAGS += -DCIRCUITPY_OPT_LOAD_ATTR_FAST_PATH=$(CIRCUITPY_OPT_LOAD_ATTR_FAST_PATH) +CIRCUITPY_CYW43 ?= 0 +CFLAGS += -DCIRCUITPY_CYW43=$(CIRCUITPY_CYW43) -CIRCUITPY_OPT_MAP_LOOKUP_CACHE ?= $(CIRCUITPY_FULL_BUILD) -CFLAGS += -DCIRCUITPY_OPT_MAP_LOOKUP_CACHE=$(CIRCUITPY_OPT_MAP_LOOKUP_CACHE) +CIRCUITPY_DIGITALIO ?= 1 +CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO) + +CIRCUITPY_COPROC ?= 0 +CFLAGS += -DCIRCUITPY_COPROC=$(CIRCUITPY_COPROC) CIRCUITPY_COUNTIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO) @@ -195,9 +208,6 @@ CFLAGS += -DCIRCUITPY_BITMAPTOOLS=$(CIRCUITPY_BITMAPTOOLS) CFLAGS += -DCIRCUITPY_FRAMEBUFFERIO=$(CIRCUITPY_FRAMEBUFFERIO) CFLAGS += -DCIRCUITPY_VECTORIO=$(CIRCUITPY_VECTORIO) -CIRCUITPY_DOTENV ?= $(CIRCUITPY_FULL_BUILD) -CFLAGS += -DCIRCUITPY_DOTENV=$(CIRCUITPY_DOTENV) - CIRCUITPY_DUALBANK ?= 0 CFLAGS += -DCIRCUITPY_DUALBANK=$(CIRCUITPY_DUALBANK) @@ -205,15 +215,23 @@ CFLAGS += -DCIRCUITPY_DUALBANK=$(CIRCUITPY_DUALBANK) CIRCUITPY_ENABLE_MPY_NATIVE ?= 0 CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE) +CIRCUITPY_OS_GETENV ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_OS_GETENV=$(CIRCUITPY_OS_GETENV) + CIRCUITPY_ERRNO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_ERRNO=$(CIRCUITPY_ERRNO) -# CIRCUITPY_ESPIDF is handled in the espressif tree. -# Only for ESP32S chips. -# Assume not a ESP build. +# Espressif specific modules. +# Assume not an Espressif build. CIRCUITPY_ESPIDF ?= 0 CFLAGS += -DCIRCUITPY_ESPIDF=$(CIRCUITPY_ESPIDF) +CIRCUITPY_ESPULP ?= 0 +CFLAGS += -DCIRCUITPY_ESPULP=$(CIRCUITPY_ESPULP) + +CIRCUITPY_ESPCAMERA ?= 0 +CFLAGS += -DCIRCUITPY_ESPCAMERA=$(CIRCUITPY_ESPCAMERA) + CIRCUITPY__EVE ?= 0 CFLAGS += -DCIRCUITPY__EVE=$(CIRCUITPY__EVE) @@ -230,7 +248,8 @@ CIRCUITPY_GETPASS ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_GETPASS=$(CIRCUITPY_GETPASS) ifeq ($(CIRCUITPY_DISPLAYIO),1) -CIRCUITPY_GIFIO ?= $(CIRCUITPY_CAMERA) +#CIRCUITPY_GIFIO ?= $(CIRCUITPY_CAMERA) +CIRCUITPY_GIFIO ?= 1 else CIRCUITPY_GIFIO ?= 0 endif @@ -242,12 +261,16 @@ CFLAGS += -DCIRCUITPY_GNSS=$(CIRCUITPY_GNSS) CIRCUITPY_HASHLIB ?= $(CIRCUITPY_WEB_WORKFLOW) CFLAGS += -DCIRCUITPY_HASHLIB=$(CIRCUITPY_HASHLIB) -CIRCUITPY_I2CPERIPHERAL ?= $(CIRCUITPY_FULL_BUILD) -CFLAGS += -DCIRCUITPY_I2CPERIPHERAL=$(CIRCUITPY_I2CPERIPHERAL) +CIRCUITPY_I2CTARGET ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_I2CTARGET=$(CIRCUITPY_I2CTARGET) CIRCUITPY_IMAGECAPTURE ?= 0 CFLAGS += -DCIRCUITPY_IMAGECAPTURE=$(CIRCUITPY_IMAGECAPTURE) +# io - needed by JSON support +CIRCUITPY_IO ?= $(CIRCUITPY_JSON) +CFLAGS += -DCIRCUITPY_IO=$(CIRCUITPY_IO) + CIRCUITPY_IPADDRESS ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_IPADDRESS=$(CIRCUITPY_IPADDRESS) @@ -263,6 +286,9 @@ CFLAGS += -DCIRCUITPY_KEYPAD=$(CIRCUITPY_KEYPAD) CIRCUITPY_MATH ?= 1 CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH) +CIRCUITPY_MEMORYMAP ?= 0 +CFLAGS += -DCIRCUITPY_MEMORYMAP=$(CIRCUITPY_MEMORYMAP) + CIRCUITPY_MEMORYMONITOR ?= 0 CFLAGS += -DCIRCUITPY_MEMORYMONITOR=$(CIRCUITPY_MEMORYMONITOR) @@ -284,6 +310,12 @@ CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM) CIRCUITPY_ONEWIREIO ?= $(CIRCUITPY_BUSIO) CFLAGS += -DCIRCUITPY_ONEWIREIO=$(CIRCUITPY_ONEWIREIO) +CIRCUITPY_OPT_LOAD_ATTR_FAST_PATH ?= 1 +CFLAGS += -DCIRCUITPY_OPT_LOAD_ATTR_FAST_PATH=$(CIRCUITPY_OPT_LOAD_ATTR_FAST_PATH) + +CIRCUITPY_OPT_MAP_LOOKUP_CACHE ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_OPT_MAP_LOOKUP_CACHE=$(CIRCUITPY_OPT_MAP_LOOKUP_CACHE) + CIRCUITPY_OS ?= 1 CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS) @@ -293,6 +325,9 @@ CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW) CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF) +CIRCUITPY_PIXELMAP ?= $(CIRCUITPY_PIXELBUF) +CFLAGS += -DCIRCUITPY_PIXELMAP=$(CIRCUITPY_PIXELMAP) + # Only for SAMD boards for the moment CIRCUITPY_PS2IO ?= 0 CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO) @@ -338,6 +373,10 @@ CFLAGS += -DCIRCUITPY_ROTARYIO_SOFTENCODER=$(CIRCUITPY_ROTARYIO_SOFTENCODER) CIRCUITPY_RTC ?= 1 CFLAGS += -DCIRCUITPY_RTC=$(CIRCUITPY_RTC) +# Enable support for safemode.py +CIRCUITPY_SAFEMODE_PY ?= 1 +CFLAGS += -DCIRCUITPY_SAFEMODE_PY=$(CIRCUITPY_SAFEMODE_PY) + # CIRCUITPY_SAMD is handled in the atmel-samd tree. # Only for SAMD chips. # Assume not a SAMD build. @@ -359,22 +398,33 @@ CFLAGS += -DCIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY=$(CIRCUITPY_SETTABLE_PROCESSO CIRCUITPY_SHARPDISPLAY ?= $(CIRCUITPY_FRAMEBUFFERIO) CFLAGS += -DCIRCUITPY_SHARPDISPLAY=$(CIRCUITPY_SHARPDISPLAY) +# Disable the safe mode blink at boot. Speeds up boot time, but makes it +# impossible to enter safe mode by pressing buttons on boot. +CIRCUITPY_SKIP_SAFE_MODE_WAIT ?= 0 +CFLAGS += -DCIRCUITPY_SKIP_SAFE_MODE_WAIT=$(CIRCUITPY_SKIP_SAFE_MODE_WAIT) + CIRCUITPY_SOCKETPOOL ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_SOCKETPOOL=$(CIRCUITPY_SOCKETPOOL) CIRCUITPY_SSL ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_SSL=$(CIRCUITPY_SSL) +CIRCUITPY_SSL_MBEDTLS ?= 0 +CFLAGS += -DCIRCUITPY_SSL_MBEDTLS=$(CIRCUITPY_SSL_MBEDTLS) + # Currently always off. CIRCUITPY_STAGE ?= 0 CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE) -CIRCUITPY_STATUS_BAR ?= $(CIRCUITPY_WEB_WORKFLOW) +CIRCUITPY_STATUS_BAR ?= 1 CFLAGS += -DCIRCUITPY_STATUS_BAR=$(CIRCUITPY_STATUS_BAR) CIRCUITPY_STORAGE ?= 1 CFLAGS += -DCIRCUITPY_STORAGE=$(CIRCUITPY_STORAGE) +CIRCUITPY_STORAGE_EXTEND ?= $(CIRCUITPY_DUALBANK) +CFLAGS += -DCIRCUITPY_STORAGE_EXTEND=$(CIRCUITPY_STORAGE_EXTEND) + CIRCUITPY_STRUCT ?= 1 CFLAGS += -DCIRCUITPY_STRUCT=$(CIRCUITPY_STRUCT) @@ -384,9 +434,17 @@ CFLAGS += -DCIRCUITPY_SUPERVISOR=$(CIRCUITPY_SUPERVISOR) CIRCUITPY_SYNTHIO ?= $(CIRCUITPY_AUDIOCORE) CFLAGS += -DCIRCUITPY_SYNTHIO=$(CIRCUITPY_SYNTHIO) +CIRCUITPY_SYS ?= 1 +CFLAGS += -DCIRCUITPY_SYS=$(CIRCUITPY_SYS) + CIRCUITPY_TERMINALIO ?= $(CIRCUITPY_DISPLAYIO) CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO) +ifeq ($(CIRCUITPY_DISPLAYIO),1) +CIRCUITPY_FONTIO ?= $(CIRCUITPY_TERMINALIO) +endif +CFLAGS += -DCIRCUITPY_FONTIO=$(CIRCUITPY_FONTIO) + CIRCUITPY_TIME ?= 1 CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME) @@ -436,6 +494,9 @@ CFLAGS += -DCIRCUITPY_USB_HID_ENABLED_DEFAULT=$(CIRCUITPY_USB_HID_ENABLED_DEFAUL CIRCUITPY_USB_HOST ?= 0 CFLAGS += -DCIRCUITPY_USB_HOST=$(CIRCUITPY_USB_HOST) +CIRCUITPY_USB_IDENTIFICATION ?= $(CIRCUITPY_USB) +CFLAGS += -DCIRCUITPY_USB_IDENTIFICATION=$(CIRCUITPY_USB_IDENTIFICATION) + # MIDI is available by default, but is not turned on if there are fewer than 8 endpoints. CIRCUITPY_USB_MIDI ?= $(CIRCUITPY_USB) CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI) @@ -486,6 +547,9 @@ CFLAGS += -DCIRCUITPY_WIFI=$(CIRCUITPY_WIFI) CIRCUITPY_WEB_WORKFLOW ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_WEB_WORKFLOW=$(CIRCUITPY_WEB_WORKFLOW) +CIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS?= 1 +CFLAGS += -DCIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS=$(CIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS) + # tinyusb port tailored configuration CIRCUITPY_TUSB_MEM_ALIGN ?= 4 CFLAGS += -DCIRCUITPY_TUSB_MEM_ALIGN=$(CIRCUITPY_TUSB_MEM_ALIGN) diff --git a/py/enum.c b/py/enum.c index 681c3b3103..22b9090196 100644 --- a/py/enum.c +++ b/py/enum.c @@ -40,10 +40,8 @@ mp_obj_t cp_enum_find(const mp_obj_type_t *type, int value) { return mp_const_none; } -int cp_enum_value(const mp_obj_type_t *type, mp_obj_t obj) { - if (!mp_obj_is_type(obj, type)) { - mp_raise_TypeError_varg(MP_ERROR_TEXT("Expected a %q"), type->name); - } +int cp_enum_value(const mp_obj_type_t *type, mp_obj_t obj, qstr arg_name) { + (void)mp_arg_validate_type(obj, type, arg_name); return ((cp_enum_obj_t *)MP_OBJ_TO_PTR(obj))->value; } diff --git a/py/enum.h b/py/enum.h index d0b8529a4d..63191047e0 100644 --- a/py/enum.h +++ b/py/enum.h @@ -61,5 +61,5 @@ typedef struct { mp_obj_t cp_enum_find(const mp_obj_type_t *type, int value); -int cp_enum_value(const mp_obj_type_t *type, mp_obj_t obj); +int cp_enum_value(const mp_obj_type_t *type, mp_obj_t obj, qstr arg_name); void cp_enum_obj_print_helper(uint16_t module, const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); diff --git a/py/formatfloat.c b/py/formatfloat.c index 06775167c0..d75cfc6658 100644 --- a/py/formatfloat.c +++ b/py/formatfloat.c @@ -25,6 +25,7 @@ */ #include "py/mpconfig.h" +#include "py/misc.h" #if MICROPY_FLOAT_IMPL != MICROPY_FLOAT_IMPL_NONE #include @@ -96,7 +97,16 @@ static inline int fp_isless1(float x) { #define fp_iszero(x) (x == 0) #define fp_isless1(x) (x < 1.0) -#endif +#endif // MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT/DOUBLE + +static inline int fp_ge_eps(FPTYPE x, FPTYPE y) { + mp_float_union_t fb_y = {y}; + // Back off 2 eps. + // This is valid for almost all values, but in practice + // it's only used when y = 1eX for X>=0. + fb_y.i -= 2; + return x >= fb_y.f; +} static const FPTYPE g_pos_pow[] = { #if FPDECEXP > 32 @@ -173,6 +183,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch int num_digits = 0; const FPTYPE *pos_pow = g_pos_pow; const FPTYPE *neg_pow = g_neg_pow; + int signed_e = 0; if (fp_iszero(f)) { e = 0; @@ -192,31 +203,24 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch } } } else if (fp_isless1(f)) { - // We need to figure out what an integer digit will be used - // in case 'f' is used (or we revert other format to it below). - // As we just tested number to be <1, this is obviously 0, - // but we can round it up to 1 below. - char first_dig = '0'; - if (f >= FPROUND_TO_ONE) { - first_dig = '1'; - } - + FPTYPE f_mod = f; // Build negative exponent for (e = 0, e1 = FPDECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) { - if (*neg_pow > f) { + if (*neg_pow > f_mod) { e += e1; - f *= *pos_pow; + f_mod *= *pos_pow; } } + char e_sign_char = '-'; - if (fp_isless1(f) && f >= FPROUND_TO_ONE) { - f = FPCONST(1.0); + if (fp_isless1(f_mod) && f_mod >= FPROUND_TO_ONE) { + f_mod = FPCONST(1.0); if (e == 0) { e_sign_char = '+'; } - } else if (fp_isless1(f)) { + } else if (fp_isless1(f_mod)) { e++; - f *= FPCONST(10.0); + f_mod *= FPCONST(10.0); } // If the user specified 'g' format, and e is <= 4, then we'll switch @@ -224,8 +228,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch if (fmt == 'f' || (fmt == 'g' && e <= 4)) { fmt = 'f'; - dec = -1; - *s++ = first_dig; + dec = 0; if (org_fmt == 'g') { prec += (e - 1); @@ -237,13 +240,8 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch } num_digits = prec; - if (num_digits) { - *s++ = '.'; - while (--e && num_digits) { - *s++ = '0'; - num_digits--; - } - } + signed_e = 0; + ++num_digits; } else { // For e & g formats, we'll be printing the exponent, so set the // sign. @@ -256,22 +254,29 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch prec++; } } + signed_e = -e; } } else { - // Build positive exponent - for (e = 0, e1 = FPDECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) { - if (*pos_pow <= f) { + // Build positive exponent. + // We don't modify f at this point to avoid innaccuracies from + // scaling it. Instead, we find the product of powers of 10 + // that is not greater than it, and use that to start the + // mantissa. + FPTYPE u_base = FPCONST(1.0); + for (e = 0, e1 = FPDECEXP; e1; e1 >>= 1, pos_pow++) { + FPTYPE next_u = u_base * *pos_pow; + // fp_ge_eps performs "f >= (next_u - 2eps)" so that if, for + // numerical reasons, f is very close to a power of ten but + // not strictly equal, we still treat it as that power of 10. + // The comparison was failing for maybe 10% of 1eX values, but + // although rounding fixed many of them, there were still some + // rendering as 9.99999998e(X-1). + if (fp_ge_eps(f, next_u)) { + u_base = next_u; e += e1; - f *= *neg_pow; } } - // It can be that f was right on the edge of an entry in pos_pow needs to be reduced - if ((int)f >= 10) { - e += 1; - f *= FPCONST(0.1); - } - // If the user specified fixed format (fmt == 'f') and e makes the // number too big to fit into the available buffer, then we'll // switch to the 'e' format. @@ -310,15 +315,15 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch } else { e_sign = '+'; } + signed_e = e; } if (prec < 0) { // This can happen when the prec is trimmed to prevent buffer overflow prec = 0; } - // We now have num.f as a floating point number between >= 1 and < 10 - // (or equal to zero), and e contains the absolute value of the power of - // 10 exponent. and (dec + 1) == the number of dgits before the decimal. + // At this point e contains the absolute value of the power of 10 exponent. + // (dec + 1) == the number of dgits before the decimal. // For e, prec is # digits after the decimal // For f, prec is # digits after the decimal @@ -336,25 +341,63 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch num_digits = prec; } - // Print the digits of the mantissa - for (int i = 0; i < num_digits; ++i, --dec) { - int32_t d = (int32_t)f; - if (d < 0) { - *s++ = '0'; - } else { - *s++ = '0' + d; + if (signed_e < 0) { + // The algorithm below treats numbers smaller than 1 by scaling them + // repeatedly by 10 to bring the new digit to the top. Our input number + // was smaller than 1, so scale it up to be 1 <= f < 10. + FPTYPE u_base = FPCONST(1.0); + const FPTYPE *pow_u = g_pos_pow; + for (int m = FPDECEXP; m; m >>= 1, pow_u++) { + if (m & e) { + u_base *= *pow_u; + } } - if (dec == 0 && prec > 0) { - *s++ = '.'; - } - f -= (FPTYPE)d; - f *= FPCONST(10.0); + f *= u_base; } - // Round - // If we print non-exponential format (i.e. 'f'), but a digit we're going - // to round by (e) is too far away, then there's nothing to round. - if ((org_fmt != 'f' || e <= num_digits) && f >= FPCONST(5.0)) { + int d = 0; + int num_digits_left = num_digits; + for (int digit_index = signed_e; num_digits_left >= 0; --digit_index) { + FPTYPE u_base = FPCONST(1.0); + if (digit_index > 0) { + // Generate 10^digit_index for positive digit_index. + const FPTYPE *pow_u = g_pos_pow; + int target_index = digit_index; + for (int m = FPDECEXP; m; m >>= 1, pow_u++) { + if (m & target_index) { + u_base *= *pow_u; + } + } + } + for (d = 0; d < 9; ++d) { + // This is essentially "if (f < u_base)", but with 2eps margin + // so that if f is just a tiny bit smaller, we treat it as + // equal (and accept the additional digit value). + if (!fp_ge_eps(f, u_base)) { + break; + } + f -= u_base; + } + // We calculate one more digit than we display, to use in rounding + // below. So only emit the digit if it's one that we display. + if (num_digits_left > 0) { + // Emit this number (the leading digit). + *s++ = '0' + d; + if (dec == 0 && prec > 0) { + *s++ = '.'; + } + } + --dec; + --num_digits_left; + if (digit_index <= 0) { + // Once we get below 1.0, we scale up f instead of calculting + // negative powers of 10 in u_base. This provides better + // renditions of exact decimals like 1/16 etc. + f *= FPCONST(10.0); + } + } + // Rounding. If the next digit to print is >= 5, round up. + if (d >= 5) { char *rs = s; rs--; while (1) { @@ -394,7 +437,10 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch } } else { // Need at extra digit at the end to make room for the leading '1' - s++; + // but if we're at the buffer size limit, just drop the final digit. + if ((size_t)(s + 1 - buf) < buf_size) { + s++; + } } char *ss = s; while (ss > rs) { diff --git a/py/gc.c b/py/gc.c index 826540d353..0ced4c854d 100644 --- a/py/gc.c +++ b/py/gc.c @@ -138,7 +138,6 @@ void gc_init(void *start, void *end) { MP_STATE_MEM(gc_alloc_table_start) = (byte *)start; #if MICROPY_ENABLE_FINALISER - size_t gc_finaliser_table_byte_len = (MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB; MP_STATE_MEM(gc_finaliser_table_start) = MP_STATE_MEM(gc_alloc_table_start) + MP_STATE_MEM(gc_alloc_table_byte_len) + 1; #endif @@ -147,18 +146,16 @@ void gc_init(void *start, void *end) { MP_STATE_MEM(gc_pool_end) = end; #if MICROPY_ENABLE_FINALISER + size_t gc_finaliser_table_byte_len = (MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB; + (void)gc_finaliser_table_byte_len; // avoid unused variable diagnostic if asserts are disabled assert(MP_STATE_MEM(gc_pool_start) >= MP_STATE_MEM(gc_finaliser_table_start) + gc_finaliser_table_byte_len); #endif - // Clear ATBs plus one more byte. The extra byte might be read when we read the final ATB and - // then try to count its tail. Clearing the byte ensures it is 0 and ends the chain. Without an - // FTB, it'll just clear the pool byte early. - memset(MP_STATE_MEM(gc_alloc_table_start), 0, MP_STATE_MEM(gc_alloc_table_byte_len) + 1); - - #if MICROPY_ENABLE_FINALISER - // clear FTBs - memset(MP_STATE_MEM(gc_finaliser_table_start), 0, gc_finaliser_table_byte_len); - #endif + // Clear ATBs & finalisers (if enabled). This also clears the extra byte + // which appears between ATBs and finalisers that ensures every chain in + // the ATB terminates, rather than erroneously using bits from the + // finalisers. + memset(MP_STATE_MEM(gc_alloc_table_start), 0, MP_STATE_MEM(gc_pool_start) - MP_STATE_MEM(gc_alloc_table_start)); // Set first free ATB index to the start of the heap. for (size_t i = 0; i < MICROPY_ATB_INDICES; i++) { @@ -521,7 +518,7 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags, bool long_lived) { } if (MP_STATE_MEM(gc_pool_start) == 0) { - reset_into_safe_mode(GC_ALLOC_OUTSIDE_VM); + reset_into_safe_mode(SAFE_MODE_GC_ALLOC_OUTSIDE_VM); } GC_ENTER(); @@ -715,7 +712,7 @@ void gc_free(void *ptr) { GC_EXIT(); } else { if (MP_STATE_MEM(gc_pool_start) == 0) { - reset_into_safe_mode(GC_ALLOC_OUTSIDE_VM); + reset_into_safe_mode(SAFE_MODE_GC_ALLOC_OUTSIDE_VM); } // get the GC block number corresponding to this pointer assert(VERIFY_PTR(ptr)); diff --git a/py/genlast.py b/py/genlast.py index ad44745d97..1c5089fdfc 100644 --- a/py/genlast.py +++ b/py/genlast.py @@ -12,7 +12,7 @@ import subprocess from makeqstrdefs import qstr_unescape, QSTRING_BLOCK_LIST re_line = re.compile(r"#[line]*\s(\d+)\s\"([^\"]+)\"", re.DOTALL) -re_qstr = re.compile(r"MP_QSTR_[_a-zA-Z0-9]+", re.DOTALL) +re_qstr = re.compile(r"\bMP_QSTR_[_a-zA-Z0-9]+", re.DOTALL) re_translate = re.compile(r"translate\(\"((?:(?=(\\?))\2.)*?)\"\)", re.DOTALL) @@ -59,7 +59,6 @@ def maybe_preprocess(command, output_dir, fn): if __name__ == "__main__": - idx1 = sys.argv.index("--") idx2 = sys.argv.index("--", idx1 + 1) output_dir = sys.argv[1] diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 2abbdedefd..d16bb0d09a 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -249,6 +249,7 @@ static_qstr_list = [ "zip", ] + # this must match the equivalent function in qstr.c def compute_hash(qstr, bytes_hash): hash = 5381 diff --git a/py/makeqstrdefs.py b/py/makeqstrdefs.py index f035ed5745..974227f2a5 100644 --- a/py/makeqstrdefs.py +++ b/py/makeqstrdefs.py @@ -65,6 +65,7 @@ name2codepoint["tilde"] = ord("~") # These are just vexing! del name2codepoint["and"] del name2codepoint["or"] +del name2codepoint["not"] def preprocess(): diff --git a/py/maketranslationdata.py b/py/maketranslationdata.py index c0ae85f4e0..a07f70265c 100644 --- a/py/maketranslationdata.py +++ b/py/maketranslationdata.py @@ -10,6 +10,7 @@ supervisor/shared/translate/translate.h from __future__ import print_function import bisect +from dataclasses import dataclass import re import sys @@ -83,6 +84,7 @@ C_ESCAPES = { '"': '\\"', } + # this must match the equivalent function in qstr.c def compute_hash(qstr, bytes_hash): hash = 5381 @@ -146,15 +148,69 @@ def iter_substrings(s, minlen, maxlen): yield s[begin : begin + n] -def compute_huffman_coding(translations, f): +translation_requires_uint16 = {"cs", "ja", "ko", "pl", "tr", "zh_Latn_pinyin"} + + +def compute_unicode_offset(texts): + all_ch = set(" ".join(texts)) + ch_160 = sorted(c for c in all_ch if 160 <= ord(c) < 255) + ch_256 = sorted(c for c in all_ch if 255 < ord(c)) + if not ch_256: + return 0, 0 + min_256 = ord(min(ch_256)) + span = ord(max(ch_256)) - ord(min(ch_256)) + 1 + + if ch_160: + max_160 = ord(max(ch_160)) + 1 + else: + max_160 = max(160, 255 - span) + + if max_160 + span > 256: + return 0, 0 + + offstart = max_160 + offset = min_256 - max_160 + return offstart, offset + + +@dataclass +class EncodingTable: + values: object + lengths: object + words: object + canonical: object + extractor: object + apply_offset: object + remove_offset: object + + +def compute_huffman_coding(translation_name, translations, f): texts = [t[1] for t in translations] words = [] start_unused = 0x80 end_unused = 0xFF max_ord = 0 + offstart, offset = compute_unicode_offset(texts) + + def apply_offset(c): + oc = ord(c) + if oc >= offstart: + oc += offset + return chr(oc) + + def remove_offset(c): + oc = ord(c) + if oc >= offstart: + oc = oc - offset + try: + return chr(oc) + except Exception as e: + raise ValueError(f"remove_offset {offstart=} {oc=}") from e + for text in texts: for c in text: + c = remove_offset(c) ord_c = ord(c) max_ord = max(ord_c, max_ord) if 0x80 <= ord_c < 0xFF: @@ -163,6 +219,12 @@ def compute_huffman_coding(translations, f): bits_per_codepoint = 16 if max_ord > 255 else 8 values_type = "uint16_t" if max_ord > 255 else "uint8_t" + translation_name = translation_name.split("/")[-1].split(".")[0] + if max_ord > 255 and translation_name not in translation_requires_uint16: + raise ValueError( + f"Translation {translation_name} expected to fit in 8 bits but required 16 bits" + ) + while len(words) < max_words: # Until the dictionary is filled to capacity, use a heuristic to find # the best "word" (2- to 11-gram) to add to it. @@ -216,7 +278,7 @@ def compute_huffman_coding(translations, f): counter = collections.Counter() for t in texts: - for (found, word) in extractor.iter_words(t): + for found, word in extractor.iter_words(t): if not found: for substr in iter_substrings(word, minlen=2, maxlen=11): counter[substr] += 1 @@ -267,15 +329,17 @@ def compute_huffman_coding(translations, f): length_count[length] += 1 if last_length: renumbered <<= length - last_length - canonical[atom] = "{0:0{width}b}".format(renumbered, width=length) # print(f"atom={repr(atom)} code={code}", file=sys.stderr) + canonical[atom] = "{0:0{width}b}".format(renumbered, width=length) if len(atom) > 1: o = words.index(atom) + 0x80 s = "".join(C_ESCAPES.get(ch1, ch1) for ch1 in atom) + f.write(f"// {o} {s} {counter[atom]} {canonical[atom]} {renumbered}\n") else: s = C_ESCAPES.get(atom, atom) + canonical[atom] = "{0:0{width}b}".format(renumbered, width=length) o = ord(atom) - f.write(f"// {o} {s} {counter[atom]} {canonical[atom]} {renumbered}\n") + f.write(f"// {o} {s} {counter[atom]} {canonical[atom]} {renumbered}\n") renumbered += 1 last_length = length lengths = bytearray() @@ -297,7 +361,11 @@ def compute_huffman_coding(translations, f): f.write("typedef {} mchar_t;\n".format(values_type)) f.write("const uint8_t lengths[] = {{ {} }};\n".format(", ".join(map(str, lengths)))) - f.write("const mchar_t values[] = {{ {} }};\n".format(", ".join(str(ord(u)) for u in values))) + f.write( + "const mchar_t values[] = {{ {} }};\n".format( + ", ".join(str(ord(remove_offset(u))) for u in values) + ) + ) f.write( "#define compress_max_length_bits ({})\n".format( max_translation_encoded_length.bit_length() @@ -305,7 +373,7 @@ def compute_huffman_coding(translations, f): ) f.write( "const mchar_t words[] = {{ {} }};\n".format( - ", ".join(str(ord(c)) for w in words for c in w) + ", ".join(str(ord(remove_offset(c))) for w in words for c in w) ) ) f.write("const uint8_t wlencount[] = {{ {} }};\n".format(", ".join(str(p) for p in wlencount))) @@ -313,12 +381,17 @@ def compute_huffman_coding(translations, f): f.write("#define word_end {}\n".format(word_end)) f.write("#define minlen {}\n".format(minlen)) f.write("#define maxlen {}\n".format(maxlen)) + f.write("#define translation_offstart {}\n".format(offstart)) + f.write("#define translation_offset {}\n".format(offset)) - return (values, lengths, words, canonical, extractor) + return EncodingTable(values, lengths, words, canonical, extractor, apply_offset, remove_offset) def decompress(encoding_table, encoded, encoded_length_bits): - (values, lengths, words, _, _) = encoding_table + values = encoding_table.values + lengths = encoding_table.lengths + words = encoding_table.words + dec = [] this_byte = 0 this_bit = 7 @@ -376,7 +449,8 @@ def decompress(encoding_table, encoded, encoded_length_bits): def compress(encoding_table, decompressed, encoded_length_bits, len_translation_encoded): if not isinstance(decompressed, str): raise TypeError() - (_, _, _, canonical, extractor) = encoding_table + canonical = encoding_table.canonical + extractor = encoding_table.extractor enc = bytearray(len(decompressed) * 3) current_bit = 7 @@ -522,5 +596,7 @@ if __name__ == "__main__": i18ns = parse_input_headers(args.infiles) i18ns = sorted(i18ns) translations = translate(args.translation, i18ns) - encoding_table = compute_huffman_coding(translations, args.compression_filename) + encoding_table = compute_huffman_coding( + args.translation, translations, args.compression_filename + ) output_translation_data(encoding_table, translations, args.translation_filename) diff --git a/py/makeversionhdr.py b/py/makeversionhdr.py index e4ddf9fa1e..6576c3abbb 100644 --- a/py/makeversionhdr.py +++ b/py/makeversionhdr.py @@ -59,29 +59,25 @@ def get_version_info_from_git(): return git_tag, git_hash, ver -def get_version_info_from_docs_conf(): - with open(os.path.join(os.path.dirname(sys.argv[0]), "..", "conf.py")) as f: - for line in f: - if line.startswith("version = release = '"): - ver = line.strip().split(" = ")[2].strip("'") - git_tag = "v" + ver - ver = ver.split(".") - if len(ver) == 2: - ver.append("0") - return git_tag, "", ver - return None +def cannot_determine_version(): + raise SystemExit( + """Cannot determine version. + +CircuitPython must be built from a git clone with tags. +If you cloned from a fork, fetch the tags from adafruit/circuitpython as follows: + + git fetch --tags --recurse-submodules=no --shallow-since="2021-07-01" https://github.com/adafruit/circuitpython HEAD""" + ) def make_version_header(filename): - # Get version info using git, with fallback to docs/conf.py + # Get version info using git (required) info = get_version_info_from_git() if info is None: - info = get_version_info_from_docs_conf() - + cannot_determine_version() git_tag, git_hash, ver = info if len(ver) < 3: - ver = ("0", "0", "0") - version_string = git_hash + cannot_determine_version() else: version_string = ".".join(ver) diff --git a/py/malloc.c b/py/malloc.c index 5c09a2d283..7200285687 100644 --- a/py/malloc.c +++ b/py/malloc.c @@ -207,6 +207,99 @@ void m_free(void *ptr) { #endif } +#if MICROPY_TRACKED_ALLOC + +#define MICROPY_TRACKED_ALLOC_STORE_SIZE (!MICROPY_ENABLE_GC) + +typedef struct _m_tracked_node_t { + struct _m_tracked_node_t *prev; + struct _m_tracked_node_t *next; + #if MICROPY_TRACKED_ALLOC_STORE_SIZE + uintptr_t size; + #endif + uint8_t data[]; +} m_tracked_node_t; + +#if MICROPY_DEBUG_VERBOSE +STATIC size_t m_tracked_count_links(size_t *nb) { + m_tracked_node_t *node = MP_STATE_VM(m_tracked_head); + size_t n = 0; + *nb = 0; + while (node != NULL) { + ++n; + #if MICROPY_TRACKED_ALLOC_STORE_SIZE + *nb += node->size; + #else + *nb += gc_nbytes(node); + #endif + node = node->next; + } + return n; +} +#endif + +void *m_tracked_calloc(size_t nmemb, size_t size) { + m_tracked_node_t *node = m_malloc_maybe(sizeof(m_tracked_node_t) + nmemb * size, false); + if (node == NULL) { + return NULL; + } + #if MICROPY_DEBUG_VERBOSE + size_t nb; + size_t n = m_tracked_count_links(&nb); + DEBUG_printf("m_tracked_calloc(%u, %u) -> (%u;%u) %p\n", (int)nmemb, (int)size, (int)n, (int)nb, node); + #endif + if (MP_STATE_VM(m_tracked_head) != NULL) { + MP_STATE_VM(m_tracked_head)->prev = node; + } + node->prev = NULL; + node->next = MP_STATE_VM(m_tracked_head); + MP_STATE_VM(m_tracked_head) = node; + #if MICROPY_TRACKED_ALLOC_STORE_SIZE + node->size = nmemb * size; + #endif + #if !MICROPY_GC_CONSERVATIVE_CLEAR + memset(&node->data[0], 0, nmemb * size); + #endif + return &node->data[0]; +} + +void m_tracked_free(void *ptr_in) { + if (ptr_in == NULL) { + return; + } + m_tracked_node_t *node = (m_tracked_node_t *)((uint8_t *)ptr_in - sizeof(m_tracked_node_t)); + #if MICROPY_DEBUG_VERBOSE + size_t data_bytes; + #if MICROPY_TRACKED_ALLOC_STORE_SIZE + data_bytes = node->size; + #else + data_bytes = gc_nbytes(node); + #endif + size_t nb; + size_t n = m_tracked_count_links(&nb); + DEBUG_printf("m_tracked_free(%p, [%p, %p], nbytes=%u, links=%u;%u)\n", node, node->prev, node->next, (int)data_bytes, (int)n, (int)nb); + #endif + if (node->next != NULL) { + node->next->prev = node->prev; + } + if (node->prev != NULL) { + node->prev->next = node->next; + } else { + MP_STATE_VM(m_tracked_head) = node->next; + } + m_free(node + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + #if MICROPY_TRACKED_ALLOC_STORE_SIZE + , node->size + #else + , gc_nbytes(node) + #endif + #endif + ); +} + +#endif + #if MICROPY_MEM_STATS size_t m_get_total_bytes_allocated(void) { return MP_STATE_MEM(total_bytes_allocated); diff --git a/py/misc.h b/py/misc.h index 8f2d3a187a..1ced7c622e 100644 --- a/py/misc.h +++ b/py/misc.h @@ -112,6 +112,13 @@ void m_free(void *ptr); #endif NORETURN void m_malloc_fail(size_t num_bytes); +#if MICROPY_TRACKED_ALLOC +// These alloc/free functions track the pointers in a linked list so the GC does not reclaim +// them. They can be used by code that requires traditional C malloc/free semantics. +void *m_tracked_calloc(size_t nmemb, size_t size); +void m_tracked_free(void *ptr_in); +#endif + #if MICROPY_MEM_STATS size_t m_get_total_bytes_allocated(void); size_t m_get_current_bytes_allocated(void); diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 4e9fbfcd93..072ba8675f 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -759,7 +759,6 @@ STATIC const mp_rom_map_elem_t mp_module_builtins_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_KeyError), MP_ROM_PTR(&mp_type_KeyError) }, { MP_ROM_QSTR(MP_QSTR_LookupError), MP_ROM_PTR(&mp_type_LookupError) }, { MP_ROM_QSTR(MP_QSTR_MemoryError), MP_ROM_PTR(&mp_type_MemoryError) }, - { MP_ROM_QSTR(MP_QSTR_MpyError), MP_ROM_PTR(&mp_type_MpyError) }, { MP_ROM_QSTR(MP_QSTR_NameError), MP_ROM_PTR(&mp_type_NameError) }, { MP_ROM_QSTR(MP_QSTR_NotImplementedError), MP_ROM_PTR(&mp_type_NotImplementedError) }, { MP_ROM_QSTR(MP_QSTR_OSError), MP_ROM_PTR(&mp_type_OSError) }, diff --git a/py/modmath.c b/py/modmath.c index 167d46d02b..bf27e68eaf 100644 --- a/py/modmath.c +++ b/py/modmath.c @@ -254,7 +254,7 @@ STATIC mp_obj_t mp_math_log(size_t n_args, const mp_obj_t *args) { if (base <= (mp_float_t)0.0) { math_error(); } else if (base == (mp_float_t)1.0) { - mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("division by zero")); + mp_raise_ZeroDivisionError(); } return mp_obj_new_float(l / MICROPY_FLOAT_C_FUN(log)(base)); } diff --git a/py/mpconfig.h b/py/mpconfig.h index 386a9765eb..9d68f4ce9d 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -773,6 +773,16 @@ typedef long long mp_longint_impl_t; #define MICROPY_WARNINGS (0) #endif +// Whether to support chained exceptions +#ifndef MICROPY_CPYTHON_EXCEPTION_CHAIN +#define MICROPY_CPYTHON_EXCEPTION_CHAIN (0) +#endif + +// Whether the statically allocated GeneratorExit exception may be const +#ifndef MICROPY_CONST_GENERATOREXIT_OBJ +#define MICROPY_CONST_GENERATOREXIT_OBJ (!MICROPY_CPYTHON_EXCEPTION_CHAIN) +#endif + // Whether to support warning categories #ifndef MICROPY_WARNINGS_CATEGORY #define MICROPY_WARNINGS_CATEGORY (0) diff --git a/py/mpstate.h b/py/mpstate.h index bfbc29d55a..cf1711b8ad 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -119,6 +119,10 @@ typedef struct _mp_state_vm_t { qstr_pool_t *last_pool; + #if MICROPY_TRACKED_ALLOC + struct _m_tracked_node_t *m_tracked_head; + #endif + // non-heap memory for creating a traceback if we can't allocate RAM mp_obj_traceback_t mp_emergency_traceback_obj; diff --git a/py/nlrthumb.c b/py/nlrthumb.c index 30f9f2c196..4b20d30c6e 100644 --- a/py/nlrthumb.c +++ b/py/nlrthumb.c @@ -36,7 +36,7 @@ // For reference, arm/thumb callee save regs are: // r4-r11, r13=sp -__attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) { +__attribute__((naked, returns_twice)) unsigned int nlr_push(nlr_buf_t *nlr) { __asm volatile ( "str r4, [r0, #12] \n" // store r4 into nlr_buf diff --git a/py/obj.c b/py/obj.c index da609aa8ce..c394656016 100644 --- a/py/obj.c +++ b/py/obj.c @@ -142,9 +142,33 @@ void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_print_helper(MP_PYTHON_PRINTER, o_in, kind); } +static void mp_obj_print_inner_exception(const mp_print_t *print, mp_obj_t self_in, mp_int_t limit) { + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + mp_obj_exception_t *self = mp_obj_exception_get_native(self_in); + const compressed_string_t *msg = MP_ERROR_TEXT("During handling of the above exception, another exception occurred:"); + mp_obj_exception_t *inner = NULL; + if (self->cause) { + msg = MP_ERROR_TEXT("The above exception was the direct cause of the following exception:"); + inner = self->cause; + } else if (!self->suppress_context) { + inner = self->context; + } + if (inner && !inner->marked) { + inner->marked = true; + mp_obj_print_exception_with_limit(print, MP_OBJ_FROM_PTR(inner), limit); + inner->marked = false; + mp_printf(print, "\n"); + mp_cprintf(print, msg); + mp_printf(print, "\n\n"); + } + #endif +} + // helper function to print an exception with traceback void mp_obj_print_exception_with_limit(const mp_print_t *print, mp_obj_t exc, mp_int_t limit) { if (mp_obj_is_exception_instance(exc) && stack_ok()) { + mp_obj_print_inner_exception(print, exc, limit); + size_t n, *values; mp_obj_exception_get_traceback(exc, &n, &values); if (n > 0) { @@ -488,14 +512,7 @@ void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { size_t seq_len; mp_obj_get_array(o, &seq_len, items); - if (seq_len != len) { - #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE - mp_raise_ValueError(MP_ERROR_TEXT("tuple/list has wrong length")); - #else - mp_raise_ValueError_varg( - MP_ERROR_TEXT("requested length %d but object has length %d"), (int)len, (int)seq_len); - #endif - } + mp_arg_validate_length(seq_len, len, mp_obj_get_type(o)->name); } // is_slice determines whether the index is a slice index @@ -504,13 +521,7 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool if (mp_obj_is_small_int(index)) { i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { - #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE - mp_raise_TypeError(MP_ERROR_TEXT("indices must be integers")); - #else - mp_raise_TypeError_varg( - MP_ERROR_TEXT("%q indices must be integers, not %s"), - type->name, mp_obj_get_type_str(index)); - #endif + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q, not %q"), MP_QSTR_index, MP_QSTR_int, mp_obj_get_type(index)->name); } if (i < 0) { @@ -523,14 +534,7 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool i = len; } } else { - if (i < 0 || (mp_uint_t)i >= len) { - #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE - mp_raise_IndexError(MP_ERROR_TEXT("index out of range")); - #else - mp_raise_msg_varg(&mp_type_IndexError, - MP_ERROR_TEXT("%q index out of range"), type->name); - #endif - } + mp_arg_validate_index_range(i, 0, len - 1, MP_QSTR_index); } // By this point 0 <= i <= len and so fits in a size_t diff --git a/py/obj.h b/py/obj.h index 8f38a4c7c0..86fbe5155f 100644 --- a/py/obj.h +++ b/py/obj.h @@ -419,7 +419,7 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t; // Declare a module as a builtin, processed by makemoduledefs.py // param module_name: MP_QSTR_ // param obj_module: mp_obj_module_t instance -// prarm enabled_define: used as `#if (enabled_define) around entry` +// param enabled_define: used as `#if (enabled_define) around entry` #define MP_REGISTER_MODULE(module_name, obj_module, enabled_define) @@ -742,7 +742,6 @@ extern const mp_obj_type_t mp_type_ReloadException; extern const mp_obj_type_t mp_type_KeyError; extern const mp_obj_type_t mp_type_LookupError; extern const mp_obj_type_t mp_type_MemoryError; -extern const mp_obj_type_t mp_type_MpyError; extern const mp_obj_type_t mp_type_NameError; extern const mp_obj_type_t mp_type_NotImplementedError; extern const mp_obj_type_t mp_type_OSError; @@ -792,7 +791,9 @@ extern const struct _mp_obj_dict_t mp_const_empty_dict_obj; extern const struct _mp_obj_traceback_t mp_const_empty_traceback_obj; extern const struct _mp_obj_singleton_t mp_const_ellipsis_obj; extern const struct _mp_obj_singleton_t mp_const_notimplemented_obj; -extern const struct _mp_obj_exception_t mp_const_GeneratorExit_obj; +#if MICROPY_CONST_GENERATOREXIT_OBJ +extern const struct _mp_obj_exception_t mp_static_GeneratorExit_obj; +#endif // Fixed empty map. Useful when calling keyword-receiving functions // without any keywords from C, etc. diff --git a/py/objarray.c b/py/objarray.c index a66a73a5ac..763ec15cdb 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -458,26 +458,32 @@ STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) { // allow to extend by anything that has the buffer protocol (extension to CPython) mp_buffer_info_t arg_bufinfo; - mp_get_buffer_raise(arg_in, &arg_bufinfo, MP_BUFFER_READ); + if (mp_get_buffer(arg_in, &arg_bufinfo, MP_BUFFER_READ)) { + size_t sz = mp_binary_get_size('@', self->typecode, NULL); - size_t sz = mp_binary_get_size('@', self->typecode, NULL); + // convert byte count to element count + size_t len = arg_bufinfo.len / sz; - // convert byte count to element count - size_t len = arg_bufinfo.len / sz; + // make sure we have enough room to extend + // TODO: alloc policy; at the moment we go conservative + if (self->free < len) { + self->items = m_renew(byte, self->items, (self->len + self->free) * sz, (self->len + len) * sz); + self->free = 0; + } else { + self->free -= len; + } - // make sure we have enough room to extend - // TODO: alloc policy; at the moment we go conservative - if (self->free < len) { - self->items = m_renew(byte, self->items, (self->len + self->free) * sz, (self->len + len) * sz); - self->free = 0; + // extend + mp_seq_copy((byte *)self->items + self->len * sz, arg_bufinfo.buf, len * sz, byte); + self->len += len; } else { - self->free -= len; + // Otherwise argument must be an iterable of items to append + mp_obj_t iterable = mp_getiter(arg_in, NULL); + mp_obj_t item; + while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + array_append(self_in, item); + } } - - // extend - mp_seq_copy((byte *)self->items + self->len * sz, arg_bufinfo.buf, len * sz, byte); - self->len += len; - return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_extend_obj, array_extend); diff --git a/py/objcomplex.c b/py/objcomplex.c index f205249bb4..7f4fd621e6 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -217,7 +217,7 @@ mp_obj_t mp_obj_complex_binary_op(mp_binary_op_t op, mp_float_t lhs_real, mp_flo case MP_BINARY_OP_INPLACE_TRUE_DIVIDE: if (rhs_imag == 0) { if (rhs_real == 0) { - mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("complex division by zero")); + mp_raise_ZeroDivisionError(); } lhs_real /= rhs_real; lhs_imag /= rhs_real; diff --git a/py/objexcept.c b/py/objexcept.c index 230f9d11ba..24fb564e23 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -155,6 +155,12 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin mp_obj_tuple_print(print, MP_OBJ_FROM_PTR(o->args), kind); } +void mp_obj_exception_initialize0(mp_obj_exception_t *o_exc, const mp_obj_type_t *type) { + o_exc->base.type = type; + o_exc->args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj; + mp_obj_exception_clear_traceback(o_exc); +} + mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); @@ -218,16 +224,45 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in); if (dest[0] != MP_OBJ_NULL) { // store/delete attribute + #if MICROPY_CONST_GENERATOREXIT_OBJ + if (self == &mp_static_GeneratorExit_obj) { + mp_raise_AttributeError(MP_ERROR_TEXT("can't set attribute")); + } + #endif if (attr == MP_QSTR___traceback__) { if (dest[1] == mp_const_none) { self->traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; } else { if (!mp_obj_is_type(dest[1], &mp_type_traceback)) { - mp_raise_TypeError(MP_ERROR_TEXT("invalid traceback")); + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q or %q, not %q"), MP_QSTR___context__, MP_QSTR_traceback, MP_QSTR_None, mp_obj_get_type(dest[1])->name); } self->traceback = MP_OBJ_TO_PTR(dest[1]); } dest[0] = MP_OBJ_NULL; // indicate success + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + } else if (attr == MP_QSTR___cause__) { + if (dest[1] == mp_const_none) { + self->cause = NULL; + } else if (!mp_obj_is_type(dest[1], &mp_type_BaseException)) { + self->cause = dest[1]; + } else { + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q or %q, not %q"), attr, MP_QSTR_BaseException, MP_QSTR_None, mp_obj_get_type(dest[1])->name); + } + self->suppress_context = true; + dest[0] = MP_OBJ_NULL; // indicate success + } else if (attr == MP_QSTR___context__) { + if (dest[1] == mp_const_none) { + self->context = NULL; + } else if (!mp_obj_is_type(dest[1], &mp_type_BaseException)) { + self->context = dest[1]; + } else { + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q or %q, not %q"), attr, MP_QSTR_BaseException, MP_QSTR_None, mp_obj_get_type(dest[1])->name); + } + dest[0] = MP_OBJ_NULL; // indicate success + } else if (attr == MP_QSTR___suppress_context__) { + self->suppress_context = mp_obj_is_true(dest[1]); + dest[0] = MP_OBJ_NULL; // indicate success + #endif } return; } @@ -237,6 +272,14 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { dest[0] = mp_obj_exception_get_value(self_in); } else if (attr == MP_QSTR___traceback__) { dest[0] = (self->traceback) ? MP_OBJ_FROM_PTR(self->traceback) : mp_const_none; + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + } else if (attr == MP_QSTR___cause__) { + dest[0] = (self->cause) ? MP_OBJ_FROM_PTR(self->cause) : mp_const_none; + } else if (attr == MP_QSTR___context__) { + dest[0] = (self->context) ? MP_OBJ_FROM_PTR(self->context) : mp_const_none; + } else if (attr == MP_QSTR___suppress_context__) { + dest[0] = mp_obj_new_bool(self->suppress_context); + #endif #if MICROPY_CPYTHON_COMPAT } else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(self->base.type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { if (attr == MP_QSTR_errno) { @@ -347,7 +390,6 @@ MP_DEFINE_EXCEPTION(UnicodeError, ValueError) #if CIRCUITPY_ALARM MP_DEFINE_EXCEPTION(DeepSleepRequest, BaseException) #endif -MP_DEFINE_EXCEPTION(MpyError, ValueError) /* MP_DEFINE_EXCEPTION(Warning, Exception) MP_DEFINE_EXCEPTION(DeprecationWarning, Warning) @@ -547,6 +589,12 @@ void mp_obj_exception_clear_traceback(mp_obj_t self_in) { // just set the traceback to the empty traceback object // we don't want to call any memory management functions here self->traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + self->cause = 0; + self->context = 0; + self->suppress_context = false; + self->marked = false; + #endif } void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block) { diff --git a/py/objexcept.h b/py/objexcept.h index f28f50f5dc..1230fdf18a 100644 --- a/py/objexcept.h +++ b/py/objexcept.h @@ -34,10 +34,16 @@ typedef struct _mp_obj_exception_t { mp_obj_base_t base; mp_obj_tuple_t *args; mp_obj_traceback_t *traceback; + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + struct _mp_obj_exception_t *cause, *context; + bool suppress_context; + bool marked; + #endif } mp_obj_exception_t; void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest); +void mp_obj_exception_initialize0(mp_obj_exception_t *o_exc, const mp_obj_type_t *type); mp_obj_exception_t *mp_obj_exception_get_native(mp_obj_t self_in); #define MP_DEFINE_EXCEPTION(exc_name, base_name) \ diff --git a/py/objfloat.c b/py/objfloat.c index f8261df933..7aebcfdeb2 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -266,7 +266,7 @@ mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: if (rhs_val == 0) { zero_division_error: - mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("divide by zero")); + mp_raise_ZeroDivisionError(); } // Python specs require that x == (x//y)*y + (x%y) so we must // call divmod to compute the correct floor division, which diff --git a/py/objgenerator.c b/py/objgenerator.c index b18101cfa1..7c3ec99307 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -38,7 +38,13 @@ #include "supervisor/shared/translate/translate.h" // Instance of GeneratorExit exception - needed by generator.close() -const mp_obj_exception_t mp_const_GeneratorExit_obj = {{&mp_type_GeneratorExit}, (mp_obj_tuple_t *)&mp_const_empty_tuple_obj, (mp_obj_traceback_t *)&mp_const_empty_traceback_obj}; +#if MICROPY_CONST_GENERATOREXIT_OBJ +const +mp_obj_exception_t mp_static_GeneratorExit_obj = {{&mp_type_GeneratorExit}, (mp_obj_tuple_t *)&mp_const_empty_tuple_obj, (mp_obj_traceback_t *)&mp_const_empty_traceback_obj}; +#else +static +mp_obj_exception_t mp_static_GeneratorExit_obj; +#endif /******************************************************************************/ /* generator wrapper */ @@ -330,7 +336,8 @@ STATIC mp_obj_t gen_instance_await(mp_obj_t self_in) { if (!self->coroutine_generator) { // Pretend like a generator does not have this coroutine behavior. // Pay no attention to the dir() behind the curtain - mp_raise_AttributeError(MP_ERROR_TEXT("type object 'generator' has no attribute '__await__'")); + mp_raise_msg_varg(&mp_type_AttributeError, MP_ERROR_TEXT("type object '%q' has no attribute '%q'"), + MP_QSTR_generator, MP_QSTR___await__); } // You can directly call send on a coroutine generator or you can __await__ then send on the return of that. return self; @@ -361,9 +368,17 @@ STATIC mp_obj_t gen_instance_throw(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gen_instance_throw_obj, 2, 4, gen_instance_throw); +static mp_obj_t generatorexit(void) { + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + MP_STATIC_ASSERT(!MICROPY_CONST_GENERATOREXIT_OBJ); + mp_obj_exception_initialize0(&mp_static_GeneratorExit_obj, &mp_type_GeneratorExit); + #endif + return MP_OBJ_FROM_PTR(&mp_static_GeneratorExit_obj); +} + STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) { mp_obj_t ret; - switch (mp_obj_gen_resume(self_in, mp_const_none, MP_OBJ_FROM_PTR(&mp_const_GeneratorExit_obj), &ret)) { + switch (mp_obj_gen_resume(self_in, mp_const_none, generatorexit(), &ret)) { case MP_VM_RETURN_YIELD: mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("generator ignored GeneratorExit")); diff --git a/py/objint.c b/py/objint.c index b44a2e3b4a..6dc675823f 100644 --- a/py/objint.c +++ b/py/objint.c @@ -396,7 +396,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i // This is called only with strings whose value doesn't fit in SMALL_INT mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) { - mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("long int not supported in this build")); + mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("small int overflow")); return mp_const_none; } diff --git a/py/objint_longlong.c b/py/objint_longlong.c index 67ec844f47..d318eab38e 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -236,7 +236,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i } zero_division: - mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("division by zero")); + mp_raise_ZeroDivisionError(); } mp_obj_t mp_obj_new_int(mp_int_t value) { diff --git a/py/objint_mpz.c b/py/objint_mpz.c index fd74803fe7..e147e5f08a 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -244,7 +244,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: { if (mpz_is_zero(zrhs)) { zero_division_error: - mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("divide by zero")); + mp_raise_ZeroDivisionError(); } mpz_t rem; mpz_init_zero(&rem); diff --git a/py/objmodule.c b/py/objmodule.c index a9d20c7ee5..8f04a44597 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -218,9 +218,6 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { #if MICROPY_PY_UJSON && !CIRCUITPY { MP_ROM_QSTR(MP_QSTR_ujson), MP_ROM_PTR(&mp_module_ujson) }, #endif - #if CIRCUITPY_ULAB - { MP_ROM_QSTR(MP_QSTR_ulab), MP_ROM_PTR(&ulab_user_cmodule) }, - #endif #if MICROPY_PY_URE && !CIRCUITPY { MP_ROM_QSTR(MP_QSTR_ure), MP_ROM_PTR(&mp_module_ure) }, #endif diff --git a/py/objrange.c b/py/objrange.c index b0c74815dc..78a5fcd0f8 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -110,7 +110,7 @@ STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t if (n_args == 3) { o->step = mp_obj_get_int(args[2]); if (o->step == 0) { - mp_raise_ValueError(MP_ERROR_TEXT("zero step")); + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q step cannot be zero"), MP_QSTR_range); } } } diff --git a/py/objslice.c b/py/objslice.c index 3172f798c0..395af727e8 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -157,7 +157,7 @@ void mp_obj_slice_indices(mp_obj_t self_in, mp_int_t length, mp_bound_slice_t *r } else { step = mp_obj_get_int(self->step); if (step == 0) { - mp_raise_ValueError(MP_ERROR_TEXT("slice step cannot be zero")); + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q step cannot be zero"), MP_QSTR_slice); } } diff --git a/py/objstr.c b/py/objstr.c index df735a45cd..fbb044c65e 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -986,7 +986,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else - mp_raise_ValueError(MP_ERROR_TEXT("single '}' encountered in format string")); + mp_raise_ValueError_varg(MP_ERROR_TEXT("unmatched '%c' in format"), '}'); #endif } if (*str != '{') { @@ -1063,7 +1063,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else - mp_raise_ValueError(MP_ERROR_TEXT("unmatched '{' in format")); + mp_raise_ValueError_varg(MP_ERROR_TEXT("unmatched '%c' in format"), '{'); #endif } if (*str != '}') { diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 0f26da62cf..b3b23d0f01 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -159,7 +159,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s if (mp_obj_is_small_int(index)) { i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { - mp_raise_TypeError_varg(MP_ERROR_TEXT("string indices must be integers, not %q"), mp_obj_get_type_qstr(index)); + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q, not %q"), MP_QSTR_index, MP_QSTR_int, mp_obj_get_type(index)->name); } const byte *s, *top = self_data + self_len; if (i < 0) { diff --git a/py/objtype.c b/py/objtype.c index 071065041f..76b9551be8 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -106,7 +106,9 @@ STATIC mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *pos_args // copy in args memcpy(args2, pos_args, n_args * sizeof(mp_obj_t)); // copy in kwargs - memcpy(args2 + n_args, kw_args->table, 2 * n_kw * sizeof(mp_obj_t)); + if (n_kw) { + memcpy(args2 + n_args, kw_args->table, 2 * n_kw * sizeof(mp_obj_t)); + } self->subobj[0] = native_base->make_new(native_base, n_args, n_kw, args2); m_del(mp_obj_t, args2, n_args + 2 * n_kw); @@ -1181,9 +1183,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) mp_obj_t *bases_items; mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items); for (size_t i = 0; i < bases_len; i++) { - if (!mp_obj_is_type(bases_items[i], &mp_type_type)) { - mp_raise_TypeError(MP_ERROR_TEXT("type is not an acceptable base type")); - } + mp_arg_validate_type(bases_items[i], &mp_type_type, MP_QSTR___class__); mp_obj_type_t *t = MP_OBJ_TO_PTR(bases_items[i]); // TODO: Verify with CPy, tested on function type if (t->make_new == NULL) { diff --git a/py/parsenum.c b/py/parsenum.c index adf2a4d84d..24d46705a7 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -55,9 +55,9 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m mp_obj_t ret_val; // check radix base - if ((base != 0 && base < 2) || base > 36) { + if (base != 0) { // this won't be reached if lex!=NULL - mp_raise_ValueError(MP_ERROR_TEXT("int() arg 2 must be >= 2 and <= 36")); + mp_arg_validate_int_range(base, 2, 36, MP_QSTR_base); } // skip leading space diff --git a/py/persistentcode.c b/py/persistentcode.c index 787f724bf6..0431b30a29 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -582,7 +582,7 @@ mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) { || MPY_FEATURE_DECODE_FLAGS(header[2]) != MPY_FEATURE_FLAGS || header[3] > mp_small_int_bits() || read_uint(reader, NULL) > QSTR_WINDOW_SIZE) { - mp_raise_MpyError(MP_ERROR_TEXT("Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info.")); + mp_raise_ValueError(MP_ERROR_TEXT("Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info.")); } if (MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE) { byte arch = MPY_FEATURE_DECODE_ARCH(header[2]); diff --git a/py/py.mk b/py/py.mk index 6827fbe786..c598f44cbd 100644 --- a/py/py.mk +++ b/py/py.mk @@ -243,7 +243,7 @@ $(HEADER_BUILD)/mpversion.h: FORCE | $(HEADER_BUILD) MPCONFIGPORT_MK = $(wildcard mpconfigport.mk) $(HEADER_BUILD)/$(TRANSLATION).mo: $(TOP)/locale/$(TRANSLATION).po | $(HEADER_BUILD) - $(Q)msgfmt -o $@ $^ + $(Q)$(PYTHON) $(TOP)/tools/msgfmt.py -o $@ $^ $(HEADER_BUILD)/qstrdefs.preprocessed.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) mpconfigport.h $(MPCONFIGPORT_MK) $(PY_SRC)/mpconfig.h | $(HEADER_BUILD) $(STEPECHO) "GEN $@" @@ -262,8 +262,15 @@ $(HEADER_BUILD)/qstrdefs.generated.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/ $(STEPECHO) "GEN $@" $(Q)$(PYTHON) $(PY_SRC)/makeqstrdata.py --output_type=data $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ -$(PY_BUILD)/translations-$(TRANSLATION).c $(HEADER_BUILD)/compression.generated.h: $(PY_SRC)/maketranslationdata.py $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h +# Is generated as a side-effect of building compression.generated.h +# Specifying both in a single rule actually causes the rule to be run twice! +# This alternative makes it run just once. +$(PY_BUILD)/translations-$(TRANSLATION).c: $(HEADER_BUILD)/compression.generated.h + @true + +$(HEADER_BUILD)/compression.generated.h: $(PY_SRC)/maketranslationdata.py $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h $(STEPECHO) "GEN $@" + $(Q)mkdir -p $(PY_BUILD) $(Q)$(PYTHON) $(PY_SRC)/maketranslationdata.py --compression_filename $(HEADER_BUILD)/compression.generated.h --translation $(HEADER_BUILD)/$(TRANSLATION).mo --translation_filename $(PY_BUILD)/translations-$(TRANSLATION).c $(HEADER_BUILD)/qstrdefs.preprocessed.h PY_CORE_O += $(PY_BUILD)/translations-$(TRANSLATION).o diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 02b87f4ec3..70753866bd 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -49,7 +49,6 @@ Q({:#x}) Q({:#b}) Q( ) Q(\n) -Q(maximum recursion depth exceeded) Q() Q() Q() @@ -63,7 +62,3 @@ Q(utf-8) #if MICROPY_MODULE_FROZEN Q(.frozen) #endif - -#if MICROPY_ENABLE_PYSTACK -Q(pystack exhausted) -#endif diff --git a/py/ringbuf.c b/py/ringbuf.c index fe47b50068..8a4cb33cbc 100644 --- a/py/ringbuf.c +++ b/py/ringbuf.c @@ -27,86 +27,85 @@ #include "ringbuf.h" -bool ringbuf_init(ringbuf_t *r, uint8_t *buf, size_t capacity) { +bool ringbuf_init(ringbuf_t *r, uint8_t *buf, size_t size) { r->buf = buf; - r->size = capacity; - r->iget = r->iput = 0; + r->size = size; + r->used = 0; + r->next_read = 0; + r->next_write = 0; return r->buf != NULL; } -// Dynamic initialization. This should be accessible from a root pointer. -// capacity is the number of bytes the ring buffer can hold. The actual -// size of the buffer is one greater than that, due to how the buffer -// handles empty and full statuses. -bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived) { - r->buf = gc_alloc(capacity + 1, false, long_lived); - r->size = capacity + 1; - r->iget = r->iput = 0; - return r->buf != NULL; +// Dynamic initialization. This should be accessible from a root pointer.. +bool ringbuf_alloc(ringbuf_t *r, size_t size, bool long_lived) { + bool result = ringbuf_init(r, gc_alloc(size, false, long_lived), size); + return result; } -void ringbuf_free(ringbuf_t *r) { - // Free buf by letting gc take care of it. If the VM has finished already, +void ringbuf_deinit(ringbuf_t *r) { + // Free buf by doing nothing and letting gc take care of it. If the VM has finished already, // this will be safe. r->buf = (uint8_t *)NULL; r->size = 0; ringbuf_clear(r); } -size_t ringbuf_capacity(ringbuf_t *r) { - return r->size - 1; +size_t ringbuf_size(ringbuf_t *r) { + return r->size; } -// Returns -1 if buffer is empty, else returns byte fetched. +// Return -1 if buffer is empty, else return byte fetched. int ringbuf_get(ringbuf_t *r) { - if (r->iget == r->iput) { + if (r->used < 1) { return -1; } - uint8_t v = r->buf[r->iget++]; - if (r->iget >= r->size) { - r->iget = 0; + uint8_t v = r->buf[r->next_read]; + r->next_read++; + if (r->next_read >= r->size) { + r->next_read = 0; } + r->used--; return v; } int ringbuf_get16(ringbuf_t *r) { - int v = ringbuf_peek16(r); - if (v == -1) { - return v; - } - r->iget += 2; - if (r->iget >= r->size) { - r->iget -= r->size; - } - return v; -} - -// Returns -1 if no room in buffer, else returns 0. -int ringbuf_put(ringbuf_t *r, uint8_t v) { - uint32_t iput_new = r->iput + 1; - if (iput_new >= r->size) { - iput_new = 0; - } - if (iput_new == r->iget) { + if (r->used < 2) { return -1; } - r->buf[r->iput] = v; - r->iput = iput_new; + + int high_byte = ringbuf_get(r); + int low_byte = ringbuf_get(r); + return (high_byte << 8) | low_byte; +} + +// Return -1 if no room in buffer, else return 0. +int ringbuf_put(ringbuf_t *r, uint8_t v) { + if (r->used >= r->size) { + return -1; + } + r->buf[r->next_write] = v; + r->next_write++; + if (r->next_write >= r->size) { + r->next_write = 0; + } + r->used++; return 0; } void ringbuf_clear(ringbuf_t *r) { - r->iput = r->iget = 0; + r->next_write = 0; + r->next_read = 0; + r->used = 0; } // Number of free slots that can be written. size_t ringbuf_num_empty(ringbuf_t *r) { - return (r->size + r->iget - r->iput - 1) % r->size; + return r->size - r->used; } // Number of bytes available to read. size_t ringbuf_num_filled(ringbuf_t *r) { - return (r->size + r->iput - r->iget) % r->size; + return r->used; } // If the ring buffer fills up, not all bytes will be written. @@ -134,37 +133,12 @@ size_t ringbuf_get_n(ringbuf_t *r, uint8_t *buf, size_t bufsize) { return bufsize; } -int ringbuf_peek16(ringbuf_t *r) { - if (r->iget == r->iput) { - return -1; - } - uint32_t iget_a = r->iget + 1; - if (iget_a == r->size) { - iget_a = 0; - } - if (iget_a == r->iput) { - return -1; - } - return (r->buf[r->iget] << 8) | (r->buf[iget_a]); -} - int ringbuf_put16(ringbuf_t *r, uint16_t v) { - uint32_t iput_a = r->iput + 1; - if (iput_a == r->size) { - iput_a = 0; - } - if (iput_a == r->iget) { + if (r->size - r->used < 2) { return -1; } - uint32_t iput_b = iput_a + 1; - if (iput_b == r->size) { - iput_b = 0; - } - if (iput_b == r->iget) { - return -1; - } - r->buf[r->iput] = (v >> 8) & 0xff; - r->buf[iput_a] = v & 0xff; - r->iput = iput_b; + + ringbuf_put(r, (v >> 8) & 0xff); + ringbuf_put(r, v & 0xff); return 0; } diff --git a/py/ringbuf.h b/py/ringbuf.h index d868eff1e4..2725bedcca 100644 --- a/py/ringbuf.h +++ b/py/ringbuf.h @@ -33,19 +33,23 @@ typedef struct _ringbuf_t { uint8_t *buf; - // Allocated size; capacity is one less. Don't reference this directly. uint32_t size; - uint32_t iget; - uint32_t iput; + uint32_t used; + uint32_t next_read; + uint32_t next_write; } ringbuf_t; -// Note that the capacity of the buffer is N-1! - -// For static initialization use ringbuf_init() +// For static initialization with an existing buffer, use ringbuf_init(). bool ringbuf_init(ringbuf_t *r, uint8_t *buf, size_t capacity); + +// For allocation of a buffer on the heap, use ringbuf_alloc(). bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived); -void ringbuf_free(ringbuf_t *r); -size_t ringbuf_capacity(ringbuf_t *r); + +// Mark ringbuf as no longer in use, and allow any heap storage to be freed by gc. +void ringbuf_deinit(ringbuf_t *r); + +// Note: Ringbuf operations are not atomic. +size_t ringbuf_size(ringbuf_t *r); int ringbuf_get(ringbuf_t *r); int ringbuf_put(ringbuf_t *r, uint8_t v); void ringbuf_clear(ringbuf_t *r); @@ -54,9 +58,8 @@ size_t ringbuf_num_filled(ringbuf_t *r); size_t ringbuf_put_n(ringbuf_t *r, const uint8_t *buf, size_t bufsize); size_t ringbuf_get_n(ringbuf_t *r, uint8_t *buf, size_t bufsize); -// Note: big-endian. No-op if not enough room available for both bytes. +// Note: big-endian. Return -1 if can't read or write two bytes. int ringbuf_get16(ringbuf_t *r); -int ringbuf_peek16(ringbuf_t *r); int ringbuf_put16(ringbuf_t *r, uint16_t v); #endif // MICROPY_INCLUDED_PY_RINGBUF_H diff --git a/py/runtime.c b/py/runtime.c index 7fcad7366a..9227594d83 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -78,14 +78,10 @@ void mp_init(void) { #if MICROPY_KBD_EXCEPTION // initialise the exception object for raising KeyboardInterrupt - MP_STATE_VM(mp_kbd_exception).base.type = &mp_type_KeyboardInterrupt; - MP_STATE_VM(mp_kbd_exception).args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj; - MP_STATE_VM(mp_kbd_exception).traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; + mp_obj_exception_initialize0(&MP_STATE_VM(mp_kbd_exception), &mp_type_KeyboardInterrupt); #endif - MP_STATE_VM(mp_reload_exception).base.type = &mp_type_ReloadException; - MP_STATE_VM(mp_reload_exception).args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj; - MP_STATE_VM(mp_reload_exception).traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; + mp_obj_exception_initialize0(&MP_STATE_VM(mp_reload_exception), &mp_type_ReloadException); // call port specific initialization if any #ifdef MICROPY_PORT_INIT_FUNC @@ -310,7 +306,7 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) { } #else if (op == MP_UNARY_OP_INT) { - mp_raise_TypeError_varg(MP_ERROR_TEXT("can't convert %q to int"), mp_obj_get_type_qstr(arg)); + mp_raise_TypeError_varg(MP_ERROR_TEXT("can't convert %q to %q"), mp_obj_get_type_qstr(arg), MP_QSTR_int); } else { mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported type for %q: '%q'"), mp_unary_op_method_name[op], mp_obj_get_type_qstr(arg)); @@ -631,7 +627,7 @@ unsupported_op: #endif zero_division: - mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("division by zero")); + mp_raise_ZeroDivisionError(); } mp_obj_t mp_call_function_0(mp_obj_t fun) { @@ -1247,8 +1243,8 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { mp_raise_AttributeError(MP_ERROR_TEXT("no such attribute")); #else mp_raise_msg_varg(&mp_type_AttributeError, - MP_ERROR_TEXT("'%s' object has no attribute '%q'"), - mp_obj_get_type_str(base), attr); + MP_ERROR_TEXT("can't set attribute '%q'"), + attr); #endif } @@ -1742,10 +1738,6 @@ NORETURN void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...) { va_end(argptr); } -NORETURN void mp_raise_MpyError(const compressed_string_t *msg) { - mp_raise_msg(&mp_type_MpyError, msg); -} - NORETURN void mp_raise_type_arg(const mp_obj_type_t *exc_type, mp_obj_t arg) { nlr_raise(mp_obj_new_exception_arg1(exc_type, arg)); } @@ -1769,3 +1761,7 @@ NORETURN void mp_raise_recursion_depth(void) { mp_raise_RuntimeError(MP_ERROR_TEXT("maximum recursion depth exceeded")); } #endif + +NORETURN void mp_raise_ZeroDivisionError(void) { + mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("division by zero")); +} diff --git a/py/runtime.h b/py/runtime.h index a78969780b..1a7a5d1698 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -91,7 +91,9 @@ static inline void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_mi } void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); +#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE NORETURN void mp_arg_error_terse_mismatch(void); +#endif NORETURN void mp_arg_error_unimpl_kw(void); NORETURN void mp_arg_error_invalid(qstr arg_name); @@ -108,6 +110,8 @@ mp_uint_t mp_arg_validate_length_range(mp_uint_t length, mp_uint_t min, mp_uint_ mp_uint_t mp_arg_validate_length(mp_uint_t length, mp_uint_t required_length, qstr arg_name); mp_int_t mp_arg_validate_index_range(mp_int_t index, mp_int_t min, mp_int_t max, qstr arg_name); mp_obj_t mp_arg_validate_type(mp_obj_t obj, const mp_obj_type_t *type, qstr arg_name); +mp_obj_t mp_arg_validate_type_in(mp_obj_t obj, const mp_obj_type_t *type, qstr arg_name); +mp_obj_t mp_arg_validate_type_or_none(mp_obj_t obj, const mp_obj_type_t *type, qstr arg_name); mp_int_t mp_arg_validate_type_int(mp_obj_t obj, qstr arg_name); mp_obj_t mp_arg_validate_type_string(mp_obj_t obj, qstr arg_name); @@ -225,8 +229,8 @@ NORETURN void mp_raise_BrokenPipeError(void); NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg); NORETURN void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...); NORETURN void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...); -NORETURN void mp_raise_MpyError(const compressed_string_t *msg); NORETURN void mp_raise_recursion_depth(void); +NORETURN void mp_raise_ZeroDivisionError(void); #endif #if MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG diff --git a/py/stream.c b/py/stream.c index 27609043fc..e7e77341bd 100644 --- a/py/stream.c +++ b/py/stream.c @@ -31,6 +31,7 @@ #include "py/objstr.h" #include "py/stream.h" #include "py/runtime.h" +#include "py/unicode.h" #include "supervisor/shared/translate/translate.h" // This file defines generic Python stream read/write methods which @@ -43,6 +44,13 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in); #define STREAM_CONTENT_TYPE(stream) (((stream)->is_text) ? &mp_type_str : &mp_type_bytes) +static mp_obj_t mp_obj_new_str_from_vstr_check(const mp_obj_type_t *type, vstr_t *vstr) { + if (type == &mp_type_str && !utf8_check((void *)vstr->buf, vstr->len)) { + mp_raise_msg(&mp_type_UnicodeError, NULL); + } + return mp_obj_new_str_from_vstr(type, vstr); +} + // Returns error condition in *errcode, if non-zero, return value is number of bytes written // before error condition occurred. If *errcode == 0, returns total bytes written (which will // be equal to input size). @@ -201,8 +209,7 @@ STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte fl } } } - - return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + return mp_obj_new_str_from_vstr_check(&mp_type_str, &vstr); } #endif @@ -223,7 +230,7 @@ STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte fl mp_raise_OSError(error); } else { vstr.len = out_sz; - return mp_obj_new_str_from_vstr(STREAM_CONTENT_TYPE(stream_p), &vstr); + return mp_obj_new_str_from_vstr_check(STREAM_CONTENT_TYPE(stream_p), &vstr); } } @@ -364,7 +371,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) { } vstr.len = total_size; - return mp_obj_new_str_from_vstr(STREAM_CONTENT_TYPE(stream_p), &vstr); + return mp_obj_new_str_from_vstr_check(STREAM_CONTENT_TYPE(stream_p), &vstr); } // Unbuffered, inefficient implementation of readline() for raw I/O files. @@ -417,7 +424,7 @@ STATIC mp_obj_t stream_unbuffered_readline(size_t n_args, const mp_obj_t *args) } } - return mp_obj_new_str_from_vstr(STREAM_CONTENT_TYPE(stream_p), &vstr); + return mp_obj_new_str_from_vstr_check(STREAM_CONTENT_TYPE(stream_p), &vstr); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_unbuffered_readline_obj, 1, 2, stream_unbuffered_readline); diff --git a/py/vm.c b/py/vm.c index 12a0f2d445..2663b5fd68 100644 --- a/py/vm.c +++ b/py/vm.c @@ -183,6 +183,15 @@ #define TRACE_TICK(current_ip, current_sp, is_exception) #endif // MICROPY_PY_SYS_SETTRACE +STATIC mp_obj_t get_active_exception(mp_exc_stack_t *exc_sp, mp_exc_stack_t *exc_stack) { + for (mp_exc_stack_t *e = exc_sp; e >= exc_stack; --e) { + if (e->prev_exc != NULL) { + return MP_OBJ_FROM_PTR(e->prev_exc); + } + } + return MP_OBJ_NULL; +} + // fastn has items in reverse order (fastn[0] is local[0], fastn[-1] is local[1], etc) // sp points to bottom of stack which grows up // returns: @@ -1129,13 +1138,7 @@ unwind_return: ENTRY(MP_BC_RAISE_LAST): { MARK_EXC_IP_SELECTIVE(); // search for the inner-most previous exception, to reraise it - mp_obj_t obj = MP_OBJ_NULL; - for (mp_exc_stack_t *e = exc_sp; e >= exc_stack; --e) { - if (e->prev_exc != NULL) { - obj = MP_OBJ_FROM_PTR(e->prev_exc); - break; - } - } + mp_obj_t obj = get_active_exception(exc_sp, exc_stack); if (obj == MP_OBJ_NULL) { obj = mp_obj_new_exception_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("no active exception to reraise")); } @@ -1145,14 +1148,30 @@ unwind_return: ENTRY(MP_BC_RAISE_OBJ): { MARK_EXC_IP_SELECTIVE(); mp_obj_t obj = mp_make_raise_obj(TOP()); + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + mp_obj_t active_exception = get_active_exception(exc_sp, exc_stack); + if (active_exception != MP_OBJ_NULL && active_exception != obj) { + mp_store_attr(obj, MP_QSTR___context__, active_exception); + } + #endif RAISE(obj); } ENTRY(MP_BC_RAISE_FROM): { MARK_EXC_IP_SELECTIVE(); - mp_warning(NULL, "exception chaining not supported"); - sp--; // ignore (pop) "from" argument + mp_obj_t cause = POP(); mp_obj_t obj = mp_make_raise_obj(TOP()); + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + // search for the inner-most previous exception, to chain it + mp_obj_t active_exception = get_active_exception(exc_sp, exc_stack); + if (active_exception != MP_OBJ_NULL && active_exception != obj) { + mp_store_attr(obj, MP_QSTR___context__, active_exception); + } + mp_store_attr(obj, MP_QSTR___cause__, cause); + #else + (void)cause; + mp_warning(NULL, "exception chaining not supported"); + #endif RAISE(obj); } @@ -1391,7 +1410,10 @@ unwind_loop: // - constant GeneratorExit object, because it's const // - exceptions re-raised by END_FINALLY // - exceptions re-raised explicitly by "raise" - if (nlr.ret_val != &mp_const_GeneratorExit_obj + if ( true + #if MICROPY_CONST_GENERATOREXIT_OBJ + && nlr.ret_val != &mp_static_GeneratorExit_obj + #endif && *code_state->ip != MP_BC_END_FINALLY && *code_state->ip != MP_BC_RAISE_LAST) { const byte *ip = code_state->fun_bc->bytecode; @@ -1434,10 +1456,19 @@ unwind_loop: // catch exception and pass to byte code code_state->ip = exc_sp->handler; mp_obj_t *sp = MP_TAGPTR_PTR(exc_sp->val_sp); + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + mp_obj_t active_exception = get_active_exception(exc_sp, exc_stack); + #endif // save this exception in the stack so it can be used in a reraise, if needed exc_sp->prev_exc = nlr.ret_val; + mp_obj_t obj = MP_OBJ_FROM_PTR(nlr.ret_val); + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + if (active_exception != MP_OBJ_NULL && active_exception != obj) { + mp_store_attr(obj, MP_QSTR___context__, active_exception); + } + #endif // push exception object so it can be handled by bytecode - PUSH(MP_OBJ_FROM_PTR(nlr.ret_val)); + PUSH(obj); code_state->sp = sp; #if MICROPY_STACKLESS diff --git a/requirements-ci.txt b/requirements-ci.txt index 81deb34beb..2f6e042fb8 100644 --- a/requirements-ci.txt +++ b/requirements-ci.txt @@ -1,2 +1,2 @@ # For uploading artifacts -awscli +# awscli diff --git a/requirements-dev.txt b/requirements-dev.txt index 3b4411bd3a..5e8fe3d3f6 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,13 +1,12 @@ # For nvm.toml cascadetoml jinja2 -# Undo this pin when click and typer are again compatible. -typer==0.4.0 +typer sh -# Undo this pin when click and typer are again compatible. -click==8.0.4 +click cpp-coveralls + requests requests-cache @@ -15,8 +14,9 @@ requests-cache polib # For pre-commit -pyyaml black +pyyaml +pre-commit # for combining the Nordic SoftDevice with CircuitPython intelhex @@ -24,8 +24,8 @@ intelhex # for building & testing natmods pyelftools -# for stubs and annotations -adafruit-circuitpython-typing +# for mbedtls certificate store +cryptography # for web workflow minify minify_html diff --git a/requirements-doc.txt b/requirements-doc.txt index 2eaf513d3d..43e99fa32f 100644 --- a/requirements-doc.txt +++ b/requirements-doc.txt @@ -5,11 +5,11 @@ isort twine wheel astroid -setuptools +setuptools>=45 setuptools_scm # For sphinx -sphinx>=4.0.0 +sphinx!=5.2.0.post0 sphinx-autoapi sphinx-rtd-theme sphinxcontrib-svg2pdfconverter diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c index ce1080934e..a45f17ca2c 100644 --- a/shared-bindings/_bleio/Adapter.c +++ b/shared-bindings/_bleio/Adapter.c @@ -64,7 +64,9 @@ //| connections and also initiate connections.""" //| -//| def __init__(self, *, uart: busio.UART, rts: digitalio.DigitalInOut, cts: digitalio.DigitalInOut) -> None: +//| def __init__( +//| self, *, uart: busio.UART, rts: digitalio.DigitalInOut, cts: digitalio.DigitalInOut +//| ) -> None: //| """On boards that do not have native BLE, you can use an HCI co-processor. //| Pass the uart and pins used to communicate with the co-processor, such as an Adafruit AirLift. //| The co-processor must have been reset and put into BLE mode beforehand @@ -80,7 +82,6 @@ //| Use `_bleio.adapter` to access the sole instance already available. //| """ //| ... -//| STATIC mp_obj_t bleio_adapter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_BLEIO_HCI bleio_adapter_obj_t *self = common_hal_bleio_allocate_adapter_or_raise(); @@ -110,10 +111,8 @@ STATIC mp_obj_t bleio_adapter_make_new(const mp_obj_type_t *type, size_t n_args, #endif // CIRCUITPY_BLEIO_HCI } -//| //| enabled: bool //| """State of the BLE adapter.""" -//| STATIC mp_obj_t bleio_adapter_get_enabled(mp_obj_t self) { return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled(self)); } @@ -134,7 +133,6 @@ MP_PROPERTY_GETSET(bleio_adapter_enabled_obj, //| address: Address //| """MAC address of the BLE adapter.""" -//| STATIC mp_obj_t bleio_adapter_get_address(mp_obj_t self) { return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_address(self)); @@ -157,11 +155,10 @@ MP_PROPERTY_GETSET(bleio_adapter_address_obj, //| """name of the BLE adapter used once connected. //| The name is "CIRCUITPY" + the last four hex digits of ``adapter.address``, //| to make it easy to distinguish multiple CircuitPython boards.""" -//| -STATIC mp_obj_t bleio_adapter_get_name(mp_obj_t self) { +STATIC mp_obj_t _bleio_adapter_get_name(mp_obj_t self) { return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_name(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_name_obj, bleio_adapter_get_name); +MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_name_obj, _bleio_adapter_get_name); STATIC mp_obj_t bleio_adapter_set_name(mp_obj_t self, mp_obj_t new_name) { @@ -174,10 +171,18 @@ MP_PROPERTY_GETSET(bleio_adapter_name_obj, (mp_obj_t)&bleio_adapter_get_name_obj, (mp_obj_t)&bleio_adapter_set_name_obj); -//| def start_advertising(self, data: ReadableBuffer, *, -//| scan_response: Optional[ReadableBuffer] = None, connectable: bool = True, -//| anonymous: bool = False, timeout: int = 0, interval: float = 0.1, -//| tx_power: int = 0, directed_to: Optional[Address] = None) -> None: +//| def start_advertising( +//| self, +//| data: ReadableBuffer, +//| *, +//| scan_response: Optional[ReadableBuffer] = None, +//| connectable: bool = True, +//| anonymous: bool = False, +//| timeout: int = 0, +//| interval: float = 0.1, +//| tx_power: int = 0, +//| directed_to: Optional[Address] = None +//| ) -> None: //| """Starts advertising until `stop_advertising` is called or if connectable, another device //| connects to us. //| @@ -196,7 +201,6 @@ MP_PROPERTY_GETSET(bleio_adapter_name_obj, //| :param tx_power int: transmitter power while advertising in dBm //| :param directed_to Address: peer to advertise directly to""" //| ... -//| STATIC mp_obj_t bleio_adapter_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -259,7 +263,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_start_advertising_obj, 1, bleio_ //| def stop_advertising(self) -> None: //| """Stop sending advertising packets.""" //| ... -//| STATIC mp_obj_t bleio_adapter_stop_advertising(mp_obj_t self_in) { bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -269,7 +272,18 @@ STATIC mp_obj_t bleio_adapter_stop_advertising(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_advertising_obj, bleio_adapter_stop_advertising); -//| def start_scan(self, prefixes: ReadableBuffer = b"", *, buffer_size: int = 512, extended: bool = False, timeout: Optional[float] = None, interval: float = 0.1, window: float = 0.1, minimum_rssi: int = -80, active: bool = True) -> Iterable[ScanEntry]: +//| def start_scan( +//| self, +//| prefixes: ReadableBuffer = b"", +//| *, +//| buffer_size: int = 512, +//| extended: bool = False, +//| timeout: Optional[float] = None, +//| interval: float = 0.1, +//| window: float = 0.1, +//| minimum_rssi: int = -80, +//| active: bool = True +//| ) -> Iterable[ScanEntry]: //| """Starts a BLE scan and returns an iterator of results. Advertisements and scan responses are //| filtered and returned separately. //| @@ -288,7 +302,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_advertising_obj, bleio_adapt //| :returns: an iterable of `_bleio.ScanEntry` objects //| :rtype: iterable""" //| ... -//| STATIC mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_prefixes, ARG_buffer_size, ARG_extended, ARG_timeout, ARG_interval, ARG_window, ARG_minimum_rssi, ARG_active }; static const mp_arg_t allowed_args[] = { @@ -352,7 +365,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_start_scan_obj, 1, bleio_adapter //| def stop_scan(self) -> None: //| """Stop the current scan.""" //| ... -//| STATIC mp_obj_t bleio_adapter_stop_scan(mp_obj_t self_in) { bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -364,7 +376,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_scan_obj, bleio_adapter_stop //| advertising: bool //| """True when the adapter is currently advertising. (read-only)""" -//| STATIC mp_obj_t bleio_adapter_get_advertising(mp_obj_t self) { return mp_obj_new_bool(common_hal_bleio_adapter_get_advertising(self)); @@ -377,7 +388,6 @@ MP_PROPERTY_GETTER(bleio_adapter_advertising_obj, //| connected: bool //| """True when the adapter is connected to another device regardless of who initiated the //| connection. (read-only)""" -//| STATIC mp_obj_t bleio_adapter_get_connected(mp_obj_t self) { return mp_obj_new_bool(common_hal_bleio_adapter_get_connected(self)); @@ -390,7 +400,6 @@ MP_PROPERTY_GETTER(bleio_adapter_connected_obj, //| connections: Tuple[Connection] //| """Tuple of active connections including those initiated through //| :py:meth:`_bleio.Adapter.connect`. (read-only)""" -//| STATIC mp_obj_t bleio_adapter_get_connections(mp_obj_t self) { return common_hal_bleio_adapter_get_connections(self); } @@ -405,7 +414,6 @@ MP_PROPERTY_GETTER(bleio_adapter_connections_obj, //| :param Address address: The address of the peripheral to connect to //| :param float/int timeout: Try to connect for timeout seconds.""" //| ... -//| STATIC mp_obj_t bleio_adapter_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); diff --git a/shared-bindings/_bleio/Adapter.h b/shared-bindings/_bleio/Adapter.h index 1dce615a40..49bb4421e7 100644 --- a/shared-bindings/_bleio/Adapter.h +++ b/shared-bindings/_bleio/Adapter.h @@ -50,6 +50,9 @@ extern bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self); extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self); extern bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_address_obj_t *address); +// Copies the adapter name into the given buffer up to len and returns the full length (may be more +// than len if the buffer was too short.) +uint16_t bleio_adapter_get_name(char *buf, uint16_t len); extern mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self); extern void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *name); diff --git a/shared-bindings/_bleio/Address.c b/shared-bindings/_bleio/Address.c index 26aeec3036..236ca9e39e 100644 --- a/shared-bindings/_bleio/Address.c +++ b/shared-bindings/_bleio/Address.c @@ -46,7 +46,6 @@ //| :param int address_type: one of the integer values: `PUBLIC`, `RANDOM_STATIC`, //| `RANDOM_PRIVATE_RESOLVABLE`, or `RANDOM_PRIVATE_NON_RESOLVABLE`.""" //| ... -//| STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_address, ARG_address_type }; static const mp_arg_t allowed_args[] = { @@ -93,7 +92,6 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, //|
//| >>> _bleio.adapter.address.address_bytes //| b'5\\xa8\\xed\\xf5\\x1d\\xc8'""" -//| STATIC mp_obj_t bleio_address_get_address_bytes(mp_obj_t self_in) { bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -109,7 +107,6 @@ MP_PROPERTY_GETTER(bleio_address_address_bytes_obj, //| //| One of the integer values: `PUBLIC`, `RANDOM_STATIC`, `RANDOM_PRIVATE_RESOLVABLE`, //| or `RANDOM_PRIVATE_NON_RESOLVABLE`.""" -//| STATIC mp_obj_t bleio_address_get_type(mp_obj_t self_in) { bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -123,7 +120,6 @@ MP_PROPERTY_GETTER(bleio_address_type_obj, //| def __eq__(self, other: object) -> bool: //| """Two Address objects are equal if their addresses and address types are equal.""" //| ... -//| STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { switch (op) { // Two Addresses are equal if their address bytes and address_type are equal @@ -149,7 +145,6 @@ STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_o //| def __hash__(self) -> int: //| """Returns a hash for the Address data.""" //| ... -//| STATIC mp_obj_t bleio_address_unary_op(mp_unary_op_t op, mp_obj_t self_in) { switch (op) { // Two Addresses are equal if their address bytes and address_type are equal diff --git a/shared-bindings/_bleio/Attribute.c b/shared-bindings/_bleio/Attribute.c index d639f2a421..176198d450 100644 --- a/shared-bindings/_bleio/Attribute.c +++ b/shared-bindings/_bleio/Attribute.c @@ -39,7 +39,6 @@ //| def __init__(self) -> None: //| """You cannot create an instance of :py:class:`~_bleio.Attribute`.""" //| ... -//| STATIC const mp_rom_map_elem_t bleio_attribute_locals_dict_table[] = { diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c index 6f72d96056..823250c365 100644 --- a/shared-bindings/_bleio/Characteristic.c +++ b/shared-bindings/_bleio/Characteristic.c @@ -35,7 +35,7 @@ //| class Characteristic: //| """Stores information about a BLE service characteristic and allows reading -//| and writing of the characteristic's value.""" +//| and writing of the characteristic's value.""" //| //| def __init__(self) -> None: //| """There is no regular constructor for a Characteristic. A new local Characteristic can be created @@ -43,13 +43,20 @@ //| Remote Characteristic objects are created by `Connection.discover_remote_services()` //| as part of remote Services.""" //| ... -//| -//| def add_to_service(self, service: Service, uuid: UUID, *, properties: int = 0, -//| read_perm: int = Attribute.OPEN, write_perm: int = Attribute.OPEN, -//| max_length: int = 20, fixed_length: bool = False, -//| initial_value: Optional[ReadableBuffer] = None, -//| user_description: Optional[str] = None) -> Characteristic: +//| def add_to_service( +//| self, +//| service: Service, +//| uuid: UUID, +//| *, +//| properties: int = 0, +//| read_perm: int = Attribute.OPEN, +//| write_perm: int = Attribute.OPEN, +//| max_length: int = 20, +//| fixed_length: bool = False, +//| initial_value: Optional[ReadableBuffer] = None, +//| user_description: Optional[str] = None +//| ) -> Characteristic: //| """Create a new Characteristic object, and add it to this Service. //| //| :param Service service: The service that will provide this characteristic @@ -73,7 +80,6 @@ //| //| :return: the new Characteristic.""" //| ... -//| STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // class is arg[0], which we can ignore. @@ -157,7 +163,6 @@ STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(bleio_characteristic_add_to_service_obj, //| """An int bitmask representing which properties are set, specified as bitwise or'ing of //| of these possible values. //| `BROADCAST`, `INDICATE`, `NOTIFY`, `READ`, `WRITE`, `WRITE_NO_RESPONSE`.""" -//| STATIC mp_obj_t bleio_characteristic_get_properties(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -172,7 +177,6 @@ MP_PROPERTY_GETTER(bleio_characteristic_properties_obj, //| """The UUID of this characteristic. (read-only) //| //| Will be ``None`` if the 128-bit UUID for this characteristic is not known.""" -//| STATIC mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -186,7 +190,6 @@ MP_PROPERTY_GETTER(bleio_characteristic_uuid_obj, //| value: bytearray //| """The value of this characteristic.""" -//| STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -214,7 +217,6 @@ MP_PROPERTY_GETSET(bleio_characteristic_value_obj, //| max_length: int //| """The max length of this characteristic.""" -//| STATIC mp_obj_t bleio_characteristic_get_max_length(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -227,7 +229,6 @@ MP_PROPERTY_GETTER(bleio_characteristic_max_length_obj, //| descriptors: Descriptor //| """A tuple of :py:class:`Descriptor` objects related to this characteristic. (read-only)""" -//| STATIC mp_obj_t bleio_characteristic_get_descriptors(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); // Return list as a tuple so user won't be able to change it. @@ -241,7 +242,6 @@ MP_PROPERTY_GETTER(bleio_characteristic_descriptors_obj, //| service: Service //| """The Service this Characteristic is a part of.""" -//| STATIC mp_obj_t bleio_characteristic_get_service(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -256,9 +256,9 @@ MP_PROPERTY_GETTER(bleio_characteristic_service_obj, //| """Set the remote characteristic's CCCD to enable or disable notification and indication. //| //| :param bool notify: True if Characteristic should receive notifications of remote writes -//| :param float indicate: True if Characteristic should receive indications of remote writes""" +//| :param float indicate: True if Characteristic should receive indications of remote writes +//| """ //| ... -//| STATIC mp_obj_t bleio_characteristic_set_cccd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -279,6 +279,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_set_cccd_obj, 1, bleio_ch STATIC const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_add_to_service), MP_ROM_PTR(&bleio_characteristic_add_to_service_obj) }, + { MP_ROM_QSTR(MP_QSTR_descriptors), MP_ROM_PTR(&bleio_characteristic_descriptors_obj) }, { MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&bleio_characteristic_properties_obj) }, { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) }, { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) }, diff --git a/shared-bindings/_bleio/CharacteristicBuffer.c b/shared-bindings/_bleio/CharacteristicBuffer.c index aea77fb633..1efb992c72 100644 --- a/shared-bindings/_bleio/CharacteristicBuffer.c +++ b/shared-bindings/_bleio/CharacteristicBuffer.c @@ -25,7 +25,7 @@ */ #include "py/mperrno.h" -#include "py/ioctl.h" +#include "py/stream.h" #include "py/objproperty.h" #include "py/runtime.h" #include "py/stream.h" @@ -44,8 +44,9 @@ STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self //| class CharacteristicBuffer: //| """Accumulates a Characteristic's incoming values in a FIFO buffer.""" //| -//| def __init__(self, characteristic: Characteristic, *, timeout: int = 1, buffer_size: int = 64) -> None: -//| +//| def __init__( +//| self, characteristic: Characteristic, *, timeout: int = 1, buffer_size: int = 64 +//| ) -> None: //| """Monitor the given Characteristic. Each time a new value is written to the Characteristic //| add the newly-written bytes to a FIFO buffer. //| @@ -56,7 +57,6 @@ STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self //| :param int buffer_size: Size of ring buffer that stores incoming data coming from client. //| Must be >= 1.""" //| ... -//| STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_characteristic, ARG_timeout, ARG_buffer_size, }; static const mp_arg_t allowed_args[] = { @@ -99,21 +99,18 @@ STATIC void check_for_deinit(bleio_characteristic_buffer_obj_t *self) { //| :return: Data read //| :rtype: bytes or None""" //| ... -//| //| def readinto(self, buf: WriteableBuffer) -> Optional[int]: //| """Read bytes into the ``buf``. Read at most ``len(buf)`` bytes. //| //| :return: number of bytes read and stored into ``buf`` //| :rtype: int or None (on a non-blocking error)""" //| ... -//| //| def readline(self) -> bytes: //| """Read a line, ending in a newline character. //| //| :return: the line read //| :rtype: int or None""" //| ... -//| // These three methods are used by the shared stream methods. STATIC mp_uint_t bleio_characteristic_buffer_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { @@ -140,15 +137,15 @@ STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r check_for_deinit(self); raise_error_if_not_connected(self); mp_uint_t ret; - if (request == MP_IOCTL_POLL) { + if (request == MP_STREAM_POLL) { mp_uint_t flags = arg; ret = 0; - if ((flags & MP_IOCTL_POLL_RD) && common_hal_bleio_characteristic_buffer_rx_characters_available(self) > 0) { - ret |= MP_IOCTL_POLL_RD; + if ((flags & MP_STREAM_POLL_RD) && common_hal_bleio_characteristic_buffer_rx_characters_available(self) > 0) { + ret |= MP_STREAM_POLL_RD; } // No writing provided. -// if ((flags & MP_IOCTL_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) { -// ret |= MP_IOCTL_POLL_WR; +// if ((flags & MP_STREAM_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) { +// ret |= MP_STREAM_POLL_WR; // } } else { *errcode = MP_EINVAL; @@ -159,11 +156,15 @@ STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r //| in_waiting: int //| """The number of bytes in the input buffer, available to be read""" -//| STATIC mp_obj_t bleio_characteristic_buffer_obj_get_in_waiting(mp_obj_t self_in) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_buffer_rx_characters_available(self)); + uint32_t available = common_hal_bleio_characteristic_buffer_rx_characters_available(self); + if (available == 0) { + // Only check if connected when none available, otherwise, allow code to continue. + raise_error_if_not_connected(self); + } + return MP_OBJ_NEW_SMALL_INT(available); } MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_get_in_waiting_obj, bleio_characteristic_buffer_obj_get_in_waiting); @@ -173,7 +174,6 @@ MP_PROPERTY_GETTER(bleio_characteristic_buffer_in_waiting_obj, //| def reset_input_buffer(self) -> None: //| """Discard any unread characters in the input buffer.""" //| ... -//| STATIC mp_obj_t bleio_characteristic_buffer_obj_reset_input_buffer(mp_obj_t self_in) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/_bleio/CharacteristicBuffer.h b/shared-bindings/_bleio/CharacteristicBuffer.h index de85f019bc..9dc3252d5a 100644 --- a/shared-bindings/_bleio/CharacteristicBuffer.h +++ b/shared-bindings/_bleio/CharacteristicBuffer.h @@ -27,6 +27,8 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTICBUFFER_H +#include + #include "common-hal/_bleio/CharacteristicBuffer.h" extern const mp_obj_type_t bleio_characteristic_buffer_type; @@ -35,7 +37,8 @@ void _common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buff bleio_characteristic_obj_t *characteristic, mp_float_t timeout, uint8_t *buffer, size_t buffer_size, - void *static_handler_entry); + void *static_handler_entry, + bool watch_for_interrupt_char); void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, mp_float_t timeout, diff --git a/shared-bindings/_bleio/Connection.c b/shared-bindings/_bleio/Connection.c index 7a85ccddc2..f76ecc8167 100644 --- a/shared-bindings/_bleio/Connection.c +++ b/shared-bindings/_bleio/Connection.c @@ -72,11 +72,9 @@ void bleio_connection_ensure_connected(bleio_connection_obj_t *self) { //| Connections may also be made when another device initiates a connection. To use a Connection //| created by a peer, read the `Adapter.connections` property.""" //| ... -//| //| def disconnect(self) -> None: //| """Disconnects from the remote peripheral. Does nothing if already disconnected.""" //| ... -//| STATIC mp_obj_t bleio_connection_disconnect(mp_obj_t self_in) { bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in); // common_hal_bleio_connection_disconnect() does nothing if already disconnected. @@ -89,7 +87,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_disconnect_obj, bleio_connecti //| def pair(self, *, bond: bool = True) -> None: //| """Pair to the peer to improve security.""" //| ... -//| STATIC mp_obj_t bleio_connection_pair(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_connection_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -108,7 +105,9 @@ STATIC mp_obj_t bleio_connection_pair(mp_uint_t n_args, const mp_obj_t *pos_args } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_connection_pair_obj, 1, bleio_connection_pair); -//| def discover_remote_services(self, service_uuids_whitelist: Optional[Iterable[UUID]] = None) -> Tuple[Service, ...]: +//| def discover_remote_services( +//| self, service_uuids_whitelist: Optional[Iterable[UUID]] = None +//| ) -> Tuple[Service, ...]: //| """Do BLE discovery for all services or for the given service UUIDS, //| to find their handles and characteristics, and return the discovered services. //| `Connection.connected` must be True. @@ -131,7 +130,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_connection_pair_obj, 1, bleio_connection //| //| :return: A tuple of `_bleio.Service` objects provided by the remote peripheral.""" //| ... -//| STATIC mp_obj_t bleio_connection_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_connection_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -153,7 +151,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_connection_discover_remote_services_obj, //| connected: bool //| """True if connected to the remote peer.""" -//| STATIC mp_obj_t bleio_connection_get_connected(mp_obj_t self_in) { bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -167,7 +164,6 @@ MP_PROPERTY_GETTER(bleio_connection_connected_obj, //| paired: bool //| """True if paired to the remote peer.""" -//| STATIC mp_obj_t bleio_connection_get_paired(mp_obj_t self_in) { bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -188,7 +184,6 @@ MP_PROPERTY_GETTER(bleio_connection_paired_obj, //| //| Apple has additional guidelines that dictate should be a multiple of 15ms except if HID is //| available. When HID is available Apple devices may accept 11.25ms intervals.""" -//| STATIC mp_obj_t bleio_connection_get_connection_interval(mp_obj_t self_in) { bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c index 0e662655c4..9ebe95432e 100644 --- a/shared-bindings/_bleio/Descriptor.c +++ b/shared-bindings/_bleio/Descriptor.c @@ -44,9 +44,18 @@ //| and attached to a Characteristic by calling `add_to_characteristic()`. //| Remote Descriptor objects are created by `Connection.discover_remote_services()` //| as part of remote Characteristics in the remote Services that are discovered.""" -//| //| @classmethod -//| def add_to_characteristic(cls, characteristic: Characteristic, uuid: UUID, *, read_perm: int = Attribute.OPEN, write_perm: int = Attribute.OPEN, max_length: int = 20, fixed_length: bool = False, initial_value: ReadableBuffer = b'') -> Descriptor: +//| def add_to_characteristic( +//| cls, +//| characteristic: Characteristic, +//| uuid: UUID, +//| *, +//| read_perm: int = Attribute.OPEN, +//| write_perm: int = Attribute.OPEN, +//| max_length: int = 20, +//| fixed_length: bool = False, +//| initial_value: ReadableBuffer = b"" +//| ) -> Descriptor: //| """Create a new Descriptor object, and add it to this Service. //| //| :param Characteristic characteristic: The characteristic that will hold this descriptor @@ -65,7 +74,6 @@ //| //| :return: the new Descriptor.""" //| ... -//| STATIC mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // class is arg[0], which we can ignore. @@ -133,7 +141,6 @@ STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(bleio_descriptor_add_to_characteristic_ob //| uuid: UUID //| """The descriptor uuid. (read-only)""" -//| STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) { bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -147,7 +154,6 @@ MP_PROPERTY_GETTER(bleio_descriptor_uuid_obj, //| characteristic: Characteristic //| """The Characteristic this Descriptor is a part of.""" -//| STATIC mp_obj_t bleio_descriptor_get_characteristic(mp_obj_t self_in) { bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/_bleio/PacketBuffer.c b/shared-bindings/_bleio/PacketBuffer.c index 30eb8dd8c7..0ce74beff4 100644 --- a/shared-bindings/_bleio/PacketBuffer.c +++ b/shared-bindings/_bleio/PacketBuffer.c @@ -25,7 +25,7 @@ */ #include "py/mperrno.h" -#include "py/ioctl.h" +#include "py/stream.h" #include "py/objproperty.h" #include "py/runtime.h" #include "py/stream.h" @@ -44,7 +44,13 @@ //| When we're the server, we ignore all connections besides the first to subscribe to //| notifications.""" //| -//| def __init__(self, characteristic: Characteristic, *, buffer_size: int, max_packet_size: Optional[int] = None) -> None: +//| def __init__( +//| self, +//| characteristic: Characteristic, +//| *, +//| buffer_size: int, +//| max_packet_size: Optional[int] = None +//| ) -> None: //| """Monitor the given Characteristic. Each time a new value is written to the Characteristic //| add the newly-written bytes to a FIFO buffer. //| @@ -59,7 +65,6 @@ //| :param int max_packet_size: Maximum size of packets. Overrides value from the characteristic. //| (Remote characteristics may not have the correct length.)""" //| ... -//| STATIC mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_characteristic, ARG_buffer_size, ARG_max_packet_size }; static const mp_arg_t allowed_args[] = { @@ -101,7 +106,6 @@ STATIC void check_for_deinit(bleio_packet_buffer_obj_t *self) { //| :return: number of bytes read and stored into ``buf`` //| :rtype: int""" //| ... -//| STATIC mp_obj_t bleio_packet_buffer_readinto(mp_obj_t self_in, mp_obj_t buffer_obj) { bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -127,7 +131,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_packet_buffer_readinto_obj, bleio_packet_ //| :return: number of bytes written. May include header bytes when packet is empty. //| :rtype: int""" //| ... -//| // TODO: Add a kwarg `merge=False` to dictate whether subsequent writes are merged into a pending // one. STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -182,7 +185,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_deinit_obj, bleio_packet_bu //| incoming_packet_length: int //| """Maximum length in bytes of a packet we are reading.""" -//| STATIC mp_obj_t bleio_packet_buffer_get_incoming_packet_length(mp_obj_t self_in) { bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/_bleio/ScanEntry.c b/shared-bindings/_bleio/ScanEntry.c index d9434f39cf..83966d1719 100644 --- a/shared-bindings/_bleio/ScanEntry.c +++ b/shared-bindings/_bleio/ScanEntry.c @@ -44,29 +44,24 @@ //| def __init__(self) -> None: //| """Cannot be instantiated directly. Use `_bleio.Adapter.start_scan`.""" //| ... -//| //| def matches(self, prefixes: ScanEntry, *, match_all: bool = True) -> bool: //| """Returns True if the ScanEntry matches all prefixes when ``match_all`` is True. This is stricter //| than the scan filtering which accepts any advertisements that match any of the prefixes -//| where ``match_all`` is False. -//| -//| ``all`` also works for ``match_all`` but will be removed in CircuitPython 8.""" +//| where ``match_all`` is False.""" //| ... -//| STATIC mp_obj_t bleio_scanentry_matches(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - enum { ARG_prefixes, ARG_all, ARG_match_all }; + enum { ARG_prefixes, ARG_match_all }; static const mp_arg_t allowed_args[] = { { MP_QSTR_prefixes, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_all, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_match_all, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - bool match_all = args[ARG_all].u_bool && args[ARG_match_all].u_bool; + bool match_all = args[ARG_match_all].u_bool; mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_prefixes].u_obj, &bufinfo, MP_BUFFER_READ); @@ -76,7 +71,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_scanentry_matches_obj, 1, bleio_scanentr //| address: Address //| """The address of the device (read-only), of type `_bleio.Address`.""" -//| STATIC mp_obj_t bleio_scanentry_get_address(mp_obj_t self_in) { bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_bleio_scanentry_get_address(self); @@ -88,7 +82,6 @@ MP_PROPERTY_GETTER(bleio_scanentry_address_obj, //| advertisement_bytes: bytes //| """All the advertisement data present in the packet, returned as a ``bytes`` object. (read-only)""" -//| STATIC mp_obj_t scanentry_get_advertisement_bytes(mp_obj_t self_in) { bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_bleio_scanentry_get_advertisement_bytes(self); @@ -100,7 +93,6 @@ MP_PROPERTY_GETTER(bleio_scanentry_advertisement_bytes_obj, //| rssi: int //| """The signal strength of the device at the time of the scan, in integer dBm. (read-only)""" -//| STATIC mp_obj_t scanentry_get_rssi(mp_obj_t self_in) { bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_bleio_scanentry_get_rssi(self)); @@ -112,7 +104,6 @@ MP_PROPERTY_GETTER(bleio_scanentry_rssi_obj, //| connectable: bool //| """True if the device can be connected to. (read-only)""" -//| STATIC mp_obj_t scanentry_get_connectable(mp_obj_t self_in) { bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_bleio_scanentry_get_connectable(self)); diff --git a/shared-bindings/_bleio/ScanResults.c b/shared-bindings/_bleio/ScanResults.c index bee6cfa89c..ec4e0c72e8 100644 --- a/shared-bindings/_bleio/ScanResults.c +++ b/shared-bindings/_bleio/ScanResults.c @@ -49,14 +49,13 @@ STATIC mp_obj_t scanresults_iternext(mp_obj_t self_in) { //| def __init__(self) -> None: //| """Cannot be instantiated directly. Use `_bleio.Adapter.start_scan`.""" //| ... -//| //| def __iter__(self) -> Iterator[ScanEntry]: //| """Returns itself since it is the iterator.""" //| ... -//| //| def __next__(self) -> ScanEntry: //| """Returns the next `_bleio.ScanEntry`. Blocks if none have been received and scanning is still -//| active. Raises `StopIteration` if scanning is finished and no other results are available.""" +//| active. Raises `StopIteration` if scanning is finished and no other results are available. +//| """ //| ... //| diff --git a/shared-bindings/_bleio/Service.c b/shared-bindings/_bleio/Service.c index ddbdecdf79..7b357882f0 100644 --- a/shared-bindings/_bleio/Service.c +++ b/shared-bindings/_bleio/Service.c @@ -47,7 +47,6 @@ //| //| :return: the new Service""" //| ... -//| STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_uuid, ARG_secondary }; static const mp_arg_t allowed_args[] = { @@ -73,7 +72,6 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, //| characteristics: Tuple[Characteristic, ...] //| """A tuple of :py:class:`Characteristic` designating the characteristics that are offered by //| this service. (read-only)""" -//| STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) { bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_FROM_PTR(common_hal_bleio_service_get_characteristics(self)); @@ -85,7 +83,6 @@ MP_PROPERTY_GETTER(bleio_service_characteristics_obj, //| remote: bool //| """True if this is a service provided by a remote device. (read-only)""" -//| STATIC mp_obj_t bleio_service_get_remote(mp_obj_t self_in) { bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -98,7 +95,6 @@ MP_PROPERTY_GETTER(bleio_service_remote_obj, //| secondary: bool //| """True if this is a secondary service. (read-only)""" -//| STATIC mp_obj_t bleio_service_get_secondary(mp_obj_t self_in) { bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/_bleio/UUID.c b/shared-bindings/_bleio/UUID.c index 599a89a581..922b1ac5fb 100644 --- a/shared-bindings/_bleio/UUID.c +++ b/shared-bindings/_bleio/UUID.c @@ -50,7 +50,6 @@ //| :param value: The uuid value to encapsulate //| :type value: int, ~circuitpython_typing.ReadableBuffer or str""" //| ... -//| STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); @@ -124,7 +123,6 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si //| """The 16-bit part of the UUID. (read-only) //| //| :type: int""" -//| STATIC mp_obj_t bleio_uuid_get_uuid16(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_uuid16(self)); @@ -140,7 +138,6 @@ MP_PROPERTY_GETTER(bleio_uuid_uuid16_obj, //| Raises AttributeError if this is a 16-bit UUID. (read-only) //| //| :type: bytes""" -//| STATIC mp_obj_t bleio_uuid_get_uuid128(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -162,7 +159,6 @@ MP_PROPERTY_GETTER(bleio_uuid_uuid128_obj, //| 16-bit Bluetooth SIG assigned UUID. (read-only) 32-bit UUIDs are not currently supported. //| //| :type: int""" -//| STATIC mp_obj_t bleio_uuid_get_size(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_size(self)); @@ -177,7 +173,6 @@ MP_PROPERTY_GETTER(bleio_uuid_size_obj, //| def pack_into(self, buffer: WriteableBuffer, offset: int = 0) -> None: //| """Packs the UUID into the given buffer at the given offset.""" //| ... -//| STATIC mp_obj_t bleio_uuid_pack_into(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c index 72d96846aa..f34d3af5c5 100644 --- a/shared-bindings/_bleio/__init__.c +++ b/shared-bindings/_bleio/__init__.c @@ -54,7 +54,6 @@ //| CircuitPython library instead, which builds on `_bleio`, and //| provides higher-level convenience functionality, including predefined beacons, clients, //| servers.""" -//| //| adapter: Adapter //| """BLE Adapter used to manage device discovery and connections. @@ -63,7 +62,9 @@ //| class BluetoothError(Exception): //| """Catchall exception for Bluetooth related errors.""" +//| //| ... +//| MP_DEFINE_BLEIO_EXCEPTION(BluetoothError, Exception) NORETURN void mp_raise_bleio_BluetoothError(const compressed_string_t *fmt, ...) { va_list argptr; @@ -76,6 +77,7 @@ NORETURN void mp_raise_bleio_BluetoothError(const compressed_string_t *fmt, ...) //| class RoleError(BluetoothError): //| """Raised when a resource is used as the mismatched role. For example, if a local CCCD is //| attempted to be set but they can only be set when remote.""" +//| //| ... //| MP_DEFINE_BLEIO_EXCEPTION(RoleError, bleio_BluetoothError) @@ -85,6 +87,7 @@ NORETURN void mp_raise_bleio_RoleError(const compressed_string_t *msg) { //| class SecurityError(BluetoothError): //| """Raised when a security related error occurs.""" +//| //| ... //| MP_DEFINE_BLEIO_EXCEPTION(SecurityError, bleio_BluetoothError) @@ -119,9 +122,7 @@ STATIC mp_obj_dict_t bleio_module_globals; //| mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj) { #if CIRCUITPY_BLEIO_HCI - if (adapter_obj != mp_const_none && !mp_obj_is_type(adapter_obj, &bleio_adapter_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), bleio_adapter_type.name); - } + (void)mp_arg_validate_type_or_none(adapter_obj, &bleio_adapter_type, MP_QSTR_adapter); // Equivalent of: // bleio.adapter = adapter_obj @@ -130,7 +131,7 @@ mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj) { elem->value = adapter_obj; } #else - mp_raise_NotImplementedError(translate("Not settable")); + mp_raise_NotImplementedError(translate("Read-only")); #endif return mp_const_none; } diff --git a/shared-bindings/_eve/__init__.c b/shared-bindings/_eve/__init__.c index 13e51cb882..5975ee1ca1 100644 --- a/shared-bindings/_eve/__init__.c +++ b/shared-bindings/_eve/__init__.c @@ -40,10 +40,9 @@ //| contains methods for constructing EVE command //| buffers and appending basic graphics commands.""" //| - //| class _EVE: -//| - +//| def __init__(self) -> None: +//| """Create an _EVE object""" typedef struct _mp_obj__EVE_t { mp_obj_base_t base; common_hal__eve_t _eve; @@ -54,9 +53,7 @@ STATIC const mp_obj_type_t _EVE_type; #define EVEHAL(s) \ (&((mp_obj__EVE_t *)mp_obj_cast_to_native_base((s), &_EVE_type))->_eve) -//| def register(self, o: object) -> None: -//| ... -//| +//| def register(self, o: object) -> None: ... STATIC mp_obj_t _register(mp_obj_t self, mp_obj_t o) { common_hal__eve_t *eve = EVEHAL(self); mp_load_method(o, MP_QSTR_write, eve->dest); @@ -69,7 +66,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(register_obj, _register); //| //| :param int width: The width of the grid in tiles, or 1 for sprites.""" //| ... -//| STATIC mp_obj_t _flush(mp_obj_t self) { common_hal__eve_flush(EVEHAL(self)); return mp_const_none; @@ -81,7 +77,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(flush_obj, _flush); //| //| :param ~circuitpython_typing.ReadableBuffer b: The bytes to add""" //| ... -//| STATIC mp_obj_t _cc(mp_obj_t self, mp_obj_t b) { mp_buffer_info_t buffer_info; mp_get_buffer_raise(b, &buffer_info, MP_BUFFER_READ); @@ -98,9 +93,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(cc_obj, _cc); //| :param int func: specifies the test function, one of ``NEVER``, ``LESS``, ``LEQUAL``, ``GREATER``, ``GEQUAL``, ``EQUAL``, ``NOTEQUAL``, or ``ALWAYS``. Range 0-7. The initial value is ALWAYS(7) //| :param int ref: specifies the reference value for the alpha test. Range 0-255. The initial value is 0 //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _alphafunc(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t func = mp_obj_get_int_truncated(a0); @@ -115,9 +110,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(alphafunc_obj, _alphafunc); //| //| :param int prim: graphics primitive. //| -//| Valid primitives are ``BITMAPS``, ``POINTS``, ``LINES``, ``LINE_STRIP``, ``EDGE_STRIP_R``, ``EDGE_STRIP_L``, ``EDGE_STRIP_A``, ``EDGE_STRIP_B`` and ``RECTS``.""" +//| Valid primitives are ``BITMAPS``, ``POINTS``, ``LINES``, ``LINE_STRIP``, ``EDGE_STRIP_R``, ``EDGE_STRIP_L``, ``EDGE_STRIP_A``, ``EDGE_STRIP_B`` and ``RECTS``. +//| """ //| ... -//| STATIC mp_obj_t _begin(mp_obj_t self, mp_obj_t a0) { uint32_t prim = mp_obj_get_int_truncated(a0); @@ -131,7 +126,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(begin_obj, _begin); //| //| :param int format: bitmap pixel format.""" //| ... -//| STATIC mp_obj_t _bitmapextformat(mp_obj_t self, mp_obj_t a0) { uint32_t fmt = mp_obj_get_int_truncated(a0); @@ -145,9 +139,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(bitmapextformat_obj, _bitmapextformat); //| //| :param int handle: bitmap handle. Range 0-31. The initial value is 0 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _bitmaphandle(mp_obj_t self, mp_obj_t a0) { uint32_t handle = mp_obj_get_int_truncated(a0); @@ -162,7 +156,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(bitmaphandle_obj, _bitmaphandle); //| :param int linestride: high part of bitmap line stride, in bytes. Range 0-7 //| :param int height: high part of bitmap height, in lines. Range 0-3""" //| ... -//| STATIC mp_obj_t _bitmaplayouth(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t linestride = mp_obj_get_int_truncated(a0); @@ -179,7 +172,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaplayouth_obj, _bitmaplayouth); //| :param int linestride: bitmap line stride, in bytes. Range 0-1023 //| :param int height: bitmap height, in lines. Range 0-511""" //| ... -//| STATIC mp_obj_t _bitmaplayout(size_t n_args, const mp_obj_t *args) { uint32_t format = mp_obj_get_int_truncated(args[1]); @@ -196,7 +188,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmaplayout_obj, 4, 4, _bitmaplayout //| :param int width: high part of drawn bitmap width, in pixels. Range 0-3 //| :param int height: high part of drawn bitmap height, in pixels. Range 0-3""" //| ... -//| STATIC mp_obj_t _bitmapsizeh(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t width = mp_obj_get_int_truncated(a0); @@ -215,7 +206,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmapsizeh_obj, _bitmapsizeh); //| :param int width: drawn bitmap width, in pixels. Range 0-511 //| :param int height: drawn bitmap height, in pixels. Range 0-511""" //| ... -//| STATIC mp_obj_t _bitmapsize(size_t n_args, const mp_obj_t *args) { uint32_t filter = mp_obj_get_int_truncated(args[1]); @@ -231,9 +221,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmapsize_obj, 6, 6, _bitmapsize); //| def BitmapSource(self, addr: int) -> None: //| """Set the source address for bitmap graphics //| -//| :param int addr: Bitmap start address, pixel-aligned. May be in SRAM or flash. Range 0-16777215""" +//| :param int addr: Bitmap start address, pixel-aligned. May be in SRAM or flash. Range 0-16777215 +//| """ //| ... -//| STATIC mp_obj_t _bitmapsource(mp_obj_t self, mp_obj_t a0) { uint32_t addr = mp_obj_get_int_truncated(a0); @@ -250,7 +240,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(bitmapsource_obj, _bitmapsource); //| :param int b: blue component source channel. Range 0-7 //| :param int a: alpha component source channel. Range 0-7""" //| ... -//| STATIC mp_obj_t _bitmapswizzle(size_t n_args, const mp_obj_t *args) { uint32_t r = mp_obj_get_int_truncated(args[1]); @@ -270,9 +259,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmapswizzle_obj, 5, 5, _bitmapswizz //| //| The initial value is **p** = 0, **v** = 256. This represents the value 1.0. //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _bitmaptransforma(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t p = mp_obj_get_int_truncated(a0); @@ -290,9 +279,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransforma_obj, _bitmaptransforma); //| //| The initial value is **p** = 0, **v** = 0. This represents the value 0.0. //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _bitmaptransformb(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t p = mp_obj_get_int_truncated(a0); @@ -307,9 +296,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransformb_obj, _bitmaptransformb); //| //| :param int v: The :math:`c` component of the bitmap transform matrix, in signed 15.8 bit fixed-point form. Range 0-16777215. The initial value is 0 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _bitmaptransformc(mp_obj_t self, mp_obj_t a0) { uint32_t v = mp_obj_get_int_truncated(a0); @@ -326,9 +315,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(bitmaptransformc_obj, _bitmaptransformc); //| //| The initial value is **p** = 0, **v** = 0. This represents the value 0.0. //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _bitmaptransformd(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t p = mp_obj_get_int_truncated(a0); @@ -346,9 +335,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransformd_obj, _bitmaptransformd); //| //| The initial value is **p** = 0, **v** = 256. This represents the value 1.0. //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _bitmaptransforme(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t p = mp_obj_get_int_truncated(a0); @@ -363,9 +352,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransforme_obj, _bitmaptransforme); //| //| :param int v: The :math:`f` component of the bitmap transform matrix, in signed 15.8 bit fixed-point form. Range 0-16777215. The initial value is 0 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _bitmaptransformf(mp_obj_t self, mp_obj_t a0) { uint32_t v = mp_obj_get_int_truncated(a0); @@ -380,9 +369,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(bitmaptransformf_obj, _bitmaptransformf); //| :param int src: specifies how the source blending factor is computed. One of ``ZERO``, ``ONE``, ``SRC_ALPHA``, ``DST_ALPHA``, ``ONE_MINUS_SRC_ALPHA`` or ``ONE_MINUS_DST_ALPHA``. Range 0-7. The initial value is SRC_ALPHA(2) //| :param int dst: specifies how the destination blending factor is computed, one of the same constants as **src**. Range 0-7. The initial value is ONE_MINUS_SRC_ALPHA(4) //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _blendfunc(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t src = mp_obj_get_int_truncated(a0); @@ -397,7 +386,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(blendfunc_obj, _blendfunc); //| //| :param int dest: display list address. Range 0-65535""" //| ... -//| STATIC mp_obj_t _call(mp_obj_t self, mp_obj_t a0) { uint32_t dest = mp_obj_get_int_truncated(a0); @@ -411,9 +399,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(call_obj, _call); //| //| :param int cell: bitmap cell number. Range 0-127. The initial value is 0 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _cell(mp_obj_t self, mp_obj_t a0) { uint32_t cell = mp_obj_get_int_truncated(a0); @@ -427,9 +415,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(cell_obj, _cell); //| //| :param int alpha: alpha value used when the color buffer is cleared. Range 0-255. The initial value is 0 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _clearcolora(mp_obj_t self, mp_obj_t a0) { uint32_t alpha = mp_obj_get_int_truncated(a0); @@ -445,9 +433,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(clearcolora_obj, _clearcolora); //| :param int green: green value used when the color buffer is cleared. Range 0-255. The initial value is 0 //| :param int blue: blue value used when the color buffer is cleared. Range 0-255. The initial value is 0 //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _clearcolorrgb(size_t n_args, const mp_obj_t *args) { uint32_t red = mp_obj_get_int_truncated(args[1]); @@ -465,7 +453,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(clearcolorrgb_obj, 4, 4, _clearcolorr //| :param int s: clear stencil buffer. Range 0-1 //| :param int t: clear tag buffer. Range 0-1""" //| ... -//| STATIC mp_obj_t _clear(size_t n_args, const mp_obj_t *args) { uint32_t c = (n_args > 1) ? mp_obj_get_int_truncated(args[1]) : 1; @@ -481,9 +468,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(clear_obj, 1, 4, _clear); //| //| :param int s: value used when the stencil buffer is cleared. Range 0-255. The initial value is 0 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _clearstencil(mp_obj_t self, mp_obj_t a0) { uint32_t s = mp_obj_get_int_truncated(a0); @@ -497,8 +484,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(clearstencil_obj, _clearstencil); //| //| :param int s: value used when the tag buffer is cleared. Range 0-255. The initial value is 0 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" -//| +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ STATIC mp_obj_t _cleartag(mp_obj_t self, mp_obj_t a0) { uint32_t s = mp_obj_get_int_truncated(a0); @@ -512,9 +499,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(cleartag_obj, _cleartag); //| //| :param int alpha: alpha for the current color. Range 0-255. The initial value is 255 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _colora(mp_obj_t self, mp_obj_t a0) { uint32_t alpha = mp_obj_get_int_truncated(a0); @@ -531,9 +518,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(colora_obj, _colora); //| :param int b: allow updates to the frame buffer blue component. Range 0-1. The initial value is 1 //| :param int a: allow updates to the frame buffer alpha component. Range 0-1. The initial value is 1 //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _colormask(size_t n_args, const mp_obj_t *args) { uint32_t r = mp_obj_get_int_truncated(args[1]); @@ -552,9 +539,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(colormask_obj, 5, 5, _colormask); //| :param int green: green for the current color. Range 0-255. The initial value is 255 //| :param int blue: blue for the current color. Range 0-255. The initial value is 255 //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _colorrgb(size_t n_args, const mp_obj_t *args) { uint32_t red = mp_obj_get_int_truncated(args[1]); @@ -579,9 +566,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(display_obj, _display); //| def End(self) -> None: //| """End drawing a graphics primitive //| -//| :meth:`Vertex2ii` and :meth:`Vertex2f` calls are ignored until the next :meth:`Begin`.""" +//| :meth:`Vertex2ii` and :meth:`Vertex2f` calls are ignored until the next :meth:`Begin`. +//| """ //| ... -//| STATIC mp_obj_t _end(mp_obj_t self) { @@ -595,7 +582,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(end_obj, _end); //| //| :param int dest: display list address. Range 0-65535""" //| ... -//| STATIC mp_obj_t _jump(mp_obj_t self, mp_obj_t a0) { uint32_t dest = mp_obj_get_int_truncated(a0); @@ -609,7 +595,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(jump_obj, _jump); //| //| :param int m: macro register to read. Range 0-1""" //| ... -//| STATIC mp_obj_t _macro(mp_obj_t self, mp_obj_t a0) { uint32_t m = mp_obj_get_int_truncated(a0); @@ -621,7 +606,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(macro_obj, _macro); //| def Nop(self) -> None: //| """No operation""" //| ... -//| STATIC mp_obj_t _nop(mp_obj_t self) { @@ -635,9 +619,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(nop_obj, _nop); //| //| :param int addr: Address in graphics SRAM, 2-byte aligned. Range 0-4194303. The initial value is 0 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _palettesource(mp_obj_t self, mp_obj_t a0) { uint32_t addr = mp_obj_get_int_truncated(a0); @@ -649,7 +633,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(palettesource_obj, _palettesource); //| def RestoreContext(self) -> None: //| """Restore the current graphics context from the context stack""" //| ... -//| STATIC mp_obj_t _restorecontext(mp_obj_t self) { @@ -661,7 +644,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(restorecontext_obj, _restorecontext); //| def Return(self) -> None: //| """Return from a previous call command""" //| ... -//| STATIC mp_obj_t _return(mp_obj_t self) { @@ -673,7 +655,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(return_obj, _return); //| def SaveContext(self) -> None: //| """Push the current graphics context on the context stack""" //| ... -//| STATIC mp_obj_t _savecontext(mp_obj_t self) { @@ -688,9 +669,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(savecontext_obj, _savecontext); //| :param int width: The width of the scissor clip rectangle, in pixels. Range 0-4095. The initial value is hsize //| :param int height: The height of the scissor clip rectangle, in pixels. Range 0-4095. The initial value is 2048 //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _scissorsize(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t width = mp_obj_get_int_truncated(a0); @@ -706,9 +687,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(scissorsize_obj, _scissorsize); //| :param int x: The :math:`x` coordinate of the scissor clip rectangle, in pixels. Range 0-2047. The initial value is 0 //| :param int y: The :math:`y` coordinate of the scissor clip rectangle, in pixels. Range 0-2047. The initial value is 0 //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _scissorxy(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t x = mp_obj_get_int_truncated(a0); @@ -725,9 +706,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(scissorxy_obj, _scissorxy); //| :param int ref: specifies the reference value for the stencil test. Range 0-255. The initial value is 0 //| :param int mask: specifies a mask that is ANDed with the reference value and the stored stencil value. Range 0-255. The initial value is 255 //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _stencilfunc(size_t n_args, const mp_obj_t *args) { uint32_t func = mp_obj_get_int_truncated(args[1]); @@ -743,9 +724,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stencilfunc_obj, 4, 4, _stencilfunc); //| //| :param int mask: the mask used to enable writing stencil bits. Range 0-255. The initial value is 255 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _stencilmask(mp_obj_t self, mp_obj_t a0) { uint32_t mask = mp_obj_get_int_truncated(a0); @@ -760,9 +741,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(stencilmask_obj, _stencilmask); //| :param int sfail: specifies the action to take when the stencil test fails, one of ``KEEP``, ``ZERO``, ``REPLACE``, ``INCR``, ``INCR_WRAP``, ``DECR``, ``DECR_WRAP``, and ``INVERT``. Range 0-7. The initial value is KEEP(1) //| :param int spass: specifies the action to take when the stencil test passes, one of the same constants as **sfail**. Range 0-7. The initial value is KEEP(1) //| -//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _stencilop(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t sfail = mp_obj_get_int_truncated(a0); @@ -777,9 +758,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(stencilop_obj, _stencilop); //| //| :param int mask: allow updates to the tag buffer. Range 0-1. The initial value is 1 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _tagmask(mp_obj_t self, mp_obj_t a0) { uint32_t mask = mp_obj_get_int_truncated(a0); @@ -793,9 +774,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(tagmask_obj, _tagmask); //| //| :param int s: tag value. Range 0-255. The initial value is 255 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _tag(mp_obj_t self, mp_obj_t a0) { uint32_t s = mp_obj_get_int_truncated(a0); @@ -819,7 +800,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertexformat_obj, _vertexformat); //| //| This method is an alternative to :meth:`Vertex2f`.""" //| ... -//| STATIC mp_obj_t _vertex2ii(size_t n_args, const mp_obj_t *args) { uint32_t x = mp_obj_get_int_truncated(args[1]); @@ -892,7 +872,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(vertex2ii_obj, 3, 5, _vertex2ii); //| :param float x: pixel x-coordinate //| :param float y: pixel y-coordinate""" //| ... -//| STATIC mp_obj_t _vertex2f(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { mp_float_t x = mp_obj_get_float(a0); mp_float_t y = mp_obj_get_float(a1); @@ -906,9 +885,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(vertex2f_obj, _vertex2f); //| //| :param float width: line width in pixels. Range 0-511. The initial value is 1 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _linewidth(mp_obj_t self, mp_obj_t a0) { mp_float_t width = mp_obj_get_float(a0); @@ -922,9 +901,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(linewidth_obj, _linewidth); //| //| :param float size: point diameter in pixels. Range 0-1023. The initial value is 1 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _pointsize(mp_obj_t self, mp_obj_t a0) { mp_float_t size = mp_obj_get_float(a0); @@ -938,9 +917,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pointsize_obj, _pointsize); //| //| :param float x: signed x-coordinate in pixels. Range ±4095. The initial value is 0 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _vertextranslatex(mp_obj_t self, mp_obj_t a0) { mp_float_t x = mp_obj_get_float(a0); @@ -954,9 +933,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatex_obj, _vertextranslatex); //| //| :param float y: signed y-coordinate in pixels. Range ±4095. The initial value is 0 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| STATIC mp_obj_t _vertextranslatey(mp_obj_t self, mp_obj_t a0) { @@ -971,9 +950,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatey_obj, _vertextranslatey); //| //| :param int frac: Number of fractional bits in X,Y coordinates, 0-4. Range 0-7. The initial value is 4 //| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. +//| """ //| ... -//| // } @@ -989,7 +968,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatey_obj, _vertextranslatey); //| This method is used by the ``eve`` module to efficiently add //| commands to the FIFO.""" //| ... -//| STATIC mp_obj_t _cmd0(mp_obj_t self, mp_obj_t n) { uint32_t code = 0xffffff00 | mp_obj_get_int_truncated(n); diff --git a/shared-bindings/_pew/__init__.c b/shared-bindings/_pew/__init__.c index e338869d18..13b9715bbd 100644 --- a/shared-bindings/_pew/__init__.c +++ b/shared-bindings/_pew/__init__.c @@ -49,7 +49,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(get_ticks_obj, get_ticks); //| """LED matrix driver""" -//| STATIC const mp_rom_map_elem_t pew_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__pew) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PewPew), MP_ROM_PTR(&pewpew_type)}, diff --git a/shared-bindings/_pixelmap/PixelMap.c b/shared-bindings/_pixelmap/PixelMap.c new file mode 100644 index 0000000000..94fa4d5c96 --- /dev/null +++ b/shared-bindings/_pixelmap/PixelMap.c @@ -0,0 +1,269 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Rose Hooper + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" + +#include "shared-bindings/_pixelmap/PixelMap.h" +#include "shared-bindings/adafruit_pixelbuf/PixelBuf.h" +#include "shared-module/_pixelmap/PixelMap.h" + +//| from adafruit_pixelbuf import PixelBuf, PixelReturnType, PixelSequence, PixelType +//| +//| class PixelMap: +//| def __init__(self, pixelbuf: PixelBuf, indices: Tuple[Union[int, Tuple[int]]]) -> None: +//| """Construct a PixelMap object that uses the given indices of the underlying pixelbuf""" + +STATIC mp_obj_t pixelmap_pixelmap_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_pixelbuf, ARG_indices }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pixelbuf, MP_ARG_REQUIRED }, + { MP_QSTR_indices, MP_ARG_REQUIRED }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t pixelbuf = args[ARG_pixelbuf].u_obj; + + mp_obj_t native_pixelbuf = mp_obj_cast_to_native_base(pixelbuf, &pixelbuf_pixelbuf_type); + if (!native_pixelbuf) { + (void)mp_arg_validate_type(args[ARG_pixelbuf].u_obj, &pixelbuf_pixelbuf_type, MP_QSTR_pixelbuf); + } + mp_obj_assert_native_inited(native_pixelbuf); + + size_t buflen = common_hal_adafruit_pixelbuf_pixelbuf_get_len(pixelbuf); + + mp_obj_t indices = mp_arg_validate_type(args[ARG_indices].u_obj, &mp_type_tuple, MP_QSTR_indices); + + // validate indices + size_t len; + mp_obj_t *items; + mp_obj_tuple_get(indices, &len, &items); + mp_arg_validate_length_min(len, 1, MP_QSTR_items); + + for (size_t i = 0; i < len; i++) { + mp_obj_t item = items[i]; + if (mp_obj_is_small_int(item)) { + mp_arg_validate_index_range(MP_OBJ_SMALL_INT_VALUE(item), 0, buflen - 1, MP_QSTR_index); + } else if (mp_obj_is_tuple_compatible(item)) { + size_t len1; + mp_obj_t *items1; + mp_obj_tuple_get(item, &len1, &items1); + for (size_t j = 0; j < len1; j++) { + mp_obj_t item1 = items1[j]; + if (!mp_obj_is_small_int(item1)) { + mp_raise_TypeError(translate("nested index must be int")); + } + mp_arg_validate_index_range(MP_OBJ_SMALL_INT_VALUE(item1), 0, buflen - 1, MP_QSTR_index); + } + } else { + mp_raise_TypeError(translate("index must be tuple or int")); + } + } + + pixelmap_pixelmap_obj_t *self = m_new_obj(pixelmap_pixelmap_obj_t); + self->base.type = &pixelmap_pixelmap_type; + shared_module_pixelmap_pixelmap_construct(self, pixelbuf, indices); + + return MP_OBJ_FROM_PTR(self); +} + +//| auto_write: bool +//| """True if updates should be automatically written""" +STATIC mp_obj_t pixelmap_pixelmap_auto_write_get(const mp_obj_t self_in) { + pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(shared_module_pixelmap_pixelmap_auto_write_get(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_auto_write_get_obj, pixelmap_pixelmap_auto_write_get); + +STATIC mp_obj_t pixelmap_pixelmap_auto_write_set(const mp_obj_t self_in, const mp_obj_t arg) { + pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); + shared_module_pixelmap_pixelmap_auto_write_set(self, mp_obj_is_true(arg)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_auto_write_set_obj, pixelmap_pixelmap_auto_write_set); + +MP_PROPERTY_GETSET(pixelmap_pixelmap_auto_write_obj, + (mp_obj_t)&pixelmap_pixelmap_auto_write_get_obj, + (mp_obj_t)&pixelmap_pixelmap_auto_write_set_obj); + +//| bpp: int +//| """The number of bytes per pixel in the buffer (read-only)""" +STATIC mp_obj_t pixelmap_pixelmap_obj_get_bpp(mp_obj_t self_in) { + pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_adafruit_pixelbuf_pixelbuf_get_bpp(self->pixelbuf)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_get_bpp_obj, pixelmap_pixelmap_obj_get_bpp); + +MP_PROPERTY_GETTER(pixelmap_pixelmap_bpp_obj, + (mp_obj_t)&pixelmap_pixelmap_get_bpp_obj); + +//| byteorder: str +//| """byteorder string for the buffer (read-only)""" +STATIC mp_obj_t pixelmap_pixelmap_obj_get_byteorder(mp_obj_t self_in) { + pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_adafruit_pixelbuf_pixelbuf_get_byteorder_string(self->pixelbuf); +} +MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_get_byteorder, pixelmap_pixelmap_obj_get_byteorder); +MP_PROPERTY_GETTER(pixelmap_pixelmap_byteorder_obj, + (mp_obj_t)&pixelmap_pixelmap_get_byteorder); + +//| +//| def fill(self, color: PixelType) -> None: +//| """Fill all the pixels in the map with the given color""" +STATIC mp_obj_t pixelmap_pixelmap_fill(const mp_obj_t self_in, const mp_obj_t color) { + pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); + + shared_module_pixelmap_pixelmap_fill(self, color); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_fill_obj, pixelmap_pixelmap_fill); + +//| +//| def indices(self, index: int) -> Tuple[int]: +//| """Return the PixelBuf indices for a PixelMap index""" +STATIC mp_obj_t pixelmap_pixelmap_indices(const mp_obj_t self_in, const mp_obj_t index) { + pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return shared_module_pixelmap_pixelmap_indices(self, mp_obj_get_int(index)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_indices_obj, pixelmap_pixelmap_indices); + + +//| @overload +//| def __getitem__(self, index: slice) -> PixelReturnSequence: +//| """Retrieve the value of the underlying pixels.""" +//| ... +//| @overload +//| def __getitem__(self, index: int) -> PixelReturnType: +//| """Retrieve the value of one of the underlying pixels at 'index'.""" +//| ... +//| @overload +//| def __setitem__(self, index: slice, value: PixelSequence) -> None: ... +//| @overload +//| def __setitem__(self, index: int, value: PixelType) -> None: +//| """Sets the pixel value at the given index. Value can either be a tuple or integer. Tuples are +//| The individual (Red, Green, Blue[, White]) values between 0 and 255. If given an integer, the +//| red, green and blue values are packed into the lower three bytes (0xRRGGBB). +//| For RGBW byteorders, if given only RGB values either as an int or as a tuple, the white value +//| is used instead when the red, green, and blue values are the same.""" +//| ... +STATIC mp_obj_t pixelmap_pixelmap_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { + pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (value == MP_OBJ_NULL) { + // delete + return MP_OBJ_NULL; // op not supported + } + + if (0) { + #if MICROPY_PY_BUILTINS_SLICE + } else if (mp_obj_is_type(index_in, &mp_type_slice)) { + mp_bound_slice_t slice; + mp_seq_get_fast_slice_indexes(self->len, index_in, &slice); + size_t slice_len; + if (slice.step > 0) { + slice_len = slice.stop - slice.start; + } else { + slice_len = 1 + slice.start - slice.stop; + } + if (slice.step > 1 || slice.step < -1) { + size_t step = slice.step > 0 ? slice.step : slice.step * -1; + slice_len = (slice_len / step) + (slice_len % step ? 1 : 0); + } + + if (value == MP_OBJ_SENTINEL) { // Get + return shared_module_pixelmap_pixelmap_getslice(self, slice, slice_len); + } else { // Set + shared_module_pixelmap_pixelmap_setslice(self, value, slice, slice_len); + return mp_const_none; + } + #endif + } else { // single index + int index = mp_obj_get_int(index_in); + + if (value == MP_OBJ_SENTINEL) { // Get + return shared_module_pixelmap_pixelmap_getitem(self, index); + } else { + shared_module_pixelmap_pixelmap_setitem(self, mp_obj_get_int(index_in), value); + return mp_const_none; + } + } +} + +//| def __len__(self) -> int: +//| """Length of the map""" +STATIC mp_obj_t pixelmap_pixelmap_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); + switch (op) { + case MP_UNARY_OP_BOOL: + return mp_const_true; + case MP_UNARY_OP_LEN: + return MP_OBJ_NEW_SMALL_INT(self->len); + default: + return MP_OBJ_NULL; // op not supported + } +} + +//| def show(self) -> None: +//| """Transmits the color data to the pixels so that they are shown. This is done automatically +//| when `auto_write` is True.""" +//| ... +//| + +STATIC mp_obj_t pixelmap_pixelmap_show(mp_obj_t self_in) { + pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_adafruit_pixelbuf_pixelbuf_show(self->pixelbuf); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelmap_pixelmap_show_obj, pixelmap_pixelmap_show); + +STATIC const mp_rom_map_elem_t pixelmap_pixelmap_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_auto_write), MP_ROM_PTR(&pixelmap_pixelmap_auto_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_bpp), MP_ROM_PTR(&pixelmap_pixelmap_bpp_obj) }, + { MP_ROM_QSTR(MP_QSTR_byteorder), MP_ROM_PTR(&pixelmap_pixelmap_byteorder_obj) }, + { MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&pixelmap_pixelmap_fill_obj) }, + { MP_ROM_QSTR(MP_QSTR_indices), MP_ROM_PTR(&pixelmap_pixelmap_indices_obj) }, + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&pixelmap_pixelmap_show_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(pixelmap_pixelmap_locals_dict, pixelmap_pixelmap_locals_dict_table); + + +const mp_obj_type_t pixelmap_pixelmap_type = { + { &mp_type_type }, + .name = MP_QSTR_PixelMap, + .flags = MP_TYPE_FLAG_EXTENDED, + .locals_dict = (mp_obj_t)&pixelmap_pixelmap_locals_dict, + .make_new = pixelmap_pixelmap_make_new, + MP_TYPE_EXTENDED_FIELDS( + .subscr = pixelmap_pixelmap_subscr, + .unary_op = pixelmap_pixelmap_unary_op, + ), +}; diff --git a/shared-bindings/_pixelmap/PixelMap.h b/shared-bindings/_pixelmap/PixelMap.h new file mode 100644 index 0000000000..fef0db44d0 --- /dev/null +++ b/shared-bindings/_pixelmap/PixelMap.h @@ -0,0 +1,43 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Rose Hooper + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once +#include "py/obj.h" + +extern const mp_obj_type_t pixelmap_pixelmap_type; + +typedef struct _pixelmap_pixelmap_obj pixelmap_pixelmap_obj_t; + +void shared_module_pixelmap_pixelmap_construct(pixelmap_pixelmap_obj_t *self, mp_obj_t pixelbuf, mp_obj_t indices); +bool shared_module_pixelmap_pixelmap_auto_write_get(pixelmap_pixelmap_obj_t *self); +void shared_module_pixelmap_pixelmap_auto_write_set(pixelmap_pixelmap_obj_t *self, bool auto_write); +void shared_module_pixelmap_pixelmap_fill(pixelmap_pixelmap_obj_t *self, const mp_obj_t color); +mp_obj_t shared_module_pixelmap_pixelmap_indices(pixelmap_pixelmap_obj_t *self, int index); +void shared_module_pixelmap_pixelmap_setslice(pixelmap_pixelmap_obj_t *self, const mp_obj_t value, mp_bound_slice_t slice, size_t slice_len); +mp_obj_t shared_module_pixelmap_pixelmap_getslice(pixelmap_pixelmap_obj_t *self, mp_bound_slice_t slice, size_t slice_len); +mp_obj_t shared_module_pixelmap_pixelmap_getitem(pixelmap_pixelmap_obj_t *self, mp_int_t index); +void shared_module_pixelmap_pixelmap_setitem(pixelmap_pixelmap_obj_t *self, mp_int_t index, const mp_obj_t value); diff --git a/shared-bindings/_pixelmap/__init__.c b/shared-bindings/_pixelmap/__init__.c new file mode 100644 index 0000000000..13a09d69d2 --- /dev/null +++ b/shared-bindings/_pixelmap/__init__.c @@ -0,0 +1,62 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Rose Hooper + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/objproperty.h" + +#include "shared-bindings/_pixelmap/__init__.h" +#include "shared-bindings/_pixelmap/PixelMap.h" + + +//| """A fast pixel mapping library +//| +//| The `_pixelmap` module provides the :py:class:`PixelMap` class to accelerate +//| RGB(W) strip/matrix manipulation, such as DotStar and Neopixel.""" +//| +//| # The types accepted when getting a pixel value +//| PixelReturnType = Union[ +//| Tuple[int, int, int], Tuple[int, int, int, int], Tuple[int, int, int, float] +//| ] +//| PixelReturnSequence = Tuple[PixelReturnType] +//| # The types returned when getting a pixel value +//| PixelType = Union[int, PixelReturnType] +//| PixelSequence = Union[Tuple[PixelType], List[PixelType]] + +STATIC const mp_rom_map_elem_t pixelmap_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__pixelmap) }, + { MP_ROM_QSTR(MP_QSTR_PixelMap), MP_ROM_PTR(&pixelmap_pixelmap_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(pixelmap_module_globals, pixelmap_module_globals_table); + +const mp_obj_module_t pixelmap_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&pixelmap_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR__pixelmap, pixelmap_module, CIRCUITPY_PIXELMAP); diff --git a/shared-bindings/_pixelmap/__init__.h b/shared-bindings/_pixelmap/__init__.h new file mode 100644 index 0000000000..9a84bc68a7 --- /dev/null +++ b/shared-bindings/_pixelmap/__init__.h @@ -0,0 +1,30 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Rose Hooper + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef CP_SHARED_BINDINGS_PIXELBUF_INIT_H +#define CP_SHARED_BINDINGS_PIXELBUF_INIT_H + +#endif // CP_SHARED_BINDINGS_PIXELBUF_INIT_H diff --git a/shared-bindings/_stage/Layer.c b/shared-bindings/_stage/Layer.c index 9e64a252db..81d76321f0 100644 --- a/shared-bindings/_stage/Layer.c +++ b/shared-bindings/_stage/Layer.c @@ -33,7 +33,14 @@ //| class Layer: //| """Keep information about a single layer of graphics""" //| -//| def __init__(self, width: int, height: int, graphic: ReadableBuffer, palette: ReadableBuffer, grid: ReadableBuffer) -> None: +//| def __init__( +//| self, +//| width: int, +//| height: int, +//| graphic: ReadableBuffer, +//| palette: ReadableBuffer, +//| grid: ReadableBuffer, +//| ) -> None: //| """Keep internal information about a layer of graphics (either a //| ``Grid`` or a ``Sprite``) in a format suitable for fast rendering //| with the ``render()`` function. @@ -47,7 +54,6 @@ //| This class is intended for internal use in the ``stage`` library and //| it shouldn't be used on its own.""" //| ... -//| STATIC mp_obj_t layer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 4, 5, false); @@ -91,7 +97,6 @@ STATIC mp_obj_t layer_make_new(const mp_obj_type_t *type, size_t n_args, //| def move(self, x: int, y: int) -> None: //| """Set the offset of the layer to the specified values.""" //| ... -//| STATIC mp_obj_t layer_move(mp_obj_t self_in, mp_obj_t x_in, mp_obj_t y_in) { layer_obj_t *self = MP_OBJ_TO_PTR(self_in); self->x = mp_obj_get_int(x_in); diff --git a/shared-bindings/_stage/Text.c b/shared-bindings/_stage/Text.c index 48747bfd67..c735669861 100644 --- a/shared-bindings/_stage/Text.c +++ b/shared-bindings/_stage/Text.c @@ -33,7 +33,14 @@ //| class Text: //| """Keep information about a single grid of text""" //| -//| def __init__(self, width: int, height: int, font: ReadableBuffer, palette: ReadableBuffer, chars: ReadableBuffer) -> None: +//| def __init__( +//| self, +//| width: int, +//| height: int, +//| font: ReadableBuffer, +//| palette: ReadableBuffer, +//| chars: ReadableBuffer, +//| ) -> None: //| """Keep internal information about a grid of text //| in a format suitable for fast rendering //| with the ``render()`` function. @@ -47,7 +54,6 @@ //| This class is intended for internal use in the ``stage`` library and //| it shouldn't be used on its own.""" //| ... -//| STATIC mp_obj_t text_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 5, 5, false); diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c index ebaa06898e..b2542f9df4 100644 --- a/shared-bindings/_stage/__init__.c +++ b/shared-bindings/_stage/__init__.c @@ -39,7 +39,17 @@ //| The `_stage` module contains native code to speed-up the ```stage`` Library //| `_.""" //| -//| def render(x0: int, y0: int, x1: int, y1: int, layers: List[Layer], buffer: WriteableBuffer, display: displayio.Display, scale: int, background: int) -> None: +//| def render( +//| x0: int, +//| y0: int, +//| x1: int, +//| y1: int, +//| layers: List[Layer], +//| buffer: WriteableBuffer, +//| display: displayio.Display, +//| scale: int, +//| background: int, +//| ) -> None: //| """Render and send to the display a fragment of the screen. //| //| :param int x0: Left edge of the fragment. diff --git a/shared-bindings/adafruit_bus_device/__init__.c b/shared-bindings/adafruit_bus_device/__init__.c index be2378b154..410c6fb2f2 100644 --- a/shared-bindings/adafruit_bus_device/__init__.c +++ b/shared-bindings/adafruit_bus_device/__init__.c @@ -63,7 +63,6 @@ const mp_obj_module_t adafruit_bus_device_spi_device_module = { //| For example, they manage locking the bus to prevent other concurrent access. For SPI //| devices, it manages the chip select and protocol changes such as mode. For I2C, it //| manages the device address.""" -//| STATIC const mp_rom_map_elem_t adafruit_bus_device_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_adafruit_bus_device) }, { MP_ROM_QSTR(MP_QSTR_i2c_device), MP_ROM_PTR(&adafruit_bus_device_i2c_device_module) }, diff --git a/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c b/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c index 3ae5fc2a2f..a77179c886 100644 --- a/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c +++ b/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c @@ -43,7 +43,6 @@ //| """I2C Device Manager""" //| //| def __init__(self, i2c: busio.I2C, device_address: int, probe: bool = True) -> None: -//| //| """Represents a single I2C device and manages locking the bus and the device //| address. //| @@ -64,9 +63,8 @@ //| # A second transaction //| with device: //| device.write(bytes_read) -//| """ +//| """ //| ... -//| STATIC mp_obj_t adafruit_bus_device_i2cdevice_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { adafruit_bus_device_i2cdevice_obj_t *self = m_new_obj(adafruit_bus_device_i2cdevice_obj_t); self->base.type = &adafruit_bus_device_i2cdevice_type; @@ -92,7 +90,6 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_make_new(const mp_obj_type_t *type //| def __enter__(self) -> I2CDevice: //| """Context manager entry to lock bus.""" //| ... -//| STATIC mp_obj_t adafruit_bus_device_i2cdevice_obj___enter__(mp_obj_t self_in) { adafruit_bus_device_i2cdevice_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_adafruit_bus_device_i2cdevice_lock(self); @@ -103,7 +100,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(adafruit_bus_device_i2cdevice___enter___obj, ad //| def __exit__(self) -> None: //| """Automatically unlocks the bus on exit.""" //| ... -//| STATIC mp_obj_t adafruit_bus_device_i2cdevice_obj___exit__(size_t n_args, const mp_obj_t *args) { common_hal_adafruit_bus_device_i2cdevice_unlock(MP_OBJ_TO_PTR(args[0])); return mp_const_none; @@ -111,7 +107,9 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_obj___exit__(size_t n_args, const STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(adafruit_bus_device_i2cdevice___exit___obj, 4, 4, adafruit_bus_device_i2cdevice_obj___exit__); //| import sys -//| def readinto(self, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize) -> None: +//| def readinto( +//| self, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize +//| ) -> None: //| """Read into ``buffer`` from the device. //| //| If ``start`` or ``end`` is provided, then the buffer will be sliced @@ -123,7 +121,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(adafruit_bus_device_i2cdevice___exit_ //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... -//| STATIC mp_obj_t adafruit_bus_device_i2cdevice_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -170,7 +167,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_readinto_obj, 1, //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... -//| STATIC mp_obj_t adafruit_bus_device_i2cdevice_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -205,7 +201,16 @@ MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_write_obj, 1, adafruit_ //| import sys -//| def write_then_readinto(self, out_buffer: ReadableBuffer, in_buffer: WriteableBuffer, *, out_start: int = 0, out_end: int = sys.maxsize, in_start: int = 0, in_end: int = sys.maxsize) -> None: +//| def write_then_readinto( +//| self, +//| out_buffer: ReadableBuffer, +//| in_buffer: WriteableBuffer, +//| *, +//| out_start: int = 0, +//| out_end: int = sys.maxsize, +//| in_start: int = 0, +//| in_end: int = sys.maxsize +//| ) -> None: //| """Write the bytes from ``out_buffer`` to the device, then immediately //| reads into ``in_buffer`` from the device. //| diff --git a/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c b/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c index f7cc357e91..6108247aa1 100644 --- a/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +++ b/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c @@ -41,8 +41,16 @@ //| class SPIDevice: //| """SPI Device Manager""" //| -//| def __init__(self, spi: busio.SPI, chip_select: microcontroller.Pin, *, baudrate: int = 100000, polarity: int = 0, phase: int = 0, extra_clocks : int = 0) -> None: -//| +//| def __init__( +//| self, +//| spi: busio.SPI, +//| chip_select: digitalio.DigitalInOut, +//| *, +//| baudrate: int = 100000, +//| polarity: int = 0, +//| phase: int = 0, +//| extra_clocks: int = 0 +//| ) -> None: //| """ //| Represents a single SPI device and manages locking the bus and the device address. //| @@ -70,7 +78,6 @@ //| with device as spi: //| spi.write(bytes_read)""" //| ... -//| STATIC mp_obj_t adafruit_bus_device_spidevice_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { adafruit_bus_device_spidevice_obj_t *self = m_new_obj(adafruit_bus_device_spidevice_obj_t); self->base.type = &adafruit_bus_device_spidevice_type; @@ -89,15 +96,21 @@ STATIC mp_obj_t adafruit_bus_device_spidevice_make_new(const mp_obj_type_t *type busio_spi_obj_t *spi = args[ARG_spi].u_obj; + mp_arg_validate_type(args[ARG_chip_select].u_obj, &digitalio_digitalinout_type, MP_QSTR_chip_select); + common_hal_adafruit_bus_device_spidevice_construct(MP_OBJ_TO_PTR(self), spi, args[ARG_chip_select].u_obj, args[ARG_cs_active_value].u_bool, args[ARG_baudrate].u_int, args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_extra_clocks].u_int); if (args[ARG_chip_select].u_obj != MP_OBJ_NULL) { digitalinout_result_t result = common_hal_digitalio_digitalinout_switch_to_output(MP_OBJ_TO_PTR(args[ARG_chip_select].u_obj), true, DRIVE_MODE_PUSH_PULL); + #if CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY if (result == DIGITALINOUT_INPUT_ONLY) { mp_raise_NotImplementedError(translate("Pin is input only")); } + #else + (void)result; + #endif } return (mp_obj_t)self; @@ -106,7 +119,6 @@ STATIC mp_obj_t adafruit_bus_device_spidevice_make_new(const mp_obj_type_t *type //| def __enter__(self) -> busio.SPI: //| """Starts a SPI transaction by configuring the SPI and asserting chip select.""" //| ... -//| STATIC mp_obj_t adafruit_bus_device_spidevice_obj___enter__(mp_obj_t self_in) { adafruit_bus_device_spidevice_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_adafruit_bus_device_spidevice_enter(self); diff --git a/shared-bindings/adafruit_pixelbuf/PixelBuf.c b/shared-bindings/adafruit_pixelbuf/PixelBuf.c index 8f1ea4eac2..2848a02c62 100644 --- a/shared-bindings/adafruit_pixelbuf/PixelBuf.c +++ b/shared-bindings/adafruit_pixelbuf/PixelBuf.c @@ -40,7 +40,7 @@ #include "shared-module/adafruit_pixelbuf/PixelBuf.h" #include "shared-bindings/digitalio/DigitalInOut.h" -#ifdef CIRCUITPY_ULAB +#if CIRCUITPY_ULAB #include "extmod/ulab/code/ndarray.h" #endif @@ -53,7 +53,16 @@ static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t //| class PixelBuf: //| """A fast RGB[W] pixel buffer for LED and similar devices.""" //| -//| def __init__(self, size: int, *, byteorder: str = "BGR", brightness: float = 0, auto_write: bool = False, header: ReadableBuffer = b"", trailer: ReadableBuffer = b"") -> None: +//| def __init__( +//| self, +//| size: int, +//| *, +//| byteorder: str = "BGR", +//| brightness: float = 0, +//| auto_write: bool = False, +//| header: ReadableBuffer = b"", +//| trailer: ReadableBuffer = b"" +//| ) -> None: //| """Create a PixelBuf object of the specified size, byteorder, and bits per pixel. //| //| When brightness is less than 1.0, a second buffer will be used to store the color values @@ -69,9 +78,9 @@ static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t //| :param float brightness: Brightness (0 to 1.0, default 1.0) //| :param bool auto_write: Whether to automatically write pixels (Default False) //| :param ~circuitpython_typing.ReadableBuffer header: Sequence of bytes to always send before pixel values. -//| :param ~circuitpython_typing.ReadableBuffer trailer: Sequence of bytes to always send after pixel values.""" +//| :param ~circuitpython_typing.ReadableBuffer trailer: Sequence of bytes to always send after pixel values. +//| """ //| ... -//| STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_size, ARG_byteorder, ARG_brightness, ARG_auto_write, ARG_header, ARG_trailer }; static const mp_arg_t allowed_args[] = { @@ -121,9 +130,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a } static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t *parsed) { - if (!mp_obj_is_str(byteorder_obj)) { - mp_raise_TypeError(translate("byteorder is not a string")); - } + mp_arg_validate_type_string(byteorder_obj, MP_QSTR_byteorder); size_t bo_len; const char *byteorder = mp_obj_str_get_data(byteorder_obj, &bo_len); @@ -159,7 +166,6 @@ static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t //| bpp: int //| """The number of bytes per pixel in the buffer (read-only)""" -//| STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_bpp(mp_obj_t self_in) { return MP_OBJ_NEW_SMALL_INT(common_hal_adafruit_pixelbuf_pixelbuf_get_bpp(self_in)); } @@ -174,7 +180,6 @@ MP_PROPERTY_GETTER(pixelbuf_pixelbuf_bpp_obj, //| //| When brightness is less than 1.0, a second buffer will be used to store the color values //| before they are adjusted for brightness.""" -//| STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_brightness(mp_obj_t self_in) { return mp_obj_new_float(common_hal_adafruit_pixelbuf_pixelbuf_get_brightness(self_in)); } @@ -199,7 +204,6 @@ MP_PROPERTY_GETSET(pixelbuf_pixelbuf_brightness_obj, //| auto_write: bool //| """Whether to automatically write the pixels after each update.""" -//| STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_auto_write(mp_obj_t self_in) { return mp_obj_new_bool(common_hal_adafruit_pixelbuf_pixelbuf_get_auto_write(self_in)); } @@ -218,7 +222,6 @@ MP_PROPERTY_GETSET(pixelbuf_pixelbuf_auto_write_obj, //| byteorder: str //| """byteorder string for the buffer (read-only)""" -//| STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_byteorder(mp_obj_t self_in) { return common_hal_adafruit_pixelbuf_pixelbuf_get_byteorder_string(self_in); } @@ -242,7 +245,6 @@ STATIC mp_obj_t pixelbuf_pixelbuf_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| """Transmits the color data to the pixels so that they are shown. This is done automatically //| when `auto_write` is True.""" //| ... -//| STATIC mp_obj_t pixelbuf_pixelbuf_show(mp_obj_t self_in) { common_hal_adafruit_pixelbuf_pixelbuf_show(self_in); @@ -250,10 +252,9 @@ STATIC mp_obj_t pixelbuf_pixelbuf_show(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_show_obj, pixelbuf_pixelbuf_show); -//| def fill(self, color: Union[int, Tuple[int, int, int], Tuple[int, int, int, float]]) -> None: +//| def fill(self, color: PixelType) -> None: //| """Fills the given pixelbuf with the given color.""" //| ... -//| STATIC mp_obj_t pixelbuf_pixelbuf_fill(mp_obj_t self_in, mp_obj_t value) { common_hal_adafruit_pixelbuf_pixelbuf_fill(self_in, value); @@ -263,20 +264,21 @@ STATIC mp_obj_t pixelbuf_pixelbuf_fill(mp_obj_t self_in, mp_obj_t value) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_fill_obj, pixelbuf_pixelbuf_fill); //| @overload -//| def __getitem__(self, index: slice) -> Union[Tuple[Tuple[int, int, int], ...], Tuple[Tuple[int, int, int, float], ...]]: ... -//| @overload -//| def __getitem__(self, index: int) -> Union[Tuple[int, int, int], Tuple[int, int, int, float]]: +//| def __getitem__(self, index: slice) -> PixelReturnSequence: //| """Returns the pixel value at the given index as a tuple of (Red, Green, Blue[, White]) values //| between 0 and 255. When in PWM (DotStar) mode, the 4th tuple value is a float of the pixel //| intensity from 0-1.0.""" //| ... -//| //| @overload -//| def __setitem__(self, index: slice, value: Tuple[Union[int, Tuple[float, ...], List[float]], ...]) -> None: ... +//| def __getitem__(self, index: int) -> PixelReturnType: +//| """Returns the pixel value at the given index as a tuple of (Red, Green, Blue[, White]) values +//| between 0 and 255. When in PWM (DotStar) mode, the 4th tuple value is a float of the pixel +//| intensity from 0-1.0.""" +//| ... //| @overload -//| def __setitem__(self, index: slice, value: List[Union[int, Tuple[float, ...], List[float]]]) -> None: ... +//| def __setitem__(self, index: slice, value: PixelSequence) -> None: ... //| @overload -//| def __setitem__(self, index: int, value: Union[int, Tuple[float, ...], List[float]]) -> None: +//| def __setitem__(self, index: int, value: PixelType) -> None: //| """Sets the pixel value at the given index. Value can either be a tuple or integer. Tuples are //| The individual (Red, Green, Blue[, White]) values between 0 and 255. If given an integer, the //| red, green and blue values are packed into the lower three bytes (0xRRGGBB). diff --git a/shared-bindings/adafruit_pixelbuf/PixelBuf.h b/shared-bindings/adafruit_pixelbuf/PixelBuf.h index 7ae3d6acf8..e77153322d 100644 --- a/shared-bindings/adafruit_pixelbuf/PixelBuf.h +++ b/shared-bindings/adafruit_pixelbuf/PixelBuf.h @@ -27,10 +27,18 @@ #ifndef CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H #define CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H +#include "py/objtuple.h" #include "shared-module/adafruit_pixelbuf/PixelBuf.h" extern const mp_obj_type_t pixelbuf_pixelbuf_type; +typedef union { + struct { + uint8_t r, g, b, w; + }; + uint32_t rgbw; +} color_u; + void common_hal_adafruit_pixelbuf_pixelbuf_construct(pixelbuf_pixelbuf_obj_t *self, size_t n, pixelbuf_byteorder_details_t *byteorder, mp_float_t brightness, bool auto_write, uint8_t *header, size_t header_len, uint8_t *trailer, size_t trailer_len); @@ -48,5 +56,7 @@ void common_hal_adafruit_pixelbuf_pixelbuf_show(mp_obj_t self); mp_obj_t common_hal_adafruit_pixelbuf_pixelbuf_get_pixel(mp_obj_t self, size_t index); void common_hal_adafruit_pixelbuf_pixelbuf_set_pixel(mp_obj_t self, size_t index, mp_obj_t item); void common_hal_adafruit_pixelbuf_pixelbuf_set_pixels(mp_obj_t self_in, size_t start, mp_int_t step, size_t slice_len, mp_obj_t *values, mp_obj_tuple_t *flatten_to); +void common_hal_adafruit_pixelbuf_pixelbuf_parse_color(mp_obj_t self, mp_obj_t color, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *w); +void common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(mp_obj_t self, size_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t w); #endif // CP_SHARED_BINDINGS_PIXELBUF_PIXELBUF_H diff --git a/shared-bindings/adafruit_pixelbuf/__init__.c b/shared-bindings/adafruit_pixelbuf/__init__.c index 7b8d0da829..fd2915ee0a 100644 --- a/shared-bindings/adafruit_pixelbuf/__init__.c +++ b/shared-bindings/adafruit_pixelbuf/__init__.c @@ -38,9 +38,16 @@ //| The `adafruit_pixelbuf` module provides the :py:class:`PixelBuf` class to accelerate //| RGB(W) strip/matrix manipulation, such as DotStar and Neopixel. //| -//| Also available as ``_pixelbuf``. This usage has been deprecated. -//| //| Byteorders are configured with strings, such as "RGB" or "RGBD".""" +//| +//| # The types accepted when getting a pixel value +//| PixelReturnType = Union[ +//| Tuple[int, int, int], Tuple[int, int, int, int], Tuple[int, int, int, float] +//| ] +//| PixelReturnSequence = Tuple[PixelReturnType] +//| # The types returned when getting a pixel value +//| PixelType = Union[int, PixelReturnType] +//| PixelSequence = Union[Tuple[PixelType], List[PixelType]] // TODO: Pull in docs from adafruit_pixelbuf. STATIC const mp_rom_map_elem_t pixelbuf_module_globals_table[] = { diff --git a/shared-bindings/aesio/__init__.c b/shared-bindings/aesio/__init__.c index 716d20393e..f3e1d7dd17 100644 --- a/shared-bindings/aesio/__init__.c +++ b/shared-bindings/aesio/__init__.c @@ -34,7 +34,11 @@ //| """AES encryption routines //| //| The `AES` module contains classes used to implement encryption -//| and decryption. It aims to be low overhead in terms of memory.""" +//| and decryption. It aims to be low overhead in terms of memory. +//| +//| For more information on AES, refer to `the Wikipedia entry +//| `_. +//| """ STATIC const mp_obj_tuple_t mp_aes_key_size_obj = { diff --git a/shared-bindings/aesio/aes.c b/shared-bindings/aesio/aes.c index 27d52d8566..c5c50515ea 100644 --- a/shared-bindings/aesio/aes.c +++ b/shared-bindings/aesio/aes.c @@ -16,33 +16,40 @@ //| class AES: //| """Encrypt and decrypt AES streams""" //| -//| def __init__(self, key: ReadableBuffer, mode: int = 0, iv: Optional[ReadableBuffer] = None, segment_size: int = 8) -> None: +//| def __init__( +//| self, +//| key: ReadableBuffer, +//| mode: int = 0, +//| IV: Optional[ReadableBuffer] = None, +//| segment_size: int = 8, +//| ) -> None: //| """Create a new AES state with the given key. //| -//| :param ~circuitpython_typing.ReadableBuffer key: A 16-, 24-, or 32-byte key -//| :param int mode: AES mode to use. One of: `MODE_ECB`, `MODE_CBC`, or -//| `MODE_CTR` -//| :param ~circuitpython_typing.ReadableBuffer iv: Initialization vector to use for CBC or CTR mode +//| :param ~circuitpython_typing.ReadableBuffer key: A 16-, 24-, or 32-byte key +//| :param int mode: AES mode to use. One of: `MODE_ECB`, `MODE_CBC`, or +//| `MODE_CTR` +//| :param ~circuitpython_typing.ReadableBuffer IV: Initialization vector to use for CBC or CTR mode //| -//| Additional arguments are supported for legacy reasons. +//| Additional arguments are supported for legacy reasons. //| -//| Encrypting a string:: +//| Encrypting a string:: //| -//| import aesio -//| from binascii import hexlify +//| import aesio +//| from binascii import hexlify //| -//| key = b'Sixteen byte key' -//| inp = b'CircuitPython!!!' # Note: 16-bytes long -//| outp = bytearray(len(inp)) -//| cipher = aesio.AES(key, aesio.MODE_ECB) -//| cipher.encrypt_into(inp, outp) -//| hexlify(outp)""" +//| key = b'Sixteen byte key' +//| inp = b'CircuitPython!!!' # Note: 16-bytes long +//| outp = bytearray(len(inp)) +//| cipher = aesio.AES(key, aesio.MODE_ECB) +//| cipher.encrypt_into(inp, outp) +//| hexlify(outp)""" //| ... -//| STATIC mp_obj_t aesio_aes_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - (void)type; + aesio_aes_obj_t *self = m_new_obj(aesio_aes_obj_t); + self->base.type = &aesio_aes_type; + enum { ARG_key, ARG_mode, ARG_IV, ARG_counter, ARG_segment_size }; static const mp_arg_t allowed_args[] = { {MP_QSTR_key, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, @@ -56,16 +63,13 @@ STATIC mp_obj_t aesio_aes_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - aesio_aes_obj_t *self = m_new_obj(aesio_aes_obj_t); - self->base.type = &aesio_aes_type; - mp_buffer_info_t bufinfo; const uint8_t *key = NULL; uint32_t key_length = 0; mp_get_buffer_raise(args[ARG_key].u_obj, &bufinfo, MP_BUFFER_READ); if ((bufinfo.len != 16) && (bufinfo.len != 24) && (bufinfo.len != 32)) { - mp_raise_TypeError(translate("Key must be 16, 24, or 32 bytes long")); + mp_raise_ValueError(translate("Key must be 16, 24, or 32 bytes long")); } key = bufinfo.buf; key_length = bufinfo.len; @@ -77,17 +81,15 @@ STATIC mp_obj_t aesio_aes_make_new(const mp_obj_type_t *type, size_t n_args, case AES_MODE_CTR: break; default: - mp_raise_TypeError(translate("Requested AES mode is unsupported")); + mp_raise_NotImplementedError(translate("Requested AES mode is unsupported")); } // IV is required for CBC mode and is ignored for other modes. const uint8_t *iv = NULL; if (args[ARG_IV].u_obj != NULL && mp_get_buffer(args[ARG_IV].u_obj, &bufinfo, MP_BUFFER_READ)) { - if (bufinfo.len != AES_BLOCKLEN) { - mp_raise_TypeError_varg(translate("IV must be %d bytes long"), - AES_BLOCKLEN); - } + (void)mp_arg_validate_length(bufinfo.len, AES_BLOCKLEN, MP_QSTR_IV); + iv = bufinfo.buf; } @@ -96,36 +98,49 @@ STATIC mp_obj_t aesio_aes_make_new(const mp_obj_type_t *type, size_t n_args, return MP_OBJ_FROM_PTR(self); } -STATIC mp_obj_t aesio_aes_rekey(size_t n_args, const mp_obj_t *pos_args) { +//| def rekey( +//| self, +//| key: ReadableBuffer, +//| IV: Optional[ReadableBuffer] = None, +//| ) -> None: +//| """Update the AES state with the given key. +//| +//| :param ~circuitpython_typing.ReadableBuffer key: A 16-, 24-, or 32-byte key +//| :param ~circuitpython_typing.ReadableBuffer IV: Initialization vector to use +//| for CBC or CTR mode""" +//| ... +STATIC mp_obj_t aesio_aes_rekey(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { aesio_aes_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + enum { ARG_key, ARG_IV }; + static const mp_arg_t allowed_args[] = { + {MP_QSTR_key, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, + {MP_QSTR_IV, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_buffer_info_t bufinfo; - mp_get_buffer_raise(pos_args[1], &bufinfo, MP_BUFFER_READ); + + mp_get_buffer_raise(args[ARG_key].u_obj, &bufinfo, MP_BUFFER_READ); const uint8_t *key = bufinfo.buf; size_t key_length = bufinfo.len; - if (key == NULL) { - mp_raise_ValueError(translate("No key was specified")); - } + if ((key_length != 16) && (key_length != 24) && (key_length != 32)) { - mp_raise_TypeError(translate("Key must be 16, 24, or 32 bytes long")); + mp_raise_ValueError(translate("Key must be 16, 24, or 32 bytes long")); } const uint8_t *iv = NULL; - if (n_args > 2) { - mp_get_buffer_raise(pos_args[2], &bufinfo, MP_BUFFER_READ); - size_t iv_length = bufinfo.len; - iv = (const uint8_t *)bufinfo.buf; - if (iv_length != AES_BLOCKLEN) { - mp_raise_TypeError_varg(translate("IV must be %d bytes long"), - AES_BLOCKLEN); - } + if (args[ARG_IV].u_obj != NULL && + mp_get_buffer(args[ARG_IV].u_obj, &bufinfo, MP_BUFFER_READ)) { + (void)mp_arg_validate_length(bufinfo.len, AES_BLOCKLEN, MP_QSTR_IV); + + iv = bufinfo.buf; } common_hal_aesio_aes_rekey(self, key, key_length, iv); return mp_const_none; } - -MP_DEFINE_CONST_FUN_OBJ_VAR(aesio_aes_rekey_obj, 2, aesio_aes_rekey); +MP_DEFINE_CONST_FUN_OBJ_KW(aesio_aes_rekey_obj, 1, aesio_aes_rekey); STATIC void validate_length(aesio_aes_obj_t *self, size_t src_length, size_t dest_length) { @@ -137,14 +152,12 @@ STATIC void validate_length(aesio_aes_obj_t *self, size_t src_length, switch (self->mode) { case AES_MODE_ECB: if (src_length != 16) { - mp_raise_msg(&mp_type_ValueError, - translate("ECB only operates on 16 bytes at a time")); + mp_raise_ValueError(translate("ECB only operates on 16 bytes at a time")); } break; case AES_MODE_CBC: if ((src_length & 15) != 0) { - mp_raise_msg(&mp_type_ValueError, - translate("CBC blocks must be multiples of 16 bytes")); + mp_raise_ValueError(translate("CBC blocks must be multiples of 16 bytes")); } break; case AES_MODE_CTR: @@ -155,78 +168,58 @@ STATIC void validate_length(aesio_aes_obj_t *self, size_t src_length, //| def encrypt_into(self, src: ReadableBuffer, dest: WriteableBuffer) -> None: //| """Encrypt the buffer from ``src`` into ``dest``. //| -//| For ECB mode, the buffers must be 16 bytes long. For CBC mode, the -//| buffers must be a multiple of 16 bytes, and must be equal length. For -//| CTX mode, there are no restrictions.""" +//| For ECB mode, the buffers must be 16 bytes long. For CBC mode, the +//| buffers must be a multiple of 16 bytes, and must be equal length. For +//| CTX mode, there are no restrictions.""" //| ... -//| -STATIC mp_obj_t aesio_aes_encrypt_into(mp_obj_t aesio_obj, mp_obj_t src, - mp_obj_t dest) { - if (!mp_obj_is_type(aesio_obj, &aesio_aes_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name); - } - // Convert parameters into expected types. - aesio_aes_obj_t *aes = MP_OBJ_TO_PTR(aesio_obj); +STATIC mp_obj_t aesio_aes_encrypt_into(mp_obj_t self_in, mp_obj_t src, mp_obj_t dest) { + aesio_aes_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t srcbufinfo, destbufinfo; mp_get_buffer_raise(src, &srcbufinfo, MP_BUFFER_READ); mp_get_buffer_raise(dest, &destbufinfo, MP_BUFFER_WRITE); - validate_length(aes, srcbufinfo.len, destbufinfo.len); + validate_length(self, srcbufinfo.len, destbufinfo.len); memcpy(destbufinfo.buf, srcbufinfo.buf, srcbufinfo.len); - common_hal_aesio_aes_encrypt(aes, (uint8_t *)destbufinfo.buf, - destbufinfo.len); + common_hal_aesio_aes_encrypt(self, (uint8_t *)destbufinfo.buf, destbufinfo.len); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_3(aesio_aes_encrypt_into_obj, - aesio_aes_encrypt_into); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(aesio_aes_encrypt_into_obj, aesio_aes_encrypt_into); //| def decrypt_into(self, src: ReadableBuffer, dest: WriteableBuffer) -> None: //| """Decrypt the buffer from ``src`` into ``dest``. -//| For ECB mode, the buffers must be 16 bytes long. For CBC mode, the -//| buffers must be a multiple of 16 bytes, and must be equal length. For -//| CTX mode, there are no restrictions.""" +//| For ECB mode, the buffers must be 16 bytes long. For CBC mode, the +//| buffers must be a multiple of 16 bytes, and must be equal length. For +//| CTX mode, there are no restrictions.""" //| ... //| -STATIC mp_obj_t aesio_aes_decrypt_into(mp_obj_t aesio_obj, mp_obj_t src, - mp_obj_t dest) { - if (!mp_obj_is_type(aesio_obj, &aesio_aes_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name); - } - // Convert parameters into expected types. - aesio_aes_obj_t *aes = MP_OBJ_TO_PTR(aesio_obj); +STATIC mp_obj_t aesio_aes_decrypt_into(mp_obj_t self_in, mp_obj_t src, mp_obj_t dest) { + aesio_aes_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t srcbufinfo, destbufinfo; mp_get_buffer_raise(src, &srcbufinfo, MP_BUFFER_READ); mp_get_buffer_raise(dest, &destbufinfo, MP_BUFFER_WRITE); - validate_length(aes, srcbufinfo.len, destbufinfo.len); + validate_length(self, srcbufinfo.len, destbufinfo.len); memcpy(destbufinfo.buf, srcbufinfo.buf, srcbufinfo.len); - common_hal_aesio_aes_decrypt(aes, (uint8_t *)destbufinfo.buf, - destbufinfo.len); + common_hal_aesio_aes_decrypt(self, (uint8_t *)destbufinfo.buf, destbufinfo.len); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_3(aesio_aes_decrypt_into_obj, - aesio_aes_decrypt_into); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(aesio_aes_decrypt_into_obj, aesio_aes_decrypt_into); + +STATIC mp_obj_t aesio_aes_get_mode(mp_obj_t self_in) { + aesio_aes_obj_t *self = MP_OBJ_TO_PTR(self_in); -STATIC mp_obj_t aesio_aes_get_mode(mp_obj_t aesio_obj) { - if (!mp_obj_is_type(aesio_obj, &aesio_aes_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name); - } - aesio_aes_obj_t *self = MP_OBJ_TO_PTR(aesio_obj); return MP_OBJ_NEW_SMALL_INT(self->mode); } MP_DEFINE_CONST_FUN_OBJ_1(aesio_aes_get_mode_obj, aesio_aes_get_mode); -STATIC mp_obj_t aesio_aes_set_mode(mp_obj_t aesio_obj, mp_obj_t mode_obj) { - if (!mp_obj_is_type(aesio_obj, &aesio_aes_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name); - } - aesio_aes_obj_t *self = MP_OBJ_TO_PTR(aesio_obj); +STATIC mp_obj_t aesio_aes_set_mode(mp_obj_t self_in, mp_obj_t mode_obj) { + aesio_aes_obj_t *self = MP_OBJ_TO_PTR(self_in); int mode = mp_obj_get_int(mode_obj); switch (mode) { @@ -235,7 +228,7 @@ STATIC mp_obj_t aesio_aes_set_mode(mp_obj_t aesio_obj, mp_obj_t mode_obj) { case AES_MODE_CTR: break; default: - mp_raise_TypeError(translate("Requested AES mode is unsupported")); + mp_raise_NotImplementedError(translate("Requested AES mode is unsupported")); } common_hal_aesio_aes_set_mode(self, mode); diff --git a/shared-bindings/alarm/SleepMemory.c b/shared-bindings/alarm/SleepMemory.c index b4e68c964c..0304abfbcc 100644 --- a/shared-bindings/alarm/SleepMemory.c +++ b/shared-bindings/alarm/SleepMemory.c @@ -42,27 +42,27 @@ //| instance of :class:`SleepMemory` is available at //| :attr:`alarm.sleep_memory`. //| +//| **Limitations:** Not supported on RP2040. +//| //| Usage:: //| //| import alarm //| alarm.sleep_memory[0] = True //| alarm.sleep_memory[1] = 12 //| """ +//| //| def __init__(self) -> None: //| """Not used. Access the sole instance through `alarm.sleep_memory`.""" //| ... -//| //| def __bool__(self) -> bool: //| """``sleep_memory`` is ``True`` if its length is greater than zero. //| This is an easy way to check for its existence. //| """ //| ... -//| //| def __len__(self) -> int: //| """Return the length. This is used by (`len`)""" //| ... -//| STATIC mp_obj_t alarm_sleep_memory_unary_op(mp_unary_op_t op, mp_obj_t self_in) { alarm_sleep_memory_obj_t *self = MP_OBJ_TO_PTR(self_in); uint16_t len = common_hal_alarm_sleep_memory_get_length(self); @@ -87,7 +87,6 @@ STATIC MP_DEFINE_CONST_DICT(alarm_sleep_memory_locals_dict, alarm_sleep_memory_l //| def __getitem__(self, index: int) -> int: //| """Returns the value at the given index.""" //| ... -//| //| @overload //| def __setitem__(self, index: slice, value: ReadableBuffer) -> None: ... //| @overload diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 7fd14b7641..29c9b49d3f 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -27,11 +27,16 @@ #include "py/obj.h" #include "py/runtime.h" +#if CIRCUITPY_ESPULP +#include "bindings/espulp/ULPAlarm.h" +#endif + #include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/SleepMemory.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/alarm/touch/TouchAlarm.h" +#include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/supervisor/Runtime.h" #include "shared-bindings/time/__init__.h" #include "supervisor/shared/workflow.h" @@ -63,7 +68,6 @@ //| sleep_memory: SleepMemory //| """Memory that persists during deep sleep. //| This object is the sole instance of `alarm.SleepMemory`.""" -//| //| wake_alarm: Optional[circuitpython_typing.Alarm] //| """The most recently triggered alarm. If CircuitPython was sleeping, the alarm that woke it from sleep. @@ -77,14 +81,19 @@ STATIC void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { for (size_t i = 0; i < n_args; i++) { if (mp_obj_is_type(objs[i], &alarm_pin_pinalarm_type) || mp_obj_is_type(objs[i], &alarm_time_timealarm_type) || + #if CIRCUITPY_ESPULP + mp_obj_is_type(objs[i], &espulp_ulpalarm_type) || + #endif mp_obj_is_type(objs[i], &alarm_touch_touchalarm_type)) { continue; } - mp_raise_TypeError_varg(translate("Expected an alarm")); + mp_raise_TypeError_varg(translate("Expected a kind of %q"), MP_QSTR_Alarm); } } -//| def light_sleep_until_alarms(*alarms: circuitpython_typing.Alarm) -> circuitpython_typing.Alarm: +//| def light_sleep_until_alarms( +//| *alarms: circuitpython_typing.Alarm, +//| ) -> circuitpython_typing.Alarm: //| """Go into a light sleep until awakened one of the alarms. The alarm causing the wake-up //| is returned, and is also available as `alarm.wake_alarm`. //| @@ -112,7 +121,9 @@ STATIC mp_obj_t alarm_light_sleep_until_alarms(size_t n_args, const mp_obj_t *ar } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_light_sleep_until_alarms); -//| def exit_and_deep_sleep_until_alarms(*alarms: circuitpython_typing.Alarm) -> None: +//| def exit_and_deep_sleep_until_alarms( +//| *alarms: circuitpython_typing.Alarm, preserve_dios: Sequence[digitalio.DigitalInOut] = () +//| ) -> None: //| """Exit the program and go into a deep sleep, until awakened by one of the alarms. //| This function does not return. //| @@ -126,6 +137,30 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OB //| //| If no alarms are specified, the microcontroller will deep sleep until reset. //| +//| :param circuitpython_typing.Alarm alarms: the alarms that can wake the microcontroller. +//| :param Sequence[digitalio.DigitalInOut] preserve_dios: A sequence of `DigitalInOut` objects +//| whose state should be preserved during deep sleep. +//| If a `DigitalInOut` in the sequence is set to be an output, +//| its current `DigitalInOut.value` (``True`` or ``False``) +//| will be preserved during the deep sleep. +//| If a `DigitalInOut` in the sequence is set to be an input, +//| its current `DigitalInOut.pull` value (``DOWN``, ``UP``, or ``None``) +//| will be preserved during deep sleep. +//| +//| Preserving `DigitalInOut` states during deep sleep can be used to ensure that +//| external or on-board devices are powered or unpowered during sleep, among other purposes. +//| +//| On some microcontrollers, some pins cannot remain in their original state for hardware reasons. +//| +//| **Limitations:** ``preserve_dios`` is currently only available on Espressif. +//| +//| .. note:: +//| On Espressif chips, preserving pin settings during deep sleep may consume extra current. +//| On ESP32, this was measured to be 250 uA or more. +//| Consider not preserving pins unless you need to. +//| Measure power consumption carefully both with no pins preserved and with the pins you might want to +//| preserve to achieve the lowest consumption. +//| //| **If CircuitPython is connected to a host computer via USB or BLE //| the first time a deep sleep is requested, //| the connection will be maintained and the system will not go into deep sleep.** @@ -136,28 +171,47 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OB //| the next deep sleep will still be a true deep sleep. You must do a hard reset //| or power-cycle to exit a true deep sleep loop. //| -//| Here is skeletal example that deep-sleeps and restarts every 60 seconds: +//| Here is a skeletal example: //| //| .. code-block:: python //| //| import alarm //| import time +//| import board //| //| print("Waking up") //| -//| # Set an alarm for 60 seconds from now. +//| # Create an alarm for 60 seconds from now, and also a pin alarm. //| time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 60) +//| pin_alarm = alarm.pin.PinAlarm(board.D7, False) //| -//| # Deep sleep until the alarm goes off. Then restart the program. -//| alarm.exit_and_deep_sleep_until_alarms(time_alarm) +//| # Deep sleep until one of the alarm goes off. Then restart the program. +//| alarm.exit_and_deep_sleep_until_alarms(time_alarm, pin_alarm) //| """ //| ... //| -STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_obj_t *args) { - validate_objs_are_alarms(n_args, args); +STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_preserve_dios }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_preserve_dios, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_tuple} }, + }; - // Validate the alarms and set them. - common_hal_alarm_set_deep_sleep_alarms(n_args, args); + // args will contain only the value for preserve_dios. The *alarms args are in pos_args. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(0, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + validate_objs_are_alarms(n_args, pos_args); + + mp_obj_t preserve_dios = args[ARG_preserve_dios].u_obj; + const size_t num_dios = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(preserve_dios)); + digitalio_digitalinout_obj_t *dios_array[num_dios]; + + for (mp_uint_t i = 0; i < num_dios; i++) { + mp_obj_t dio = mp_obj_subscr(preserve_dios, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL); + dios_array[i] = mp_arg_validate_type(dio, &digitalio_digitalinout_type, MP_QSTR_alarm); + } + + common_hal_alarm_set_deep_sleep_alarms(n_args, pos_args, num_dios, dios_array); // Raise an exception, which will be processed in main.c. mp_raise_type_arg(&mp_type_DeepSleepRequest, NULL); @@ -165,7 +219,7 @@ STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_o // Doesn't get here. return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_exit_and_deep_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_exit_and_deep_sleep_until_alarms); +MP_DEFINE_CONST_FUN_OBJ_KW(alarm_exit_and_deep_sleep_until_alarms_obj, 0, alarm_exit_and_deep_sleep_until_alarms); STATIC const mp_map_elem_t alarm_pin_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pin) }, diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index eb67917dce..82bfae4286 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -30,6 +30,7 @@ #include "py/obj.h" #include "common-hal/alarm/__init__.h" +#include "common-hal/digitalio/DigitalInOut.h" // Light sleep fully self-contained and does not exit user code. It will return // the same alarm object that was orignally passed in, unlike deep sleep, which @@ -42,7 +43,7 @@ extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const // supervisor will idle using `port_wait_for_interrupt`. After each call, it will // call alarm_woken_from_sleep to see if we've been woken by an alarm and if so, // it will exit idle as if deep sleep was exited -extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms); +extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t **preserve_dios); extern NORETURN void common_hal_alarm_enter_deep_sleep(void); @@ -54,7 +55,7 @@ extern void common_hal_alarm_pretending_deep_sleep(void); extern mp_obj_t shared_alarm_get_wake_alarm(void); // Creates a new alarm object after exiting deep sleep (real or fake) -extern mp_obj_t common_hal_alarm_create_wake_alarm(void); +extern mp_obj_t common_hal_alarm_record_wake_alarm(void); // Saves alarm to global array void shared_alarm_save_wake_alarm(mp_obj_t alarm); diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index 06ad77c56d..c75061b77a 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -38,7 +38,9 @@ //| class PinAlarm: //| """Trigger an alarm when a pin changes state.""" //| -//| def __init__(self, pin: microcontroller.Pin, value: bool, edge: bool = False, pull: bool = False) -> None: +//| def __init__( +//| self, pin: microcontroller.Pin, value: bool, edge: bool = False, pull: bool = False +//| ) -> None: //| """Create an alarm triggered by a `microcontroller.Pin` level. The alarm is not active //| until it is passed to an `alarm`-enabling function, such as `alarm.light_sleep_until_alarms()` or //| `alarm.exit_and_deep_sleep_until_alarms()`. @@ -59,7 +61,6 @@ //| pulls it high. //| """ //| ... -//| STATIC mp_obj_t alarm_pin_pinalarm_make_new(const mp_obj_type_t *type, mp_uint_t n_args, size_t n_kw, const mp_obj_t *all_args) { alarm_pin_pinalarm_obj_t *self = m_new_obj(alarm_pin_pinalarm_obj_t); self->base.type = &alarm_pin_pinalarm_type; @@ -73,7 +74,7 @@ STATIC mp_obj_t alarm_pin_pinalarm_make_new(const mp_obj_type_t *type, mp_uint_t mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); common_hal_alarm_pin_pinalarm_construct(self, pin, @@ -86,7 +87,6 @@ STATIC mp_obj_t alarm_pin_pinalarm_make_new(const mp_obj_type_t *type, mp_uint_t //| pin: microcontroller.Pin //| """The trigger pin.""" -//| STATIC mp_obj_t alarm_pin_pinalarm_obj_get_pin(mp_obj_t self_in) { alarm_pin_pinalarm_obj_t *self = MP_OBJ_TO_PTR(self_in); const mcu_pin_obj_t *pin = common_hal_alarm_pin_pinalarm_get_pin(self); diff --git a/shared-bindings/alarm/time/TimeAlarm.c b/shared-bindings/alarm/time/TimeAlarm.c index 0b77913c9b..abbb050c64 100644 --- a/shared-bindings/alarm/time/TimeAlarm.c +++ b/shared-bindings/alarm/time/TimeAlarm.c @@ -44,19 +44,21 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) { //| class TimeAlarm: //| """Trigger an alarm when the specified time is reached.""" //| -//| def __init__(self, monotonic_time: Optional[float] = None, epoch_time: Optional[int] = None) -> None: +//| def __init__( +//| self, monotonic_time: Optional[float] = None, epoch_time: Optional[int] = None +//| ) -> None: //| """Create an alarm that will be triggered when `time.monotonic()` would equal //| ``monotonic_time``, or when `time.time()` would equal ``epoch_time``. //| Only one of the two arguments can be given. //| The alarm is not active until it is passed to an -//| `alarm`-enabling function, such as `alarm.light_sleep_until_alarms()` or +//| `alarm`-enabling sleep function, such as `alarm.light_sleep_until_alarms()` or //| `alarm.exit_and_deep_sleep_until_alarms()`. //| -//| If the given time is in the past when sleep occurs, the alarm will be triggered -//| immediately. +//| If the given time is already in the past, then an exception is raised. +//| If the sleep happens after the given time, then it will wake immediately +//| due to this time alarm. //| """ //| ... -//| STATIC mp_obj_t alarm_time_timealarm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { alarm_time_timealarm_obj_t *self = m_new_obj(alarm_time_timealarm_obj_t); diff --git a/shared-bindings/alarm/touch/TouchAlarm.c b/shared-bindings/alarm/touch/TouchAlarm.c index ce5074f7c0..20612cb106 100644 --- a/shared-bindings/alarm/touch/TouchAlarm.c +++ b/shared-bindings/alarm/touch/TouchAlarm.c @@ -39,9 +39,10 @@ //| //| :param microcontroller.Pin pin: The pin to monitor. On some ports, the choice of pin //| may be limited due to hardware restrictions, particularly for deep-sleep alarms. +//| +//| **Limitations:** Not available on SAMD, nRF, or RP2040. //| """ //| ... -//| STATIC mp_obj_t alarm_touch_touchalarm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { alarm_touch_touchalarm_obj_t *self = m_new_obj(alarm_touch_touchalarm_obj_t); @@ -55,7 +56,7 @@ STATIC mp_obj_t alarm_touch_touchalarm_make_new(const mp_obj_type_t *type, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); common_hal_alarm_touch_touchalarm_construct(self, pin); diff --git a/shared-bindings/analogbufio/BufferedIn.c b/shared-bindings/analogbufio/BufferedIn.c new file mode 100644 index 0000000000..4641df6891 --- /dev/null +++ b/shared-bindings/analogbufio/BufferedIn.c @@ -0,0 +1,172 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2022 Lee Atkinson, MeanStride Technology, Inc. + * + * TODO: Based on analogio/AnalogIn.c from Scott Shaw + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "py/nlr.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/analogbufio/BufferedIn.h" +#include "shared-bindings/util.h" + +//| class BufferedIn: +//| """Capture multiple analog voltage levels to the supplied buffer +//| +//| Usage:: +//| +//| import board +//| import analogbufio +//| import array +//| +//| length = 1000 +//| mybuffer = array.array("H", [0x0000] * length) +//| rate = 500000 +//| adcbuf = analogbufio.BufferedIn(board.GP26, sample_rate=rate) +//| adcbuf.readinto(mybuffer) +//| adcbuf.deinit() +//| for i in range(length): +//| print(i, mybuffer[i]) +//| +//| (TODO) The reference voltage varies by platform so use +//| ``reference_voltage`` to read the configured setting. +//| (TODO) Provide mechanism to read CPU Temperature.""" +//| + +//| def __init__(self, pin: microcontroller.Pin, *, sample_rate: int) -> None: +//| """Create a `BufferedIn` on the given pin and given sample rate. +//| +//| :param ~microcontroller.Pin pin: the pin to read from +//| :param ~int sample_rate: rate: sampling frequency, in samples per second""" +//| ... +STATIC mp_obj_t analogbufio_bufferedin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_pin, ARG_sample_rate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_sample_rate, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Validate Pin + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); + + // Create local object + analogbufio_bufferedin_obj_t *self = m_new_obj_with_finaliser(analogbufio_bufferedin_obj_t); + self->base.type = &analogbufio_bufferedin_type; + + // Call local interface in ports/common-hal/analogbufio + common_hal_analogbufio_bufferedin_construct(self, pin, args[ARG_sample_rate].u_int); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Shut down the `BufferedIn` and release the pin for other use.""" +//| ... +STATIC mp_obj_t analogbufio_bufferedin_deinit(mp_obj_t self_in) { + analogbufio_bufferedin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_analogbufio_bufferedin_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(analogbufio_bufferedin_deinit_obj, analogbufio_bufferedin_deinit); + +STATIC void check_for_deinit(analogbufio_bufferedin_obj_t *self) { + if (common_hal_analogbufio_bufferedin_deinited(self)) { + raise_deinited_error(); + } +} +//| def __enter__(self) -> BufferedIn: +//| """No-op used by Context Managers.""" +//| ... +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +STATIC mp_obj_t analogbufio_bufferedin___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_analogbufio_bufferedin_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogbufio_bufferedin___exit___obj, 4, 4, analogbufio_bufferedin___exit__); + +//| def readinto(self, buffer: WriteableBuffer) -> int: +//| """Fills the provided buffer with ADC voltage values. +//| +//| ADC values will be read into the given buffer at the supplied sample_rate. +//| Depending on the buffer typecode, 'B', 'H', samples are 8-bit byte-arrays or +//| 16-bit half-words and are always unsigned. +//| The ADC most significant bits of the ADC are kept. (See +//| https://docs.circuitpython.org/en/latest/docs/library/array.html) +//| +//| :param ~circuitpython_typing.WriteableBuffer buffer: buffer: A buffer for samples""" +//| ... +//| +STATIC mp_obj_t analogbufio_bufferedin_obj_readinto(mp_obj_t self_in, mp_obj_t buffer_obj) { + analogbufio_bufferedin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + // Buffer defined and allocated by user + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buffer_obj, &bufinfo, MP_BUFFER_READ); + + uint8_t bytes_per_sample = 1; + + // Bytes Per Sample + if (bufinfo.typecode == 'H') { + bytes_per_sample = 2; + } else if (bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE) { + mp_raise_ValueError_varg(translate("%q must be a bytearray or array of type 'H' or 'B'"), MP_QSTR_buffer); + } + + mp_uint_t captured = common_hal_analogbufio_bufferedin_readinto(self, bufinfo.buf, bufinfo.len, bytes_per_sample); + return MP_OBJ_NEW_SMALL_INT(captured); +} +MP_DEFINE_CONST_FUN_OBJ_2(analogbufio_bufferedin_readinto_obj, analogbufio_bufferedin_obj_readinto); + +STATIC const mp_rom_map_elem_t analogbufio_bufferedin_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&analogbufio_bufferedin_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&analogbufio_bufferedin_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&analogbufio_bufferedin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&analogbufio_bufferedin_readinto_obj)}, + +}; + +STATIC MP_DEFINE_CONST_DICT(analogbufio_bufferedin_locals_dict, analogbufio_bufferedin_locals_dict_table); + +const mp_obj_type_t analogbufio_bufferedin_type = { + { &mp_type_type }, + .name = MP_QSTR_BufferedIn, + .make_new = analogbufio_bufferedin_make_new, + .locals_dict = (mp_obj_t)&analogbufio_bufferedin_locals_dict, +}; diff --git a/shared-bindings/analogbufio/BufferedIn.h b/shared-bindings/analogbufio/BufferedIn.h new file mode 100644 index 0000000000..cfd8050bc5 --- /dev/null +++ b/shared-bindings/analogbufio/BufferedIn.h @@ -0,0 +1,40 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2022 Lee Atkinson, MeanStride Technology, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGBUFIO_BUFFEREDIN_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGBUFIO_BUFFEREDIN_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/analogbufio/BufferedIn.h" + +extern const mp_obj_type_t analogbufio_bufferedin_type; + +void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *self, const mcu_pin_obj_t *pin, uint32_t sample_rate); +void common_hal_analogbufio_bufferedin_deinit(analogbufio_bufferedin_obj_t *self); +bool common_hal_analogbufio_bufferedin_deinited(analogbufio_bufferedin_obj_t *self); +uint32_t common_hal_analogbufio_bufferedin_readinto(analogbufio_bufferedin_obj_t *self, uint8_t *buffer, uint32_t len, uint8_t bytes_per_sample); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGBUFIO_BUFFEREDIN_H__ diff --git a/shared-bindings/analogbufio/__init__.c b/shared-bindings/analogbufio/__init__.c new file mode 100644 index 0000000000..749f1aec09 --- /dev/null +++ b/shared-bindings/analogbufio/__init__.c @@ -0,0 +1,62 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2022 Lee Atkinson, MeanStride Technology, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include "py/obj.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/analogbufio/__init__.h" +#include "shared-bindings/analogbufio/BufferedIn.h" + +//| """Analog Buffered IO Hardware Support +//| +//| The `analogbufio` module contains classes to provide access to analog-to-digital +//| conversion and digital-to-analog (DAC) for multiple value transfer. +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| TODO: For the essentials of `analogbufio`, see the `CircuitPython Essentials +//| Learn guide `_ +//| +//| TODO: For more information on using `analogbufio`, see `this additional Learn guide +//| `_ +//| """ + +STATIC const mp_rom_map_elem_t analogbufio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_analogbufio) }, + { MP_ROM_QSTR(MP_QSTR_BufferedIn), MP_ROM_PTR(&analogbufio_bufferedin_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(analogbufio_module_globals, analogbufio_module_globals_table); + +const mp_obj_module_t analogbufio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&analogbufio_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_analogbufio, analogbufio_module, CIRCUITPY_ANALOGBUFIO); diff --git a/ports/espressif/supervisor/esp_port.h b/shared-bindings/analogbufio/__init__.h similarity index 78% rename from ports/espressif/supervisor/esp_port.h rename to shared-bindings/analogbufio/__init__.h index 90ba3f65f1..d66dd4e8d6 100644 --- a/ports/espressif/supervisor/esp_port.h +++ b/shared-bindings/analogbufio/__init__.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * SPDX-FileCopyrightText: Copyright (c) 2022 Lee Atkinson, MeanStride Technology, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,12 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ESPRESSIF_SUPERVISOR_PORT_H -#define MICROPY_INCLUDED_ESPRESSIF_SUPERVISOR_PORT_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGBUFIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGBUFIO___INIT___H -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" +#include "py/obj.h" -extern TaskHandle_t circuitpython_task; +// Nothing now. -#endif // MICROPY_INCLUDED_ESPRESSIF_SUPERVISOR_PORT_H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGBUFIO___INIT___H diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c index f2c888f727..3b71f688c8 100644 --- a/shared-bindings/analogio/AnalogIn.c +++ b/shared-bindings/analogio/AnalogIn.c @@ -36,6 +36,10 @@ #include "shared-bindings/analogio/AnalogIn.h" #include "shared-bindings/util.h" +MP_WEAK const mcu_pin_obj_t *common_hal_analogio_analogin_validate_pin(mp_obj_t obj) { + return validate_obj_is_free_pin(obj, MP_QSTR_pin); +} + //| class AnalogIn: //| """Read analog voltage levels //| @@ -54,15 +58,13 @@ //| //| :param ~microcontroller.Pin pin: the pin to read from""" //| ... -//| STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, size_t n_kw, const mp_obj_t *args) { // check number of arguments mp_arg_check_num(n_args, n_kw, 1, 1, false); // 1st argument is the pin - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]); - + const mcu_pin_obj_t *pin = common_hal_analogio_analogin_validate_pin(args[0]); analogio_analogin_obj_t *self = m_new_obj(analogio_analogin_obj_t); self->base.type = &analogio_analogin_type; common_hal_analogio_analogin_construct(self, pin); @@ -73,7 +75,6 @@ STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, //| def deinit(self) -> None: //| """Turn off the AnalogIn and release the pin for other use.""" //| ... -//| STATIC mp_obj_t analogio_analogin_deinit(mp_obj_t self_in) { analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_analogio_analogin_deinit(self); @@ -89,14 +90,12 @@ STATIC void check_for_deinit(analogio_analogin_obj_t *self) { //| def __enter__(self) -> AnalogIn: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t analogio_analogin___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_analogio_analogin_deinit(args[0]); @@ -109,7 +108,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogin___exit___obj, 4, 4, //| //| Even if the underlying analog to digital converter (ADC) is lower //| resolution, the value is 16-bit.""" -//| STATIC mp_obj_t analogio_analogin_obj_get_value(mp_obj_t self_in) { analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -122,7 +120,7 @@ MP_PROPERTY_GETTER(analogio_analogin_value_obj, //| reference_voltage: float //| """The maximum voltage measurable (also known as the reference voltage) as a -//| `float` in Volts. Note the ADC value may not scale to the actual voltage linearly +//| ``float`` in Volts. Note the ADC value may not scale to the actual voltage linearly //| at ends of the analog range.""" //| STATIC mp_obj_t analogio_analogin_obj_get_reference_voltage(mp_obj_t self_in) { diff --git a/shared-bindings/analogio/AnalogIn.h b/shared-bindings/analogio/AnalogIn.h index 9f80416267..7d667ed3f4 100644 --- a/shared-bindings/analogio/AnalogIn.h +++ b/shared-bindings/analogio/AnalogIn.h @@ -32,6 +32,7 @@ extern const mp_obj_type_t analogio_analogin_type; +const mcu_pin_obj_t *common_hal_analogio_analogin_validate_pin(mp_obj_t obj); void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const mcu_pin_obj_t *pin); void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self); bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self); diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c index 41c9b053eb..6b10d37571 100644 --- a/shared-bindings/analogio/AnalogOut.c +++ b/shared-bindings/analogio/AnalogOut.c @@ -39,6 +39,9 @@ //| class AnalogOut: //| """Output analog values (a specific voltage). //| +//| **Limitations:** Not available on nRF, RP2040, Spresense, as there is no on-chip DAC. +//| On Espressif, available only on ESP32 and ESP32-S2; other chips do not have a DAC. +//| //| Example usage:: //| //| import analogio @@ -50,14 +53,15 @@ //| def __init__(self, pin: microcontroller.Pin) -> None: //| """Use the AnalogOut on the given pin. //| -//| :param ~microcontroller.Pin pin: the pin to output to""" -//| ... +//| :param ~microcontroller.Pin pin: the pin to output to //| +//| """ +//| ... STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t n_args, size_t n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 1, 1, false); - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0], MP_QSTR_pin); analogio_analogout_obj_t *self = m_new_obj(analogio_analogout_obj_t); self->base.type = &analogio_analogout_type; @@ -69,7 +73,6 @@ STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t //| def deinit(self) -> None: //| """Turn off the AnalogOut and release the pin for other use.""" //| ... -//| STATIC mp_obj_t analogio_analogout_deinit(mp_obj_t self_in) { analogio_analogout_obj_t *self = self_in; @@ -82,14 +85,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogout_deinit_obj, analogio_analogo //| def __enter__(self) -> AnalogOut: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t analogio_analogout___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_analogio_analogout_deinit(args[0]); diff --git a/shared-bindings/analogio/__init__.c b/shared-bindings/analogio/__init__.c index eb956d0eb7..2e7ccf7115 100644 --- a/shared-bindings/analogio/__init__.c +++ b/shared-bindings/analogio/__init__.c @@ -65,7 +65,6 @@ //| For more information on using `analogio`, see `this additional Learn guide //| `_ //| """ -//| STATIC const mp_rom_map_elem_t analogio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_analogio) }, diff --git a/shared-bindings/atexit/__init__.c b/shared-bindings/atexit/__init__.c index dd27adaa98..9a91e0bc80 100644 --- a/shared-bindings/atexit/__init__.c +++ b/shared-bindings/atexit/__init__.c @@ -39,20 +39,21 @@ //| ... //| -//| def register(func: Callable[..., Any], *args: Optional[Any], **kwargs: Optional[Any]) -> Callable[..., Any]: -//| +//| def register( +//| func: Callable[..., Any], *args: Optional[Any], **kwargs: Optional[Any] +//| ) -> Callable[..., Any]: //| """Register func as a function to be executed at termination. //| -//| Any optional arguments that are to be passed to func must be passed as arguments to `register()`. -//| It is possible to register the same function and arguments more than once. +//| Any optional arguments that are to be passed to func must be passed as arguments to `register()`. +//| It is possible to register the same function and arguments more than once. //| -//| At normal program termination (for instance, if `sys.exit()` is called or the vm execution completes), -//| all functions registered are called in last in, first out order. +//| At normal program termination (for instance, if `sys.exit()` is called or the vm execution completes), +//| all functions registered are called in last in, first out order. //| -//| If an exception is raised during execution of the exit handler, -//| a traceback is printed (unless `SystemExit` is raised) and the execution stops. +//| If an exception is raised during execution of the exit handler, +//| a traceback is printed (unless `SystemExit` is raised) and the execution stops. //| -//| This function returns func, which makes it possible to use it as a decorator. +//| This function returns func, which makes it possible to use it as a decorator. //| //| """ //| ... @@ -64,11 +65,10 @@ STATIC mp_obj_t atexit_register(size_t n_args, const mp_obj_t *pos_args, mp_map_ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(atexit_register_obj, 1, atexit_register); //| def unregister(func: Callable[..., Any]) -> None: -//| //| """Remove func from the list of functions to be run at termination. //| -//| `unregister()` silently does nothing if func was not previously registered. If func has been registered more than once, -//| every occurrence of that function in the atexit call stack will be removed. +//| `unregister()` silently does nothing if func was not previously registered. If func has been registered more than once, +//| every occurrence of that function in the atexit call stack will be removed. //| //| """ //| ... diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c index 7c660abc4a..3713caeb7b 100644 --- a/shared-bindings/audiobusio/I2SOut.c +++ b/shared-bindings/audiobusio/I2SOut.c @@ -38,7 +38,14 @@ //| class I2SOut: //| """Output an I2S audio signal""" //| -//| def __init__(self, bit_clock: microcontroller.Pin, word_select: microcontroller.Pin, data: microcontroller.Pin, *, left_justified: bool) -> None: +//| def __init__( +//| self, +//| bit_clock: microcontroller.Pin, +//| word_select: microcontroller.Pin, +//| data: microcontroller.Pin, +//| *, +//| left_justified: bool +//| ) -> None: //| """Create a I2SOut object associated with the given pins. //| //| :param ~microcontroller.Pin bit_clock: The bit clock (or serial clock) pin @@ -88,7 +95,6 @@ //| pass //| print("stopped")""" //| ... -//| STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if !CIRCUITPY_AUDIOBUSIO_I2SOUT mp_raise_NotImplementedError(translate("I2SOut not available")); @@ -104,9 +110,9 @@ STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *bit_clock = validate_obj_is_free_pin(args[ARG_bit_clock].u_obj); - const mcu_pin_obj_t *word_select = validate_obj_is_free_pin(args[ARG_word_select].u_obj); - const mcu_pin_obj_t *data = validate_obj_is_free_pin(args[ARG_data].u_obj); + const mcu_pin_obj_t *bit_clock = validate_obj_is_free_pin(args[ARG_bit_clock].u_obj, MP_QSTR_bit_clock); + const mcu_pin_obj_t *word_select = validate_obj_is_free_pin(args[ARG_word_select].u_obj, MP_QSTR_word_select); + const mcu_pin_obj_t *data = validate_obj_is_free_pin(args[ARG_data].u_obj, MP_QSTR_data); audiobusio_i2sout_obj_t *self = m_new_obj_with_finaliser(audiobusio_i2sout_obj_t); self->base.type = &audiobusio_i2sout_type; @@ -121,7 +127,6 @@ STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a //| def deinit(self) -> None: //| """Deinitialises the I2SOut and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t audiobusio_i2sout_deinit(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiobusio_i2sout_deinit(self); @@ -138,14 +143,12 @@ STATIC void check_for_deinit(audiobusio_i2sout_obj_t *self) { //| def __enter__(self) -> I2SOut: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t audiobusio_i2sout_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audiobusio_i2sout_deinit(args[0]); @@ -162,7 +165,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_i2sout___exit___obj, 4, 4, //| //| The sample itself should consist of 8 bit or 16 bit samples.""" //| ... -//| STATIC mp_obj_t audiobusio_i2sout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -184,7 +186,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiobusio_i2sout_play_obj, 1, audiobusio_i2sout_obj_ //| def stop(self) -> None: //| """Stops playback.""" //| ... -//| STATIC mp_obj_t audiobusio_i2sout_obj_stop(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -195,7 +196,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_stop_obj, audiobusio_i2sout_obj_stop //| playing: bool //| """True when the audio sample is being output. (read-only)""" -//| STATIC mp_obj_t audiobusio_i2sout_obj_get_playing(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -209,7 +209,6 @@ MP_PROPERTY_GETTER(audiobusio_i2sout_playing_obj, //| def pause(self) -> None: //| """Stops playback temporarily while remembering the position. Use `resume` to resume playback.""" //| ... -//| STATIC mp_obj_t audiobusio_i2sout_obj_pause(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -225,7 +224,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_pause_obj, audiobusio_i2sout_obj_pau //| def resume(self) -> None: //| """Resumes sample playback after :py:func:`pause`.""" //| ... -//| STATIC mp_obj_t audiobusio_i2sout_obj_resume(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index 29752a442c..b6a316fadb 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -39,7 +39,17 @@ //| class PDMIn: //| """Record an input PDM audio stream""" //| -//| def __init__(self, clock_pin: microcontroller.Pin, data_pin: microcontroller.Pin, *, sample_rate: int = 16000, bit_depth: int = 8, mono: bool = True, oversample: int = 64, startup_delay: float = 0.11) -> None: +//| def __init__( +//| self, +//| clock_pin: microcontroller.Pin, +//| data_pin: microcontroller.Pin, +//| *, +//| sample_rate: int = 16000, +//| bit_depth: int = 8, +//| mono: bool = True, +//| oversample: int = 64, +//| startup_delay: float = 0.11 +//| ) -> None: //| """Create a PDMIn object associated with the given pins. This allows you to //| record audio signals from the given pins. Individual ports may put further //| restrictions on the recording parameters. The overall sample rate is @@ -55,10 +65,13 @@ //| :param int oversample: Number of single bit samples to decimate into a final sample. Must be divisible by 8 //| :param float startup_delay: seconds to wait after starting microphone clock //| to allow microphone to turn on. Most require only 0.01s; some require 0.1s. Longer is safer. -//| Must be in range 0.0-1.0 seconds.""" +//| Must be in range 0.0-1.0 seconds. //| - -//| """Record 8-bit unsigned samples to buffer:: +//| **Limitations:** On SAMD and RP2040, supports only 8 or 16 bit mono input, with 64x oversampling. +//| On nRF52840, supports only 16 bit mono input at 16 kHz; oversampling is fixed at 64x. Not provided +//| on nRF52833 for space reasons. Not available on Espressif. +//| +//| For example, to record 8-bit unsigned samples to a buffer:: //| //| import audiobusio //| import board @@ -68,21 +81,17 @@ //| with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000) as mic: //| mic.record(b, len(b)) //| -//| Record 16-bit unsigned samples to buffer:: +//| To record 16-bit unsigned samples to a buffer:: //| //| import audiobusio //| import board //| -//| # Prep a buffer to record into. The array interface doesn't allow for -//| # constructing with a set size so we append to it until we have the size -//| # we want. -//| b = array.array("H") -//| for i in range(200): -//| b.append(0) +//| # Prep a buffer to record into. +//| b = array.array("H", [0] * 200) //| with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16) as mic: -//| mic.record(b, len(b))""" -//| ... -//| +//| mic.record(b, len(b)) +//| """ +//| ... STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if !CIRCUITPY_AUDIOBUSIO_PDMIN mp_raise_NotImplementedError(translate("PDMIn not available")); @@ -103,8 +112,8 @@ STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *clock_pin = validate_obj_is_free_pin(args[ARG_clock_pin].u_obj); - const mcu_pin_obj_t *data_pin = validate_obj_is_free_pin(args[ARG_data_pin].u_obj); + const mcu_pin_obj_t *clock_pin = validate_obj_is_free_pin(args[ARG_clock_pin].u_obj, MP_QSTR_clock_pin); + const mcu_pin_obj_t *data_pin = validate_obj_is_free_pin(args[ARG_data_pin].u_obj, MP_QSTR_data_pin); // create PDMIn object from the given pin audiobusio_pdmin_obj_t *self = m_new_obj(audiobusio_pdmin_obj_t); @@ -142,7 +151,6 @@ STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the PDMIn and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t audiobusio_pdmin_deinit(mp_obj_t self_in) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiobusio_pdmin_deinit(self); @@ -158,13 +166,11 @@ STATIC void check_for_deinit(audiobusio_pdmin_obj_t *self) { //| def __enter__(self) -> PDMIn: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context.""" //| ... -//| STATIC mp_obj_t audiobusio_pdmin_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audiobusio_pdmin_deinit(args[0]); @@ -184,14 +190,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_pdmin___exit___obj, 4, 4, //| :return: The number of samples recorded. If this is less than ``destination_length``, //| some samples were missed due to processing time.""" //| ... -//| STATIC mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destination, mp_obj_t destination_length) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_obj); check_for_deinit(self); - if (!mp_obj_is_small_int(destination_length) || MP_OBJ_SMALL_INT_VALUE(destination_length) < 0) { - mp_raise_TypeError(translate("destination_length must be an int >= 0")); - } - uint32_t length = MP_OBJ_SMALL_INT_VALUE(destination_length); + uint32_t length = mp_arg_validate_type_int(destination_length, MP_QSTR_length); + mp_arg_validate_length_min(length, 0, MP_QSTR_length); mp_buffer_info_t bufinfo; if (mp_obj_is_type(destination, &mp_type_fileio)) { diff --git a/shared-bindings/audiobusio/__init__.c b/shared-bindings/audiobusio/__init__.c index 34ce9ef696..937028ee1f 100644 --- a/shared-bindings/audiobusio/__init__.c +++ b/shared-bindings/audiobusio/__init__.c @@ -44,7 +44,6 @@ //| All classes change hardware state and should be deinitialized when they //| are no longer needed. To do so, either call :py:meth:`!deinit` or use a //| context manager.""" -//| STATIC const mp_rom_map_elem_t audiobusio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiobusio) }, diff --git a/shared-bindings/audiocore/RawSample.c b/shared-bindings/audiocore/RawSample.c index 02d4bbaa2f..d185476f03 100644 --- a/shared-bindings/audiocore/RawSample.c +++ b/shared-bindings/audiocore/RawSample.c @@ -37,7 +37,9 @@ //| class RawSample: //| """A raw audio sample buffer in memory""" //| -//| def __init__(self, buffer: ReadableBuffer, *, channel_count: int = 1, sample_rate: int = 8000) -> None: +//| def __init__( +//| self, buffer: ReadableBuffer, *, channel_count: int = 1, sample_rate: int = 8000 +//| ) -> None: //| """Create a RawSample based on the given buffer of signed values. If channel_count is more than //| 1 then each channel's samples should alternate. In other words, for a two channel buffer, the //| first sample will be for channel 1, the second sample will be for channel two, the third for @@ -68,7 +70,6 @@ //| time.sleep(1) //| dac.stop()""" //| ... -//| STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_buffer, ARG_channel_count, ARG_sample_rate }; static const mp_arg_t allowed_args[] = { @@ -88,7 +89,7 @@ STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_a if (bufinfo.typecode == 'h' || bufinfo.typecode == 'H') { bytes_per_sample = 2; } else if (bufinfo.typecode != 'b' && bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE) { - mp_raise_ValueError(translate("sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or 'B'")); + mp_raise_ValueError_varg(translate("%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'"), MP_QSTR_buffer); } common_hal_audioio_rawsample_construct(self, ((uint8_t *)bufinfo.buf), bufinfo.len, bytes_per_sample, signed_samples, args[ARG_channel_count].u_int, @@ -100,7 +101,6 @@ STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_a //| def deinit(self) -> None: //| """Deinitialises the RawSample and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t audioio_rawsample_deinit(mp_obj_t self_in) { audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audioio_rawsample_deinit(self); @@ -117,14 +117,12 @@ STATIC void check_for_deinit(audioio_rawsample_obj_t *self) { //| def __enter__(self) -> RawSample: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t audioio_rawsample_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audioio_rawsample_deinit(args[0]); diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c index b1c51a9746..36204fa2b2 100644 --- a/shared-bindings/audiocore/WaveFile.c +++ b/shared-bindings/audiocore/WaveFile.c @@ -40,16 +40,15 @@ //| be 8 bit unsigned or 16 bit signed. If a buffer is provided, it will be used instead of allocating //| an internal buffer, which can prevent memory fragmentation.""" //| -//| def __init__(self, file: typing.BinaryIO, buffer: WriteableBuffer) -> None: +//| def __init__(self, file: Union[str, typing.BinaryIO], buffer: WriteableBuffer) -> None: //| """Load a .wav file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`. //| -//| :param typing.BinaryIO file: Already opened wave file +//| :param Union[str, typing.BinaryIO] file: The name of a wave file (preferred) or an already opened wave file //| :param ~circuitpython_typing.WriteableBuffer buffer: Optional pre-allocated buffer, //| that will be split in half and used for double-buffering of the data. //| The buffer must be 8 to 1024 bytes long. //| If not provided, two 256 byte buffers are initially allocated internally. //| -//| //| Playing a wave file from flash:: //| //| import board @@ -61,23 +60,27 @@ //| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) //| speaker_enable.switch_to_output(value=True) //| -//| data = open("cplay-5.1-16bit-16khz.wav", "rb") -//| wav = audiocore.WaveFile(data) +//| wav = audiocore.WaveFile("cplay-5.1-16bit-16khz.wav") //| a = audioio.AudioOut(board.A0) //| //| print("playing") //| a.play(wav) //| while a.playing: //| pass -//| print("stopped")""" +//| print("stopped") +//| """ //| ... -//| STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 2, false); + mp_obj_t arg = args[0]; + + if (mp_obj_is_str(arg)) { + arg = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), arg, MP_ROM_QSTR(MP_QSTR_rb)); + } audioio_wavefile_obj_t *self = m_new_obj(audioio_wavefile_obj_t); self->base.type = &audioio_wavefile_type; - if (!mp_obj_is_type(args[0], &mp_type_fileio)) { + if (!mp_obj_is_type(arg, &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); } uint8_t *buffer = NULL; @@ -88,7 +91,7 @@ STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_ar buffer = bufinfo.buf; buffer_size = mp_arg_validate_length_range(bufinfo.len, 8, 1024, MP_QSTR_buffer); } - common_hal_audioio_wavefile_construct(self, MP_OBJ_TO_PTR(args[0]), + common_hal_audioio_wavefile_construct(self, MP_OBJ_TO_PTR(arg), buffer, buffer_size); return MP_OBJ_FROM_PTR(self); @@ -113,14 +116,12 @@ STATIC void check_for_deinit(audioio_wavefile_obj_t *self) { //| def __enter__(self) -> WaveFile: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t audioio_wavefile_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audioio_wavefile_deinit(args[0]); @@ -132,7 +133,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_wavefile___exit___obj, 4, 4, //| """32 bit value that dictates how quickly samples are loaded into the DAC //| in Hertz (cycles per second). When the sample is looped, this can change //| the pitch output without changing the underlying sample.""" -//| STATIC mp_obj_t audioio_wavefile_obj_get_sample_rate(mp_obj_t self_in) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -154,7 +154,6 @@ MP_PROPERTY_GETSET(audioio_wavefile_sample_rate_obj, //| bits_per_sample: int //| """Bits per sample. (read only)""" -//| STATIC mp_obj_t audioio_wavefile_obj_get_bits_per_sample(mp_obj_t self_in) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/audiocore/__init__.c b/shared-bindings/audiocore/__init__.c index f03c64ccf8..2e3b479cf6 100644 --- a/shared-bindings/audiocore/__init__.c +++ b/shared-bindings/audiocore/__init__.c @@ -36,7 +36,6 @@ // #include "shared-bindings/audiomixer/Mixer.h" //| """Support for audio samples""" -//| STATIC const mp_rom_map_elem_t audiocore_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiocore) }, diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index 75ba7b5ec5..7909176114 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -39,7 +39,13 @@ //| class AudioOut: //| """Output an analog audio signal""" //| -//| def __init__(self, left_channel: microcontroller.Pin, *, right_channel: Optional[microcontroller.Pin] = None, quiescent_value: int = 0x8000) -> None: +//| def __init__( +//| self, +//| left_channel: microcontroller.Pin, +//| *, +//| right_channel: Optional[microcontroller.Pin] = None, +//| quiescent_value: int = 0x8000 +//| ) -> None: //| """Create a AudioOut object associated with the given pin(s). This allows you to //| play audio signals out on the given pin(s). //| @@ -89,7 +95,6 @@ //| pass //| print("stopped")""" //| ... -//| STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_left_channel, ARG_right_channel, ARG_quiescent_value }; static const mp_arg_t allowed_args[] = { @@ -100,8 +105,10 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *left_channel_pin = validate_obj_is_free_pin(args[ARG_left_channel].u_obj); - const mcu_pin_obj_t *right_channel_pin = validate_obj_is_free_pin_or_none(args[ARG_right_channel].u_obj); + const mcu_pin_obj_t *left_channel_pin = + validate_obj_is_free_pin(args[ARG_left_channel].u_obj, MP_QSTR_left_channel); + const mcu_pin_obj_t *right_channel_pin = + validate_obj_is_free_pin_or_none(args[ARG_right_channel].u_obj, MP_QSTR_right_channel); // create AudioOut object from the given pin audioio_audioout_obj_t *self = m_new_obj(audioio_audioout_obj_t); @@ -114,7 +121,6 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the AudioOut and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t audioio_audioout_deinit(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audioio_audioout_deinit(self); @@ -130,14 +136,12 @@ STATIC void check_for_deinit(audioio_audioout_obj_t *self) { //| def __enter__(self) -> AudioOut: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t audioio_audioout_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audioio_audioout_deinit(args[0]); @@ -156,7 +160,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_audioout___exit___obj, 4, 4, //| resolution will use the highest order bits to output. For example, the SAMD21 has a 10 bit //| DAC that ignores the lowest 6 bits when playing 16 bit samples.""" //| ... -//| STATIC mp_obj_t audioio_audioout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -178,7 +181,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audioio_audioout_play_obj, 1, audioio_audioout_obj_pl //| def stop(self) -> None: //| """Stops playback and resets to the start of the sample.""" //| ... -//| STATIC mp_obj_t audioio_audioout_obj_stop(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -189,7 +191,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_stop_obj, audioio_audioout_obj_stop); //| playing: bool //| """True when an audio sample is being output even if `paused`. (read-only)""" -//| STATIC mp_obj_t audioio_audioout_obj_get_playing(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -203,7 +204,6 @@ MP_PROPERTY_GETTER(audioio_audioout_playing_obj, //| def pause(self) -> None: //| """Stops playback temporarily while remembering the position. Use `resume` to resume playback.""" //| ... -//| STATIC mp_obj_t audioio_audioout_obj_pause(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -219,7 +219,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_pause_obj, audioio_audioout_obj_pause //| def resume(self) -> None: //| """Resumes sample playback after :py:func:`pause`.""" //| ... -//| STATIC mp_obj_t audioio_audioout_obj_resume(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c index 9f8411f484..b76b534a7d 100644 --- a/shared-bindings/audioio/__init__.c +++ b/shared-bindings/audioio/__init__.c @@ -42,13 +42,16 @@ //| call :py:meth:`!deinit` or use a context manager. See //| :ref:`lifetime-and-contextmanagers` for more info. //| +//| For more information on working with this module, refer to the +//| `CircuitPython Essentials Learn Guide +//| `_. +//| //| Since CircuitPython 5, `RawSample` and `WaveFile` are moved //| to :mod:`audiocore`, and `Mixer` is moved to :mod:`audiomixer`. //| //| For compatibility with CircuitPython 4.x, some builds allow the items in //| `audiocore` to be imported from `audioio`. This will be removed for all //| boards in a future build of CircuitPython.""" -//| STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audioio) }, diff --git a/shared-bindings/audiomixer/Mixer.c b/shared-bindings/audiomixer/Mixer.c index 47dbd94f19..58c618fc11 100644 --- a/shared-bindings/audiomixer/Mixer.c +++ b/shared-bindings/audiomixer/Mixer.c @@ -41,7 +41,15 @@ //| class Mixer: //| """Mixes one or more audio samples together into one sample.""" //| -//| def __init__(self, voice_count: int = 2, buffer_size: int = 1024, channel_count: int = 2, bits_per_sample: int = 16, samples_signed: bool = True, sample_rate: int = 8000) -> None: +//| def __init__( +//| self, +//| voice_count: int = 2, +//| buffer_size: int = 1024, +//| channel_count: int = 2, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| sample_rate: int = 8000, +//| ) -> None: //| """Create a Mixer object that can mix multiple channels with the same sample rate. //| Samples are accessed and controlled with the mixer's `audiomixer.MixerVoice` objects. //| @@ -77,7 +85,6 @@ //| time.sleep(1) //| print("stopped")""" //| ... -//| STATIC mp_obj_t audiomixer_mixer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_voice_count, ARG_buffer_size, ARG_channel_count, ARG_bits_per_sample, ARG_samples_signed, ARG_sample_rate }; static const mp_arg_t allowed_args[] = { @@ -114,7 +121,6 @@ STATIC mp_obj_t audiomixer_mixer_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the Mixer and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t audiomixer_mixer_deinit(mp_obj_t self_in) { audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiomixer_mixer_deinit(self); @@ -131,14 +137,12 @@ STATIC void check_for_deinit(audiomixer_mixer_obj_t *self) { //| def __enter__(self) -> Mixer: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t audiomixer_mixer_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audiomixer_mixer_deinit(args[0]); @@ -148,7 +152,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomixer_mixer___exit___obj, 4, 4, //| playing: bool //| """True when any voice is being output. (read-only)""" -//| STATIC mp_obj_t audiomixer_mixer_obj_get_playing(mp_obj_t self_in) { audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -161,7 +164,6 @@ MP_PROPERTY_GETTER(audiomixer_mixer_playing_obj, //| sample_rate: int //| """32 bit value that dictates how quickly samples are played in Hertz (cycles per second).""" -//| STATIC mp_obj_t audiomixer_mixer_obj_get_sample_rate(mp_obj_t self_in) { audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -189,7 +191,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_get_voice_obj, audiomixer_mixer_obj_g MP_PROPERTY_GETTER(audiomixer_mixer_voice_obj, (mp_obj_t)&audiomixer_mixer_get_voice_obj); -//| def play(self, sample: circuitpython_typing.AudioSample, *, voice: int = 0, loop: bool = False) -> None: +//| def play( +//| self, sample: circuitpython_typing.AudioSample, *, voice: int = 0, loop: bool = False +//| ) -> None: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| @@ -197,7 +201,6 @@ MP_PROPERTY_GETTER(audiomixer_mixer_voice_obj, //| //| The sample must match the Mixer's encoding settings given in the constructor.""" //| ... -//| STATIC mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_voice, ARG_loop }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c index f7bf16fb49..16a1be520f 100644 --- a/shared-bindings/audiomixer/MixerVoice.c +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -45,7 +45,6 @@ //| def __init__(self) -> None: //| """MixerVoice instance object(s) created by `audiomixer.Mixer`.""" //| ... -//| // TODO: support mono or stereo voices STATIC mp_obj_t audiomixer_mixervoice_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 0, 0, false); @@ -63,9 +62,9 @@ STATIC mp_obj_t audiomixer_mixervoice_make_new(const mp_obj_type_t *type, size_t //| //| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, `audiomixer.Mixer` or `audiomp3.MP3Decoder`. //| -//| The sample must match the `audiomixer.Mixer`'s encoding settings given in the constructor.""" +//| The sample must match the `audiomixer.Mixer`'s encoding settings given in the constructor. +//| """ //| ... -//| STATIC mp_obj_t audiomixer_mixervoice_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -85,7 +84,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_play_obj, 1, audiomixer_mixervo //| def stop(self) -> None: //| """Stops playback of the sample on this voice.""" //| ... -//| STATIC mp_obj_t audiomixer_mixervoice_obj_stop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_voice }; static const mp_arg_t allowed_args[] = { @@ -103,7 +101,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_stop_obj, 1, audiomixer_mixervo //| level: float //| """The volume level of a voice, as a floating point number between 0 and 1.""" -//| STATIC mp_obj_t audiomixer_mixervoice_obj_get_level(mp_obj_t self_in) { return mp_obj_new_float(common_hal_audiomixer_mixervoice_get_level(self_in)); } diff --git a/shared-bindings/audiomixer/__init__.c b/shared-bindings/audiomixer/__init__.c index a29d4f18ef..8292be9e95 100644 --- a/shared-bindings/audiomixer/__init__.c +++ b/shared-bindings/audiomixer/__init__.c @@ -33,7 +33,6 @@ #include "shared-bindings/audiomixer/Mixer.h" //| """Support for audio mixing""" -//| STATIC const mp_rom_map_elem_t audiomixer_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiomixer) }, diff --git a/shared-bindings/audiomp3/MP3Decoder.c b/shared-bindings/audiomp3/MP3Decoder.c index 8251b26c73..68e78cb0d5 100644 --- a/shared-bindings/audiomp3/MP3Decoder.c +++ b/shared-bindings/audiomp3/MP3Decoder.c @@ -44,11 +44,10 @@ //| https://learn.adafruit.com/Memory-saving-tips-for-CircuitPython/reducing-memory-fragmentation //| """ //| -//| def __init__(self, file: typing.BinaryIO, buffer: WriteableBuffer) -> None: -//| +//| def __init__(self, file: Union[str, typing.BinaryIO], buffer: WriteableBuffer) -> None: //| """Load a .mp3 file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`. //| -//| :param typing.BinaryIO file: Already opened mp3 file +//| :param Union[str, typing.BinaryIO] file: The name of a mp3 file (preferred) or an already opened mp3 file //| :param ~circuitpython_typing.WriteableBuffer buffer: Optional pre-allocated buffer, that will be split in half and used for double-buffering of the data. If not provided, two buffers are allocated internally. The specific buffer size required depends on the mp3 file. //| //| Playback of mp3 audio is CPU intensive, and the @@ -77,23 +76,28 @@ //| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) //| speaker_enable.switch_to_output(value=True) //| -//| data = open("cplay-16bit-16khz-64kbps.mp3", "rb") -//| mp3 = audiomp3.MP3Decoder(data) +//| mp3 = audiomp3.MP3Decoder("cplay-16bit-16khz-64kbps.mp3") //| a = audioio.AudioOut(board.A0) //| //| print("playing") //| a.play(mp3) //| while a.playing: //| pass -//| print("stopped")""" +//| print("stopped") +//| """ //| ... -//| + STATIC mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 2, false); + mp_obj_t arg = args[0]; + + if (mp_obj_is_str(arg)) { + arg = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), arg, MP_ROM_QSTR(MP_QSTR_rb)); + } audiomp3_mp3file_obj_t *self = m_new_obj(audiomp3_mp3file_obj_t); self->base.type = &audiomp3_mp3file_type; - if (!mp_obj_is_type(args[0], &mp_type_fileio)) { + if (!mp_obj_is_type(arg, &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); } uint8_t *buffer = NULL; @@ -104,7 +108,7 @@ STATIC mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_ar buffer = bufinfo.buf; buffer_size = bufinfo.len; } - common_hal_audiomp3_mp3file_construct(self, MP_OBJ_TO_PTR(args[0]), + common_hal_audiomp3_mp3file_construct(self, MP_OBJ_TO_PTR(arg), buffer, buffer_size); return MP_OBJ_FROM_PTR(self); @@ -113,7 +117,6 @@ STATIC mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the MP3 and releases all memory resources for reuse.""" //| ... -//| STATIC mp_obj_t audiomp3_mp3file_deinit(mp_obj_t self_in) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiomp3_mp3file_deinit(self); @@ -130,14 +133,12 @@ STATIC void check_for_deinit(audiomp3_mp3file_obj_t *self) { //| def __enter__(self) -> MP3Decoder: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t audiomp3_mp3file_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_audiomp3_mp3file_deinit(args[0]); @@ -147,7 +148,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomp3_mp3file___exit___obj, 4, 4, //| file: typing.BinaryIO //| """File to play back.""" -//| STATIC mp_obj_t audiomp3_mp3file_obj_get_file(mp_obj_t self_in) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -166,6 +166,20 @@ STATIC mp_obj_t audiomp3_mp3file_obj_set_file(mp_obj_t self_in, mp_obj_t file) { } MP_DEFINE_CONST_FUN_OBJ_2(audiomp3_mp3file_set_file_obj, audiomp3_mp3file_obj_set_file); +//| def open(self, filepath: str) -> None: +//| """Takes in the name of a mp3 file, opens it, and replaces the old playback file.""" +//| ... +STATIC mp_obj_t audiomp3_mp3file_obj_open(mp_obj_t self_in, mp_obj_t path) { + audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + mp_obj_t file = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), path, MP_ROM_QSTR(MP_QSTR_rb)); + + common_hal_audiomp3_mp3file_set_file(self, file); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiomp3_mp3file_open_obj, audiomp3_mp3file_obj_open); + MP_PROPERTY_GETSET(audiomp3_mp3file_file_obj, (mp_obj_t)&audiomp3_mp3file_get_file_obj, (mp_obj_t)&audiomp3_mp3file_set_file_obj); @@ -176,7 +190,6 @@ MP_PROPERTY_GETSET(audiomp3_mp3file_file_obj, //| """32 bit value that dictates how quickly samples are loaded into the DAC //| in Hertz (cycles per second). When the sample is looped, this can change //| the pitch output without changing the underlying sample.""" -//| STATIC mp_obj_t audiomp3_mp3file_obj_get_sample_rate(mp_obj_t self_in) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -198,7 +211,6 @@ MP_PROPERTY_GETSET(audiomp3_mp3file_sample_rate_obj, //| bits_per_sample: int //| """Bits per sample. (read only)""" -//| STATIC mp_obj_t audiomp3_mp3file_obj_get_bits_per_sample(mp_obj_t self_in) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -211,7 +223,6 @@ MP_PROPERTY_GETTER(audiomp3_mp3file_bits_per_sample_obj, //| channel_count: int //| """Number of audio channels. (read only)""" -//| STATIC mp_obj_t audiomp3_mp3file_obj_get_channel_count(mp_obj_t self_in) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -224,7 +235,6 @@ MP_PROPERTY_GETTER(audiomp3_mp3file_channel_count_obj, //| rms_level: float //| """The RMS audio level of a recently played moment of audio. (read only)""" -//| STATIC mp_obj_t audiomp3_mp3file_obj_get_rms_level(mp_obj_t self_in) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -250,6 +260,7 @@ MP_PROPERTY_GETTER(audiomp3_mp3file_samples_decoded_obj, STATIC const mp_rom_map_elem_t audiomp3_mp3file_locals_dict_table[] = { // Methods + { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&audiomp3_mp3file_open_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiomp3_mp3file_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiomp3_mp3file___exit___obj) }, diff --git a/shared-bindings/audiomp3/__init__.c b/shared-bindings/audiomp3/__init__.c index 13f02b1ea9..948910c45e 100644 --- a/shared-bindings/audiomp3/__init__.c +++ b/shared-bindings/audiomp3/__init__.c @@ -37,7 +37,6 @@ //| see `this CircuitPython Essentials Learn guide page //| `_. //| """ -//| STATIC const mp_rom_map_elem_t audiomp3_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiomp3) }, diff --git a/shared-bindings/audiopwmio/PWMAudioOut.c b/shared-bindings/audiopwmio/PWMAudioOut.c index f4f3675750..b4cea75184 100644 --- a/shared-bindings/audiopwmio/PWMAudioOut.c +++ b/shared-bindings/audiopwmio/PWMAudioOut.c @@ -39,7 +39,13 @@ //| class PWMAudioOut: //| """Output an analog audio signal by varying the PWM duty cycle.""" //| -//| def __init__(self, left_channel: microcontroller.Pin, *, right_channel: Optional[microcontroller.Pin] = None, quiescent_value: int = 0x8000) -> None: +//| def __init__( +//| self, +//| left_channel: microcontroller.Pin, +//| *, +//| right_channel: Optional[microcontroller.Pin] = None, +//| quiescent_value: int = 0x8000 +//| ) -> None: //| """Create a PWMAudioOut object associated with the given pin(s). This allows you to //| play audio signals out on the given pin(s). In contrast to mod:`audioio`, //| the pin(s) specified are digital pins, and are driven with a device-dependent PWM @@ -92,7 +98,6 @@ //| pass //| print("stopped")""" //| ... -//| STATIC mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_left_channel, ARG_right_channel, ARG_quiescent_value }; static const mp_arg_t allowed_args[] = { @@ -103,8 +108,10 @@ STATIC mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *left_channel_pin = validate_obj_is_free_pin(args[ARG_left_channel].u_obj); - const mcu_pin_obj_t *right_channel_pin = validate_obj_is_free_pin_or_none(args[ARG_right_channel].u_obj); + const mcu_pin_obj_t *left_channel_pin = + validate_obj_is_free_pin(args[ARG_left_channel].u_obj, MP_QSTR_left_channel); + const mcu_pin_obj_t *right_channel_pin = + validate_obj_is_free_pin_or_none(args[ARG_right_channel].u_obj, MP_QSTR_right_channel); // create AudioOut object from the given pin audiopwmio_pwmaudioout_obj_t *self = m_new_obj(audiopwmio_pwmaudioout_obj_t); @@ -117,7 +124,6 @@ STATIC mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_ //| def deinit(self) -> None: //| """Deinitialises the PWMAudioOut and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t audiopwmio_pwmaudioout_deinit(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiopwmio_pwmaudioout_deinit(self); @@ -133,7 +139,6 @@ STATIC void check_for_deinit(audiopwmio_pwmaudioout_obj_t *self) { //| def __enter__(self) -> PWMAudioOut: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: @@ -157,7 +162,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiopwmio_pwmaudioout___exit___obj, //| The sample itself should consist of 16 bit samples. Microcontrollers with a lower output //| resolution will use the highest order bits to output.""" //| ... -//| STATIC mp_obj_t audiopwmio_pwmaudioout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -179,7 +183,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiopwmio_pwmaudioout_play_obj, 1, audiopwmio_pwmaud //| def stop(self) -> None: //| """Stops playback and resets to the start of the sample.""" //| ... -//| STATIC mp_obj_t audiopwmio_pwmaudioout_obj_stop(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -190,7 +193,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_stop_obj, audiopwmio_pwmaudioou //| playing: bool //| """True when an audio sample is being output even if `paused`. (read-only)""" -//| STATIC mp_obj_t audiopwmio_pwmaudioout_obj_get_playing(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -204,7 +206,6 @@ MP_PROPERTY_GETTER(audiopwmio_pwmaudioout_playing_obj, //| def pause(self) -> None: //| """Stops playback temporarily while remembering the position. Use `resume` to resume playback.""" //| ... -//| STATIC mp_obj_t audiopwmio_pwmaudioout_obj_pause(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -220,7 +221,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_pause_obj, audiopwmio_pwmaudioo //| def resume(self) -> None: //| """Resumes sample playback after :py:func:`pause`.""" //| ... -//| STATIC mp_obj_t audiopwmio_pwmaudioout_obj_resume(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/audiopwmio/__init__.c b/shared-bindings/audiopwmio/__init__.c index 41a756e8b6..441bca2132 100644 --- a/shared-bindings/audiopwmio/__init__.c +++ b/shared-bindings/audiopwmio/__init__.c @@ -44,7 +44,6 @@ //| //| Since CircuitPython 5, `Mixer`, `RawSample` and `WaveFile` are moved //| to :mod:`audiocore`.""" -//| STATIC const mp_rom_map_elem_t audiopwmio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiopwmio) }, diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index 9c0555dd5a..9684b87df2 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -33,6 +33,7 @@ #include "shared/runtime/buffer_helper.h" #include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" #include "py/mperrno.h" #include "py/runtime.h" #include "supervisor/shared/translate/translate.h" @@ -40,7 +41,14 @@ //| class I2C: //| """Two wire serial protocol""" //| -//| def __init__(self, scl: microcontroller.Pin, sda: microcontroller.Pin, *, frequency: int = 400000, timeout: int = 255) -> None: +//| def __init__( +//| self, +//| scl: microcontroller.Pin, +//| sda: microcontroller.Pin, +//| *, +//| frequency: int = 400000, +//| timeout: int = 255 +//| ) -> None: //| """I2C is a two-wire protocol for communicating between devices. At the //| physical level it consists of 2 wires: SCL and SDA, the clock and data //| lines respectively. @@ -58,7 +66,6 @@ //| :param int frequency: The clock frequency of the bus //| :param int timeout: The maximum clock stretching timeout in microseconds""" //| ... -//| STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout }; static const mp_arg_t allowed_args[] = { @@ -70,8 +77,8 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj); - const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj); + const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj, MP_QSTR_scl); + const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj, MP_QSTR_sda); bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t); self->base.type = &bitbangio_i2c_type; @@ -82,7 +89,6 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, //| def deinit(self) -> None: //| """Releases control of the underlying hardware so other classes can use it.""" //| ... -//| STATIC mp_obj_t bitbangio_i2c_obj_deinit(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); shared_module_bitbangio_i2c_deinit(self); @@ -99,14 +105,12 @@ STATIC void check_for_deinit(bitbangio_i2c_obj_t *self) { //| def __enter__(self) -> I2C: //| """No-op used in Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware on context exit. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t bitbangio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; shared_module_bitbangio_i2c_deinit(args[0]); @@ -125,7 +129,6 @@ static void check_lock(bitbangio_i2c_obj_t *self) { //| those that respond. A device responds if it pulls the SDA line low after //| its address (including a read bit) is sent on the bus.""" //| ... -//| STATIC mp_obj_t bitbangio_i2c_scan(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -145,7 +148,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_scan_obj, bitbangio_i2c_scan); //| def try_lock(self) -> bool: //| """Attempts to grab the I2C lock. Returns True on success.""" //| ... -//| STATIC mp_obj_t bitbangio_i2c_obj_try_lock(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -156,7 +158,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_try_lock_obj, bitbangio_i2c_obj_try_lock //| def unlock(self) -> None: //| """Releases the I2C lock.""" //| ... -//| STATIC mp_obj_t bitbangio_i2c_obj_unlock(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -166,7 +167,9 @@ STATIC mp_obj_t bitbangio_i2c_obj_unlock(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock); //| import sys -//| def readfrom_into(self, address: int, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize) -> None: +//| def readfrom_into( +//| self, address: int, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize +//| ) -> None: //| """Read into ``buffer`` from the device selected by ``address``. //| The number of bytes read will be the length of ``buffer``. //| At least one byte must be read. @@ -180,16 +183,20 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock); //| :param int start: Index to start writing at //| :param int end: Index to write up to but not include""" //| ... -//| // Shared arg parsing for readfrom_into and writeto_then_readfrom. STATIC void readfrom(bitbangio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer, int32_t start, mp_int_t end) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_WRITE); - size_t length = bufinfo.len; + int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); + size_t length = bufinfo.len / stride_in_bytes; normalize_buffer_bounds(&start, end, &length); mp_arg_validate_length_min(length, 1, MP_QSTR_buffer); + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + uint8_t status = shared_module_bitbangio_i2c_read(self, address, ((uint8_t *)bufinfo.buf) + start, length); if (status != 0) { mp_raise_OSError(status); @@ -217,7 +224,9 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 1, bitbangio_i2c_readfrom_into); //| import sys -//| def writeto(self, address: int, buffer: ReadableBuffer, *, start: int = 0, end: int = sys.maxsize) -> None: +//| def writeto( +//| self, address: int, buffer: ReadableBuffer, *, start: int = 0, end: int = sys.maxsize +//| ) -> None: //| """Write the bytes from ``buffer`` to the device selected by ``address`` and then transmits a //| stop bit. Use `writeto_then_readfrom` when needing a write, no stop and repeated start //| before a read. @@ -235,17 +244,21 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 1, bitbangio_i2c_rea //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... -//| // Shared arg parsing for writeto and writeto_then_readfrom. STATIC void writeto(bitbangio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer, int32_t start, mp_int_t end, bool stop) { // get the buffer to write the data from mp_buffer_info_t bufinfo; mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_READ); - size_t length = bufinfo.len; + int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); + size_t length = bufinfo.len / stride_in_bytes; normalize_buffer_bounds(&start, end, &length); - // do the transfer + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + + // Do the transfer uint8_t status = shared_module_bitbangio_i2c_write(self, address, ((uint8_t *)bufinfo.buf) + start, length, stop); @@ -276,7 +289,17 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_writeto_obj, 1, bitbangio_i2c_wr //| import sys -//| def writeto_then_readfrom(self, address: int, out_buffer: ReadableBuffer, in_buffer: ReadableBuffer, *, out_start: int = 0, out_end: int = sys.maxsize, in_start: int = 0, in_end: int = sys.maxsize) -> None: +//| def writeto_then_readfrom( +//| self, +//| address: int, +//| out_buffer: ReadableBuffer, +//| in_buffer: ReadableBuffer, +//| *, +//| out_start: int = 0, +//| out_end: int = sys.maxsize, +//| in_start: int = 0, +//| in_end: int = sys.maxsize +//| ) -> None: //| """Write the bytes from ``out_buffer`` to the device selected by ``address``, generate no stop //| bit, generate a repeated start and read into ``in_buffer``. ``out_buffer`` and //| ``in_buffer`` can be the same buffer because they are used sequentially. @@ -288,7 +311,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_writeto_obj, 1, bitbangio_i2c_wr //| If ``in_start`` or ``in_end`` is provided, then the input buffer will be sliced //| as if ``in_buffer[in_start:in_end]`` were passed, //| The number of bytes read will be the length of ``out_buffer[in_start:in_end]``. - +//| //| :param int address: 7-bit device address //| :param ~circuitpython_typing.ReadableBuffer out_buffer: buffer containing the bytes to write //| :param ~circuitpython_typing.WriteableBuffer in_buffer: buffer to write into diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 103dd9fbaa..cf4f34f0e4 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -35,6 +35,7 @@ #include "shared/runtime/buffer_helper.h" #include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" #include "py/mperrno.h" #include "py/runtime.h" #include "supervisor/shared/translate/translate.h" @@ -51,7 +52,12 @@ //| multiple secondaries can share the `!clock`, `!MOSI` and `!MISO` lines //| and therefore the hardware.)""" //| -//| def __init__(self, clock: microcontroller.Pin, MOSI: Optional[microcontroller.Pin] = None, MISO: Optional[microcontroller.Pin] = None) -> None: +//| def __init__( +//| self, +//| clock: microcontroller.Pin, +//| MOSI: Optional[microcontroller.Pin] = None, +//| MISO: Optional[microcontroller.Pin] = None, +//| ) -> None: //| """Construct an SPI object on the given pins. //| //| .. seealso:: Using this class directly requires careful lock management. @@ -67,7 +73,6 @@ //| :param ~microcontroller.Pin MOSI: the Main Out Selected In pin. //| :param ~microcontroller.Pin MISO: the Main In Selected Out pin.""" //| ... -//| // TODO(tannewt): Support LSB SPI. STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { @@ -80,9 +85,9 @@ STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj); - const mcu_pin_obj_t *mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj); - const mcu_pin_obj_t *miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj); + const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock); + const mcu_pin_obj_t *mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj, MP_QSTR_mosi); + const mcu_pin_obj_t *miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj, MP_QSTR_miso); bitbangio_spi_obj_t *self = m_new_obj(bitbangio_spi_obj_t); self->base.type = &bitbangio_spi_type; @@ -93,7 +98,6 @@ STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, //| def deinit(self) -> None: //| """Turn off the SPI bus.""" //| ... -//| STATIC mp_obj_t bitbangio_spi_obj_deinit(mp_obj_t self_in) { bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); shared_module_bitbangio_spi_deinit(self); @@ -110,14 +114,12 @@ STATIC void check_for_deinit(bitbangio_spi_obj_t *self) { //| def __enter__(self) -> SPI: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t bitbangio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; shared_module_bitbangio_spi_deinit(args[0]); @@ -132,7 +134,9 @@ static void check_lock(bitbangio_spi_obj_t *self) { } } -//| def configure(self, *, baudrate: int = 100000, polarity: int = 0, phase: int = 0, bits: int = 8) -> None: +//| def configure( +//| self, *, baudrate: int = 100000, polarity: int = 0, phase: int = 0, bits: int = 8 +//| ) -> None: //| """Configures the SPI bus. Only valid when locked. //| //| :param int baudrate: the clock rate in Hertz @@ -141,7 +145,6 @@ static void check_lock(bitbangio_spi_obj_t *self) { //| or second (1). Rising or falling depends on clock polarity. //| :param int bits: the number of bits per word""" //| ... -//| STATIC mp_obj_t bitbangio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; static const mp_arg_t allowed_args[] = { @@ -172,7 +175,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_configure_obj, 1, bitbangio_spi_configu //| :return: True when lock has been grabbed //| :rtype: bool""" //| ... -//| STATIC mp_obj_t bitbangio_spi_obj_try_lock(mp_obj_t self_in) { bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -183,7 +185,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_try_lock_obj, bitbangio_spi_obj_try_lock //| def unlock(self) -> None: //| """Releases the SPI lock.""" //| ... -//| STATIC mp_obj_t bitbangio_spi_obj_unlock(mp_obj_t self_in) { bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -192,11 +193,20 @@ STATIC mp_obj_t bitbangio_spi_obj_unlock(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock); -//| def write(self, buf: ReadableBuffer) -> None: +//| import sys +//| def write(self, buf: ReadableBuffer, *, start: int = 0, end: int = sys.maxsize) -> None: //| """Write the data contained in ``buf``. Requires the SPI being locked. -//| If the buffer is empty, nothing happens.""" -//| ... +//| If the buffer is empty, nothing happens. //| +//| If ``start`` or ``end`` is provided, then the buffer will be sliced +//| as if ``buffer[start:end]`` were passed, but without copying the data. +//| The number of bytes written will be the length of ``buffer[start:end]``. +//| +//| :param ReadableBuffer buffer: buffer containing the bytes to write +//| :param int start: beginning of buffer slice +//| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` +//| """ +//| ... STATIC mp_obj_t bitbangio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -212,10 +222,16 @@ STATIC mp_obj_t bitbangio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_ mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + // Compute bounds in terms of elements, not bytes. + int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); int32_t start = args[ARG_start].u_int; - size_t length = bufinfo.len; + size_t length = bufinfo.len / stride_in_bytes; normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + if (length == 0) { return mp_const_none; } @@ -230,7 +246,14 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_write_obj, 1, bitbangio_spi_write); //| import sys -//| def readinto(self, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize, write_value: int = 0) -> None: +//| def readinto( +//| self, +//| buffer: WriteableBuffer, +//| *, +//| start: int = 0, +//| end: int = sys.maxsize, +//| write_value: int = 0 +//| ) -> None: //| """Read into ``buffer`` while writing ``write_value`` for each byte read. //| The SPI object must be locked. //| If the number of bytes to read is 0, nothing happens. @@ -245,7 +268,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_write_obj, 1, bitbangio_spi_write); //| :param int write_value: value to write while reading //| """ //| ... -//| STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end, ARG_write_value }; static const mp_arg_t allowed_args[] = { @@ -262,10 +284,16 @@ STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); + int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); + // Compute bounds in terms of elements, not bytes. int32_t start = args[ARG_start].u_int; - size_t length = bufinfo.len; + size_t length = bufinfo.len / stride_in_bytes; normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + if (length == 0) { return mp_const_none; } @@ -279,7 +307,16 @@ STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_readinto_obj, 1, bitbangio_spi_readinto); //| import sys -//| def write_readinto(self, out_buffer: ReadableBuffer, in_buffer: WriteableBuffer, *, out_start: int = 0, out_end: int = sys.maxsize, in_start: int = 0, in_end: int = sys.maxsize) -> None: +//| def write_readinto( +//| self, +//| out_buffer: ReadableBuffer, +//| in_buffer: WriteableBuffer, +//| *, +//| out_start: int = 0, +//| out_end: int = sys.maxsize, +//| in_start: int = 0, +//| in_end: int = sys.maxsize +//| ) -> None: //| """Write out the data in ``out_buffer`` while simultaneously reading data into ``in_buffer``. //| The SPI object must be locked. //| @@ -323,16 +360,24 @@ STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_ mp_buffer_info_t buf_out_info; mp_get_buffer_raise(args[ARG_out_buffer].u_obj, &buf_out_info, MP_BUFFER_READ); + int out_stride_in_bytes = mp_binary_get_size('@', buf_out_info.typecode, NULL); int32_t out_start = args[ARG_out_start].u_int; - size_t out_length = buf_out_info.len; + size_t out_length = buf_out_info.len / out_stride_in_bytes; normalize_buffer_bounds(&out_start, args[ARG_out_end].u_int, &out_length); mp_buffer_info_t buf_in_info; mp_get_buffer_raise(args[ARG_in_buffer].u_obj, &buf_in_info, MP_BUFFER_WRITE); + int in_stride_in_bytes = mp_binary_get_size('@', buf_in_info.typecode, NULL); int32_t in_start = args[ARG_in_start].u_int; - size_t in_length = buf_in_info.len; + size_t in_length = buf_in_info.len / in_stride_in_bytes; normalize_buffer_bounds(&in_start, args[ARG_in_end].u_int, &in_length); + // Treat start and length in terms of bytes from now on. + out_start *= out_stride_in_bytes; + out_length *= out_stride_in_bytes; + in_start *= in_stride_in_bytes; + in_length *= in_stride_in_bytes; + if (out_length != in_length) { mp_raise_ValueError(translate("buffer slices must be of equal length")); } diff --git a/shared-bindings/bitbangio/__init__.c b/shared-bindings/bitbangio/__init__.c index 43117db494..1b13003e89 100644 --- a/shared-bindings/bitbangio/__init__.c +++ b/shared-bindings/bitbangio/__init__.c @@ -66,7 +66,6 @@ //| :py:meth:`~bitbangio.I2C.scan` and then :py:meth:`~bitbangio.I2C.deinit` the //| hardware. The last step is optional because CircuitPython automatically //| resets hardware after a program finishes.""" -//| STATIC const mp_rom_map_elem_t bitbangio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bitbangio) }, diff --git a/shared-bindings/bitmaptools/__init__.c b/shared-bindings/bitmaptools/__init__.c index 6c00ca44a9..1195e1811d 100644 --- a/shared-bindings/bitmaptools/__init__.c +++ b/shared-bindings/bitmaptools/__init__.c @@ -126,45 +126,54 @@ STATIC void validate_clip_region(displayio_bitmap_t *bitmap, mp_obj_t clip0_tupl } -//| //| def rotozoom( -//| dest_bitmap: displayio.Bitmap, source_bitmap: displayio.Bitmap, -//| *, -//| ox: int, oy: int, dest_clip0: Tuple[int, int], dest_clip1: Tuple[int, int], -//| px: int, py: int, source_clip0: Tuple[int, int], source_clip1: Tuple[int, int], -//| angle: float, scale: float, skip_index: int) -> None: -//| """Inserts the source bitmap region into the destination bitmap with rotation -//| (angle), scale and clipping (both on source and destination bitmaps). +//| dest_bitmap: displayio.Bitmap, +//| source_bitmap: displayio.Bitmap, +//| *, +//| ox: int, +//| oy: int, +//| dest_clip0: Tuple[int, int], +//| dest_clip1: Tuple[int, int], +//| px: int, +//| py: int, +//| source_clip0: Tuple[int, int], +//| source_clip1: Tuple[int, int], +//| angle: float, +//| scale: float, +//| skip_index: int +//| ) -> None: +//| """Inserts the source bitmap region into the destination bitmap with rotation +//| (angle), scale and clipping (both on source and destination bitmaps). //| -//| :param bitmap dest_bitmap: Destination bitmap that will be copied into -//| :param bitmap source_bitmap: Source bitmap that contains the graphical region to be copied -//| :param int ox: Horizontal pixel location in destination bitmap where source bitmap -//| point (px,py) is placed. Defaults to None which causes it to use the horizontal -//| midway point of the destination bitmap. -//| :param int oy: Vertical pixel location in destination bitmap where source bitmap -//| point (px,py) is placed. Defaults to None which causes it to use the vertical -//| midway point of the destination bitmap. -//| :param Tuple[int,int] dest_clip0: First corner of rectangular destination clipping -//| region that constrains region of writing into destination bitmap -//| :param Tuple[int,int] dest_clip1: Second corner of rectangular destination clipping -//| region that constrains region of writing into destination bitmap -//| :param int px: Horizontal pixel location in source bitmap that is placed into the -//| destination bitmap at (ox,oy). Defaults to None which causes it to use the -//| horizontal midway point in the source bitmap. -//| :param int py: Vertical pixel location in source bitmap that is placed into the -//| destination bitmap at (ox,oy). Defaults to None which causes it to use the -//| vertical midway point in the source bitmap. -//| :param Tuple[int,int] source_clip0: First corner of rectangular source clipping -//| region that constrains region of reading from the source bitmap -//| :param Tuple[int,int] source_clip1: Second corner of rectangular source clipping -//| region that constrains region of reading from the source bitmap -//| :param float angle: Angle of rotation, in radians (positive is clockwise direction). -//| Defaults to None which gets treated as 0.0 radians or no rotation. -//| :param float scale: Scaling factor. Defaults to None which gets treated as 1.0 or same -//| as original source size. -//| :param int skip_index: Bitmap palette index in the source that will not be copied, -//| set to None to copy all pixels""" -//| ... +//| :param bitmap dest_bitmap: Destination bitmap that will be copied into +//| :param bitmap source_bitmap: Source bitmap that contains the graphical region to be copied +//| :param int ox: Horizontal pixel location in destination bitmap where source bitmap +//| point (px,py) is placed. Defaults to None which causes it to use the horizontal +//| midway point of the destination bitmap. +//| :param int oy: Vertical pixel location in destination bitmap where source bitmap +//| point (px,py) is placed. Defaults to None which causes it to use the vertical +//| midway point of the destination bitmap. +//| :param Tuple[int,int] dest_clip0: First corner of rectangular destination clipping +//| region that constrains region of writing into destination bitmap +//| :param Tuple[int,int] dest_clip1: Second corner of rectangular destination clipping +//| region that constrains region of writing into destination bitmap +//| :param int px: Horizontal pixel location in source bitmap that is placed into the +//| destination bitmap at (ox,oy). Defaults to None which causes it to use the +//| horizontal midway point in the source bitmap. +//| :param int py: Vertical pixel location in source bitmap that is placed into the +//| destination bitmap at (ox,oy). Defaults to None which causes it to use the +//| vertical midway point in the source bitmap. +//| :param Tuple[int,int] source_clip0: First corner of rectangular source clipping +//| region that constrains region of reading from the source bitmap +//| :param Tuple[int,int] source_clip1: Second corner of rectangular source clipping +//| region that constrains region of reading from the source bitmap +//| :param float angle: Angle of rotation, in radians (positive is clockwise direction). +//| Defaults to None which gets treated as 0.0 radians or no rotation. +//| :param float scale: Scaling factor. Defaults to None which gets treated as 1.0 or same +//| as original source size. +//| :param int skip_index: Bitmap palette index in the source that will not be copied, +//| set to None to copy all pixels""" +//| ... //| STATIC mp_obj_t bitmaptools_obj_rotozoom(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_dest_bitmap, ARG_source_bitmap, @@ -266,8 +275,14 @@ STATIC mp_obj_t bitmaptools_obj_rotozoom(size_t n_args, const mp_obj_t *pos_args MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_rotozoom_obj, 0, bitmaptools_obj_rotozoom); // requires at least 2 arguments (destination bitmap and source bitmap) -//| -//| def alphablend(dest_bitmap: displayio.Bitmap , source_bitmap_1: displayio.Bitmap, source_bitmap_2: displayio.Bitmap, colorspace: displayio.Colorspace, factor1: float=.5, factor2: float=None) -> None: +//| def alphablend( +//| dest_bitmap: displayio.Bitmap, +//| source_bitmap_1: displayio.Bitmap, +//| source_bitmap_2: displayio.Bitmap, +//| colorspace: displayio.Colorspace, +//| factor1: float = 0.5, +//| factor2: Optional[float] = None, +//| ) -> None: //| """Alpha blend the two source bitmaps into the destination. //| //| It is permitted for the destination bitmap to be one of the two @@ -305,7 +320,7 @@ STATIC mp_obj_t bitmaptools_alphablend(size_t n_args, const mp_obj_t *pos_args, mp_float_t factor1 = (args[ARG_factor_1].u_obj == mp_const_none) ? MICROPY_FLOAT_CONST(.5) : mp_obj_get_float(args[ARG_factor_1].u_obj); mp_float_t factor2 = (args[ARG_factor_2].u_obj == mp_const_none) ? 1 - factor1 : mp_obj_get_float(args[ARG_factor_2].u_obj); - displayio_colorspace_t colorspace = (displayio_colorspace_t)cp_enum_value(&displayio_colorspace_type, args[ARG_colorspace].u_obj); + displayio_colorspace_t colorspace = (displayio_colorspace_t)cp_enum_value(&displayio_colorspace_type, args[ARG_colorspace].u_obj, MP_QSTR_colorspace); if (destination->width != source1->width || destination->height != source1->height @@ -343,23 +358,20 @@ STATIC mp_obj_t bitmaptools_alphablend(size_t n_args, const mp_obj_t *pos_args, } MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_alphablend_obj, 0, bitmaptools_alphablend); -//| //| def fill_region( -//| dest_bitmap: displayio.Bitmap, -//| x1: int, y1: int, -//| x2: int, y2: int, -//| value: int) -> None: -//| """Draws the color value into the destination bitmap within the -//| rectangular region bounded by (x1,y1) and (x2,y2), exclusive. +//| dest_bitmap: displayio.Bitmap, x1: int, y1: int, x2: int, y2: int, value: int +//| ) -> None: +//| """Draws the color value into the destination bitmap within the +//| rectangular region bounded by (x1,y1) and (x2,y2), exclusive. //| -//| :param bitmap dest_bitmap: Destination bitmap that will be written into -//| :param int x1: x-pixel position of the first corner of the rectangular fill region -//| :param int y1: y-pixel position of the first corner of the rectangular fill region -//| :param int x2: x-pixel position of the second corner of the rectangular fill region (exclusive) -//| :param int y2: y-pixel position of the second corner of the rectangular fill region (exclusive) -//| :param int value: Bitmap palette index that will be written into the rectangular -//| fill region in the destination bitmap""" -//| ... +//| :param bitmap dest_bitmap: Destination bitmap that will be written into +//| :param int x1: x-pixel position of the first corner of the rectangular fill region +//| :param int y1: y-pixel position of the first corner of the rectangular fill region +//| :param int x2: x-pixel position of the second corner of the rectangular fill region (exclusive) +//| :param int y2: y-pixel position of the second corner of the rectangular fill region (exclusive) +//| :param int value: Bitmap palette index that will be written into the rectangular +//| fill region in the destination bitmap""" +//| ... //| STATIC mp_obj_t bitmaptools_obj_fill_region(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_dest_bitmap, ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_value}; @@ -395,23 +407,25 @@ STATIC mp_obj_t bitmaptools_obj_fill_region(size_t n_args, const mp_obj_t *pos_a } MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_fill_region_obj, 0, bitmaptools_obj_fill_region); -//| //| def boundary_fill( -//| dest_bitmap: displayio.Bitmap, -//| x: int, y: int, -//| fill_color_value: int, replaced_color_value: int) -> None: -//| """Draws the color value into the destination bitmap enclosed -//| area of pixels of the background_value color. Like "Paint Bucket" -//| fill tool. +//| dest_bitmap: displayio.Bitmap, +//| x: int, +//| y: int, +//| fill_color_value: int, +//| replaced_color_value: int, +//| ) -> None: +//| """Draws the color value into the destination bitmap enclosed +//| area of pixels of the background_value color. Like "Paint Bucket" +//| fill tool. //| -//| :param bitmap dest_bitmap: Destination bitmap that will be written into -//| :param int x: x-pixel position of the first pixel to check and fill if needed -//| :param int y: y-pixel position of the first pixel to check and fill if needed -//| :param int fill_color_value: Bitmap palette index that will be written into the -//| enclosed area in the destination bitmap -//| :param int replaced_color_value: Bitmap palette index that will filled with the -//| value color in the enclosed area in the destination bitmap""" -//| ... +//| :param bitmap dest_bitmap: Destination bitmap that will be written into +//| :param int x: x-pixel position of the first pixel to check and fill if needed +//| :param int y: y-pixel position of the first pixel to check and fill if needed +//| :param int fill_color_value: Bitmap palette index that will be written into the +//| enclosed area in the destination bitmap +//| :param int replaced_color_value: Bitmap palette index that will filled with the +//| value color in the enclosed area in the destination bitmap""" +//| ... //| STATIC mp_obj_t bitmaptools_obj_boundary_fill(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_dest_bitmap, ARG_x, ARG_y, ARG_fill_color_value, ARG_replaced_color_value}; @@ -459,22 +473,19 @@ STATIC mp_obj_t bitmaptools_obj_boundary_fill(size_t n_args, const mp_obj_t *pos MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_boundary_fill_obj, 0, bitmaptools_obj_boundary_fill); // requires all 6 arguments -//| //| def draw_line( -//| dest_bitmap: displayio.Bitmap, -//| x1: int, y1: int, -//| x2: int, y2: int, -//| value: int) -> None: -//| """Draws a line into a bitmap specified two endpoints (x1,y1) and (x2,y2). +//| dest_bitmap: displayio.Bitmap, x1: int, y1: int, x2: int, y2: int, value: int +//| ) -> None: +//| """Draws a line into a bitmap specified two endpoints (x1,y1) and (x2,y2). //| -//| :param bitmap dest_bitmap: Destination bitmap that will be written into -//| :param int x1: x-pixel position of the line's first endpoint -//| :param int y1: y-pixel position of the line's first endpoint -//| :param int x2: x-pixel position of the line's second endpoint -//| :param int y2: y-pixel position of the line's second endpoint -//| :param int value: Bitmap palette index that will be written into the -//| line in the destination bitmap""" -//| ... +//| :param bitmap dest_bitmap: Destination bitmap that will be written into +//| :param int x1: x-pixel position of the line's first endpoint +//| :param int y1: y-pixel position of the line's first endpoint +//| :param int x2: x-pixel position of the line's second endpoint +//| :param int y2: y-pixel position of the line's second endpoint +//| :param int value: Bitmap palette index that will be written into the +//| line in the destination bitmap""" +//| ... //| STATIC mp_obj_t bitmaptools_obj_draw_line(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_dest_bitmap, ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_value}; @@ -504,13 +515,6 @@ STATIC mp_obj_t bitmaptools_obj_draw_line(size_t n_args, const mp_obj_t *pos_arg int16_t x2 = args[ARG_x2].u_int; int16_t y2 = args[ARG_y2].u_int; - // verify points are within the bitmap boundary (inclusive) - if ((x1 < 0) || (x2 < 0) || (y1 < 0) || (y2 < 0) || - (x1 >= destination->width) || (x2 >= destination->width) || - (y1 >= destination->height) || (y2 >= destination->height)) { - mp_raise_ValueError(translate("out of range of target")); - } - common_hal_bitmaptools_draw_line(destination, x1, y1, x2, y2, value); return mp_const_none; @@ -519,7 +523,110 @@ STATIC mp_obj_t bitmaptools_obj_draw_line(size_t n_args, const mp_obj_t *pos_arg MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_line_obj, 0, bitmaptools_obj_draw_line); // requires all 6 arguments -//| def arrayblit(bitmap: displayio.Bitmap, data: ReadableBuffer, x1: int=0, y1: int=0, x2: Optional[int]=None, y2: Optional[int]=None, skip_index:Optional[int]=None) -> None: +//| def draw_polygon( +//| dest_bitmap: displayio.Bitmap, +//| xs: ReadableBuffer, +//| ys: ReadableBuffer, +//| value: int, +//| close: Optional[bool] = True, +//| ) -> None: +//| """Draw a polygon conecting points on provided bitmap with provided value +//| +//| :param bitmap dest_bitmap: Destination bitmap that will be written into +//| :param ReadableBuffer xs: x-pixel position of the polygon's vertices +//| :param ReadableBuffer ys: y-pixel position of the polygon's vertices +//| :param int value: Bitmap palette index that will be written into the +//| line in the destination bitmap +//| :param bool close: (Optional) Wether to connect first and last point. (True) +//| +//| .. code-block:: Python +//| +//| import board +//| import displayio +//| import bitmaptools +//| +//| display = board.DISPLAY +//| main_group = displayio.Group() +//| display.root_group = main_group +//| +//| palette = displayio.Palette(3) +//| palette[0] = 0xffffff +//| palette[1] = 0x0000ff +//| palette[2] = 0xff0000 +//| +//| bmp = displayio.Bitmap(128,128, 3) +//| bmp.fill(0) +//| +//| xs = bytes([4, 101, 101, 19]) +//| ys = bytes([4, 19, 121, 101]) +//| bitmaptools.draw_polygon(bmp, xs, ys, 1) +//| +//| xs = bytes([14, 60, 110]) +//| ys = bytes([14, 24, 90]) +//| bitmaptools.draw_polygon(bmp, xs, ys, 2) +//| +//| tilegrid = displayio.TileGrid(bitmap=bmp, pixel_shader=palette) +//| main_group.append(tilegrid) +//| +//| while True: +//| pass +//| """ +//| ... +//| +STATIC mp_obj_t bitmaptools_obj_draw_polygon(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_dest_bitmap, ARG_xs, ARG_ys, ARG_value, ARG_close}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_xs, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_ys, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_close, MP_ARG_BOOL, {.u_bool = true}}, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + displayio_bitmap_t *destination = MP_OBJ_TO_PTR(args[ARG_dest_bitmap].u_obj); // the destination bitmap + + mp_buffer_info_t xs_buf, ys_buf; + mp_get_buffer_raise(args[ARG_xs].u_obj, &xs_buf, MP_BUFFER_READ); + mp_get_buffer_raise(args[ARG_ys].u_obj, &ys_buf, MP_BUFFER_READ); + size_t xs_size = mp_binary_get_size('@', xs_buf.typecode, NULL); + size_t ys_size = mp_binary_get_size('@', ys_buf.typecode, NULL); + size_t xs_len = xs_buf.len / xs_size; + size_t ys_len = ys_buf.len / ys_size; + if (xs_size != ys_size) { + mp_raise_ValueError(translate("Coordinate arrays types have different sizes")); + } + if (xs_len != ys_len) { + mp_raise_ValueError(translate("Coordinate arrays have different lengths")); + } + + uint32_t value, color_depth; + value = args[ARG_value].u_int; + color_depth = (1 << destination->bits_per_value); + if (color_depth <= value) { + mp_raise_ValueError(translate("out of range of target")); + } + + bool close = args[ARG_close].u_bool; + + common_hal_bitmaptools_draw_polygon(destination, xs_buf.buf, ys_buf.buf, xs_len, xs_size, value, close); + + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_polygon_obj, 0, bitmaptools_obj_draw_polygon); + +//| def arrayblit( +//| bitmap: displayio.Bitmap, +//| data: ReadableBuffer, +//| x1: int = 0, +//| y1: int = 0, +//| x2: Optional[int] = None, +//| y2: Optional[int] = None, +//| skip_index: Optional[int] = None, +//| ) -> None: //| """Inserts pixels from ``data`` into the rectangle of width×height pixels with the upper left corner at ``(x,y)`` //| //| The values from ``data`` are taken modulo the number of color values @@ -593,7 +700,15 @@ STATIC mp_obj_t bitmaptools_arrayblit(size_t n_args, const mp_obj_t *pos_args, m MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_arrayblit_obj, 0, bitmaptools_arrayblit); -//| def readinto(bitmap: displayio.Bitmap, file: typing.BinaryIO, bits_per_pixel: int, element_size: int = 1, reverse_pixels_in_element: bool = False, swap_bytes_in_element: bool = False, reverse_rows: bool = False) -> None: +//| def readinto( +//| bitmap: displayio.Bitmap, +//| file: typing.BinaryIO, +//| bits_per_pixel: int, +//| element_size: int = 1, +//| reverse_pixels_in_element: bool = False, +//| swap_bytes_in_element: bool = False, +//| reverse_rows: bool = False, +//| ) -> None: //| """Reads from a binary file into a bitmap. //| //| The file must be positioned so that it consists of ``bitmap.height`` rows of pixel data, where each row is the smallest multiple of ``element_size`` bytes that can hold ``bitmap.width`` pixels. @@ -688,7 +803,12 @@ MAKE_PRINTER(bitmaptools, bitmaptools_dither_algorithm); MAKE_ENUM_TYPE(bitmaptools, DitherAlgorithm, bitmaptools_dither_algorithm); -//| def dither(dest_bitmap: displayio.Bitmap, source_bitmapp: displayio.Bitmap, source_colorspace: displayio.Colorspace, algorithm: DitherAlgorithm=DitherAlgorithm.Atkinson) -> None: +//| def dither( +//| dest_bitmap: displayio.Bitmap, +//| source_bitmapp: displayio.Bitmap, +//| source_colorspace: displayio.Colorspace, +//| algorithm: DitherAlgorithm = DitherAlgorithm.Atkinson, +//| ) -> None: //| """Convert the input image into a 2-level output image using the given dither algorithm. //| //| :param bitmap dest_bitmap: Destination bitmap. It must have a value_count of 2 or 65536. The stored values are 0 and the maximum pixel value. @@ -710,8 +830,8 @@ STATIC mp_obj_t bitmaptools_dither(size_t n_args, const mp_obj_t *pos_args, mp_m mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); displayio_bitmap_t *source_bitmap = mp_arg_validate_type(args[ARG_source_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_source_bitmap); displayio_bitmap_t *dest_bitmap = mp_arg_validate_type(args[ARG_dest_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_dest_bitmap); - bitmaptools_dither_algorithm_t algorithm = cp_enum_value(&bitmaptools_dither_algorithm_type, args[ARG_algorithm].u_obj); - displayio_colorspace_t colorspace = cp_enum_value(&displayio_colorspace_type, args[ARG_source_colorspace].u_obj); + bitmaptools_dither_algorithm_t algorithm = cp_enum_value(&bitmaptools_dither_algorithm_type, args[ARG_algorithm].u_obj, MP_QSTR_algorithm); + displayio_colorspace_t colorspace = cp_enum_value(&displayio_colorspace_type, args[ARG_source_colorspace].u_obj, MP_QSTR_source_colorspace); if (source_bitmap->width != dest_bitmap->width || source_bitmap->height != dest_bitmap->height) { mp_raise_TypeError(translate("bitmap sizes must match")); @@ -759,6 +879,7 @@ STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_fill_region), MP_ROM_PTR(&bitmaptools_fill_region_obj) }, { MP_ROM_QSTR(MP_QSTR_boundary_fill), MP_ROM_PTR(&bitmaptools_boundary_fill_obj) }, { MP_ROM_QSTR(MP_QSTR_draw_line), MP_ROM_PTR(&bitmaptools_draw_line_obj) }, + { MP_ROM_QSTR(MP_QSTR_draw_polygon), MP_ROM_PTR(&bitmaptools_draw_polygon_obj) }, { MP_ROM_QSTR(MP_QSTR_dither), MP_ROM_PTR(&bitmaptools_dither_obj) }, { MP_ROM_QSTR(MP_QSTR_DitherAlgorithm), MP_ROM_PTR(&bitmaptools_dither_algorithm_type) }, }; diff --git a/shared-bindings/bitmaptools/__init__.h b/shared-bindings/bitmaptools/__init__.h index fb5c78911f..db72410cf6 100644 --- a/shared-bindings/bitmaptools/__init__.h +++ b/shared-bindings/bitmaptools/__init__.h @@ -64,6 +64,7 @@ void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination, int16_t x1, int16_t y1, uint32_t value); +void common_hal_bitmaptools_draw_polygon(displayio_bitmap_t *destination, void *xs, void *ys, size_t points_len, int point_size, uint32_t value, bool close); void common_hal_bitmaptools_readinto(displayio_bitmap_t *self, mp_obj_t *file, int element_size, int bits_per_pixel, bool reverse_pixels_in_word, bool swap_bytes, bool reverse_rows); void common_hal_bitmaptools_arrayblit(displayio_bitmap_t *self, void *data, int element_size, int x1, int y1, int x2, int y2, bool skip_specified, uint32_t skip_index); void common_hal_bitmaptools_dither(displayio_bitmap_t *dest_bitmap, displayio_bitmap_t *source_bitmap, displayio_colorspace_t colorspace, bitmaptools_dither_algorithm_t algorithm); diff --git a/shared-bindings/bitops/__init__.c b/shared-bindings/bitops/__init__.c index 0b6b98a8d1..3107b310db 100644 --- a/shared-bindings/bitops/__init__.c +++ b/shared-bindings/bitops/__init__.c @@ -31,10 +31,11 @@ //| """Routines for low-level manipulation of binary data""" //| -//| -//| def bit_transpose(input: ReadableBuffer, output: WriteableBuffer, width:int = 8) -> WriteableBuffer: -//| """"Transpose" a buffer by assembling each output byte with bits taken from each of ``width`` different input bytes. +//| def bit_transpose( +//| input: ReadableBuffer, output: WriteableBuffer, width: int = 8 +//| ) -> WriteableBuffer: +//| """ "Transpose" a buffer by assembling each output byte with bits taken from each of ``width`` different input bytes. //| //| This can be useful to convert a sequence of pixel values into a single //| stream of bytes suitable for sending via a parallel conversion method. @@ -53,6 +54,7 @@ //| //| Returns the output buffer.""" //| ... +//| STATIC mp_obj_t bit_transpose(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_input, ARG_output, ARG_width }; diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c index e4003d4f6b..971ed2f676 100644 --- a/shared-bindings/board/__init__.c +++ b/shared-bindings/board/__init__.c @@ -58,10 +58,12 @@ //| """Board ID string. The unique identifier for the board model in //| circuitpython, as well as on circuitpython.org. //| Example: "hallowing_m0_express".""" +//| //| def I2C() -> busio.I2C: //| """Returns the `busio.I2C` object for the board's designated I2C bus(es). -//| The object created is a singleton, and uses the default parameter values for `busio.I2C`.""" +//| The object created is a singleton, and uses the default parameter values for `busio.I2C`. +//| """ //| ... //| #if CIRCUITPY_BOARD_I2C @@ -78,7 +80,8 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c_0); //| def SPI() -> busio.SPI: //| """Returns the `busio.SPI` object for the board's designated SPI bus(es). -//| The object created is a singleton, and uses the default parameter values for `busio.SPI`.""" +//| The object created is a singleton, and uses the default parameter values for `busio.SPI`. +//| """ //| ... //| #if CIRCUITPY_BOARD_SPI @@ -95,7 +98,8 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi_0); //| def UART() -> busio.UART: //| """Returns the `busio.UART` object for the board's designated UART bus(es). -//| The object created is a singleton, and uses the default parameter values for `busio.UART`.""" +//| The object created is a singleton, and uses the default parameter values for `busio.UART`. +//| """ //| ... //| #if CIRCUITPY_BOARD_UART diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index b3afd9801d..5cf52eaa1a 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -33,14 +33,21 @@ #include "shared/runtime/buffer_helper.h" #include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" #include "py/runtime.h" #include "supervisor/shared/translate/translate.h" //| class I2C: //| """Two wire serial protocol""" //| -//| def __init__(self, scl: microcontroller.Pin, sda: microcontroller.Pin, *, frequency: int = 100000, timeout: int = 255) -> None: -//| +//| def __init__( +//| self, +//| scl: microcontroller.Pin, +//| sda: microcontroller.Pin, +//| *, +//| frequency: int = 100000, +//| timeout: int = 255 +//| ) -> None: //| """I2C is a two-wire protocol for communicating between devices. At the //| physical level it consists of 2 wires: SCL and SDA, the clock and data //| lines respectively. @@ -60,7 +67,6 @@ //| :class:`bitbangio.I2C`; ignored for :class:`busio.I2C`) //| """ //| ... -//| STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); self->base.type = &busio_i2c_type; @@ -74,8 +80,8 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj); - const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj); + const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj, MP_QSTR_scl); + const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj, MP_QSTR_sda); common_hal_busio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); return (mp_obj_t)self; @@ -84,7 +90,6 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz //| def deinit(self) -> None: //| """Releases control of the underlying hardware so other classes can use it.""" //| ... -//| STATIC mp_obj_t busio_i2c_obj_deinit(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_busio_i2c_deinit(self); @@ -101,14 +106,12 @@ STATIC void check_for_deinit(busio_i2c_obj_t *self) { //| def __enter__(self) -> I2C: //| """No-op used in Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware on context exit. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t busio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_busio_i2c_deinit(MP_OBJ_TO_PTR(args[0])); @@ -130,7 +133,6 @@ static void check_lock(busio_i2c_obj_t *self) { //| :return: List of device ids on the I2C bus //| :rtype: list""" //| ... -//| STATIC mp_obj_t busio_i2c_scan(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -153,7 +155,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan); //| :return: True when lock has been grabbed //| :rtype: bool""" //| ... -//| STATIC mp_obj_t busio_i2c_obj_try_lock(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -164,7 +165,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_try_lock_obj, busio_i2c_obj_try_lock); //| def unlock(self) -> None: //| """Releases the I2C lock.""" //| ... -//| STATIC mp_obj_t busio_i2c_obj_unlock(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -174,7 +174,9 @@ STATIC mp_obj_t busio_i2c_obj_unlock(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); //| import sys -//| def readfrom_into(self, address: int, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize) -> None: +//| def readfrom_into( +//| self, address: int, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize +//| ) -> None: //| """Read into ``buffer`` from the device selected by ``address``. //| At least one byte must be read. //| @@ -187,7 +189,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); //| :param int start: beginning of buffer slice //| :param int end: end of buffer slice; if not specified, use ``len(buffer)``""" //| ... -//| STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -206,12 +207,18 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); - size_t length = bufinfo.len; + // Compute bounds in terms of elements, not bytes. + int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); + size_t length = bufinfo.len / stride_in_bytes; int32_t start = args[ARG_start].u_int; const int32_t end = args[ARG_end].u_int; normalize_buffer_bounds(&start, end, &length); mp_arg_validate_length_min(length, 1, MP_QSTR_buffer); + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + uint8_t status = common_hal_busio_i2c_read(self, args[ARG_address].u_int, ((uint8_t *)bufinfo.buf) + start, length); if (status != 0) { @@ -223,7 +230,9 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 1, busio_i2c_readfrom_into); //| import sys -//| def writeto(self, address: int, buffer: ReadableBuffer, *, start: int = 0, end: int = sys.maxsize) -> None: +//| def writeto( +//| self, address: int, buffer: ReadableBuffer, *, start: int = 0, end: int = sys.maxsize +//| ) -> None: //| """Write the bytes from ``buffer`` to the device selected by ``address`` and //| then transmit a stop bit. //| @@ -240,7 +249,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 1, busio_i2c_readfrom_in //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... -//| STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -258,12 +266,18 @@ STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma // get the buffer to write the data from mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); - size_t length = bufinfo.len; + // Compute bounds in terms of elements, not bytes. + size_t length = bufinfo.len / stride_in_bytes; int32_t start = args[ARG_start].u_int; const int32_t end = args[ARG_end].u_int; normalize_buffer_bounds(&start, end, &length); + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + // do the transfer uint8_t status = common_hal_busio_i2c_write(self, args[ARG_address].u_int, ((uint8_t *)bufinfo.buf) + start, length); @@ -277,7 +291,17 @@ STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma STATIC MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_writeto_obj, 1, busio_i2c_writeto); //| import sys -//| def writeto_then_readfrom(self, address: int, out_buffer: ReadableBuffer, in_buffer: WriteableBuffer, *, out_start: int = 0, out_end: int = sys.maxsize, in_start: int = 0, in_end: int = sys.maxsize) -> None: +//| def writeto_then_readfrom( +//| self, +//| address: int, +//| out_buffer: ReadableBuffer, +//| in_buffer: WriteableBuffer, +//| *, +//| out_start: int = 0, +//| out_end: int = sys.maxsize, +//| in_start: int = 0, +//| in_end: int = sys.maxsize +//| ) -> None: //| """Write the bytes from ``out_buffer`` to the device selected by ``address``, generate no stop //| bit, generate a repeated start and read into ``in_buffer``. ``out_buffer`` and //| ``in_buffer`` can be the same buffer because they are used sequentially. @@ -289,7 +313,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_writeto_obj, 1, busio_i2c_writeto); //| If ``in_start`` or ``in_end`` is provided, then the input buffer will be sliced //| as if ``in_buffer[in_start:in_end]`` were passed, //| The number of bytes read will be the length of ``out_buffer[in_start:in_end]``. - +//| //| :param int address: 7-bit device address //| :param ~circuitpython_typing.ReadableBuffer out_buffer: buffer containing the bytes to write //| :param ~circuitpython_typing.WriteableBuffer in_buffer: buffer to write into @@ -319,25 +343,29 @@ STATIC mp_obj_t busio_i2c_writeto_then_readfrom(size_t n_args, const mp_obj_t *p mp_buffer_info_t out_bufinfo; mp_get_buffer_raise(args[ARG_out_buffer].u_obj, &out_bufinfo, MP_BUFFER_READ); - - size_t out_length = out_bufinfo.len; + int out_stride_in_bytes = mp_binary_get_size('@', out_bufinfo.typecode, NULL); + size_t out_length = out_bufinfo.len / out_stride_in_bytes; int32_t out_start = args[ARG_out_start].u_int; const int32_t out_end = args[ARG_out_end].u_int; normalize_buffer_bounds(&out_start, out_end, &out_length); mp_buffer_info_t in_bufinfo; mp_get_buffer_raise(args[ARG_in_buffer].u_obj, &in_bufinfo, MP_BUFFER_WRITE); - - size_t in_length = in_bufinfo.len; + int in_stride_in_bytes = mp_binary_get_size('@', in_bufinfo.typecode, NULL); + size_t in_length = in_bufinfo.len / in_stride_in_bytes; int32_t in_start = args[ARG_in_start].u_int; const int32_t in_end = args[ARG_in_end].u_int; normalize_buffer_bounds(&in_start, in_end, &in_length); - if (in_length == 0) { - mp_raise_ValueError_varg(translate("%q length must be >= 1"), MP_QSTR_out_buffer); - } + mp_arg_validate_length_min(in_length, 1, MP_QSTR_out_buffer); + + // Treat start and length in terms of bytes from now on. + out_start *= out_stride_in_bytes; + out_length *= out_stride_in_bytes; + in_start *= in_stride_in_bytes; + in_length *= in_stride_in_bytes; uint8_t status = common_hal_busio_i2c_write_read(self, args[ARG_address].u_int, - ((uint8_t *)out_bufinfo.buf) + out_start, out_length,((uint8_t *)in_bufinfo.buf) + in_start, in_length); + ((uint8_t *)out_bufinfo.buf) + out_start, out_length, ((uint8_t *)in_bufinfo.buf) + in_start, in_length); if (status != 0) { mp_raise_OSError(status); } diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index eb89746d05..ccdceb5760 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -35,6 +35,7 @@ #include "shared/runtime/buffer_helper.h" #include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" #include "py/mperrno.h" #include "py/objproperty.h" #include "py/runtime.h" @@ -53,8 +54,13 @@ //| multiple secondaries can share the `!clock`, `!MOSI` and `!MISO` lines //| and therefore the hardware.)""" //| -//| def __init__(self, clock: microcontroller.Pin, MOSI: Optional[microcontroller.Pin] = None, MISO: Optional[microcontroller.Pin] = None, half_duplex: bool = False) -> None: -//| +//| def __init__( +//| self, +//| clock: microcontroller.Pin, +//| MOSI: Optional[microcontroller.Pin] = None, +//| MISO: Optional[microcontroller.Pin] = None, +//| half_duplex: bool = False, +//| ) -> None: //| """Construct an SPI object on the given pins. //| //| .. note:: The SPI peripherals allocated in order of desirability, if possible, @@ -75,9 +81,11 @@ //| :param ~microcontroller.Pin clock: the pin to use for the clock. //| :param ~microcontroller.Pin MOSI: the Main Out Selected In pin. //| :param ~microcontroller.Pin MISO: the Main In Selected Out pin. -//| :param bool half_duplex: True when MOSI is used for bidirectional data. False when SPI is full-duplex or simplex.""" -//| ... +//| :param bool half_duplex: True when MOSI is used for bidirectional data. False when SPI is full-duplex or simplex. //| +//| **Limitations:** ``half_duplex`` is available only on STM; other chips do not have the hardware support. +//| """ +//| ... // TODO(tannewt): Support LSB SPI. @@ -95,9 +103,9 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj); - const mcu_pin_obj_t *mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj); - const mcu_pin_obj_t *miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj); + const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock); + const mcu_pin_obj_t *mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj, MP_QSTR_mosi); + const mcu_pin_obj_t *miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj, MP_QSTR_miso); if (!miso && !mosi) { mp_raise_ValueError(translate("Must provide MISO or MOSI pin")); @@ -114,7 +122,6 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz //| def deinit(self) -> None: //| """Turn off the SPI bus.""" //| ... -//| STATIC mp_obj_t busio_spi_obj_deinit(mp_obj_t self_in) { busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_busio_spi_deinit(self); @@ -126,13 +133,11 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_deinit_obj, busio_spi_obj_deinit); //| """No-op used by Context Managers. //| Provided by context manager helper.""" //| ... -//| //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t busio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_busio_spi_deinit(MP_OBJ_TO_PTR(args[0])); @@ -153,7 +158,9 @@ STATIC void check_for_deinit(busio_spi_obj_t *self) { } } -//| def configure(self, *, baudrate: int = 100000, polarity: int = 0, phase: int = 0, bits: int = 8) -> None: +//| def configure( +//| self, *, baudrate: int = 100000, polarity: int = 0, phase: int = 0, bits: int = 8 +//| ) -> None: //| """Configures the SPI bus. The SPI object must be locked. //| //| :param int baudrate: the desired clock rate in Hertz. The actual clock rate may be higher or lower @@ -175,7 +182,6 @@ STATIC void check_for_deinit(busio_spi_obj_t *self) { //| Two SPI objects may be created, except on the Circuit Playground Bluefruit, //| which allows only one (to allow for an additional I2C object).""" //| ... -//| STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; @@ -209,7 +215,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure); //| :return: True when lock has been grabbed //| :rtype: bool""" //| ... -//| STATIC mp_obj_t busio_spi_obj_try_lock(mp_obj_t self_in) { busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -220,7 +225,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_try_lock_obj, busio_spi_obj_try_lock); //| def unlock(self) -> None: //| """Releases the SPI lock.""" //| ... -//| STATIC mp_obj_t busio_spi_obj_unlock(mp_obj_t self_in) { busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -244,7 +248,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock); //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... -//| STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; @@ -261,10 +264,16 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_ mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + // Compute bounds in terms of elements, not bytes. + int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); int32_t start = args[ARG_start].u_int; - size_t length = bufinfo.len; + size_t length = bufinfo.len / stride_in_bytes; normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + if (length == 0) { return mp_const_none; } @@ -279,7 +288,14 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 1, busio_spi_write); //| import sys -//| def readinto(self, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize, write_value: int = 0) -> None: +//| def readinto( +//| self, +//| buffer: WriteableBuffer, +//| *, +//| start: int = 0, +//| end: int = sys.maxsize, +//| write_value: int = 0 +//| ) -> None: //| """Read into ``buffer`` while writing ``write_value`` for each byte read. //| The SPI object must be locked. //| If the number of bytes to read is 0, nothing happens. @@ -296,7 +312,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 1, busio_spi_write); //| :param int write_value: value to write while reading //| """ //| ... -//| STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end, ARG_write_value }; @@ -314,10 +329,16 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); + // Compute bounds in terms of elements, not bytes. + int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); int32_t start = args[ARG_start].u_int; - size_t length = bufinfo.len; + size_t length = bufinfo.len / stride_in_bytes; normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + if (length == 0) { return mp_const_none; } @@ -331,7 +352,16 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 1, busio_spi_readinto); //| import sys -//| def write_readinto(self, out_buffer: ReadableBuffer, in_buffer: WriteableBuffer, *, out_start: int = 0, out_end: int = sys.maxsize, in_start: int = 0, in_end: int = sys.maxsize) -> None: +//| def write_readinto( +//| self, +//| out_buffer: ReadableBuffer, +//| in_buffer: WriteableBuffer, +//| *, +//| out_start: int = 0, +//| out_end: int = sys.maxsize, +//| in_start: int = 0, +//| in_end: int = sys.maxsize +//| ) -> None: //| """Write out the data in ``out_buffer`` while simultaneously reading data into ``in_buffer``. //| The SPI object must be locked. //| @@ -355,7 +385,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 1, busio_spi_readinto); //| :param int in_end: end of ``in_buffer slice``; if not specified, use ``len(in_buffer)`` //| """ //| ... -//| STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_out_buffer, ARG_in_buffer, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; @@ -375,16 +404,24 @@ STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args mp_buffer_info_t buf_out_info; mp_get_buffer_raise(args[ARG_out_buffer].u_obj, &buf_out_info, MP_BUFFER_READ); + int out_stride_in_bytes = mp_binary_get_size('@', buf_out_info.typecode, NULL); int32_t out_start = args[ARG_out_start].u_int; - size_t out_length = buf_out_info.len; + size_t out_length = buf_out_info.len / out_stride_in_bytes; normalize_buffer_bounds(&out_start, args[ARG_out_end].u_int, &out_length); mp_buffer_info_t buf_in_info; mp_get_buffer_raise(args[ARG_in_buffer].u_obj, &buf_in_info, MP_BUFFER_WRITE); + int in_stride_in_bytes = mp_binary_get_size('@', buf_in_info.typecode, NULL); int32_t in_start = args[ARG_in_start].u_int; - size_t in_length = buf_in_info.len; + size_t in_length = buf_in_info.len / in_stride_in_bytes; normalize_buffer_bounds(&in_start, args[ARG_in_end].u_int, &in_length); + // Treat start and length in terms of bytes from now on. + out_start *= out_stride_in_bytes; + out_length *= out_stride_in_bytes; + in_start *= in_stride_in_bytes; + in_length *= in_stride_in_bytes; + if (out_length != in_length) { mp_raise_ValueError(translate("buffer slices must be of equal length")); } @@ -446,9 +483,6 @@ const mp_obj_type_t busio_spi_type = { .locals_dict = (mp_obj_dict_t *)&busio_spi_locals_dict, }; -busio_spi_obj_t *validate_obj_is_spi_bus(mp_obj_t obj) { - if (!mp_obj_is_type(obj, &busio_spi_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), busio_spi_type.name); - } - return MP_OBJ_TO_PTR(obj); +busio_spi_obj_t *validate_obj_is_spi_bus(mp_obj_t obj, qstr arg_name) { + return mp_arg_validate_type(obj, &busio_spi_type, arg_name); } diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h index 76166580a0..3b8f831219 100644 --- a/shared-bindings/busio/SPI.h +++ b/shared-bindings/busio/SPI.h @@ -70,6 +70,6 @@ uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t *self); // This is used by the supervisor to claim SPI devices indefinitely. extern void common_hal_busio_spi_never_reset(busio_spi_obj_t *self); -extern busio_spi_obj_t *validate_obj_is_spi_bus(mp_obj_t obj_in); +extern busio_spi_obj_t *validate_obj_is_spi_bus(mp_obj_t obj_in, qstr arg_name); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_H diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index baa7f2cdba..77d7036c2e 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -33,7 +33,7 @@ #include "shared/runtime/context_manager_helpers.h" #include "shared/runtime/interrupt_char.h" -#include "py/ioctl.h" +#include "py/stream.h" #include "py/objproperty.h" #include "py/objtype.h" #include "py/runtime.h" @@ -45,7 +45,23 @@ //| class UART: //| """A bidirectional serial protocol""" -//| def __init__(self, tx: microcontroller.Pin, rx: microcontroller.Pin, *, baudrate: int = 9600, bits: int = 8, parity: Optional[Parity] = None, stop: int = 1, timeout: float = 1, receiver_buffer_size: int = 64) -> None: +//| +//| def __init__( +//| self, +//| tx: Optional[microcontroller.Pin] = None, +//| rx: Optional[microcontroller.Pin] = None, +//| *, +//| rts: Optional[microcontroller.Pin] = None, +//| cts: Optional[microcontroller.Pin] = None, +//| rs485_dir: Optional[microcontroller.Pin] = None, +//| rs485_invert: bool = False, +//| baudrate: int = 9600, +//| bits: int = 8, +//| parity: Optional[Parity] = None, +//| stop: int = 1, +//| timeout: float = 1, +//| receiver_buffer_size: int = 64 +//| ) -> None: //| """A common bidirectional serial protocol that uses an an agreed upon speed //| rather than a shared clock line. //| @@ -62,15 +78,17 @@ //| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters when reading. Raises ``ValueError`` if timeout >100 seconds. //| :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.) //| +//| ``tx`` and ``rx`` cannot both be ``None``. +//| //| *New in CircuitPython 4.0:* ``timeout`` has incompatibly changed units from milliseconds to seconds. //| The new upper limit on ``timeout`` is meant to catch mistaken use of milliseconds. //| -//| .. note:: RS485 support on i.MX and Raspberry Pi RP2040 is implemented in software. -//| The timing for the ``rs485_dir`` pin signal is done on a best-effort basis, and may not meet -//| RS485 specifications intermittently. +//| **Limitations:** RS485 is not supported on SAMD, nRF, Broadcom, Spresense, or STM. +//| On i.MX and Raspberry Pi RP2040, RS485 support is implemented in software: +//| The timing for the ``rs485_dir`` pin signal is done on a best-effort basis, and may not meet +//| RS485 specifications intermittently. //| """ //| ... -//| typedef struct { mp_obj_base_t base; } busio_uart_parity_obj_t; @@ -79,9 +97,7 @@ extern const busio_uart_parity_obj_t busio_uart_parity_odd_obj; #if CIRCUITPY_BUSIO_UART STATIC void validate_timeout(mp_float_t timeout) { - if (timeout < (mp_float_t)0.0f || timeout > (mp_float_t)100.0f) { - mp_raise_ValueError(translate("timeout must be 0.0-100.0 seconds")); - } + mp_arg_validate_int_range((int)timeout, 0, 100, MP_QSTR_timeout); } #endif // CIRCUITPY_BUSIO_UART @@ -106,13 +122,23 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, si mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *rx = validate_obj_is_free_pin_or_none(args[ARG_rx].u_obj); - const mcu_pin_obj_t *tx = validate_obj_is_free_pin_or_none(args[ARG_tx].u_obj); - + const mcu_pin_obj_t *rx = validate_obj_is_free_pin_or_none(args[ARG_rx].u_obj, MP_QSTR_rx); + const mcu_pin_obj_t *tx = validate_obj_is_free_pin_or_none(args[ARG_tx].u_obj, MP_QSTR_tx); + const mcu_pin_obj_t *rts = validate_obj_is_free_pin_or_none(args[ARG_rts].u_obj, MP_QSTR_rts); + const mcu_pin_obj_t *cts = validate_obj_is_free_pin_or_none(args[ARG_cts].u_obj, MP_QSTR_cts); + const mcu_pin_obj_t *rs485_dir = validate_obj_is_free_pin_or_none(args[ARG_rs485_dir].u_obj, MP_QSTR_rs485_dir); if ((tx == NULL) && (rx == NULL)) { mp_raise_ValueError(translate("tx and rx cannot both be None")); } + // Pins must be distinct. + if ((tx != NULL && (tx == rx || tx == rts || tx == cts || tx == rs485_dir)) || + (rx != NULL && (rx == rts || rx == cts || rx == rs485_dir)) || + (rts != NULL && (rts == cts || rts == rs485_dir)) || + (cts != NULL && (cts == rs485_dir))) { + raise_ValueError_invalid_pins(); + } + uint8_t bits = (uint8_t)mp_arg_validate_int_range(args[ARG_bits].u_int, 5, 9, MP_QSTR_bits); busio_uart_parity_t parity = BUSIO_UART_PARITY_NONE; @@ -127,10 +153,6 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, si mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); validate_timeout(timeout); - const mcu_pin_obj_t *rts = validate_obj_is_free_pin_or_none(args[ARG_rts].u_obj); - const mcu_pin_obj_t *cts = validate_obj_is_free_pin_or_none(args[ARG_cts].u_obj); - const mcu_pin_obj_t *rs485_dir = validate_obj_is_free_pin_or_none(args[ARG_rs485_dir].u_obj); - const bool rs485_invert = args[ARG_rs485_invert].u_bool; // Always initially allocate the UART object within the long-lived heap. @@ -145,7 +167,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, si args[ARG_receiver_buffer_size].u_int, NULL, false); return (mp_obj_t)self; #else - mp_raise_ValueError(translate("Invalid pins")); + mp_raise_NotImplementedError(NULL); #endif // CIRCUITPY_BUSIO_UART } @@ -165,7 +187,6 @@ STATIC busio_uart_obj_t *native_uart(mp_obj_t uart_obj) { //| def deinit(self) -> None: //| """Deinitialises the UART and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t busio_uart_obj_deinit(mp_obj_t self_in) { busio_uart_obj_t *self = native_uart(self_in); common_hal_busio_uart_deinit(self); @@ -182,14 +203,12 @@ STATIC void check_for_deinit(busio_uart_obj_t *self) { //| def __enter__(self) -> UART: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t busio_uart_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_busio_uart_deinit(MP_OBJ_TO_PTR(args[0])); @@ -200,15 +219,18 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_ // These are standard stream methods. Code is in py/stream.c. // //| def read(self, nbytes: Optional[int] = None) -> Optional[bytes]: -//| """Read characters. If ``nbytes`` is specified then read at most that many +//| """Read bytes. If ``nbytes`` is specified then read at most that many //| bytes. Otherwise, read everything that arrives until the connection //| times out. Providing the number of bytes expected is highly recommended -//| because it will be faster. +//| because it will be faster. If no bytes are read, return ``None``. +//| +//| .. note:: When no bytes are read due to a timeout, this function returns ``None``. +//| This matches the behavior of `io.RawIOBase.read` in Python 3, but +//| differs from pyserial which returns ``b''`` in that situation. //| //| :return: Data read //| :rtype: bytes or None""" //| ... -//| //| def readinto(self, buf: WriteableBuffer) -> Optional[int]: //| """Read bytes into the ``buf``. Read at most ``len(buf)`` bytes. @@ -218,27 +240,25 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_ //| //| *New in CircuitPython 4.0:* No length parameter is permitted.""" //| ... -//| //| def readline(self) -> bytes: //| """Read a line, ending in a newline character, or -//| return None if a timeout occurs sooner, or -//| return everything readable if no newline is found and timeout=0 +//| return ``None`` if a timeout occurs sooner, or +//| return everything readable if no newline is found and +//| ``timeout=0`` //| //| :return: the line read //| :rtype: bytes or None""" //| ... -//| -//| def write(self, buf: WriteableBuffer) -> Optional[int]: +//| def write(self, buf: ReadableBuffer) -> Optional[int]: //| """Write the buffer of bytes to the bus. //| -//| *New in CircuitPython 4.0:* ``buf`` must be bytes, not a string. +//| *New in CircuitPython 4.0:* ``buf`` must be bytes, not a string. //| -//| :return: the number of bytes written -//| :rtype: int or None""" +//| :return: the number of bytes written +//| :rtype: int or None""" //| ... -//| // These three methods are used by the shared stream methods. STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { @@ -267,14 +287,14 @@ STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t busio_uart_obj_t *self = native_uart(self_in); check_for_deinit(self); mp_uint_t ret; - if (request == MP_IOCTL_POLL) { + if (request == MP_STREAM_POLL) { mp_uint_t flags = arg; ret = 0; - if ((flags & MP_IOCTL_POLL_RD) && common_hal_busio_uart_rx_characters_available(self) > 0) { - ret |= MP_IOCTL_POLL_RD; + if ((flags & MP_STREAM_POLL_RD) && common_hal_busio_uart_rx_characters_available(self) > 0) { + ret |= MP_STREAM_POLL_RD; } - if ((flags & MP_IOCTL_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) { - ret |= MP_IOCTL_POLL_WR; + if ((flags & MP_STREAM_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) { + ret |= MP_STREAM_POLL_WR; } } else { *errcode = MP_EINVAL; @@ -285,7 +305,6 @@ STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t //| baudrate: int //| """The current baudrate.""" -//| STATIC mp_obj_t busio_uart_obj_get_baudrate(mp_obj_t self_in) { busio_uart_obj_t *self = native_uart(self_in); check_for_deinit(self); @@ -308,7 +327,6 @@ MP_PROPERTY_GETSET(busio_uart_baudrate_obj, //| in_waiting: int //| """The number of bytes in the input buffer, available to be read""" -//| STATIC mp_obj_t busio_uart_obj_get_in_waiting(mp_obj_t self_in) { busio_uart_obj_t *self = native_uart(self_in); check_for_deinit(self); @@ -321,7 +339,6 @@ MP_PROPERTY_GETTER(busio_uart_in_waiting_obj, //| timeout: float //| """The current timeout, in seconds (float).""" -//| STATIC mp_obj_t busio_uart_obj_get_timeout(mp_obj_t self_in) { busio_uart_obj_t *self = native_uart(self_in); check_for_deinit(self); diff --git a/shared-bindings/busio/__init__.c b/shared-bindings/busio/__init__.c index 969c10e938..4d62c8333e 100644 --- a/shared-bindings/busio/__init__.c +++ b/shared-bindings/busio/__init__.c @@ -78,7 +78,6 @@ //| Tutorial for UART: //| https://learn.adafruit.com/circuitpython-essentials/circuitpython-uart-serial //| """ -//| STATIC const mp_rom_map_elem_t busio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_busio) }, diff --git a/shared-bindings/camera/Camera.c b/shared-bindings/camera/Camera.c index f7bc9eec6a..4f6023c9fd 100644 --- a/shared-bindings/camera/Camera.c +++ b/shared-bindings/camera/Camera.c @@ -60,7 +60,6 @@ //| def __init__(self) -> None: //| """Initialize camera.""" //| ... -//| STATIC mp_obj_t camera_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { camera_obj_t *self = m_new_obj(camera_obj_t); self->base.type = &camera_type; @@ -74,7 +73,6 @@ STATIC mp_obj_t camera_make_new(const mp_obj_type_t *type, size_t n_args, size_t //| def deinit(self) -> None: //| """De-initialize camera.""" //| ... -//| STATIC mp_obj_t camera_obj_deinit(mp_obj_t self_in) { camera_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_camera_deinit(self); diff --git a/shared-bindings/camera/ImageFormat.c b/shared-bindings/camera/ImageFormat.c index 3ff687b7bf..1a0c3c88d6 100644 --- a/shared-bindings/camera/ImageFormat.c +++ b/shared-bindings/camera/ImageFormat.c @@ -31,7 +31,6 @@ //| //| def __init__(self) -> None: //| """Enum-like class to define the image format.""" -//| //| JPG: ImageFormat //| """JPG format.""" //| diff --git a/shared-bindings/camera/__init__.c b/shared-bindings/camera/__init__.c index 12cebae7db..e4ee263f58 100644 --- a/shared-bindings/camera/__init__.c +++ b/shared-bindings/camera/__init__.c @@ -33,7 +33,6 @@ //| """Support for camera input //| //| The `camera` module contains classes to control the camera and take pictures.""" -//| STATIC const mp_rom_map_elem_t camera_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_camera) }, { MP_ROM_QSTR(MP_QSTR_Camera), MP_ROM_PTR(&camera_type) }, diff --git a/shared-bindings/canio/CAN.c b/shared-bindings/canio/CAN.c index e8aec7f0a1..bce581f501 100644 --- a/shared-bindings/canio/CAN.c +++ b/shared-bindings/canio/CAN.c @@ -37,19 +37,19 @@ #include "py/objproperty.h" #include "py/runtime.h" -//| //| class CAN: //| """CAN bus protocol""" //| -//| def __init__(self, -//| tx: microcontroller.Pin, -//| rx: microcontroller.Pin, -//| *, -//| baudrate: int = 250000, -//| loopback: bool = False, -//| silent: bool = False, -//| auto_restart: bool = False, -//| ) -> None: +//| def __init__( +//| self, +//| tx: microcontroller.Pin, +//| rx: microcontroller.Pin, +//| *, +//| baudrate: int = 250000, +//| loopback: bool = False, +//| silent: bool = False, +//| auto_restart: bool = False, +//| ) -> None: //| """A common shared-bus protocol. The rx and tx pins are generally //| connected to a transceiver which controls the H and L pins on a //| shared bus. @@ -62,7 +62,6 @@ //| :param bool auto_restart: If True, will restart communications after entering bus-off state //| """ //| ... -//| STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_loopback, ARG_silent, ARG_auto_restart, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -78,8 +77,8 @@ STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *rx_pin = validate_obj_is_free_pin_or_none(args[ARG_rx].u_obj); - const mcu_pin_obj_t *tx_pin = validate_obj_is_free_pin_or_none(args[ARG_tx].u_obj); + const mcu_pin_obj_t *rx_pin = validate_obj_is_free_pin_or_none(args[ARG_rx].u_obj, MP_QSTR_rx); + const mcu_pin_obj_t *tx_pin = validate_obj_is_free_pin_or_none(args[ARG_tx].u_obj, MP_QSTR_tx); if (!rx_pin && !tx_pin) { mp_raise_ValueError(translate("tx and rx cannot both be None")); } @@ -96,7 +95,6 @@ STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, siz //| auto_restart: bool //| """If True, will restart communications after entering bus-off state""" -//| STATIC mp_obj_t canio_can_auto_restart_get(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -119,7 +117,6 @@ MP_PROPERTY_GETSET(canio_can_auto_restart_obj, //| baudrate: int //| """The baud rate (read-only)""" -//| STATIC mp_obj_t canio_can_baudrate_get(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -132,7 +129,6 @@ MP_PROPERTY_GETTER(canio_can_baudrate_obj, //| transmit_error_count: int //| """The number of transmit errors (read-only). Increased for a detected transmission error, decreased for successful transmission. Limited to the range from 0 to 255 inclusive. Also called TEC.""" -//| STATIC mp_obj_t canio_can_transmit_error_count_get(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -145,7 +141,6 @@ MP_PROPERTY_GETTER(canio_can_transmit_error_count_obj, //| receive_error_count: int //| """The number of receive errors (read-only). Increased for a detected reception error, decreased for successful reception. Limited to the range from 0 to 255 inclusive. Also called REC.""" -//| STATIC mp_obj_t canio_can_receive_error_count_get(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -173,7 +168,6 @@ MP_PROPERTY_GETTER(canio_can_state_obj, //| def restart(self) -> None: //| """If the device is in the bus off state, restart it.""" //| ... -//| STATIC mp_obj_t canio_can_restart(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -182,7 +176,9 @@ STATIC mp_obj_t canio_can_restart(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_restart_obj, canio_can_restart); -//| def listen(self, matches: Optional[Sequence[Match]]=None, *, timeout: float=10) -> Listener: +//| def listen( +//| self, matches: Optional[Sequence[Match]] = None, *, timeout: float = 10 +//| ) -> Listener: //| """Start receiving messages that match any one of the filters. //| //| Creating a listener is an expensive operation and can interfere with reception of messages by other listeners. @@ -214,7 +210,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_restart_obj, canio_can_restart); //| standard address with mask or an extended address with mask. //| """ //| ... -//| STATIC mp_obj_t canio_can_listen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { canio_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); common_hal_canio_can_check_for_deinit(self); @@ -238,11 +233,7 @@ STATIC mp_obj_t canio_can_listen(size_t n_args, const mp_obj_t *pos_args, mp_map canio_match_obj_t *matches[nmatch]; for (size_t i = 0; i < nmatch; i++) { - const mp_obj_type_t *type = mp_obj_get_type(match_objects[i]); - if (type != &canio_match_type) { - mp_raise_TypeError_varg(translate("expected '%q' but got '%q'"), MP_QSTR_Match, type->name); - } - matches[i] = MP_OBJ_TO_PTR(match_objects[i]); + matches[i] = mp_arg_validate_type_in(match_objects[i], &canio_match_type, MP_QSTR_matches); } float timeout = args[ARG_timeout].u_obj ? mp_obj_get_float(args[ARG_timeout].u_obj) : 10.0f; @@ -256,7 +247,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(canio_can_listen_obj, 1, canio_can_listen); //| loopback: bool //| """True if the device was created in loopback mode, False //| otherwise (read-only)""" -//| STATIC mp_obj_t canio_can_loopback_get(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -273,13 +263,12 @@ MP_PROPERTY_GETTER(canio_can_loopback_obj, //| If the message could not be sent due to a full fifo or a bus error condition, RuntimeError is raised. //| """ //| ... -//| STATIC mp_obj_t canio_can_send(mp_obj_t self_in, mp_obj_t message_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); const mp_obj_type_t *message_type = mp_obj_get_type(message_in); if (message_type != &canio_message_type && message_type != &canio_remote_transmission_request_type) { - mp_raise_TypeError_varg(translate("expected '%q' or '%q' but got '%q'"), MP_QSTR_Message, MP_QSTR_RemoteTransmissionRequest, message_type->name); + mp_raise_TypeError_varg(translate("%q must be of type %q or %q, not %q"), MP_QSTR_message, MP_QSTR_Message, MP_QSTR_RemoteTransmissionRequest, message_type->name); } canio_message_obj_t *message = message_in; @@ -291,7 +280,6 @@ MP_DEFINE_CONST_FUN_OBJ_2(canio_can_send_obj, canio_can_send); //| silent: bool //| """True if the device was created in silent mode, False //| otherwise (read-only)""" -//| STATIC mp_obj_t canio_can_silent_get(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -306,7 +294,6 @@ MP_PROPERTY_GETTER(canio_can_silent_obj, //| def deinit(self) -> None: //| """Deinitialize this object, freeing its hardware resources""" //| ... -//| STATIC mp_obj_t canio_can_deinit(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_deinit(self); @@ -317,7 +304,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_deinit_obj, canio_can_deinit); //| def __enter__(self) -> CAN: //| """Returns self, to allow the object to be used in a `with` statement for resource control""" //| ... -//| STATIC mp_obj_t canio_can_enter(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -325,9 +311,15 @@ STATIC mp_obj_t canio_can_enter(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_can_enter_obj, canio_can_enter); -//| def __exit__(self, unused1: Optional[Type[BaseException]], unused2: Optional[BaseException], unused3: Optional[TracebackType]) -> None: +//| def __exit__( +//| self, +//| unused1: Optional[Type[BaseException]], +//| unused2: Optional[BaseException], +//| unused3: Optional[TracebackType], +//| ) -> None: //| """Calls deinit()""" //| ... +//| STATIC mp_obj_t canio_can_exit(size_t num_args, const mp_obj_t args[]) { canio_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); common_hal_canio_can_deinit(self); diff --git a/shared-bindings/canio/Listener.c b/shared-bindings/canio/Listener.c index e59801d4e4..e10f7fde6f 100644 --- a/shared-bindings/canio/Listener.c +++ b/shared-bindings/canio/Listener.c @@ -43,13 +43,12 @@ //| message arrives within ``self.timeout`` seconds.""" //| -//| def receive(self) -> Optional[Union[RemoteTransmissionRequest,Message]]: +//| def receive(self) -> Optional[Union[RemoteTransmissionRequest, Message]]: //| """Reads a message, after waiting up to ``self.timeout`` seconds //| //| If no message is received in time, `None` is returned. Otherwise, //| a `Message` or `RemoteTransmissionRequest` is returned.""" //| ... -//| STATIC mp_obj_t canio_listener_receive(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_check_for_deinit(self); @@ -68,7 +67,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_receive_obj, canio_listener_rece //| """Returns the number of messages (including remote //| transmission requests) waiting""" //| ... -//| STATIC mp_obj_t canio_listener_in_waiting(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_check_for_deinit(self); @@ -82,8 +80,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_in_waiting_obj, canio_listener_i //| This method exists so that `Listener` can be used as an //| iterable""" //| ... -//| -//| def __next__(self) -> Union[RemoteTransmissionRequest,Message]: +//| def __next__(self) -> Union[RemoteTransmissionRequest, Message]: //| """Reads a message, after waiting up to self.timeout seconds //| //| If no message is received in time, raises StopIteration. Otherwise, @@ -92,7 +89,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_in_waiting_obj, canio_listener_i //| This method enables the `Listener` to be used as an //| iterable, for instance in a for-loop.""" //| ... -//| STATIC mp_obj_t canio_iternext(mp_obj_t self_in) { mp_obj_t result = canio_listener_receive(self_in); if (result == mp_const_none) { @@ -104,7 +100,6 @@ STATIC mp_obj_t canio_iternext(mp_obj_t self_in) { //| def deinit(self) -> None: //| """Deinitialize this object, freeing its hardware resources""" //| ... -//| STATIC mp_obj_t canio_listener_deinit(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_deinit(self); @@ -115,7 +110,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_deinit_obj, canio_listener_deini //| def __enter__(self) -> CAN: //| """Returns self, to allow the object to be used in a `with` statement for resource control""" //| ... -//| STATIC mp_obj_t canio_listener_enter(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_check_for_deinit(self); @@ -123,7 +117,12 @@ STATIC mp_obj_t canio_listener_enter(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_enter_obj, canio_listener_enter); -//| def __exit__(self, unused1: Optional[Type[BaseException]], unused2: Optional[BaseException], unused3: Optional[TracebackType]) -> None: +//| def __exit__( +//| self, +//| unused1: Optional[Type[BaseException]], +//| unused2: Optional[BaseException], +//| unused3: Optional[TracebackType], +//| ) -> None: //| """Calls deinit()""" //| ... STATIC mp_obj_t canio_listener_exit(size_t num_args, const mp_obj_t args[]) { @@ -134,7 +133,8 @@ STATIC mp_obj_t canio_listener_exit(size_t num_args, const mp_obj_t args[]) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(canio_listener_exit_obj, 4, 4, canio_listener_exit); -//| timeout : float +//| timeout: float +//| STATIC mp_obj_t canio_listener_timeout_get(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_check_for_deinit(self); diff --git a/shared-bindings/canio/Match.c b/shared-bindings/canio/Match.c index 52262b0a6c..06729f9c54 100644 --- a/shared-bindings/canio/Match.c +++ b/shared-bindings/canio/Match.c @@ -32,7 +32,6 @@ //| class Match: //| """Describe CAN bus messages to match""" //| -//| //| def __init__(self, id: int, *, mask: Optional[int] = None, extended: bool = False) -> None: //| """Construct a Match with the given properties. //| @@ -40,7 +39,6 @@ //| the nonzero bits in mask. Otherwise, it matches exactly the given id. //| If extended is true then only extended ids are matched, otherwise //| only standard ids are matched.""" -//| STATIC mp_obj_t canio_match_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_id, ARG_mask, ARG_extended, NUM_ARGS }; @@ -74,7 +72,6 @@ STATIC mp_obj_t canio_match_make_new(const mp_obj_type_t *type, size_t n_args, s //| id: int //| """The id to match""" -//| STATIC mp_obj_t canio_match_id_get(mp_obj_t self_in) { canio_match_obj_t *self = self_in; @@ -85,10 +82,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(canio_match_id_get_obj, canio_match_id_get); MP_PROPERTY_GETTER(canio_match_id_obj, (mp_obj_t)&canio_match_id_get_obj); -//| //| mask: int //| """The optional mask of ids to match""" -//| STATIC mp_obj_t canio_match_mask_get(mp_obj_t self_in) { canio_match_obj_t *self = self_in; diff --git a/shared-bindings/canio/Message.c b/shared-bindings/canio/Message.c index 28c445316a..c3857256bd 100644 --- a/shared-bindings/canio/Message.c +++ b/shared-bindings/canio/Message.c @@ -41,7 +41,6 @@ //| In CAN, messages can have a length from 0 to 8 bytes. //| """ //| ... -//| STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_id, ARG_data, ARG_extended, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -67,7 +66,6 @@ STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, //| id: int //| """The numeric ID of the message""" -//| STATIC mp_obj_t canio_message_id_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; return MP_OBJ_NEW_SMALL_INT(common_hal_canio_message_get_id(self)); @@ -87,7 +85,6 @@ MP_PROPERTY_GETSET(canio_message_id_obj, //| data: bytes //| """The content of the message""" -//| STATIC mp_obj_t canio_message_data_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; return mp_obj_new_bytes((const byte *)common_hal_canio_message_get_data(self), common_hal_canio_message_get_length(self)); diff --git a/shared-bindings/canio/RemoteTransmissionRequest.c b/shared-bindings/canio/RemoteTransmissionRequest.c index 58ac3aa2de..1efc401909 100644 --- a/shared-bindings/canio/RemoteTransmissionRequest.c +++ b/shared-bindings/canio/RemoteTransmissionRequest.c @@ -41,7 +41,6 @@ //| In CAN, messages can have a length from 0 to 8 bytes. //| """ //| ... -//| STATIC mp_obj_t canio_remote_transmission_request_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_id, ARG_length, ARG_extended, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -68,7 +67,6 @@ STATIC mp_obj_t canio_remote_transmission_request_make_new(const mp_obj_type_t * //| id: int //| """The numeric ID of the message""" -//| STATIC mp_obj_t canio_remote_transmission_request_id_get(const mp_obj_t self_in) { canio_remote_transmission_request_obj_t *self = self_in; return MP_OBJ_NEW_SMALL_INT(common_hal_canio_remote_transmission_request_get_id(self)); @@ -88,7 +86,6 @@ MP_PROPERTY_GETSET(canio_remote_transmission_request_id_obj, //| extended: bool //| """True if the message's id is an extended id""" -//| STATIC mp_obj_t canio_remote_transmission_request_extended_get(const mp_obj_t self_in) { canio_remote_transmission_request_obj_t *self = self_in; return mp_obj_new_bool(common_hal_canio_remote_transmission_request_get_extended(self)); diff --git a/shared-bindings/canio/__init__.c b/shared-bindings/canio/__init__.c index ef1b90df97..ecef7ebde6 100644 --- a/shared-bindings/canio/__init__.c +++ b/shared-bindings/canio/__init__.c @@ -54,6 +54,9 @@ //| Other implementations of the CAN device may exist (for instance, attached //| via an SPI bus). If so their constructor arguments may differ, but //| otherwise we encourage implementors to follow the API that the core uses. +//| +//| For more information on working with this module, refer to +//| `this Learn Guide on using it `_. //| """ //| diff --git a/shared-bindings/countio/Counter.c b/shared-bindings/countio/Counter.c index 79ac3e75da..4f0e0a692f 100644 --- a/shared-bindings/countio/Counter.c +++ b/shared-bindings/countio/Counter.c @@ -11,10 +11,15 @@ #include "shared-bindings/util.h" //| class Counter: -//| """Count the number of rising- and/or falling-edge transitions on a given pin. -//| """ +//| """Count the number of rising- and/or falling-edge transitions on a given pin.""" //| -//| def __init__(self, pin: microcontroller.Pin, *, edge: Edge = Edge.FALL, pull: Optional[digitalio.Pull] = None) -> None: +//| def __init__( +//| self, +//| pin: microcontroller.Pin, +//| *, +//| edge: Edge = Edge.FALL, +//| pull: Optional[digitalio.Pull] = None +//| ) -> None: //| """Create a Counter object associated with the given pin that counts //| rising- and/or falling-edge transitions. At least one of ``rise`` and ``fall`` must be True. //| The default is to count only falling edges, and is for historical backward compatibility. @@ -38,7 +43,6 @@ //| print(pin_counter.count) //| """ //| ... -//| STATIC mp_obj_t countio_counter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pin, ARG_edge, ARG_pull }; static const mp_arg_t allowed_args[] = { @@ -49,7 +53,7 @@ STATIC mp_obj_t countio_counter_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); const countio_edge_t edge = validate_edge(args[ARG_edge].u_obj, MP_QSTR_edge); const digitalio_pull_t pull = validate_pull(args[ARG_pull].u_obj, MP_QSTR_pull); // Make long-lived because some implementations use a pointer to the object as interrupt-handler data. @@ -63,7 +67,6 @@ STATIC mp_obj_t countio_counter_make_new(const mp_obj_type_t *type, size_t n_arg //| def deinit(self) -> None: //| """Deinitializes the Counter and releases any hardware resources for reuse.""" -//| STATIC mp_obj_t countio_counter_deinit(mp_obj_t self_in) { countio_counter_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_countio_counter_deinit(self); @@ -79,13 +82,11 @@ STATIC void check_for_deinit(countio_counter_obj_t *self) { //| def __enter__(self) -> Counter: //| """No-op used by Context Managers.""" -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See -//| :ref:`lifetime-and-contextmanagers` for more info.""" -//| +//| :ref:`lifetime-and-contextmanagers` for more info.""" STATIC mp_obj_t countio_counter_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_countio_counter_deinit(args[0]); @@ -96,7 +97,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(countio_counter___exit___obj, 4, 4, c //| count: int //| """The current count in terms of pulses.""" -//| STATIC mp_obj_t countio_counter_obj_get_count(mp_obj_t self_in) { countio_counter_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/countio/Edge.c b/shared-bindings/countio/Edge.c index 980b3a3705..9b8e74304b 100644 --- a/shared-bindings/countio/Edge.c +++ b/shared-bindings/countio/Edge.c @@ -40,7 +40,6 @@ MAKE_ENUM_VALUE(countio_edge_type, edge, RISE_AND_FALL, EDGE_RISE_AND_FALL); //| def __init__(self) -> None: //| """Enum-like class to define which signal transitions to count.""" //| ... -//| //| RISE: Edge //| """Count the rising edges.""" //| @@ -48,7 +47,10 @@ MAKE_ENUM_VALUE(countio_edge_type, edge, RISE_AND_FALL, EDGE_RISE_AND_FALL); //| """Count the falling edges.""" //| //| RISE_AND_FALL: Edge -//| """Count the rising and falling edges.""" +//| """Count the rising and falling edges. +//| +//| **Limitations:** ``RISE_AND_FALL`` is not available to RP2040 due to hardware limitations. +//| """ //| MAKE_ENUM_MAP(countio_edge) { MAKE_ENUM_MAP_ENTRY(edge, RISE), @@ -63,5 +65,5 @@ MAKE_PRINTER(countio, countio_edge); MAKE_ENUM_TYPE(countio, Edge, countio_edge); countio_edge_t validate_edge(mp_obj_t obj, qstr arg_name) { - return cp_enum_value(&countio_edge_type, mp_arg_validate_type(obj, &countio_edge_type, arg_name)); + return cp_enum_value(&countio_edge_type, obj, arg_name); } diff --git a/shared-bindings/countio/Edge.h b/shared-bindings/countio/Edge.h index ca4cddbef3..86112fb4a3 100644 --- a/shared-bindings/countio/Edge.h +++ b/shared-bindings/countio/Edge.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2021 an Halbertfor Adafruit Industries + * Copyright (c) 2021 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/shared-bindings/countio/__init__.c b/shared-bindings/countio/__init__.c index d72ed9fd25..25e9c7d630 100644 --- a/shared-bindings/countio/__init__.c +++ b/shared-bindings/countio/__init__.c @@ -13,11 +13,14 @@ //| //| The `countio` module contains logic to read and count edge transistions //| +//| For more information on the applications of counting edges, see +//| `this Learn Guide on sequential circuits +//| `_. +//| //| All classes change hardware state and should be deinitialized when they //| are no longer needed if the program continues after use. To do so, either //| call :py:meth:`!deinit` or use a context manager. See //| :ref:`lifetime-and-contextmanagers` for more info.""" -//| STATIC const mp_rom_map_elem_t countio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_countio) }, diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index ae72b5cb55..de4d66f9d8 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -43,6 +43,35 @@ #include "shared-bindings/util.h" #include "supervisor/shared/translate/translate.h" +#if CIRCUITPY_CYW43 +#include "bindings/cyw43/__init__.h" +#endif + +STATIC void check_result(digitalinout_result_t result) { + switch (result) { + case DIGITALINOUT_OK: + return; + case DIGITALINOUT_PIN_BUSY: + mp_raise_ValueError_varg(translate("%q in use"), MP_QSTR_Pin); + #if CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY + case DIGITALINOUT_INPUT_ONLY: + mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_direction); + #endif + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL + case DIGITALINOUT_INVALID_PULL: + mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_pull); + #endif + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE + case DIGITALINOUT_INVALID_DRIVE_MODE: + mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_drive_mode); + #endif + } +} + +MP_WEAK const mcu_pin_obj_t *common_hal_digitalio_validate_pin(mp_obj_t obj) { + return validate_obj_is_free_pin(obj, MP_QSTR_pin); +} + //| class DigitalInOut: //| """Digital input and output //| @@ -57,7 +86,6 @@ //| //| :param ~microcontroller.Pin pin: The pin to control""" //| ... -//| STATIC mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); @@ -65,7 +93,7 @@ STATIC mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, digitalio_digitalinout_obj_t *self = m_new_obj(digitalio_digitalinout_obj_t); self->base.type = &digitalio_digitalinout_type; - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]); + const mcu_pin_obj_t *pin = common_hal_digitalio_validate_pin(args[0]); common_hal_digitalio_digitalinout_construct(self, pin); return MP_OBJ_FROM_PTR(self); @@ -74,7 +102,6 @@ STATIC mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, //| def deinit(self) -> None: //| """Turn off the DigitalInOut and release the pin for other use.""" //| ... -//| STATIC mp_obj_t digitalio_digitalinout_obj_deinit(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_digitalio_digitalinout_deinit(self); @@ -85,14 +112,12 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_deinit_obj, digitalio_digitalin //| def __enter__(self) -> DigitalInOut: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t digitalio_digitalinout_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_digitalio_digitalinout_deinit(MP_OBJ_TO_PTR(args[0])); @@ -106,7 +131,9 @@ STATIC void check_for_deinit(digitalio_digitalinout_obj_t *self) { } } -//| def switch_to_output(self, value: bool = False, drive_mode: DriveMode = DriveMode.PUSH_PULL) -> None: +//| def switch_to_output( +//| self, value: bool = False, drive_mode: DriveMode = DriveMode.PUSH_PULL +//| ) -> None: //| """Set the drive mode and value and then switch to writing out digital //| values. //| @@ -114,7 +141,6 @@ STATIC void check_for_deinit(digitalio_digitalinout_obj_t *self) { //| :param ~digitalio.DriveMode drive_mode: drive mode for the output //| """ //| ... -//| STATIC mp_obj_t digitalio_digitalinout_switch_to_output(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_value, ARG_drive_mode }; static const mp_arg_t allowed_args[] = { @@ -131,10 +157,7 @@ STATIC mp_obj_t digitalio_digitalinout_switch_to_output(size_t n_args, const mp_ drive_mode = DRIVE_MODE_OPEN_DRAIN; } // do the transfer - digitalinout_result_t result = common_hal_digitalio_digitalinout_switch_to_output(self, args[ARG_value].u_bool, drive_mode); - if (result == DIGITALINOUT_INPUT_ONLY) { - mp_raise_NotImplementedError(translate("Pin is input only")); - } + check_result(common_hal_digitalio_digitalinout_switch_to_output(self, args[ARG_value].u_bool, drive_mode)); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_KW(digitalio_digitalinout_switch_to_output_obj, 1, digitalio_digitalinout_switch_to_output); @@ -155,7 +178,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(digitalio_digitalinout_switch_to_output_obj, 1, digit //| switch.pull = digitalio.Pull.UP //| print(switch.value)""" //| ... -//| STATIC mp_obj_t digitalio_digitalinout_switch_to_input(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_pull }; static const mp_arg_t allowed_args[] = { @@ -166,7 +188,7 @@ STATIC mp_obj_t digitalio_digitalinout_switch_to_input(size_t n_args, const mp_o mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - common_hal_digitalio_digitalinout_switch_to_input(self, validate_pull(args[ARG_pull].u_rom_obj, MP_QSTR_pull)); + check_result(common_hal_digitalio_digitalinout_switch_to_input(self, validate_pull(args[ARG_pull].u_rom_obj, MP_QSTR_pull))); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_KW(digitalio_digitalinout_switch_to_input_obj, 1, digitalio_digitalinout_switch_to_input); @@ -178,7 +200,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(digitalio_digitalinout_switch_to_input_obj, 1, digita //| :py:meth:`switch_to_input` or :py:meth:`switch_to_output` method. If //| you want to set pull, value or drive mode prior to switching, then use //| those methods instead.""" -//| typedef struct { mp_obj_base_t base; } digitalio_digitalio_direction_obj_t; @@ -200,12 +221,9 @@ STATIC mp_obj_t digitalio_digitalinout_obj_set_direction(mp_obj_t self_in, mp_ob digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); if (value == MP_ROM_PTR(&digitalio_direction_input_obj)) { - common_hal_digitalio_digitalinout_switch_to_input(self, PULL_NONE); + check_result(common_hal_digitalio_digitalinout_switch_to_input(self, PULL_NONE)); } else if (value == MP_ROM_PTR(&digitalio_direction_output_obj)) { - digitalinout_result_t result = common_hal_digitalio_digitalinout_switch_to_output(self, false, DRIVE_MODE_PUSH_PULL); - if (result == DIGITALINOUT_INPUT_ONLY) { - mp_raise_NotImplementedError(translate("Pin is input only")); - } + check_result(common_hal_digitalio_digitalinout_switch_to_output(self, false, DRIVE_MODE_PUSH_PULL)); } else { mp_arg_error_invalid(MP_QSTR_direction); } @@ -219,7 +237,6 @@ MP_PROPERTY_GETSET(digitalio_digitalio_direction_obj, //| value: bool //| """The digital logic level of the pin.""" -//| STATIC mp_obj_t digitalio_digitalinout_obj_get_value(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -249,7 +266,6 @@ MP_PROPERTY_GETSET(digitalio_digitalinout_value_obj, //| //| - `digitalio.DriveMode.PUSH_PULL` //| - `digitalio.DriveMode.OPEN_DRAIN`""" -//| STATIC mp_obj_t digitalio_digitalinout_obj_get_drive_mode(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -276,7 +292,7 @@ STATIC mp_obj_t digitalio_digitalinout_obj_set_drive_mode(mp_obj_t self_in, mp_o if (drive_mode == MP_ROM_PTR(&digitalio_drive_mode_open_drain_obj)) { c_drive_mode = DRIVE_MODE_OPEN_DRAIN; } - common_hal_digitalio_digitalinout_set_drive_mode(self, c_drive_mode); + check_result(common_hal_digitalio_digitalinout_set_drive_mode(self, c_drive_mode)); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(digitalio_digitalinout_set_drive_mode_obj, digitalio_digitalinout_obj_set_drive_mode); @@ -319,7 +335,7 @@ STATIC mp_obj_t digitalio_digitalinout_obj_set_pull(mp_obj_t self_in, mp_obj_t p return mp_const_none; } - common_hal_digitalio_digitalinout_set_pull(self, validate_pull(pull_obj, MP_QSTR_pull)); + check_result(common_hal_digitalio_digitalinout_set_pull(self, validate_pull(pull_obj, MP_QSTR_pull))); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(digitalio_digitalinout_set_pull_obj, digitalio_digitalinout_obj_set_pull); diff --git a/shared-bindings/digitalio/DigitalInOut.h b/shared-bindings/digitalio/DigitalInOut.h index b6edbc63aa..79a700c905 100644 --- a/shared-bindings/digitalio/DigitalInOut.h +++ b/shared-bindings/digitalio/DigitalInOut.h @@ -38,7 +38,15 @@ extern const mp_obj_type_t digitalio_digitalinout_type; typedef enum { DIGITALINOUT_OK, DIGITALINOUT_PIN_BUSY, - DIGITALINOUT_INPUT_ONLY + #if CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY + DIGITALINOUT_INPUT_ONLY, + #endif + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL + DIGITALINOUT_INVALID_PULL, + #endif + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE + DIGITALINOUT_INVALID_DRIVE_MODE, + #endif } digitalinout_result_t; typedef enum { @@ -49,17 +57,18 @@ typedef enum { DIGITALINOUT_REG_TOGGLE, } digitalinout_reg_op_t; +const mcu_pin_obj_t *common_hal_digitalio_validate_pin(mp_obj_t obj); digitalinout_result_t common_hal_digitalio_digitalinout_construct(digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin); void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self); bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self); -void common_hal_digitalio_digitalinout_switch_to_input(digitalio_digitalinout_obj_t *self, digitalio_pull_t pull); +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input(digitalio_digitalinout_obj_t *self, digitalio_pull_t pull); digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output(digitalio_digitalinout_obj_t *self, bool value, digitalio_drive_mode_t drive_mode); digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(digitalio_digitalinout_obj_t *self); void common_hal_digitalio_digitalinout_set_value(digitalio_digitalinout_obj_t *self, bool value); bool common_hal_digitalio_digitalinout_get_value(digitalio_digitalinout_obj_t *self); digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode(digitalio_digitalinout_obj_t *self, digitalio_drive_mode_t drive_mode); digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode(digitalio_digitalinout_obj_t *self); -void common_hal_digitalio_digitalinout_set_pull(digitalio_digitalinout_obj_t *self, digitalio_pull_t pull); +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull(digitalio_digitalinout_obj_t *self, digitalio_pull_t pull); digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(digitalio_digitalinout_obj_t *self); void common_hal_digitalio_digitalinout_never_reset(digitalio_digitalinout_obj_t *self); digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj); diff --git a/shared-bindings/digitalio/Direction.c b/shared-bindings/digitalio/Direction.c index 0ed18f8edc..78552e025c 100644 --- a/shared-bindings/digitalio/Direction.c +++ b/shared-bindings/digitalio/Direction.c @@ -45,7 +45,6 @@ //| """Enum-like class to define which direction the digital values are //| going.""" //| ... -//| //| INPUT: Direction //| """Read digital data in""" //| diff --git a/shared-bindings/digitalio/DriveMode.c b/shared-bindings/digitalio/DriveMode.c index c7c3400411..1ebf51daea 100644 --- a/shared-bindings/digitalio/DriveMode.c +++ b/shared-bindings/digitalio/DriveMode.c @@ -33,7 +33,6 @@ //| """Enum-like class to define the drive mode used when outputting //| digital values.""" //| ... -//| //| PUSH_PULL: DriveMode //| """Output both high and low digital values""" //| diff --git a/shared-bindings/digitalio/Pull.c b/shared-bindings/digitalio/Pull.c index 364be05de0..3c7a036d1e 100644 --- a/shared-bindings/digitalio/Pull.c +++ b/shared-bindings/digitalio/Pull.c @@ -35,7 +35,6 @@ //| """Enum-like class to define the pull value, if any, used while reading //| digital values in.""" //| ... -//| //| UP: Pull //| """When the input line isn't being driven the pull up can pull the state //| of the line high so it reads as true.""" @@ -84,5 +83,5 @@ digitalio_pull_t validate_pull(mp_rom_obj_t obj, qstr arg_name) { if (obj == MP_ROM_NONE) { return PULL_NONE; } - mp_raise_TypeError_varg(translate("%q must be of type %q or None"), arg_name, MP_QSTR_Pull); + mp_raise_TypeError_varg(translate("%q must be of type %q or %q, not %q"), arg_name, MP_QSTR_Pull, MP_QSTR_None, mp_obj_get_type(obj)->name); } diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index ef5727261c..65551f4e0d 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -39,18 +39,17 @@ //| class Bitmap: //| """Stores values of a certain size in a 2D array //| -//| Bitmaps can be treated as read-only buffers. If the number of bits in a pixel is 8, 16, or 32; and the number of bytes -//| per row is a multiple of 4, then the resulting memoryview will correspond directly with the bitmap's contents. Otherwise, -//| the bitmap data is packed into the memoryview with unspecified padding. +//| Bitmaps can be treated as read-only buffers. If the number of bits in a pixel is 8, 16, or 32; and the number of bytes +//| per row is a multiple of 4, then the resulting memoryview will correspond directly with the bitmap's contents. Otherwise, +//| the bitmap data is packed into the memoryview with unspecified padding. //| -//| A Bitmap can be treated as a buffer, allowing its content to be -//| viewed and modified using e.g., with ``ulab.numpy.frombuffer``, -//| but the `displayio.Bitmap.dirty` method must be used to inform -//| displayio when a bitmap was modified through the buffer interface. +//| A Bitmap can be treated as a buffer, allowing its content to be +//| viewed and modified using e.g., with ``ulab.numpy.frombuffer``, +//| but the `displayio.Bitmap.dirty` method must be used to inform +//| displayio when a bitmap was modified through the buffer interface. //| -//| `bitmaptools.arrayblit` can also be useful to move data efficiently -//| into a Bitmap. -//| """ +//| `bitmaptools.arrayblit` can also be useful to move data efficiently +//| into a Bitmap.""" //| //| def __init__(self, width: int, height: int, value_count: int) -> None: //| """Create a Bitmap object with the given fixed size. Each pixel stores a value that is used to @@ -61,7 +60,6 @@ //| :param int height: The number of values high //| :param int value_count: The number of possible pixel values.""" //| ... -//| STATIC mp_obj_t displayio_bitmap_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 3, 3, false); uint32_t width = mp_obj_get_int(all_args[0]); @@ -88,7 +86,6 @@ STATIC mp_obj_t displayio_bitmap_make_new(const mp_obj_type_t *type, size_t n_ar } //| width: int //| """Width of the bitmap. (read only)""" -//| STATIC mp_obj_t displayio_bitmap_obj_get_width(mp_obj_t self_in) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); @@ -102,7 +99,6 @@ MP_PROPERTY_GETTER(displayio_bitmap_width_obj, //| height: int //| """Height of the bitmap. (read only)""" -//| STATIC mp_obj_t displayio_bitmap_obj_get_height(mp_obj_t self_in) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); @@ -122,7 +118,6 @@ MP_PROPERTY_GETTER(displayio_bitmap_height_obj, //| //| print(bitmap[0,1])""" //| ... -//| //| def __setitem__(self, index: Union[Tuple[int, int], int], value: int) -> None: //| """Sets the value at the given index. The index can either be an x,y tuple or an int equal //| to ``y * width + x``. @@ -131,7 +126,6 @@ MP_PROPERTY_GETTER(displayio_bitmap_height_obj, //| //| bitmap[0,1] = 3""" //| ... -//| STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { if (value_obj == mp_const_none) { // delete item @@ -177,7 +171,18 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val return mp_const_none; } -//| def blit(self, x: int, y: int, source_bitmap: Bitmap, *, x1: int, y1: int, x2: int, y2: int, skip_index: int) -> None: +//| def blit( +//| self, +//| x: int, +//| y: int, +//| source_bitmap: Bitmap, +//| *, +//| x1: int, +//| y1: int, +//| x2: int, +//| y2: int, +//| skip_index: int +//| ) -> None: //| """Inserts the source_bitmap region defined by rectangular boundaries //| (x1,y1) and (x2,y2) into the bitmap at the specified (x,y) location. //| @@ -193,7 +198,6 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val //| :param int skip_index: bitmap palette index in the source that will not be copied, //| set to None to copy all pixels""" //| ... -//| STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_x, ARG_y, ARG_source, ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_skip_index}; static const mp_arg_t allowed_args[] = { @@ -282,7 +286,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(displayio_bitmap_blit_obj, 1, displayio_bitmap_obj_bl //| def fill(self, value: int) -> None: //| """Fills the bitmap with the supplied palette index value.""" //| ... -//| STATIC mp_obj_t displayio_bitmap_obj_fill(mp_obj_t self_in, mp_obj_t value_obj) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); @@ -296,7 +299,7 @@ STATIC mp_obj_t displayio_bitmap_obj_fill(mp_obj_t self_in, mp_obj_t value_obj) } MP_DEFINE_CONST_FUN_OBJ_2(displayio_bitmap_fill_obj, displayio_bitmap_obj_fill); -//| def dirty(self, x1: int=0, y1: int=0, x2: int=-1, y2:int = -1) -> None: +//| def dirty(self, x1: int = 0, y1: int = 0, x2: int = -1, y2: int = -1) -> None: //| """Inform displayio of bitmap updates done via the buffer //| protocol. //| diff --git a/shared-bindings/displayio/Bitmap.h b/shared-bindings/displayio/Bitmap.h index 458047510a..074f7dfa5c 100644 --- a/shared-bindings/displayio/Bitmap.h +++ b/shared-bindings/displayio/Bitmap.h @@ -33,6 +33,8 @@ extern const mp_obj_type_t displayio_bitmap_type; void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t width, uint32_t height, uint32_t bits_per_value); +void common_hal_displayio_bitmap_construct_from_buffer(displayio_bitmap_t *self, uint32_t width, + uint32_t height, uint32_t bits_per_value, uint32_t *data, bool read_only); void common_hal_displayio_bitmap_load_row(displayio_bitmap_t *self, uint16_t y, uint8_t *data, uint16_t len); diff --git a/shared-bindings/displayio/ColorConverter.c b/shared-bindings/displayio/ColorConverter.c index 7b33b1ec8f..06de5a4b09 100644 --- a/shared-bindings/displayio/ColorConverter.c +++ b/shared-bindings/displayio/ColorConverter.c @@ -39,13 +39,14 @@ //| class ColorConverter: //| """Converts one color format to another.""" //| -//| def __init__(self, *, input_colorspace: Colorspace=Colorspace.RGB888, dither: bool = False) -> None: +//| def __init__( +//| self, *, input_colorspace: Colorspace = Colorspace.RGB888, dither: bool = False +//| ) -> None: //| """Create a ColorConverter object to convert color formats. //| //| :param Colorspace colorspace: The source colorspace, one of the Colorspace constants //| :param bool dither: Adds random noise to dither the output image""" //| ... -//| STATIC mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_dither, ARG_input_colorspace }; @@ -60,7 +61,7 @@ STATIC mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, siz displayio_colorconverter_t *self = m_new_obj(displayio_colorconverter_t); self->base.type = &displayio_colorconverter_type; - common_hal_displayio_colorconverter_construct(self, args[ARG_dither].u_bool, (displayio_colorspace_t)cp_enum_value(&displayio_colorspace_type, args[ARG_input_colorspace].u_obj)); + common_hal_displayio_colorconverter_construct(self, args[ARG_dither].u_bool, (displayio_colorspace_t)cp_enum_value(&displayio_colorspace_type, args[ARG_input_colorspace].u_obj, MP_QSTR_input_colorspace)); return MP_OBJ_FROM_PTR(self); } @@ -68,18 +69,12 @@ STATIC mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, siz //| def convert(self, color: int) -> int: //| """Converts the given color to RGB565 according to the Colorspace""" //| ... -//| STATIC mp_obj_t displayio_colorconverter_obj_convert(mp_obj_t self_in, mp_obj_t color_obj) { displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); - mp_int_t color; - if (!mp_obj_get_int_maybe(color_obj, &color)) { - mp_raise_ValueError(translate("color should be an int")); - } - _displayio_colorspace_t colorspace; - colorspace.depth = 16; + mp_int_t color = mp_arg_validate_type_int(color_obj, MP_QSTR_color); uint32_t output_color; - common_hal_displayio_colorconverter_convert(self, &colorspace, color, &output_color); + common_hal_displayio_colorconverter_convert(self, &self->output_colorspace, color, &output_color); return MP_OBJ_NEW_SMALL_INT(output_color); } MP_DEFINE_CONST_FUN_OBJ_2(displayio_colorconverter_convert_obj, displayio_colorconverter_obj_convert); @@ -87,7 +82,6 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_colorconverter_convert_obj, displayio_colorc //| dither: bool //| """When `True` the ColorConverter dithers the output by adding random noise when //| truncating to display bitdepth""" -//| STATIC mp_obj_t displayio_colorconverter_obj_get_dither(mp_obj_t self_in) { displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_displayio_colorconverter_get_dither(self)); @@ -112,7 +106,6 @@ MP_PROPERTY_GETSET(displayio_colorconverter_dither_obj, //| raise an Exception if there is already a selected transparent index. //| //| :param int color: The color to be transparent""" -//| STATIC mp_obj_t displayio_colorconverter_make_transparent(mp_obj_t self_in, mp_obj_t transparent_color_obj) { displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 070793415d..49194ebd1e 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -39,11 +39,10 @@ #include "shared-module/displayio/__init__.h" #include "supervisor/shared/translate/translate.h" -//| _DisplayBus = Union['FourWire', 'paralleldisplay.ParallelBus', 'I2CDisplay'] +//| _DisplayBus = Union["FourWire", "paralleldisplay.ParallelBus", "I2CDisplay"] //| """:py:class:`FourWire`, :py:class:`paralleldisplay.ParallelBus` or :py:class:`I2CDisplay`""" //| -//| //| class Display: //| """Manage updating a display over a display bus //| @@ -54,7 +53,34 @@ //| Most people should not use this class directly. Use a specific display driver instead that will //| contain the initialization sequence at minimum.""" //| -//| def __init__(self, display_bus: _DisplayBus, init_sequence: ReadableBuffer, *, width: int, height: int, colstart: int = 0, rowstart: int = 0, rotation: int = 0, color_depth: int = 16, grayscale: bool = False, pixels_in_byte_share_row: bool = True, bytes_per_cell: int = 1, reverse_pixels_in_byte: bool = False, set_column_command: int = 0x2a, set_row_command: int = 0x2b, write_ram_command: int = 0x2c, backlight_pin: Optional[microcontroller.Pin] = None, brightness_command: Optional[int] = None, brightness: float = 1.0, auto_brightness: bool = False, single_byte_bounds: bool = False, data_as_commands: bool = False, auto_refresh: bool = True, native_frames_per_second: int = 60, backlight_on_high: bool = True, SH1107_addressing: bool = False) -> None: +//| def __init__( +//| self, +//| display_bus: _DisplayBus, +//| init_sequence: ReadableBuffer, +//| *, +//| width: int, +//| height: int, +//| colstart: int = 0, +//| rowstart: int = 0, +//| rotation: int = 0, +//| color_depth: int = 16, +//| grayscale: bool = False, +//| pixels_in_byte_share_row: bool = True, +//| bytes_per_cell: int = 1, +//| reverse_pixels_in_byte: bool = False, +//| set_column_command: int = 0x2A, +//| set_row_command: int = 0x2B, +//| write_ram_command: int = 0x2C, +//| backlight_pin: Optional[microcontroller.Pin] = None, +//| brightness_command: Optional[int] = None, +//| brightness: float = 1.0, +//| single_byte_bounds: bool = False, +//| data_as_commands: bool = False, +//| auto_refresh: bool = True, +//| native_frames_per_second: int = 60, +//| backlight_on_high: bool = True, +//| SH1107_addressing: bool = False +//| ) -> None: //| r"""Create a Display object on the given display bus (`FourWire`, `ParallelBus` or `I2CDisplay`). //| //| The ``init_sequence`` is bitpacked to minimize the ram impact. Every command begins with a @@ -102,8 +128,7 @@ //| :param int write_ram_command: Command used to write pixels values into the update region. Ignored if data_as_commands is set. //| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight //| :param int brightness_command: Command to set display brightness. Usually available in OLED controllers. -//| :param float brightness: Initial display brightness. This value is ignored if auto_brightness is True. -//| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism. +//| :param float brightness: Initial display brightness. //| :param bool single_byte_bounds: Display column and row commands use single bytes //| :param bool data_as_commands: Treat all init and boundary data as SPI commands. Certain displays require this. //| :param bool auto_refresh: Automatically refresh the screen @@ -114,7 +139,6 @@ //| :param int backlight_pwm_frequency: The frequency to use to drive the PWM for backlight brightness control. Default is 50000. //| """ //| ... -//| STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, @@ -122,7 +146,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_reverse_bytes_in_word, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, - ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands, + ARG_brightness, ARG_single_byte_bounds, ARG_data_as_commands, ARG_auto_refresh, ARG_native_frames_per_second, ARG_backlight_on_high, ARG_SH1107_addressing, ARG_backlight_pwm_frequency }; static const mp_arg_t allowed_args[] = { @@ -146,7 +170,6 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, { MP_QSTR_brightness_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_BRIGHTNESS_COMMAND} }, { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, - { MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_single_byte_bounds, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_data_as_commands, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_auto_refresh, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, @@ -163,7 +186,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); - const mcu_pin_obj_t *backlight_pin = validate_obj_is_free_pin_or_none(args[ARG_backlight_pin].u_obj); + const mcu_pin_obj_t *backlight_pin = + validate_obj_is_free_pin_or_none(args[ARG_backlight_pin].u_obj, MP_QSTR_backlight_pin); mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj); @@ -196,7 +220,6 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a MP_OBJ_TO_PTR(backlight_pin), args[ARG_brightness_command].u_int, brightness, - args[ARG_auto_brightness].u_bool, args[ARG_single_byte_bounds].u_bool, args[ARG_data_as_commands].u_bool, args[ARG_auto_refresh].u_bool, @@ -217,12 +240,17 @@ static displayio_display_obj_t *native_display(mp_obj_t display_obj) { } //| def show(self, group: Group) -> None: -//| """Switches to displaying the given group of layers. When group is None, the default +//| """ +//| .. note:: `show()` is deprecated and will be removed in CircuitPython 9.0.0. +//| Use ``.root_group = group`` instead. +//| +//| Switches to displaying the given group of layers. When group is None, the default //| CircuitPython terminal will be shown. //| -//| :param Group group: The group to show.""" -//| ... +//| :param Group group: The group to show. //| +//| """ +//| ... STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) { displayio_display_obj_t *self = native_display(self_in); displayio_group_t *group = NULL; @@ -238,7 +266,12 @@ STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) } MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show); -//| def refresh(self, *, target_frames_per_second: Optional[int] = None, minimum_frames_per_second: int = 0) -> bool: +//| def refresh( +//| self, +//| *, +//| target_frames_per_second: Optional[int] = None, +//| minimum_frames_per_second: int = 0 +//| ) -> bool: //| """When auto_refresh is off, and :py:attr:`target_frames_per_second` is not `None` this waits //| for the target frame rate and then refreshes the display, //| returning `True`. If the call has taken too long since the last refresh call for the given @@ -256,9 +289,9 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show //| //| :param Optional[int] target_frames_per_second: The target frame rate that :py:func:`refresh` should try to //| achieve. Set to `None` for immediate refresh. -//| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second.""" +//| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second. +//| """ //| ... -//| STATIC mp_obj_t displayio_display_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second }; static const mp_arg_t allowed_args[] = { @@ -290,7 +323,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(displayio_display_refresh_obj, 1, displayio_display_o //| auto_refresh: bool //| """True when the display is refreshed automatically.""" -//| STATIC mp_obj_t displayio_display_obj_get_auto_refresh(mp_obj_t self_in) { displayio_display_obj_t *self = native_display(self_in); return mp_obj_new_bool(common_hal_displayio_display_get_auto_refresh(self)); @@ -311,10 +343,7 @@ MP_PROPERTY_GETSET(displayio_display_auto_refresh_obj, (mp_obj_t)&displayio_display_set_auto_refresh_obj); //| brightness: float -//| """The brightness of the display as a float. 0.0 is off and 1.0 is full brightness. When -//| `auto_brightness` is True, the value of `brightness` will change automatically. -//| If `brightness` is set, `auto_brightness` will be disabled and will be set to False.""" -//| +//| """The brightness of the display as a float. 0.0 is off and 1.0 is full brightness.""" STATIC mp_obj_t displayio_display_obj_get_brightness(mp_obj_t self_in) { displayio_display_obj_t *self = native_display(self_in); mp_float_t brightness = common_hal_displayio_display_get_brightness(self); @@ -327,7 +356,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_brightness_obj, displayio_displa STATIC mp_obj_t displayio_display_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness_obj) { displayio_display_obj_t *self = native_display(self_in); - common_hal_displayio_display_set_auto_brightness(self, false); mp_float_t brightness = mp_obj_get_float(brightness_obj); if (brightness < 0 || brightness > 1.0) { mp_raise_ValueError(translate("Brightness must be 0-1.0")); @@ -344,37 +372,8 @@ MP_PROPERTY_GETSET(displayio_display_brightness_obj, (mp_obj_t)&displayio_display_get_brightness_obj, (mp_obj_t)&displayio_display_set_brightness_obj); -//| auto_brightness: bool -//| """True when the display brightness is adjusted automatically, based on an ambient -//| light sensor or other method. Note that some displays may have this set to True by default, -//| but not actually implement automatic brightness adjustment. `auto_brightness` is set to False -//| if `brightness` is set manually.""" -//| -STATIC mp_obj_t displayio_display_obj_get_auto_brightness(mp_obj_t self_in) { - displayio_display_obj_t *self = native_display(self_in); - return mp_obj_new_bool(common_hal_displayio_display_get_auto_brightness(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_auto_brightness_obj, displayio_display_obj_get_auto_brightness); - -STATIC mp_obj_t displayio_display_obj_set_auto_brightness(mp_obj_t self_in, mp_obj_t auto_brightness) { - displayio_display_obj_t *self = native_display(self_in); - - common_hal_displayio_display_set_auto_brightness(self, mp_obj_is_true(auto_brightness)); - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_auto_brightness_obj, displayio_display_obj_set_auto_brightness); - -MP_PROPERTY_GETSET(displayio_display_auto_brightness_obj, - (mp_obj_t)&displayio_display_get_auto_brightness_obj, - (mp_obj_t)&displayio_display_set_auto_brightness_obj); - - - - //| width: int //| """Gets the width of the board""" -//| STATIC mp_obj_t displayio_display_obj_get_width(mp_obj_t self_in) { displayio_display_obj_t *self = native_display(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_get_width(self)); @@ -386,7 +385,6 @@ MP_PROPERTY_GETTER(displayio_display_width_obj, //| height: int //| """Gets the height of the board""" -//| STATIC mp_obj_t displayio_display_obj_get_height(mp_obj_t self_in) { displayio_display_obj_t *self = native_display(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_get_height(self)); @@ -398,7 +396,6 @@ MP_PROPERTY_GETTER(displayio_display_height_obj, //| rotation: int //| """The rotation of the display as an int in degrees.""" -//| STATIC mp_obj_t displayio_display_obj_get_rotation(mp_obj_t self_in) { displayio_display_obj_t *self = native_display(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_get_rotation(self)); @@ -418,8 +415,6 @@ MP_PROPERTY_GETSET(displayio_display_rotation_obj, //| bus: _DisplayBus //| """The bus being used by the display""" -//| -//| STATIC mp_obj_t displayio_display_obj_get_bus(mp_obj_t self_in) { displayio_display_obj_t *self = native_display(self_in); return common_hal_displayio_display_get_bus(self); @@ -430,24 +425,38 @@ MP_PROPERTY_GETTER(displayio_display_bus_obj, (mp_obj_t)&displayio_display_get_bus_obj); //| root_group: Group -//| """The root group on the display.""" -//| -//| +//| """The root group on the display. +//| If the root group is set to ``None``, the default CircuitPython terminal will be shown. +//| """ STATIC mp_obj_t displayio_display_obj_get_root_group(mp_obj_t self_in) { displayio_display_obj_t *self = native_display(self_in); return common_hal_displayio_display_get_root_group(self); } MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_root_group_obj, displayio_display_obj_get_root_group); -MP_PROPERTY_GETTER(displayio_display_root_group_obj, - (mp_obj_t)&displayio_display_get_root_group_obj); +STATIC mp_obj_t displayio_display_obj_set_root_group(mp_obj_t self_in, mp_obj_t group_in) { + displayio_display_obj_t *self = native_display(self_in); + displayio_group_t *group = NULL; + if (group_in != mp_const_none) { + group = MP_OBJ_TO_PTR(native_group(group_in)); + } + + common_hal_displayio_display_set_root_group(self, group); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_root_group_obj, displayio_display_obj_set_root_group); + +MP_PROPERTY_GETSET(displayio_display_root_group_obj, + (mp_obj_t)&displayio_display_get_root_group_obj, + (mp_obj_t)&displayio_display_set_root_group_obj); //| def fill_row(self, y: int, buffer: WriteableBuffer) -> WriteableBuffer: //| """Extract the pixels from a single row //| //| :param int y: The top edge of the area -//| :param ~circuitpython_typing.WriteableBuffer buffer: The buffer in which to place the pixel data""" +//| :param ~circuitpython_typing.WriteableBuffer buffer: The buffer in which to place the pixel data +//| """ //| ... //| STATIC mp_obj_t displayio_display_obj_fill_row(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -509,7 +518,6 @@ STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_auto_refresh), MP_ROM_PTR(&displayio_display_auto_refresh_obj) }, { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&displayio_display_brightness_obj) }, - { MP_ROM_QSTR(MP_QSTR_auto_brightness), MP_ROM_PTR(&displayio_display_auto_brightness_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_display_width_obj) }, { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_display_height_obj) }, diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index adc8623a69..35f23ae40f 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -42,7 +42,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t *self, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word, uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, uint8_t *init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t *backlight_pin, uint16_t brightness_command, - mp_float_t brightness, bool auto_brightness, + mp_float_t brightness, bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second, bool backlight_on_high, bool SH1107_addressing, uint16_t backlight_pwm_frequency); @@ -59,9 +59,6 @@ uint16_t common_hal_displayio_display_get_height(displayio_display_obj_t *self); uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t *self); void common_hal_displayio_display_set_rotation(displayio_display_obj_t *self, int rotation); -bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t *self); -void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t *self, bool auto_brightness); - bool common_hal_displayio_display_get_dither(displayio_display_obj_t *self); void common_hal_displayio_display_set_dither(displayio_display_obj_t *self, bool dither); @@ -70,5 +67,6 @@ bool common_hal_displayio_display_set_brightness(displayio_display_obj_t *self, mp_obj_t common_hal_displayio_display_get_bus(displayio_display_obj_t *self); mp_obj_t common_hal_displayio_display_get_root_group(displayio_display_obj_t *self); +mp_obj_t common_hal_displayio_display_set_root_group(displayio_display_obj_t *self, displayio_group_t *root_group); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_DISPLAY_H diff --git a/shared-bindings/displayio/EPaperDisplay.c b/shared-bindings/displayio/EPaperDisplay.c index 81863b2a7a..93d91110a2 100644 --- a/shared-bindings/displayio/EPaperDisplay.c +++ b/shared-bindings/displayio/EPaperDisplay.c @@ -49,21 +49,39 @@ //| Most people should not use this class directly. Use a specific display driver instead that will //| contain the startup and shutdown sequences at minimum.""" //| -//| def __init__(self, display_bus: _DisplayBus, -//| start_sequence: ReadableBuffer, stop_sequence: ReadableBuffer, *, -//| width: int, height: int, ram_width: int, ram_height: int, -//| colstart: int = 0, rowstart: int = 0, rotation: int = 0, -//| set_column_window_command: Optional[int] = None, -//| set_row_window_command: Optional[int] = None, -//| set_current_column_command: Optional[int] = None, -//| set_current_row_command: Optional[int] = None, -//| write_black_ram_command: int, black_bits_inverted: bool = False, -//| write_color_ram_command: Optional[int] = None, -//| color_bits_inverted: bool = False, highlight_color: int = 0x000000, -//| refresh_display_command: int, refresh_time: float = 40, -//| busy_pin: Optional[microcontroller.Pin] = None, busy_state: bool = True, -//| seconds_per_frame: float = 180, always_toggle_chip_select: bool = False, -//| grayscale: bool = False, two_byte_sequence_length: bool = False) -> None: +//| def __init__( +//| self, +//| display_bus: _DisplayBus, +//| start_sequence: ReadableBuffer, +//| stop_sequence: ReadableBuffer, +//| *, +//| width: int, +//| height: int, +//| ram_width: int, +//| ram_height: int, +//| colstart: int = 0, +//| rowstart: int = 0, +//| rotation: int = 0, +//| set_column_window_command: Optional[int] = None, +//| set_row_window_command: Optional[int] = None, +//| set_current_column_command: Optional[int] = None, +//| set_current_row_command: Optional[int] = None, +//| write_black_ram_command: int, +//| black_bits_inverted: bool = False, +//| write_color_ram_command: Optional[int] = None, +//| color_bits_inverted: bool = False, +//| highlight_color: int = 0x000000, +//| refresh_display_command: Union[int, circuitpython_typing.ReadableBuffer], +//| refresh_time: float = 40, +//| busy_pin: Optional[microcontroller.Pin] = None, +//| busy_state: bool = True, +//| seconds_per_frame: float = 180, +//| always_toggle_chip_select: bool = False, +//| grayscale: bool = False, +//| advanced_color_epaper: bool = False, +//| two_byte_sequence_length: bool = False, +//| start_up_time: float = 0 +//| ) -> None: //| """Create a EPaperDisplay object on the given display bus (`displayio.FourWire` or `paralleldisplay.ParallelBus`). //| //| The ``start_sequence`` and ``stop_sequence`` are bitpacked to minimize the ram impact. Every @@ -76,8 +94,8 @@ //| //| :param display_bus: The bus that the display is connected to //| :type _DisplayBus: displayio.FourWire or paralleldisplay.ParallelBus -//| :param ~circuitpython_typing.ReadableBuffer start_sequence: Byte-packed initialization sequence. -//| :param ~circuitpython_typing.ReadableBuffer stop_sequence: Byte-packed initialization sequence. +//| :param ~circuitpython_typing.ReadableBuffer start_sequence: Byte-packed command sequence. +//| :param ~circuitpython_typing.ReadableBuffer stop_sequence: Byte-packed command sequence. //| :param int width: Width in pixels //| :param int height: Height in pixels //| :param int ram_width: RAM width in pixels @@ -94,16 +112,18 @@ //| :param int write_color_ram_command: Command used to write pixels values into the update region //| :param bool color_bits_inverted: True if 0 bits are used to show the color. Otherwise, 1 means to show color. //| :param int highlight_color: RGB888 of source color to highlight with third ePaper color. -//| :param int refresh_display_command: Command used to start a display refresh +//| :param int refresh_display_command: Command used to start a display refresh. Single int or byte-packed command sequence //| :param float refresh_time: Time it takes to refresh the display before the stop_sequence should be sent. Ignored when busy_pin is provided. //| :param microcontroller.Pin busy_pin: Pin used to signify the display is busy //| :param bool busy_state: State of the busy pin when the display is busy //| :param float seconds_per_frame: Minimum number of seconds between screen refreshes //| :param bool always_toggle_chip_select: When True, chip select is toggled every byte //| :param bool grayscale: When true, the color ram is the low bit of 2-bit grayscale -//| :param bool two_byte_sequence_length: When true, use two bytes to define sequence length""" +//| :param bool advanced_color_epaper: When true, the display is a 7-color advanced color epaper (ACeP) +//| :param bool two_byte_sequence_length: When true, use two bytes to define sequence length +//| :param float start_up_time: Time to wait after reset before sending commands +//| """ //| ... -//| STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_display_bus, ARG_start_sequence, ARG_stop_sequence, ARG_width, ARG_height, ARG_ram_width, ARG_ram_height, ARG_colstart, ARG_rowstart, ARG_rotation, @@ -111,7 +131,8 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size ARG_set_current_row_command, ARG_write_black_ram_command, ARG_black_bits_inverted, ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color, ARG_refresh_display_command, ARG_refresh_time, ARG_busy_pin, ARG_busy_state, - ARG_seconds_per_frame, ARG_always_toggle_chip_select, ARG_grayscale, ARG_two_byte_sequence_length }; + ARG_seconds_per_frame, ARG_always_toggle_chip_select, ARG_grayscale, ARG_advanced_color_epaper, + ARG_two_byte_sequence_length, ARG_start_up_time }; static const mp_arg_t allowed_args[] = { { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_start_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -132,14 +153,16 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size { MP_QSTR_write_color_ram_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, { MP_QSTR_color_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_highlight_color, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} }, - { MP_QSTR_refresh_display_command, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_refresh_display_command, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_refresh_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(40)} }, { MP_QSTR_busy_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, { MP_QSTR_busy_state, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_seconds_per_frame, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(180)} }, { MP_QSTR_always_toggle_chip_select, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_advanced_color_epaper, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_two_byte_sequence_length, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_start_up_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(0)} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -152,7 +175,7 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size mp_get_buffer_raise(args[ARG_stop_sequence].u_obj, &stop_bufinfo, MP_BUFFER_READ); - const mcu_pin_obj_t *busy_pin = validate_obj_is_free_pin_or_none(args[ARG_busy_pin].u_obj); + const mcu_pin_obj_t *busy_pin = validate_obj_is_free_pin_or_none(args[ARG_busy_pin].u_obj, MP_QSTR_busy_pin); mp_int_t rotation = args[ARG_rotation].u_int; if (rotation % 90 != 0) { @@ -161,10 +184,10 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size primary_display_t *disp = allocate_display_or_raise(); displayio_epaperdisplay_obj_t *self = &disp->epaper_display; - ; mp_float_t refresh_time = mp_obj_get_float(args[ARG_refresh_time].u_obj); mp_float_t seconds_per_frame = mp_obj_get_float(args[ARG_seconds_per_frame].u_obj); + mp_float_t start_up_time = mp_obj_get_float(args[ARG_start_up_time].u_obj); mp_int_t write_color_ram_command = NO_COMMAND; mp_int_t highlight_color = args[ARG_highlight_color].u_int; @@ -172,19 +195,40 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size write_color_ram_command = mp_obj_get_int(args[ARG_write_color_ram_command].u_obj); } + bool two_byte_sequence_length = args[ARG_two_byte_sequence_length].u_bool; + + mp_obj_t refresh_obj = args[ARG_refresh_display_command].u_obj; + const uint8_t *refresh_buf; + mp_buffer_info_t refresh_bufinfo; + size_t refresh_buf_len = 0; + mp_int_t refresh_command; + if (mp_obj_get_int_maybe(refresh_obj, &refresh_command)) { + uint8_t *command_buf = m_malloc(3, true); + command_buf[0] = refresh_command; + command_buf[1] = 0; + command_buf[2] = 0; + refresh_buf = command_buf; + refresh_buf_len = two_byte_sequence_length? 3: 2; + } else if (mp_get_buffer(refresh_obj, &refresh_bufinfo, MP_BUFFER_READ)) { + refresh_buf = refresh_bufinfo.buf; + refresh_buf_len = refresh_bufinfo.len; + } else { + mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_refresh_display_command); + } + self->base.type = &displayio_epaperdisplay_type; common_hal_displayio_epaperdisplay_construct( self, display_bus, - start_bufinfo.buf, start_bufinfo.len, stop_bufinfo.buf, stop_bufinfo.len, + start_bufinfo.buf, start_bufinfo.len, start_up_time, stop_bufinfo.buf, stop_bufinfo.len, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_ram_width].u_int, args[ARG_ram_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, args[ARG_set_column_window_command].u_int, args[ARG_set_row_window_command].u_int, args[ARG_set_current_column_command].u_int, args[ARG_set_current_row_command].u_int, args[ARG_write_black_ram_command].u_int, args[ARG_black_bits_inverted].u_bool, write_color_ram_command, - args[ARG_color_bits_inverted].u_bool, highlight_color, args[ARG_refresh_display_command].u_int, refresh_time, + args[ARG_color_bits_inverted].u_bool, highlight_color, refresh_buf, refresh_buf_len, refresh_time, busy_pin, args[ARG_busy_state].u_bool, seconds_per_frame, - args[ARG_always_toggle_chip_select].u_bool, args[ARG_grayscale].u_bool, args[ARG_two_byte_sequence_length].u_bool + args[ARG_always_toggle_chip_select].u_bool, args[ARG_grayscale].u_bool, args[ARG_advanced_color_epaper].u_bool, two_byte_sequence_length ); return self; @@ -198,12 +242,15 @@ static displayio_epaperdisplay_obj_t *native_display(mp_obj_t display_obj) { } //| def show(self, group: Group) -> None: -//| """Switches to displaying the given group of layers. When group is None, the default +//| """ +//| .. note:: `show()` is deprecated and will be removed in CircuitPython 9.0.0. +//| Use ``.root_group = group`` instead. +//| +//| Switches to displaying the given group of layers. When group is None, the default //| CircuitPython terminal will be shown. //| //| :param Group group: The group to show.""" //| ... -//| STATIC mp_obj_t displayio_epaperdisplay_obj_show(mp_obj_t self_in, mp_obj_t group_in) { displayio_epaperdisplay_obj_t *self = native_display(self_in); displayio_group_t *group = NULL; @@ -219,10 +266,11 @@ STATIC mp_obj_t displayio_epaperdisplay_obj_show(mp_obj_t self_in, mp_obj_t grou } MP_DEFINE_CONST_FUN_OBJ_2(displayio_epaperdisplay_show_obj, displayio_epaperdisplay_obj_show); -//| def update_refresh_mode(self, start_sequence: ReadableBuffer, seconds_per_frame: float = 180) -> None: +//| def update_refresh_mode( +//| self, start_sequence: ReadableBuffer, seconds_per_frame: float = 180 +//| ) -> None: //| """Updates the ``start_sequence`` and ``seconds_per_frame`` parameters to enable //| varying the refresh mode of the display.""" -//| STATIC mp_obj_t displayio_epaperdisplay_update_refresh_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_start_sequence, ARG_seconds_per_frame }; static const mp_arg_t allowed_args[] = { @@ -248,7 +296,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(displayio_epaperdisplay_update_refresh_mode_obj, 1, d //| """Refreshes the display immediately or raises an exception if too soon. Use //| ``time.sleep(display.time_to_refresh)`` to sleep until a refresh can occur.""" //| ... -//| STATIC mp_obj_t displayio_epaperdisplay_obj_refresh(mp_obj_t self_in) { displayio_epaperdisplay_obj_t *self = native_display(self_in); bool ok = common_hal_displayio_epaperdisplay_refresh(self); @@ -261,7 +308,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_refresh_obj, displayio_epaperd //| time_to_refresh: float //| """Time, in fractional seconds, until the ePaper display can be refreshed.""" -//| STATIC mp_obj_t displayio_epaperdisplay_obj_get_time_to_refresh(mp_obj_t self_in) { displayio_epaperdisplay_obj_t *self = native_display(self_in); return mp_obj_new_float(common_hal_displayio_epaperdisplay_get_time_to_refresh(self) / 1000.0); @@ -274,7 +320,6 @@ MP_PROPERTY_GETTER(displayio_epaperdisplay_time_to_refresh_obj, //| busy: bool //| """True when the display is refreshing. This uses the ``busy_pin`` when available or the //| ``refresh_time`` otherwise.""" -//| STATIC mp_obj_t displayio_epaperdisplay_obj_get_busy(mp_obj_t self_in) { displayio_epaperdisplay_obj_t *self = native_display(self_in); return mp_obj_new_bool(common_hal_displayio_epaperdisplay_get_busy(self)); @@ -286,7 +331,6 @@ MP_PROPERTY_GETTER(displayio_epaperdisplay_busy_obj, //| width: int //| """Gets the width of the display in pixels""" -//| STATIC mp_obj_t displayio_epaperdisplay_obj_get_width(mp_obj_t self_in) { displayio_epaperdisplay_obj_t *self = native_display(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_epaperdisplay_get_width(self)); @@ -298,7 +342,6 @@ MP_PROPERTY_GETTER(displayio_epaperdisplay_width_obj, //| height: int //| """Gets the height of the display in pixels""" -//| STATIC mp_obj_t displayio_epaperdisplay_obj_get_height(mp_obj_t self_in) { displayio_epaperdisplay_obj_t *self = native_display(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_epaperdisplay_get_height(self)); @@ -310,7 +353,6 @@ MP_PROPERTY_GETTER(displayio_epaperdisplay_height_obj, //| rotation: int //| """The rotation of the display as an int in degrees.""" -//| STATIC mp_obj_t displayio_epaperdisplay_obj_get_rotation(mp_obj_t self_in) { displayio_epaperdisplay_obj_t *self = native_display(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_epaperdisplay_get_rotation(self)); @@ -340,6 +382,32 @@ MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_get_bus_obj, displayio_epaperd MP_PROPERTY_GETTER(displayio_epaperdisplay_bus_obj, (mp_obj_t)&displayio_epaperdisplay_get_bus_obj); +//| root_group: Group +//| """The root group on the epaper display. +//| If the root group is set to ``None``, the default CircuitPython terminal will be shown. +//| """ +//| +STATIC mp_obj_t displayio_epaperdisplay_obj_get_root_group(mp_obj_t self_in) { + displayio_epaperdisplay_obj_t *self = native_display(self_in); + return common_hal_displayio_epaperdisplay_get_root_group(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_get_root_group_obj, displayio_epaperdisplay_obj_get_root_group); + +STATIC mp_obj_t displayio_epaperdisplay_obj_set_root_group(mp_obj_t self_in, mp_obj_t group_in) { + displayio_epaperdisplay_obj_t *self = native_display(self_in); + displayio_group_t *group = NULL; + if (group_in != mp_const_none) { + group = MP_OBJ_TO_PTR(native_group(group_in)); + } + + common_hal_displayio_epaperdisplay_set_root_group(self, group); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_epaperdisplay_set_root_group_obj, displayio_epaperdisplay_obj_set_root_group); + +MP_PROPERTY_GETSET(displayio_epaperdisplay_root_group_obj, + (mp_obj_t)&displayio_epaperdisplay_get_root_group_obj, + (mp_obj_t)&displayio_epaperdisplay_set_root_group_obj); STATIC const mp_rom_map_elem_t displayio_epaperdisplay_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_epaperdisplay_show_obj) }, @@ -352,6 +420,7 @@ STATIC const mp_rom_map_elem_t displayio_epaperdisplay_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_bus), MP_ROM_PTR(&displayio_epaperdisplay_bus_obj) }, { MP_ROM_QSTR(MP_QSTR_busy), MP_ROM_PTR(&displayio_epaperdisplay_busy_obj) }, { MP_ROM_QSTR(MP_QSTR_time_to_refresh), MP_ROM_PTR(&displayio_epaperdisplay_time_to_refresh_obj) }, + { MP_ROM_QSTR(MP_QSTR_root_group), MP_ROM_PTR(&displayio_epaperdisplay_root_group_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_epaperdisplay_locals_dict, displayio_epaperdisplay_locals_dict_table); diff --git a/shared-bindings/displayio/EPaperDisplay.h b/shared-bindings/displayio/EPaperDisplay.h index ba6dffcb4b..1ef2ed4b4b 100644 --- a/shared-bindings/displayio/EPaperDisplay.h +++ b/shared-bindings/displayio/EPaperDisplay.h @@ -37,17 +37,20 @@ extern const mp_obj_type_t displayio_epaperdisplay_type; #define NO_COMMAND 0x100 void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t *self, - mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, const uint8_t *stop_sequence, uint16_t stop_sequence_len, + mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, mp_float_t start_up_time, const uint8_t *stop_sequence, uint16_t stop_sequence_len, uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t set_column_window_command, uint16_t set_row_window_command, uint16_t set_current_column_command, uint16_t set_current_row_command, - uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint16_t refresh_display_command, mp_float_t refresh_time, - const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool always_toggle_chip_select, bool grayscale, bool two_byte_sequence_length); + uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time, + const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool always_toggle_chip_select, bool grayscale, bool acep, bool two_byte_sequence_length); bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t *self); bool common_hal_displayio_epaperdisplay_show(displayio_epaperdisplay_obj_t *self, displayio_group_t *root_group); +mp_obj_t common_hal_displayio_epaperdisplay_get_root_group(displayio_epaperdisplay_obj_t *self); +bool common_hal_displayio_epaperdisplay_set_root_group(displayio_epaperdisplay_obj_t *self, displayio_group_t *root_group); + // Returns time in milliseconds. uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaperdisplay_obj_t *self); bool common_hal_displayio_epaperdisplay_get_busy(displayio_epaperdisplay_obj_t *self); diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 7e72169230..1f099f5061 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -43,7 +43,17 @@ //| """Manage updating a display over SPI four wire protocol in the background while Python code runs. //| It doesn't handle display initialization.""" //| -//| def __init__(self, spi_bus: busio.SPI, *, command: Optional[microcontroller.Pin], chip_select: microcontroller.Pin, reset: Optional[microcontroller.Pin] = None, baudrate: int = 24000000, polarity: int = 0, phase: int = 0) -> None: +//| def __init__( +//| self, +//| spi_bus: busio.SPI, +//| *, +//| command: Optional[microcontroller.Pin], +//| chip_select: microcontroller.Pin, +//| reset: Optional[microcontroller.Pin] = None, +//| baudrate: int = 24000000, +//| polarity: int = 0, +//| phase: int = 0 +//| ) -> None: //| """Create a FourWire object associated with the given pins. //| //| The SPI bus and pins are then in use by the display until `displayio.release_displays()` is @@ -65,7 +75,6 @@ //| :param int phase: the edge of the clock that data is captured. First (0) //| or second (1). Rising or falling depends on clock polarity.""" //| ... -//| STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset, ARG_baudrate, ARG_polarity, ARG_phase }; static const mp_arg_t allowed_args[] = { @@ -80,9 +89,9 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *command = validate_obj_is_free_pin_or_none(args[ARG_command].u_obj); - const mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj); - const mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj); + const mcu_pin_obj_t *command = validate_obj_is_free_pin_or_none(args[ARG_command].u_obj, MP_QSTR_command); + const mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj, MP_QSTR_chip_select); + const mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj, MP_QSTR_reset); mp_obj_t spi = mp_arg_validate_type(args[ARG_spi_bus].u_obj, &busio_spi_type, MP_QSTR_spi_bus); @@ -101,7 +110,6 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ //| """Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin //| is available.""" //| ... -//| STATIC mp_obj_t displayio_fourwire_obj_reset(mp_obj_t self_in) { displayio_fourwire_obj_t *self = self_in; @@ -112,7 +120,9 @@ STATIC mp_obj_t displayio_fourwire_obj_reset(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(displayio_fourwire_reset_obj, displayio_fourwire_obj_reset); -//| def send(self, command: int, data: ReadableBuffer, *, toggle_every_byte: bool = False) -> None: +//| def send( +//| self, command: int, data: ReadableBuffer, *, toggle_every_byte: bool = False +//| ) -> None: //| """Sends the given command value followed by the full set of data. Display state, such as //| vertical scroll, set via ``send`` may or may not be reset once the code is done.""" //| ... diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index 4a57b4a5f1..3e4569b271 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -46,7 +46,6 @@ //| :param int x: Initial x position within the parent. //| :param int y: Initial y position within the parent.""" //| ... -//| STATIC mp_obj_t displayio_group_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_scale, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { @@ -79,7 +78,6 @@ displayio_group_t *native_group(mp_obj_t group_obj) { //| hidden: bool //| """True when the Group and all of it's layers are not visible. When False, the Group's layers //| are visible if they haven't been hidden.""" -//| STATIC mp_obj_t displayio_group_obj_get_hidden(mp_obj_t self_in) { displayio_group_t *self = native_group(self_in); return mp_obj_new_bool(common_hal_displayio_group_get_hidden(self)); @@ -101,7 +99,6 @@ MP_PROPERTY_GETSET(displayio_group_hidden_obj, //| scale: int //| """Scales each pixel within the Group in both directions. For example, when scale=2 each pixel //| will be represented by 2x2 pixels.""" -//| STATIC mp_obj_t displayio_group_obj_get_scale(mp_obj_t self_in) { displayio_group_t *self = native_group(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_group_get_scale(self)); @@ -124,7 +121,6 @@ MP_PROPERTY_GETSET(displayio_group_scale_obj, //| x: int //| """X position of the Group in the parent.""" -//| STATIC mp_obj_t displayio_group_obj_get_x(mp_obj_t self_in) { displayio_group_t *self = native_group(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_group_get_x(self)); @@ -146,7 +142,6 @@ MP_PROPERTY_GETSET(displayio_group_x_obj, //| y: int //| """Y position of the Group in the parent.""" -//| STATIC mp_obj_t displayio_group_obj_get_y(mp_obj_t self_in) { displayio_group_t *self = native_group(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_group_get_y(self)); @@ -166,10 +161,12 @@ MP_PROPERTY_GETSET(displayio_group_y_obj, (mp_obj_t)&displayio_group_get_y_obj, (mp_obj_t)&displayio_group_set_y_obj); -//| def append(self, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: +//| def append( +//| self, +//| layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid], +//| ) -> None: //| """Append a layer to the group. It will be drawn above other layers.""" //| ... -//| STATIC mp_obj_t displayio_group_obj_append(mp_obj_t self_in, mp_obj_t layer) { displayio_group_t *self = native_group(self_in); common_hal_displayio_group_insert(self, common_hal_displayio_group_get_len(self), layer); @@ -177,10 +174,13 @@ STATIC mp_obj_t displayio_group_obj_append(mp_obj_t self_in, mp_obj_t layer) { } MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_append_obj, displayio_group_obj_append); -//| def insert(self, index: int, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: +//| def insert( +//| self, +//| index: int, +//| layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid], +//| ) -> None: //| """Insert a layer into the group.""" //| ... -//| STATIC mp_obj_t displayio_group_obj_insert(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t layer) { displayio_group_t *self = native_group(self_in); if ((size_t)MP_OBJ_SMALL_INT_VALUE(index_obj) == common_hal_displayio_group_get_len(self)) { @@ -193,10 +193,12 @@ STATIC mp_obj_t displayio_group_obj_insert(mp_obj_t self_in, mp_obj_t index_obj, MP_DEFINE_CONST_FUN_OBJ_3(displayio_group_insert_obj, displayio_group_obj_insert); -//| def index(self, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> int: +//| def index( +//| self, +//| layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid], +//| ) -> int: //| """Returns the index of the first copy of layer. Raises ValueError if not found.""" //| ... -//| STATIC mp_obj_t displayio_group_obj_index(mp_obj_t self_in, mp_obj_t layer) { displayio_group_t *self = native_group(self_in); mp_int_t index = common_hal_displayio_group_index(self, layer); @@ -207,10 +209,11 @@ STATIC mp_obj_t displayio_group_obj_index(mp_obj_t self_in, mp_obj_t layer) { } MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_index_obj, displayio_group_obj_index); -//| def pop(self, i: int = -1) -> Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]: +//| def pop( +//| self, i: int = -1 +//| ) -> Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]: //| """Remove the ith item and return it.""" //| ... -//| STATIC mp_obj_t displayio_group_obj_pop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_i }; static const mp_arg_t allowed_args[] = { @@ -230,10 +233,12 @@ STATIC mp_obj_t displayio_group_obj_pop(size_t n_args, const mp_obj_t *pos_args, MP_DEFINE_CONST_FUN_OBJ_KW(displayio_group_pop_obj, 1, displayio_group_obj_pop); -//| def remove(self, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: +//| def remove( +//| self, +//| layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid], +//| ) -> None: //| """Remove the first copy of layer. Raises ValueError if it is not present.""" //| ... -//| STATIC mp_obj_t displayio_group_obj_remove(mp_obj_t self_in, mp_obj_t layer) { mp_obj_t index = displayio_group_obj_index(self_in, layer); displayio_group_t *self = native_group(self_in); @@ -243,13 +248,10 @@ STATIC mp_obj_t displayio_group_obj_remove(mp_obj_t self_in, mp_obj_t layer) { } MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_remove_obj, displayio_group_obj_remove); -//| def __bool__(self) -> bool: -//| ... -//| +//| def __bool__(self) -> bool: ... //| def __len__(self) -> int: //| """Returns the number of layers in a Group""" //| ... -//| STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { displayio_group_t *self = native_group(self_in); uint16_t len = common_hal_displayio_group_get_len(self); @@ -263,22 +265,26 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { } } -//| def __getitem__(self, index: int) -> Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]: +//| def __getitem__( +//| self, index: int +//| ) -> Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]: //| """Returns the value at the given index. //| //| This allows you to:: //| //| print(group[0])""" //| ... -//| -//| def __setitem__(self, index: int, value: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: +//| def __setitem__( +//| self, +//| index: int, +//| value: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid], +//| ) -> None: //| """Sets the value at the given index. //| //| This allows you to:: //| //| group[0] = sprite""" //| ... -//| //| def __delitem__(self, index: int) -> None: //| """Deletes the value at the given index. //| @@ -286,7 +292,6 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| //| del group[0]""" //| ... -//| STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { displayio_group_t *self = native_group(self_in); diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c index 86138d8a36..f2647b0b16 100644 --- a/shared-bindings/displayio/I2CDisplay.c +++ b/shared-bindings/displayio/I2CDisplay.c @@ -43,7 +43,13 @@ //| """Manage updating a display over I2C in the background while Python code runs. //| It doesn't handle display initialization.""" //| -//| def __init__(self, i2c_bus: busio.I2C, *, device_address: int, reset: Optional[microcontroller.Pin] = None) -> None: +//| def __init__( +//| self, +//| i2c_bus: busio.I2C, +//| *, +//| device_address: int, +//| reset: Optional[microcontroller.Pin] = None +//| ) -> None: //| """Create a I2CDisplay object associated with the given I2C bus and reset pin. //| //| The I2C bus and pins are then in use by the display until `displayio.release_displays()` is @@ -53,9 +59,9 @@ //| //| :param busio.I2C i2c_bus: The I2C bus that make up the clock and data lines //| :param int device_address: The I2C address of the device -//| :param microcontroller.Pin reset: Reset pin. When None only software reset can be used""" +//| :param microcontroller.Pin reset: Reset pin. When None only software reset can be used +//| """ //| ... -//| STATIC mp_obj_t displayio_i2cdisplay_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_i2c_bus, ARG_device_address, ARG_reset }; static const mp_arg_t allowed_args[] = { @@ -66,7 +72,7 @@ STATIC mp_obj_t displayio_i2cdisplay_make_new(const mp_obj_type_t *type, size_t mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj); + const mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj, MP_QSTR_reset); mp_obj_t i2c = mp_arg_validate_type(args[ARG_i2c_bus].u_obj, &busio_i2c_type, MP_QSTR_i2c_bus); displayio_i2cdisplay_obj_t *self = &allocate_display_bus_or_raise()->i2cdisplay_bus; @@ -81,7 +87,6 @@ STATIC mp_obj_t displayio_i2cdisplay_make_new(const mp_obj_type_t *type, size_t //| """Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin //| is available.""" //| ... -//| STATIC mp_obj_t displayio_i2cdisplay_obj_reset(mp_obj_t self_in) { displayio_i2cdisplay_obj_t *self = self_in; diff --git a/shared-bindings/displayio/OnDiskBitmap.c b/shared-bindings/displayio/OnDiskBitmap.c index 02c370c3c4..a53196ef05 100644 --- a/shared-bindings/displayio/OnDiskBitmap.c +++ b/shared-bindings/displayio/OnDiskBitmap.c @@ -48,7 +48,6 @@ //| import time //| import pulseio //| -//| board.DISPLAY.auto_brightness = False //| board.DISPLAY.brightness = 0 //| splash = displayio.Group() //| board.DISPLAY.show(splash) @@ -68,7 +67,7 @@ //| while True: //| pass""" //| -//| def __init__(self, file: Union[str,typing.BinaryIO]) -> None: +//| def __init__(self, file: Union[str, typing.BinaryIO]) -> None: //| """Create an OnDiskBitmap object with the given file. //| //| :param file file: The name of the bitmap file. For backwards compatibility, a file opened in binary mode may also be passed. @@ -79,7 +78,6 @@ //| of CircuitPython will remove the ability to pass in an opened file. //| """ //| ... -//| STATIC mp_obj_t displayio_ondiskbitmap_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); mp_obj_t arg = all_args[0]; @@ -100,7 +98,6 @@ STATIC mp_obj_t displayio_ondiskbitmap_make_new(const mp_obj_type_t *type, size_ //| width: int //| """Width of the bitmap. (read only)""" -//| STATIC mp_obj_t displayio_ondiskbitmap_obj_get_width(mp_obj_t self_in) { displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in); @@ -114,7 +111,6 @@ MP_PROPERTY_GETTER(displayio_ondiskbitmap_width_obj, //| height: int //| """Height of the bitmap. (read only)""" -//| STATIC mp_obj_t displayio_ondiskbitmap_obj_get_height(mp_obj_t self_in) { displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index 89460bfc03..50deff5748 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -40,37 +40,58 @@ //| """Map a pixel palette_index to a full color. Colors are transformed to the display's format internally to //| save memory.""" //| -//| def __init__(self, color_count: int) -> None: +//| def __init__(self, color_count: int, *, dither: bool = False) -> None: //| """Create a Palette object to store a set number of colors. //| -//| :param int color_count: The number of colors in the Palette""" +//| :param int color_count: The number of colors in the Palette +//| :param bool dither: When true, dither the RGB color before converting to the display's color space +//| """ //| ... -//| // TODO(tannewt): Add support for other color formats. // TODO(tannewt): Add support for 8-bit alpha blending. //| STATIC mp_obj_t displayio_palette_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - enum { ARG_color_count }; + enum { ARG_color_count, ARG_dither }; static const mp_arg_t allowed_args[] = { { MP_QSTR_color_count, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_dither, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); displayio_palette_t *self = m_new_obj(displayio_palette_t); self->base.type = &displayio_palette_type; - common_hal_displayio_palette_construct(self, args[ARG_color_count].u_int); + common_hal_displayio_palette_construct(self, args[ARG_color_count].u_int, args[ARG_dither].u_bool); return MP_OBJ_FROM_PTR(self); } -//| def __bool__(self) -> bool: -//| ... -//| +//| dither: bool +//| """When `True` the Palette dithers the output color by adding random +//| noise when truncating to display bitdepth""" +STATIC mp_obj_t displayio_palette_obj_get_dither(mp_obj_t self_in) { + displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_displayio_palette_get_dither(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_palette_get_dither_obj, displayio_palette_obj_get_dither); + +STATIC mp_obj_t displayio_palette_obj_set_dither(mp_obj_t self_in, mp_obj_t dither) { + displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_displayio_palette_set_dither(self, mp_obj_is_true(dither)); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_palette_set_dither_obj, displayio_palette_obj_set_dither); + +MP_PROPERTY_GETSET(displayio_palette_dither_obj, + (mp_obj_t)&displayio_palette_get_dither_obj, + (mp_obj_t)&displayio_palette_set_dither_obj); + +//| def __bool__(self) -> bool: ... //| def __len__(self) -> int: //| """Returns the number of colors in a Palette""" //| ... -//| STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); switch (op) { @@ -86,8 +107,9 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| def __getitem__(self, index: int) -> Optional[int]: //| r"""Return the pixel color at the given index as an integer.""" //| ... -//| -//| def __setitem__(self, index: int, value: Union[int, ReadableBuffer, Tuple[int, int, int]]) -> None: +//| def __setitem__( +//| self, index: int, value: Union[int, ReadableBuffer, Tuple[int, int, int]] +//| ) -> None: //| r"""Sets the pixel color at the given index. The index should be an integer in the range 0 to color_count-1. //| //| The value argument represents a color, and can be from 0x000000 to 0xFFFFFF (to represent an RGB value). @@ -102,7 +124,6 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| palette[3] = bytearray(b'\x00\x00\xFF') # set using a bytearay of 3 or 4 bytes //| palette[4] = (10, 20, 30) # set using a tuple of 3 integers""" //| ... -//| STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item @@ -150,33 +171,23 @@ STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t val return mp_const_none; } -//| def make_transparent(self, palette_index: int) -> None: -//| ... -//| +//| def make_transparent(self, palette_index: int) -> None: ... STATIC mp_obj_t displayio_palette_obj_make_transparent(mp_obj_t self_in, mp_obj_t palette_index_obj) { displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); - mp_int_t palette_index; - if (!mp_obj_get_int_maybe(palette_index_obj, &palette_index)) { - mp_raise_ValueError(translate("palette_index should be an int")); - } - palette_index = mp_arg_validate_int_range(palette_index, 0, common_hal_displayio_palette_get_len(self) - 1, MP_QSTR_palette_index); + mp_int_t palette_index = mp_arg_validate_type_int(palette_index_obj, MP_QSTR_palette_index); + mp_arg_validate_int_range(palette_index, 0, common_hal_displayio_palette_get_len(self) - 1, MP_QSTR_palette_index); common_hal_displayio_palette_make_transparent(self, palette_index); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(displayio_palette_make_transparent_obj, displayio_palette_obj_make_transparent); -//| def make_opaque(self, palette_index: int) -> None: -//| ... -//| +//| def make_opaque(self, palette_index: int) -> None: ... STATIC mp_obj_t displayio_palette_obj_make_opaque(mp_obj_t self_in, mp_obj_t palette_index_obj) { displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); - mp_int_t palette_index; - if (!mp_obj_get_int_maybe(palette_index_obj, &palette_index)) { - mp_raise_ValueError(translate("palette_index should be an int")); - } + mp_int_t palette_index = mp_arg_validate_type_int(palette_index_obj, MP_QSTR_palette_index); palette_index = mp_arg_validate_int_range(palette_index, 0, common_hal_displayio_palette_get_len(self) - 1, MP_QSTR_palette_index); common_hal_displayio_palette_make_opaque(self, palette_index); @@ -191,10 +202,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_palette_make_opaque_obj, displayio_palette_o STATIC mp_obj_t displayio_palette_obj_is_transparent(mp_obj_t self_in, mp_obj_t palette_index_obj) { displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); - mp_int_t palette_index; - if (!mp_obj_get_int_maybe(palette_index_obj, &palette_index)) { - mp_raise_ValueError(translate("palette_index should be an int")); - } + mp_int_t palette_index = mp_arg_validate_type_int(palette_index_obj, MP_QSTR_palette_index); palette_index = mp_arg_validate_int_range(palette_index, 0, common_hal_displayio_palette_get_len(self) - 1, MP_QSTR_palette_index); return mp_obj_new_bool(common_hal_displayio_palette_is_transparent(self, palette_index)); @@ -202,6 +210,7 @@ STATIC mp_obj_t displayio_palette_obj_is_transparent(mp_obj_t self_in, mp_obj_t MP_DEFINE_CONST_FUN_OBJ_2(displayio_palette_is_transparent_obj, displayio_palette_obj_is_transparent); STATIC const mp_rom_map_elem_t displayio_palette_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_dither), MP_ROM_PTR(&displayio_palette_dither_obj) }, { MP_ROM_QSTR(MP_QSTR_make_transparent), MP_ROM_PTR(&displayio_palette_make_transparent_obj) }, { MP_ROM_QSTR(MP_QSTR_make_opaque), MP_ROM_PTR(&displayio_palette_make_opaque_obj) }, { MP_ROM_QSTR(MP_QSTR_is_transparent), MP_ROM_PTR(&displayio_palette_is_transparent_obj) }, diff --git a/shared-bindings/displayio/Palette.h b/shared-bindings/displayio/Palette.h index d9a798016c..2cc7417fe3 100644 --- a/shared-bindings/displayio/Palette.h +++ b/shared-bindings/displayio/Palette.h @@ -31,11 +31,14 @@ extern const mp_obj_type_t displayio_palette_type; -void common_hal_displayio_palette_construct(displayio_palette_t *self, uint16_t color_count); +void common_hal_displayio_palette_construct(displayio_palette_t *self, uint16_t color_count, bool dither); void common_hal_displayio_palette_set_color(displayio_palette_t *self, uint32_t palette_index, uint32_t color); uint32_t common_hal_displayio_palette_get_color(displayio_palette_t *self, uint32_t palette_index); uint32_t common_hal_displayio_palette_get_len(displayio_palette_t *self); +void common_hal_displayio_palette_set_dither(displayio_palette_t *self, bool dither); +bool common_hal_displayio_palette_get_dither(displayio_palette_t *self); + void common_hal_displayio_palette_make_opaque(displayio_palette_t *self, uint32_t palette_index); void common_hal_displayio_palette_make_transparent(displayio_palette_t *self, uint32_t palette_index); bool common_hal_displayio_palette_is_transparent(displayio_palette_t *self, uint32_t palette_index); diff --git a/shared-bindings/displayio/Shape.c b/shared-bindings/displayio/Shape.c index 30a51dadce..c8b3959837 100644 --- a/shared-bindings/displayio/Shape.c +++ b/shared-bindings/displayio/Shape.c @@ -37,7 +37,9 @@ //| class Shape: //| """Represents a shape made by defining boundaries that may be mirrored.""" //| -//| def __init__(self, width: int, height: int, *, mirror_x: bool = False, mirror_y: bool = False) -> None: +//| def __init__( +//| self, width: int, height: int, *, mirror_x: bool = False, mirror_y: bool = False +//| ) -> None: //| """Create a Shape object with the given fixed size. Each pixel is one bit and is stored by the //| column boundaries of the shape on each row. Each row's boundary defaults to the full row. //| @@ -46,7 +48,6 @@ //| :param bool mirror_x: When true the left boundary is mirrored to the right. //| :param bool mirror_y: When true the top boundary is mirrored to the bottom.""" //| ... -//| STATIC mp_obj_t displayio_shape_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_width, ARG_height, ARG_mirror_x, ARG_mirror_y }; static const mp_arg_t allowed_args[] = { @@ -80,18 +81,9 @@ STATIC mp_obj_t displayio_shape_make_new(const mp_obj_type_t *type, size_t n_arg STATIC mp_obj_t displayio_shape_obj_set_boundary(size_t n_args, const mp_obj_t *args) { (void)n_args; displayio_shape_t *self = MP_OBJ_TO_PTR(args[0]); - mp_int_t y; - if (!mp_obj_get_int_maybe(args[1], &y)) { - mp_raise_ValueError(translate("y should be an int")); - } - mp_int_t start_x; - if (!mp_obj_get_int_maybe(args[2], &start_x)) { - mp_raise_ValueError(translate("start_x should be an int")); - } - mp_int_t end_x; - if (!mp_obj_get_int_maybe(args[3], &end_x)) { - mp_raise_ValueError(translate("end_x should be an int")); - } + mp_int_t y = mp_arg_validate_type_int(args[1], MP_QSTR_y); + mp_int_t start_x = mp_arg_validate_type_int(args[1], MP_QSTR_start_x); + mp_int_t end_x = mp_arg_validate_type_int(args[1], MP_QSTR_end_x); common_hal_displayio_shape_set_boundary(self, y, start_x, end_x); return mp_const_none; diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index d84ff5f20f..f2e16985c3 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -48,7 +48,19 @@ //| //| A single tile grid is also known as a Sprite.""" //| -//| def __init__(self, bitmap: Union[Bitmap, OnDiskBitmap, Shape], *, pixel_shader: Union[ColorConverter, Palette], width: int = 1, height: int = 1, tile_width: Optional[int] = None, tile_height: Optional[int] = None, default_tile: int = 0, x: int = 0, y: int = 0) -> None: +//| def __init__( +//| self, +//| bitmap: Union[Bitmap, OnDiskBitmap, Shape], +//| *, +//| pixel_shader: Union[ColorConverter, Palette], +//| width: int = 1, +//| height: int = 1, +//| tile_width: Optional[int] = None, +//| tile_height: Optional[int] = None, +//| default_tile: int = 0, +//| x: int = 0, +//| y: int = 0 +//| ) -> None: //| """Create a TileGrid object. The bitmap is source for 2d pixels. The pixel_shader is used to //| convert the value and its location to a display native pixel color. This may be a simple color //| palette lookup, a gradient, a pattern or a color transformer. @@ -66,7 +78,6 @@ //| :param int default_tile: Default tile index to show. //| :param int x: Initial x position of the left edge within the parent. //| :param int y: Initial y position of the top edge within the parent.""" -//| STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_bitmap, ARG_pixel_shader, ARG_width, ARG_height, ARG_tile_width, ARG_tile_height, ARG_default_tile, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { @@ -146,7 +157,6 @@ static displayio_tilegrid_t *native_tilegrid(mp_obj_t tilegrid_obj) { //| hidden: bool //| """True when the TileGrid is hidden. This may be False even when a part of a hidden Group.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_hidden(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return mp_obj_new_bool(common_hal_displayio_tilegrid_get_hidden(self)); @@ -167,7 +177,6 @@ MP_PROPERTY_GETSET(displayio_tilegrid_hidden_obj, //| x: int //| """X position of the left edge in the parent.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_x(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_x(self)); @@ -189,7 +198,6 @@ MP_PROPERTY_GETSET(displayio_tilegrid_x_obj, //| y: int //| """Y position of the top edge in the parent.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_y(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_y(self)); @@ -211,7 +219,6 @@ MP_PROPERTY_GETSET(displayio_tilegrid_y_obj, //| width: int //| """Width of the tilegrid in tiles.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_width(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_width(self)); @@ -223,7 +230,6 @@ MP_PROPERTY_GETTER(displayio_tilegrid_width_obj, //| height: int //| """Height of the tilegrid in tiles.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_height(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_height(self)); @@ -235,7 +241,6 @@ MP_PROPERTY_GETTER(displayio_tilegrid_height_obj, //| tile_width: int //| """Width of a single tile in pixels.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_tile_width(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_tile_width(self)); @@ -247,7 +252,6 @@ MP_PROPERTY_GETTER(displayio_tilegrid_tile_width_obj, //| tile_height: int //| """Height of a single tile in pixels.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_tile_height(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_tile_height(self)); @@ -259,7 +263,6 @@ MP_PROPERTY_GETTER(displayio_tilegrid_tile_height_obj, //| flip_x: bool //| """If true, the left edge rendered will be the right edge of the right-most tile.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_flip_x(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return mp_obj_new_bool(common_hal_displayio_tilegrid_get_flip_x(self)); @@ -280,7 +283,6 @@ MP_PROPERTY_GETSET(displayio_tilegrid_flip_x_obj, //| flip_y: bool //| """If true, the top edge rendered will be the bottom edge of the bottom-most tile.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_flip_y(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return mp_obj_new_bool(common_hal_displayio_tilegrid_get_flip_y(self)); @@ -303,7 +305,6 @@ MP_PROPERTY_GETSET(displayio_tilegrid_flip_y_obj, //| transpose_xy: bool //| """If true, the TileGrid's axis will be swapped. When combined with mirroring, any 90 degree //| rotation can be achieved along with the corresponding mirrored version.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_transpose_xy(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return mp_obj_new_bool(common_hal_displayio_tilegrid_get_transpose_xy(self)); @@ -324,8 +325,7 @@ MP_PROPERTY_GETSET(displayio_tilegrid_transpose_xy_obj, //| def contains(self, touch_tuple: tuple) -> bool: //| """Returns True if the first two values in ``touch_tuple`` represent an x,y coordinate -//| inside the tilegrid rectangle bounds.""" -//| +//| inside the tilegrid rectangle bounds.""" STATIC mp_obj_t displayio_tilegrid_obj_contains(mp_obj_t self_in, mp_obj_t touch_tuple) { displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in); @@ -342,7 +342,6 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_contains_obj, displayio_tilegrid_ob //| pixel_shader: Union[ColorConverter, Palette] //| """The pixel shader of the tilegrid.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_pixel_shader(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return common_hal_displayio_tilegrid_get_pixel_shader(self); @@ -365,9 +364,8 @@ MP_PROPERTY_GETSET(displayio_tilegrid_pixel_shader_obj, (mp_obj_t)&displayio_tilegrid_get_pixel_shader_obj, (mp_obj_t)&displayio_tilegrid_set_pixel_shader_obj); -//| bitmap: Union[Bitmap,OnDiskBitmap,Shape] +//| bitmap: Union[Bitmap, OnDiskBitmap, Shape] //| """The bitmap of the tilegrid.""" -//| STATIC mp_obj_t displayio_tilegrid_obj_get_bitmap(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return common_hal_displayio_tilegrid_get_bitmap(self); @@ -436,7 +434,6 @@ MP_PROPERTY_GETSET(displayio_tilegrid_bitmap_obj, //| //| print(grid[0])""" //| ... -//| //| def __setitem__(self, index: Union[Tuple[int, int], int], value: int) -> None: //| """Sets the tile index at the given index. The index can either be an x,y tuple or an int equal //| to ``y * width + x``. diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 2e52f12e84..3fcd1d082b 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -45,6 +45,7 @@ #endif #include "shared-bindings/displayio/Shape.h" #include "shared-bindings/displayio/TileGrid.h" +#include "shared-module/displayio/__init__.h" //| """Native helpers for driving displays //| @@ -55,9 +56,9 @@ //| refer to `this Learn guide //| `_. //| """ -//| //| import paralleldisplay +//| //| def release_displays() -> None: //| """Releases any actively used displays so their busses and pins can be used again. This will also @@ -95,6 +96,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { #endif { MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) }, + { MP_ROM_QSTR(MP_QSTR_CIRCUITPYTHON_TERMINAL), MP_ROM_PTR(&circuitpython_splash) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_module_globals, displayio_module_globals_table); diff --git a/shared-bindings/dotenv/__init__.c b/shared-bindings/dotenv/__init__.c deleted file mode 100644 index 89f6fe6792..0000000000 --- a/shared-bindings/dotenv/__init__.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "extmod/vfs.h" -#include "lib/oofatfs/ff.h" -#include "lib/oofatfs/diskio.h" -#include "py/mpstate.h" -#include "py/obj.h" -#include "py/objstr.h" -#include "py/runtime.h" -#include "shared-bindings/dotenv/__init__.h" - -//| """Functions to manage environment variables from a .env file. -//| -//| A subset of the CPython `dotenv library `_. It does -//| not support variables or double quotes. -//| -//| The simplest way to define keys and values is to put them in single quotes. \ and ' are -//| escaped by \ in single quotes. Newlines can occur in quotes for multiline values. Comments -//| start with # and apply for the rest of the line. -//| -//| File format example: -//| -//| .. code-block:: -//| -//| key=value -//| key2 = value2 -//| 'key3' = 'value with spaces' -//| # comment -//| key4 = value3 # comment 2 -//| 'key5'=value4 -//| key=value5 # overrides the first one -//| multiline = 'hello -//| world -//| how are you?' -//| -//| """ -//| -//| import typing - -//| def get_key(dotenv_path: str, key_to_get: str) -> Optional[str]: -//| """Get the value for the given key from the given .env file. If the key occurs multiple -//| times in the file, then the last value will be returned. -//| -//| Returns None if the key isn't found or doesn't have a value.""" -//| ... -//| -STATIC mp_obj_t _dotenv_get_key(mp_obj_t path_in, mp_obj_t key_to_get_in) { - return common_hal_dotenv_get_key(mp_obj_str_get_str(path_in), - mp_obj_str_get_str(key_to_get_in)); -} -MP_DEFINE_CONST_FUN_OBJ_2(dotenv_get_key_obj, _dotenv_get_key); - -//| def load_dotenv() -> None: -//| """Does nothing in CircuitPython because os.getenv will automatically read .env when -//| available. -//| -//| Present in CircuitPython so CPython-compatible code can use it without error.""" -//| ... -//| -STATIC mp_obj_t dotenv_load_dotenv(void) { - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_0(dotenv_load_dotenv_obj, dotenv_load_dotenv); - -STATIC const mp_rom_map_elem_t dotenv_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_dotenv) }, - - { MP_ROM_QSTR(MP_QSTR_get_key), MP_ROM_PTR(&dotenv_get_key_obj) }, - { MP_ROM_QSTR(MP_QSTR_load_dotenv), MP_ROM_PTR(&dotenv_load_dotenv_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(dotenv_module_globals, dotenv_module_globals_table); - -const mp_obj_module_t dotenv_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&dotenv_module_globals, -}; - -MP_REGISTER_MODULE(MP_QSTR_dotenv, dotenv_module, CIRCUITPY_DOTENV); diff --git a/shared-bindings/dualbank/__init__.c b/shared-bindings/dualbank/__init__.c index f907c91e0e..b77fb6d76b 100644 --- a/shared-bindings/dualbank/__init__.c +++ b/shared-bindings/dualbank/__init__.c @@ -26,25 +26,36 @@ #include "shared-bindings/dualbank/__init__.h" -//| """DUALBANK Module +#if CIRCUITPY_STORAGE_EXTEND +#include "supervisor/flash.h" +#endif + +//| """Dualbank Module //| -//| The `dualbank` module adds ability to update and switch -//| between the two app partitions. +//| The `dualbank` module adds ability to update and switch between the +//| two identical app partitions, which can contain different firmware versions. //| -//| There are two identical partitions, these contain different -//| firmware versions. //| Having two partitions enables rollback functionality. //| -//| The two partitions are defined as boot partition and -//| next-update partition. Calling `dualbank.flash()` writes -//| the next-update partition. +//| The two partitions are defined as the boot partition and the next-update partition. +//| Calling `dualbank.flash()` writes the next-update partition. //| -//| After the next-update partition is written a validation -//| check is performed and on a successful validation this -//| partition is set as the boot partition. On next reset, -//| firmware will be loaded from this partition. +//| After the next-update partition is written a validation check is performed +//| and on a successful validation this partition is set as the boot partition. +//| On next reset, firmware will be loaded from this partition. //| -//| Here is the sequence of commands to follow: +//| Use cases: +//| * Can be used for ``OTA`` Over-The-Air updates. +//| * Can be used for ``dual-boot`` of different firmware versions or platforms. +//| +//| .. note:: +//| +//| Boards with flash ``=2MB``: +//| This module is unavailable as the flash is only large enough for one app partition. +//| +//| Boards with flash ``>2MB``: +//| This module is enabled/disabled at runtime based on whether the ``CIRCUITPY`` drive +//| is extended or not. See `storage.erase_filesystem()` for more information. //| //| .. code-block:: python //| @@ -56,11 +67,21 @@ //| ... //| -//| def flash(*buffer: ReadableBuffer, offset: int=0) -> None: -//| """Writes one of two app partitions at the given offset. +#if CIRCUITPY_STORAGE_EXTEND +STATIC void raise_error_if_storage_extended(void) { + if (supervisor_flash_get_extended()) { + mp_raise_msg_varg(&mp_type_RuntimeError, translate("%q is %q"), MP_QSTR_storage, MP_QSTR_extended); + } +} +#endif + +//| def flash(buffer: ReadableBuffer, offset: int = 0) -> None: +//| """Writes one of the two app partitions at the given offset. //| -//| This can be called multiple times when flashing the firmware -//| in small chunks. +//| This can be called multiple times when flashing the firmware in smaller chunks. +//| +//| :param ReadableBuffer buffer: The entire firmware or a partial chunk. +//| :param int offset: Start writing at this offset in the app partition. //| """ //| ... //| @@ -71,6 +92,10 @@ STATIC mp_obj_t dualbank_flash(size_t n_args, const mp_obj_t *pos_args, mp_map_t { MP_QSTR_offset, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, }; + #if CIRCUITPY_STORAGE_EXTEND + raise_error_if_storage_extended(); + #endif + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -87,14 +112,16 @@ STATIC mp_obj_t dualbank_flash(size_t n_args, const mp_obj_t *pos_args, mp_map_t STATIC MP_DEFINE_CONST_FUN_OBJ_KW(dualbank_flash_obj, 0, dualbank_flash); //| def switch() -> None: -//| """Switches the boot partition. +//| """Switches to the next-update partition. //| -//| On next reset, firmware will be loaded from the partition -//| just switched over to. +//| On next reset, firmware will be loaded from the partition just switched over to. //| """ //| ... //| STATIC mp_obj_t dualbank_switch(void) { + #if CIRCUITPY_STORAGE_EXTEND + raise_error_if_storage_extended(); + #endif common_hal_dualbank_switch(); return mp_const_none; } diff --git a/shared-bindings/floppyio/__init__.c b/shared-bindings/floppyio/__init__.c index 3ef58b2f66..b114ab46dc 100644 --- a/shared-bindings/floppyio/__init__.c +++ b/shared-bindings/floppyio/__init__.c @@ -31,11 +31,12 @@ #include #include "py/binary.h" -#include "py/enum.h" #include "py/obj.h" #include "py/runtime.h" -//| def flux_readinto(buffer: WriteableBuffer, data: digitalio.DigitalInOut, index: digitalio.DigitalInOut) -> int: +//| def flux_readinto( +//| buffer: WriteableBuffer, data: digitalio.DigitalInOut, index: digitalio.DigitalInOut +//| ) -> int: //| """Read flux transition information into the buffer. //| //| The function returns when the buffer has filled, or when the index input @@ -69,7 +70,9 @@ STATIC mp_obj_t floppyio_flux_readinto(size_t n_args, const mp_obj_t *pos_args, } MP_DEFINE_CONST_FUN_OBJ_KW(floppyio_flux_readinto_obj, 0, floppyio_flux_readinto); -//| def mfm_readinto(buffer: WriteableBuffer, data: digitalio.DigitalInOut, index: digitalio.DigitalInOut) -> int: +//| def mfm_readinto( +//| buffer: WriteableBuffer, data: digitalio.DigitalInOut, index: digitalio.DigitalInOut +//| ) -> int: //| """Read mfm blocks into the buffer. //| //| The track is assumed to consist of 512-byte sectors. @@ -110,7 +113,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(floppyio_mfm_readinto_obj, 0, floppyio_mfm_readinto); //| samplerate: int //| """The approximate sample rate in Hz used by flux_readinto.""" -//| STATIC const mp_rom_map_elem_t floppyio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_floppyio) }, diff --git a/shared-bindings/fontio/BuiltinFont.c b/shared-bindings/fontio/BuiltinFont.c index 02d3373797..cf28b6f223 100644 --- a/shared-bindings/fontio/BuiltinFont.c +++ b/shared-bindings/fontio/BuiltinFont.c @@ -36,10 +36,11 @@ #include "shared-bindings/util.h" #include "supervisor/shared/translate/translate.h" -//| from typing_extensions import Protocol # for compat with python < 3.8 +//| from typing_extensions import Protocol # for compat with python < 3.8 //| //| class FontProtocol(Protocol): //| """A protocol shared by `BuiltinFont` and classes in ``adafruit_bitmap_font``""" +//| //| def get_bounding_box(self) -> Union[Tuple[int, int], Tuple[int, int, int, int]]: //| """Retrieve the maximum bounding box of any glyph in the font. //| @@ -47,7 +48,6 @@ //| The two element version is ``(width, height)``, in which //| ``x_offset`` and ``y_offset`` are assumed to be zero.""" //| pass -//| //| def get_glyph(self, codepoint: int) -> Optional[Glyph]: //| """Retrieve the Glyph for a given code point //| @@ -63,13 +63,11 @@ //| `Adafruit_CircuitPython_Bitmap_Font `_ //| library for dynamically loaded fonts.""" //| ... -//| //| bitmap: displayio.Bitmap //| """Bitmap containing all font glyphs starting with ASCII and followed by unicode. Use //| `get_glyph` in most cases. This is useful for use with `displayio.TileGrid` and //| `terminalio.Terminal`.""" -//| STATIC mp_obj_t fontio_builtinfont_obj_get_bitmap(mp_obj_t self_in) { fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_fontio_builtinfont_get_bitmap(self); @@ -82,7 +80,6 @@ MP_PROPERTY_GETTER(fontio_builtinfont_bitmap_obj, //| def get_bounding_box(self) -> Tuple[int, int]: //| """Returns the maximum bounds of all glyphs in the font in a tuple of two values: width, height.""" //| ... -//| STATIC mp_obj_t fontio_builtinfont_obj_get_bounding_box(mp_obj_t self_in) { fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/fontio/Glyph.c b/shared-bindings/fontio/Glyph.c index 92be6daeb0..9fd49cfb1a 100644 --- a/shared-bindings/fontio/Glyph.c +++ b/shared-bindings/fontio/Glyph.c @@ -31,15 +31,17 @@ //| class Glyph: //| """Storage of glyph info""" //| -//| def __init__(self, -//| bitmap: displayio.Bitmap, -//| tile_index: int, -//| width: int, -//| height: int, -//| dx: int, -//| dy: int, -//| shift_x: int, -//| shift_y: int) -> None: +//| def __init__( +//| self, +//| bitmap: displayio.Bitmap, +//| tile_index: int, +//| width: int, +//| height: int, +//| dx: int, +//| dy: int, +//| shift_x: int, +//| shift_y: int, +//| ) -> None: //| """Named tuple used to capture a single glyph and its attributes. //| //| :param bitmap: the bitmap including the glyph diff --git a/shared-bindings/fontio/__init__.c b/shared-bindings/fontio/__init__.c index ea1b8a628b..24e1eb1e3b 100644 --- a/shared-bindings/fontio/__init__.c +++ b/shared-bindings/fontio/__init__.c @@ -42,7 +42,6 @@ //| `this Learn guide `_ //| //| """ -//| STATIC const mp_rom_map_elem_t fontio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_fontio) }, @@ -57,4 +56,4 @@ const mp_obj_module_t fontio_module = { .globals = (mp_obj_dict_t *)&fontio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_fontio, fontio_module, CIRCUITPY_DISPLAYIO && CIRCUITPY_TERMINALIO); +MP_REGISTER_MODULE(MP_QSTR_fontio, fontio_module, CIRCUITPY_FONTIO); diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c index e999ac9bc1..030b924c1e 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.c +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -47,14 +47,20 @@ //| objects in CircuitPython, Display objects live until `displayio.release_displays()` //| is called. This is done so that CircuitPython can use the display itself.""" //| -//| def __init__(self, framebuffer: circuitpython_typing.FrameBuffer, *, rotation: int = 0, auto_refresh: bool = True) -> None: +//| def __init__( +//| self, +//| framebuffer: circuitpython_typing.FrameBuffer, +//| *, +//| rotation: int = 0, +//| auto_refresh: bool = True +//| ) -> None: //| """Create a Display object with the given framebuffer (a buffer, array, ulab.array, etc) //| //| :param ~circuitpython_typing.FrameBuffer framebuffer: The framebuffer that the display is connected to //| :param bool auto_refresh: Automatically refresh the screen -//| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270)""" +//| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270) +//| """ //| ... -//| STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_framebuffer, ARG_rotation, ARG_auto_refresh, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -99,7 +105,6 @@ static framebufferio_framebufferdisplay_obj_t *native_display(mp_obj_t display_o //| //| :param Group group: The group to show.""" //| ... -//| STATIC mp_obj_t framebufferio_framebufferdisplay_obj_show(mp_obj_t self_in, mp_obj_t group_in) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); displayio_group_t *group = NULL; @@ -115,7 +120,9 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_obj_show(mp_obj_t self_in, mp_o } MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_show_obj, framebufferio_framebufferdisplay_obj_show); -//| def refresh(self, *, target_frames_per_second: int = 60, minimum_frames_per_second: int = 1) -> bool: +//| def refresh( +//| self, *, target_frames_per_second: int = 60, minimum_frames_per_second: int = 1 +//| ) -> bool: //| """When auto refresh is off, waits for the target frame rate and then refreshes the display, //| returning True. If the call has taken too long since the last refresh call for the given //| target frame rate, then the refresh returns False immediately without updating the screen to @@ -128,9 +135,9 @@ MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_show_obj, framebuffer //| without calls to this.) //| //| :param int target_frames_per_second: How many times a second `refresh` should be called and the screen updated. -//| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second.""" +//| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second. +//| """ //| ... -//| STATIC mp_obj_t framebufferio_framebufferdisplay_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second }; static const mp_arg_t allowed_args[] = { @@ -152,7 +159,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(framebufferio_framebufferdisplay_refresh_obj, 1, fram //| auto_refresh: bool //| """True when the display is refreshed automatically.""" -//| STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_auto_refresh(mp_obj_t self_in) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); return mp_obj_new_bool(common_hal_framebufferio_framebufferdisplay_get_auto_refresh(self)); @@ -173,10 +179,7 @@ MP_PROPERTY_GETSET(framebufferio_framebufferdisplay_auto_refresh_obj, (mp_obj_t)&framebufferio_framebufferdisplay_set_auto_refresh_obj); //| brightness: float -//| """The brightness of the display as a float. 0.0 is off and 1.0 is full brightness. When -//| `auto_brightness` is True, the value of `brightness` will change automatically. -//| If `brightness` is set, `auto_brightness` will be disabled and will be set to False.""" -//| +//| """The brightness of the display as a float. 0.0 is off and 1.0 is full brightness.""" STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_brightness(mp_obj_t self_in) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); mp_float_t brightness = common_hal_framebufferio_framebufferdisplay_get_brightness(self); @@ -189,7 +192,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_brightness_obj, f STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness_obj) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); - common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, false); mp_float_t brightness = mp_obj_get_float(brightness_obj); if (brightness < 0.0f || brightness > 1.0f) { mp_raise_ValueError(translate("Brightness must be 0-1.0")); @@ -206,37 +208,8 @@ MP_PROPERTY_GETSET(framebufferio_framebufferdisplay_brightness_obj, (mp_obj_t)&framebufferio_framebufferdisplay_get_brightness_obj, (mp_obj_t)&framebufferio_framebufferdisplay_set_brightness_obj); -//| auto_brightness: bool -//| """True when the display brightness is adjusted automatically, based on an ambient -//| light sensor or other method. Note that some displays may have this set to True by default, -//| but not actually implement automatic brightness adjustment. `auto_brightness` is set to False -//| if `brightness` is set manually.""" -//| -STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_auto_brightness(mp_obj_t self_in) { - framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); - return mp_obj_new_bool(common_hal_framebufferio_framebufferdisplay_get_auto_brightness(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_auto_brightness_obj, framebufferio_framebufferdisplay_obj_get_auto_brightness); - -STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_auto_brightness(mp_obj_t self_in, mp_obj_t auto_brightness) { - framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); - - bool ok = common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, mp_obj_is_true(auto_brightness)); - if (!ok) { - mp_raise_RuntimeError(translate("Brightness not adjustable")); - } - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_set_auto_brightness_obj, framebufferio_framebufferdisplay_obj_set_auto_brightness); - -MP_PROPERTY_GETSET(framebufferio_framebufferdisplay_auto_brightness_obj, - (mp_obj_t)&framebufferio_framebufferdisplay_get_auto_brightness_obj, - (mp_obj_t)&framebufferio_framebufferdisplay_set_auto_brightness_obj); - //| width: int //| """Gets the width of the framebuffer""" -//| STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_width(mp_obj_t self_in) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_framebufferio_framebufferdisplay_get_width(self)); @@ -248,7 +221,6 @@ MP_PROPERTY_GETTER(framebufferio_framebufferdisplay_width_obj, //| height: int //| """Gets the height of the framebuffer""" -//| STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_height(mp_obj_t self_in) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_framebufferio_framebufferdisplay_get_height(self)); @@ -260,7 +232,6 @@ MP_PROPERTY_GETTER(framebufferio_framebufferdisplay_height_obj, //| rotation: int //| """The rotation of the display as an int in degrees.""" -//| STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_rotation(mp_obj_t self_in) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_framebufferio_framebufferdisplay_get_rotation(self)); @@ -280,8 +251,6 @@ MP_PROPERTY_GETSET(framebufferio_framebufferdisplay_rotation_obj, //| framebuffer: circuitpython_typing.FrameBuffer //| """The framebuffer being used by the display""" -//| -//| STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_framebuffer(mp_obj_t self_in) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); return common_hal_framebufferio_framebufferdisplay_get_framebuffer(self); @@ -296,9 +265,9 @@ MP_PROPERTY_GETTER(framebufferio_framebufferframebuffer_obj, //| """Extract the pixels from a single row //| //| :param int y: The top edge of the area -//| :param ~circuitpython_typing.WriteableBuffer buffer: The buffer in which to place the pixel data""" +//| :param ~circuitpython_typing.WriteableBuffer buffer: The buffer in which to place the pixel data +//| """ //| ... -//| STATIC mp_obj_t framebufferio_framebufferdisplay_obj_fill_row(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_y, ARG_buffer }; static const mp_arg_t allowed_args[] = { @@ -356,15 +325,30 @@ MP_DEFINE_CONST_FUN_OBJ_KW(framebufferio_framebufferdisplay_fill_row_obj, 1, fra //| root_group: displayio.Group //| """The root group on the display.""" //| -//| STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_root_group(mp_obj_t self_in) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); return common_hal_framebufferio_framebufferdisplay_get_root_group(self); } MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_root_group_obj, framebufferio_framebufferdisplay_obj_get_root_group); -MP_PROPERTY_GETTER(framebufferio_framebufferdisplay_root_group_obj, - (mp_obj_t)&framebufferio_framebufferdisplay_get_root_group_obj); +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_root_group(mp_obj_t self_in, mp_obj_t group_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + displayio_group_t *group = NULL; + if (group_in != mp_const_none) { + group = MP_OBJ_TO_PTR(native_group(group_in)); + } + + bool ok = common_hal_framebufferio_framebufferdisplay_set_root_group(self, group); + if (!ok) { + mp_raise_ValueError(translate("Group already used")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_set_root_group_obj, framebufferio_framebufferdisplay_obj_set_root_group); + +MP_PROPERTY_GETSET(framebufferio_framebufferdisplay_root_group_obj, + (mp_obj_t)&framebufferio_framebufferdisplay_get_root_group_obj, + (mp_obj_t)&framebufferio_framebufferdisplay_set_root_group_obj); STATIC const mp_rom_map_elem_t framebufferio_framebufferdisplay_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&framebufferio_framebufferdisplay_show_obj) }, @@ -374,7 +358,6 @@ STATIC const mp_rom_map_elem_t framebufferio_framebufferdisplay_locals_dict_tabl { MP_ROM_QSTR(MP_QSTR_auto_refresh), MP_ROM_PTR(&framebufferio_framebufferdisplay_auto_refresh_obj) }, { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&framebufferio_framebufferdisplay_brightness_obj) }, - { MP_ROM_QSTR(MP_QSTR_auto_brightness), MP_ROM_PTR(&framebufferio_framebufferdisplay_auto_brightness_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&framebufferio_framebufferdisplay_width_obj) }, { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&framebufferio_framebufferdisplay_height_obj) }, diff --git a/shared-bindings/framebufferio/FramebufferDisplay.h b/shared-bindings/framebufferio/FramebufferDisplay.h index 8b262cf727..6526e25afb 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.h +++ b/shared-bindings/framebufferio/FramebufferDisplay.h @@ -55,14 +55,12 @@ uint16_t common_hal_framebufferio_framebufferdisplay_get_height(framebufferio_fr uint16_t common_hal_framebufferio_framebufferdisplay_get_rotation(framebufferio_framebufferdisplay_obj_t *self); void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_framebufferdisplay_obj_t *self, int rotation); -bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t *self); -bool common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t *self, bool auto_brightness); - mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t *self); bool common_hal_framebufferio_framebufferdisplay_set_brightness(framebufferio_framebufferdisplay_obj_t *self, mp_float_t brightness); mp_obj_t common_hal_framebufferio_framebufferdisplay_framebuffer(framebufferio_framebufferdisplay_obj_t *self); mp_obj_t common_hal_framebufferio_framebufferdisplay_get_root_group(framebufferio_framebufferdisplay_obj_t *self); +mp_obj_t common_hal_framebufferio_framebufferdisplay_set_root_group(framebufferio_framebufferdisplay_obj_t *self, displayio_group_t *root_group); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_FRAMEBUFFERDISPLAY_H diff --git a/shared-bindings/framebufferio/__init__.c b/shared-bindings/framebufferio/__init__.c index 5d95ef41f5..324442268e 100644 --- a/shared-bindings/framebufferio/__init__.c +++ b/shared-bindings/framebufferio/__init__.c @@ -35,7 +35,6 @@ //| It is used in conjunction with classes from `displayio` to actually //| place items on the display; and classes like `RGBMatrix` to actually //| drive the display.""" -//| #if CIRCUITPY_FRAMEBUFFERIO static const mp_rom_map_elem_t framebufferio_module_globals_table[] = { diff --git a/shared-bindings/frequencyio/FrequencyIn.c b/shared-bindings/frequencyio/FrequencyIn.c index b72627b19f..bf09196e3d 100644 --- a/shared-bindings/frequencyio/FrequencyIn.c +++ b/shared-bindings/frequencyio/FrequencyIn.c @@ -70,7 +70,6 @@ //| # as the value. //| frequency.clear()""" //| ... -//| STATIC mp_obj_t frequencyio_frequencyin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 1, 1, true); @@ -84,7 +83,7 @@ STATIC mp_obj_t frequencyio_frequencyin_make_new(const mp_obj_type_t *type, size mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); const uint16_t capture_period = args[ARG_capture_period].u_int; @@ -96,7 +95,6 @@ STATIC mp_obj_t frequencyio_frequencyin_make_new(const mp_obj_type_t *type, size //| def deinit(self) -> None: //| """Deinitialises the FrequencyIn and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t frequencyio_frequencyin_deinit(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_frequencyio_frequencyin_deinit(self); @@ -113,14 +111,12 @@ STATIC void check_for_deinit(frequencyio_frequencyin_obj_t *self) { //| def __enter__(self) -> FrequencyIn: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t frequencyio_frequencyin_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_frequencyio_frequencyin_deinit(args[0]); @@ -131,7 +127,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(frequencyio_frequencyin___exit___obj, //| def pause(self) -> None: //| """Pause frequency capture.""" //| ... -//| STATIC mp_obj_t frequencyio_frequencyin_obj_pause(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -144,7 +139,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_pause_obj, frequencyio_frequen //| def resume(self) -> None: //| """Resumes frequency capture.""" //| ... -//| STATIC mp_obj_t frequencyio_frequencyin_obj_resume(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -157,7 +151,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_resume_obj, frequencyio_freque //| def clear(self) -> None: //| """Clears the last detected frequency capture value.""" //| ... -//| STATIC mp_obj_t frequencyio_frequencyin_obj_clear(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -175,7 +168,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_clear_obj, frequencyio_frequen //| //| .. note:: When setting a new ``capture_period``, all previous capture information is //| cleared with a call to ``clear()``.""" -//| STATIC mp_obj_t frequencyio_frequencyin_obj_get_capture_period(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/frequencyio/__init__.c b/shared-bindings/frequencyio/__init__.c index ffbb7af771..18022c7f6e 100644 --- a/shared-bindings/frequencyio/__init__.c +++ b/shared-bindings/frequencyio/__init__.c @@ -38,7 +38,6 @@ //| .. warning:: This module is not available in SAMD21 builds. See the //| :ref:`module-support-matrix` for more info. //| - //| All classes change hardware state and should be deinitialized when they //| are no longer needed if the program continues after use. To do so, either //| call :py:meth:`!deinit` or use a context manager. See @@ -59,7 +58,6 @@ //| CircuitPython will automatically turn off FrequencyIn capture when it resets all //| hardware after program completion. Use ``deinit()`` or a ``with`` statement //| to do it yourself.""" -//| STATIC const mp_rom_map_elem_t frequencyio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_frequencyio) }, diff --git a/shared-bindings/getpass/__init__.c b/shared-bindings/getpass/__init__.c index 7c2de89b34..811d78e03d 100644 --- a/shared-bindings/getpass/__init__.c +++ b/shared-bindings/getpass/__init__.c @@ -35,8 +35,7 @@ //| ... //| -//| def getpass(prompt: Optional[str] = 'Password: ', stream: Optional[io.FileIO] = None) -> str: -//| +//| def getpass(prompt: Optional[str] = "Password: ", stream: Optional[io.FileIO] = None) -> str: //| """Prompt the user without echoing. //| //| :param str prompt: The user is prompted using the string ``prompt``, which defaults to ``'Password: '``. diff --git a/shared-bindings/gifio/GifWriter.c b/shared-bindings/gifio/GifWriter.c index 11dd43becd..a0de52e2cc 100644 --- a/shared-bindings/gifio/GifWriter.c +++ b/shared-bindings/gifio/GifWriter.c @@ -34,7 +34,15 @@ #include "shared/runtime/context_manager_helpers.h" //| class GifWriter: -//| def __init__(self, file: Union[typing.BinaryIO, str], width:int, height:int, colorspace: displayio.Colorspace, loop:bool=True, dither:bool=False) -> None: +//| def __init__( +//| self, +//| file: Union[typing.BinaryIO, str], +//| width: int, +//| height: int, +//| colorspace: displayio.Colorspace, +//| loop: bool = True, +//| dither: bool = False, +//| ) -> None: //| """Construct a GifWriter object //| //| :param file: Either a file open in bytes mode, or the name of a file to open in bytes mode. @@ -45,7 +53,6 @@ //| :param dither: If True, and the image is in color, a simple ordered dither is applied. //| """ //| ... -//| static mp_obj_t gifio_gifwriter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_file, ARG_width, ARG_height, ARG_colorspace, ARG_loop, ARG_dither }; static const mp_arg_t allowed_args[] = { @@ -73,7 +80,7 @@ static mp_obj_t gifio_gifwriter_make_new(const mp_obj_type_t *type, size_t n_arg file, args[ARG_width].u_int, args[ARG_height].u_int, - (displayio_colorspace_t)cp_enum_value(&displayio_colorspace_type, args[ARG_colorspace].u_obj), + (displayio_colorspace_t)cp_enum_value(&displayio_colorspace_type, args[ARG_colorspace].u_obj, MP_QSTR_colorspace), args[ARG_loop].u_bool, args[ARG_dither].u_bool, own_file); @@ -91,7 +98,6 @@ static mp_obj_t gifio_gifwriter_make_new(const mp_obj_type_t *type, size_t n_arg //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| static mp_obj_t gifio_gifwriter___exit__(size_t n_args, const mp_obj_t *args) { gifio_gifwriter_t *self = MP_OBJ_TO_PTR(args[0]); shared_module_gifio_gifwriter_deinit(self); @@ -102,7 +108,6 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gifio_gifwriter___exit___obj, 4, 4, gifio_gi //| def deinit(self) -> None: //| """Close the underlying file.""" //| ... -//| static mp_obj_t gifio_gifwriter_deinit(mp_obj_t self_in) { gifio_gifwriter_t *self = MP_OBJ_TO_PTR(self_in); shared_module_gifio_gifwriter_deinit(self); @@ -117,6 +122,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(gifio_gifwriter_deinit_obj, gifio_gifwriter_deinit); //| :param delay: The frame delay in seconds. The GIF format rounds this to the nearest 1/100 second, and the largest permitted value is 655 seconds. //| """ //| ... +//| static mp_obj_t gifio_gifwriter_add_frame(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bitmap, ARG_delay }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/gifio/OnDiskGif.c b/shared-bindings/gifio/OnDiskGif.c new file mode 100644 index 0000000000..7fb3fcf2bd --- /dev/null +++ b/shared-bindings/gifio/OnDiskGif.c @@ -0,0 +1,247 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Mark Komus + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/gifio/OnDiskGif.h" + +#include + +#include "py/runtime.h" +#include "py/objproperty.h" +#include "supervisor/shared/translate/translate.h" +#include "shared-bindings/gifio/OnDiskGif.h" + +//| class OnDiskGif: +//| """Loads one frame of a GIF into memory at a time. +//| +//| The code can be used in cooperation with displayio but this mode is relatively slow: +//| +//| .. code-block:: Python +//| +//| import board +//| import gifio +//| import displayio +//| import time +//| +//| display = board.DISPLAY +//| splash = displayio.Group() +//| display.root_group = splash +//| +//| odg = gifio.OnDiskGif('/sample.gif') +//| +//| start = time.monotonic() +//| odg.next_frame() # Load the first frame +//| end = time.monotonic() +//| overhead = end - start +//| +//| face = displayio.TileGrid( +//| odg.bitmap, +//| pixel_shader=displayio.ColorConverter( +//| input_colorspace=displayio.Colorspace.RGB565_SWAPPED +//| ), +//| ) +//| splash.append(face) +//| board.DISPLAY.refresh() +//| +//| # Display repeatedly. +//| while True: +//| # Sleep for the frame delay specified by the GIF, +//| # minus the overhead measured to advance between frames. +//| time.sleep(max(0, next_delay - overhead)) +//| next_delay = odg.next_frame() +//| +//| The displayio Group and TileGrid layers can be bypassed and the image can +//| be directly blitted to the full screen. This can give a speed-up of ~4x to +//| ~6x depending on the GIF and display. This requires an LCD that uses +//| standard codes to set the update area, and which accepts RGB565_SWAPPED +//| pixel data directly: +//| +//| .. code-block:: Python +//| +//| # Initial set-up the same as above +//| +//| # Take over display to drive directly +//| display.auto_refresh = False +//| display_bus = display.bus +//| +//| # Display repeatedly & directly. +//| while True: +//| # Sleep for the frame delay specified by the GIF, +//| # minus the overhead measured to advance between frames. +//| time.sleep(max(0, next_delay - overhead)) +//| next_delay = odg.next_frame() +//| +//| display_bus.send(42, struct.pack(">hh", 0, odg.bitmap.width - 1)) +//| display_bus.send(43, struct.pack(">hh", 0, odg.bitmap.height - 1)) +//| display_bus.send(44, d.bitmap) +//| """ +//| +//| def __init__(self, file: str) -> None: +//| """Create an `OnDiskGif` object with the given file. +//| The GIF frames are decoded into RGB565 big-endian format. +//| `displayio` expects little-endian, so the example above uses `Colorspace.RGB565_SWAPPED`. +//| +//| :param file file: The name of the GIF file. +//| """ +//| ... +STATIC mp_obj_t gifio_ondiskgif_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_obj_t arg = all_args[0]; + + if (mp_obj_is_str(arg)) { + arg = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), arg, MP_ROM_QSTR(MP_QSTR_rb)); + } + + if (!mp_obj_is_type(arg, &mp_type_fileio)) { + mp_raise_TypeError(translate("file must be a file opened in byte mode")); + } + + gifio_ondiskgif_t *self = m_new_obj(gifio_ondiskgif_t); + self->base.type = &gifio_ondiskgif_type; + common_hal_gifio_ondiskgif_construct(self, MP_OBJ_TO_PTR(arg)); + + return MP_OBJ_FROM_PTR(self); +} + +//| width: int +//| """Width of the gif. (read only)""" +STATIC mp_obj_t gifio_ondiskgif_obj_get_width(mp_obj_t self_in) { + gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_gifio_ondiskgif_get_width(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(gifio_ondiskgif_get_width_obj, gifio_ondiskgif_obj_get_width); + +MP_PROPERTY_GETTER(gifio_ondiskgif_width_obj, + (mp_obj_t)&gifio_ondiskgif_get_width_obj); + +//| height: int +//| """Height of the gif. (read only)""" +STATIC mp_obj_t gifio_ondiskgif_obj_get_height(mp_obj_t self_in) { + gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_gifio_ondiskgif_get_height(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(gifio_ondiskgif_get_height_obj, gifio_ondiskgif_obj_get_height); + +MP_PROPERTY_GETTER(gifio_ondiskgif_height_obj, + (mp_obj_t)&gifio_ondiskgif_get_height_obj); + +//| bitmap: displayio.Bitmap +//| """The bitmap used to hold the current frame.""" +STATIC mp_obj_t gifio_ondiskgif_obj_get_bitmap(mp_obj_t self_in) { + gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_gifio_ondiskgif_get_bitmap(self); +} + +MP_DEFINE_CONST_FUN_OBJ_1(gifio_ondiskgif_get_bitmap_obj, gifio_ondiskgif_obj_get_bitmap); + +MP_PROPERTY_GETTER(gifio_ondiskgif_bitmap_obj, + (mp_obj_t)&gifio_ondiskgif_get_bitmap_obj); + +//| def next_frame(self) -> float: +//| """Loads the next frame. Returns expected delay before the next frame in seconds.""" +STATIC mp_obj_t gifio_ondiskgif_obj_next_frame(mp_obj_t self_in) { + gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_float((float)common_hal_gifio_ondiskgif_next_frame(self, true) / 1000); +} + +MP_DEFINE_CONST_FUN_OBJ_1(gifio_ondiskgif_next_frame_obj, gifio_ondiskgif_obj_next_frame); + + +//| duration: float +//| """Returns the total duration of the GIF in seconds. (read only)""" +STATIC mp_obj_t gifio_ondiskgif_obj_get_duration(mp_obj_t self_in) { + gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_float((float)common_hal_gifio_ondiskgif_get_duration(self) / 1000); +} + +MP_DEFINE_CONST_FUN_OBJ_1(gifio_ondiskgif_get_duration_obj, gifio_ondiskgif_obj_get_duration); + +MP_PROPERTY_GETTER(gifio_ondiskgif_duration_obj, + (mp_obj_t)&gifio_ondiskgif_get_duration_obj); + +//| frame_count: int +//| """Returns the number of frames in the GIF. (read only)""" +STATIC mp_obj_t gifio_ondiskgif_obj_get_frame_count(mp_obj_t self_in) { + gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_gifio_ondiskgif_get_frame_count(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(gifio_ondiskgif_get_frame_count_obj, gifio_ondiskgif_obj_get_frame_count); + +MP_PROPERTY_GETTER(gifio_ondiskgif_frame_count_obj, + (mp_obj_t)&gifio_ondiskgif_get_frame_count_obj); + +//| min_delay: float +//| """The minimum delay found between frames. (read only)""" +STATIC mp_obj_t gifio_ondiskgif_obj_get_min_delay(mp_obj_t self_in) { + gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_float((float)common_hal_gifio_ondiskgif_get_min_delay(self) / 1000); +} + +MP_DEFINE_CONST_FUN_OBJ_1(gifio_ondiskgif_get_min_delay_obj, gifio_ondiskgif_obj_get_min_delay); + +MP_PROPERTY_GETTER(gifio_ondiskgif_min_delay_obj, + (mp_obj_t)&gifio_ondiskgif_get_min_delay_obj); + +//| max_delay: float +//| """The maximum delay found between frames. (read only)""" +//| +STATIC mp_obj_t gifio_ondiskgif_obj_get_max_delay(mp_obj_t self_in) { + gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_float((float)common_hal_gifio_ondiskgif_get_max_delay(self) / 1000); +} + +MP_DEFINE_CONST_FUN_OBJ_1(gifio_ondiskgif_get_max_delay_obj, gifio_ondiskgif_obj_get_max_delay); + +MP_PROPERTY_GETTER(gifio_ondiskgif_max_delay_obj, + (mp_obj_t)&gifio_ondiskgif_get_max_delay_obj); + +STATIC const mp_rom_map_elem_t gifio_ondiskgif_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&gifio_ondiskgif_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_bitmap), MP_ROM_PTR(&gifio_ondiskgif_bitmap_obj) }, + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&gifio_ondiskgif_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_next_frame), MP_ROM_PTR(&gifio_ondiskgif_next_frame_obj) }, + { MP_ROM_QSTR(MP_QSTR_duration), MP_ROM_PTR(&gifio_ondiskgif_duration_obj) }, + { MP_ROM_QSTR(MP_QSTR_frame_count), MP_ROM_PTR(&gifio_ondiskgif_frame_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_min_delay), MP_ROM_PTR(&gifio_ondiskgif_min_delay_obj) }, + { MP_ROM_QSTR(MP_QSTR_max_delay), MP_ROM_PTR(&gifio_ondiskgif_max_delay_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(gifio_ondiskgif_locals_dict, gifio_ondiskgif_locals_dict_table); + +const mp_obj_type_t gifio_ondiskgif_type = { + { &mp_type_type }, + .name = MP_QSTR_OnDiskGif, + .make_new = gifio_ondiskgif_make_new, + .locals_dict = (mp_obj_dict_t *)&gifio_ondiskgif_locals_dict, +}; diff --git a/shared-bindings/gifio/OnDiskGif.h b/shared-bindings/gifio/OnDiskGif.h new file mode 100644 index 0000000000..4ecbfca495 --- /dev/null +++ b/shared-bindings/gifio/OnDiskGif.h @@ -0,0 +1,48 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Mark Komus + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_ONDISKGIF_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_ONDISKGIF_H + +#include "shared-module/gifio/OnDiskGif.h" +#include "extmod/vfs_fat.h" + +extern const mp_obj_type_t gifio_ondiskgif_type; + +void common_hal_gifio_ondiskgif_construct(gifio_ondiskgif_t *self, pyb_file_obj_t *file); + +uint32_t common_hal_gifio_ondiskgif_get_pixel(gifio_ondiskgif_t *bitmap, + int16_t x, int16_t y); + +uint16_t common_hal_gifio_ondiskgif_get_height(gifio_ondiskgif_t *self); +mp_obj_t common_hal_gifio_ondiskgif_get_bitmap(gifio_ondiskgif_t *self); +uint16_t common_hal_gifio_ondiskgif_get_width(gifio_ondiskgif_t *self); +uint32_t common_hal_gifio_ondiskgif_next_frame(gifio_ondiskgif_t *self, bool setDirty); +int32_t common_hal_gifio_ondiskgif_get_duration(gifio_ondiskgif_t *self); +int32_t common_hal_gifio_ondiskgif_get_frame_count(gifio_ondiskgif_t *self); +int32_t common_hal_gifio_ondiskgif_get_min_delay(gifio_ondiskgif_t *self); +int32_t common_hal_gifio_ondiskgif_get_max_delay(gifio_ondiskgif_t *self); +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_ONDISKGIF_H diff --git a/shared-bindings/gifio/__init__.c b/shared-bindings/gifio/__init__.c index 317eebce9b..bfc87f0d99 100644 --- a/shared-bindings/gifio/__init__.c +++ b/shared-bindings/gifio/__init__.c @@ -27,14 +27,15 @@ #include "py/runtime.h" #include "py/mphal.h" #include "shared-bindings/gifio/GifWriter.h" +#include "shared-bindings/gifio/OnDiskGif.h" #include "shared-bindings/util.h" //| """Access GIF-format images //| """ -//| STATIC const mp_rom_map_elem_t gifio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gifio) }, { MP_OBJ_NEW_QSTR(MP_QSTR_GifWriter), MP_ROM_PTR(&gifio_gifwriter_type)}, + { MP_ROM_QSTR(MP_QSTR_OnDiskGif), MP_ROM_PTR(&gifio_ondiskgif_type) }, }; STATIC MP_DEFINE_CONST_DICT(gifio_module_globals, gifio_module_globals_table); diff --git a/shared-bindings/gnss/GNSS.c b/shared-bindings/gnss/GNSS.c index 0bd800bdc6..d3c9547787 100644 --- a/shared-bindings/gnss/GNSS.c +++ b/shared-bindings/gnss/GNSS.c @@ -36,7 +36,6 @@ //| //| :param system: satellite system to use""" //| ... -//| STATIC mp_obj_t gnss_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { gnss_obj_t *self = m_new_obj(gnss_obj_t); self->base.type = &gnss_type; @@ -71,7 +70,6 @@ STATIC mp_obj_t gnss_make_new(const mp_obj_type_t *type, size_t n_args, size_t n //| def deinit(self) -> None: //| """Turn off the GNSS.""" //| ... -//| STATIC mp_obj_t gnss_obj_deinit(mp_obj_t self_in) { gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_gnss_deinit(self); @@ -88,7 +86,6 @@ STATIC void check_for_deinit(gnss_obj_t *self) { //| def update(self) -> None: //| """Update GNSS positioning information.""" //| ... -//| STATIC mp_obj_t gnss_obj_update(mp_obj_t self_in) { gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -100,7 +97,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(gnss_update_obj, gnss_obj_update); //| latitude: float //| """Latitude of current position in degrees (float).""" -//| STATIC mp_obj_t gnss_obj_get_latitude(mp_obj_t self_in) { gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -113,7 +109,6 @@ MP_PROPERTY_GETTER(gnss_latitude_obj, //| longitude: float //| """Longitude of current position in degrees (float).""" -//| STATIC mp_obj_t gnss_obj_get_longitude(mp_obj_t self_in) { gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -126,7 +121,6 @@ MP_PROPERTY_GETTER(gnss_longitude_obj, //| altitude: float //| """Altitude of current position in meters (float).""" -//| STATIC mp_obj_t gnss_obj_get_altitude(mp_obj_t self_in) { gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -139,7 +133,6 @@ MP_PROPERTY_GETTER(gnss_altitude_obj, //| timestamp: time.struct_time //| """Time when the position data was updated.""" -//| STATIC mp_obj_t gnss_obj_get_timestamp(mp_obj_t self_in) { gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/gnss/PositionFix.c b/shared-bindings/gnss/PositionFix.c index e60611d705..35d4971b66 100644 --- a/shared-bindings/gnss/PositionFix.c +++ b/shared-bindings/gnss/PositionFix.c @@ -9,7 +9,6 @@ //| //| def __init__(self) -> None: //| """Enum-like class to define the position fix mode.""" -//| //| INVALID: PositionFix //| """No measurement.""" //| diff --git a/shared-bindings/gnss/SatelliteSystem.c b/shared-bindings/gnss/SatelliteSystem.c index edac03ddb6..4bf0d6cf4b 100644 --- a/shared-bindings/gnss/SatelliteSystem.c +++ b/shared-bindings/gnss/SatelliteSystem.c @@ -9,7 +9,6 @@ //| //| def __init__(self) -> None: //| """Enum-like class to define the satellite system type.""" -//| //| GPS: SatelliteSystem //| """Global Positioning System.""" //| diff --git a/shared-bindings/gnss/__init__.c b/shared-bindings/gnss/__init__.c index ab6cbf56cf..6029e1a54e 100644 --- a/shared-bindings/gnss/__init__.c +++ b/shared-bindings/gnss/__init__.c @@ -13,7 +13,6 @@ //| """Global Navigation Satellite System //| //| The `gnss` module contains classes to control the GNSS and acquire positioning information.""" -//| STATIC const mp_rom_map_elem_t gnss_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gnss) }, { MP_ROM_QSTR(MP_QSTR_GNSS), MP_ROM_PTR(&gnss_type) }, diff --git a/shared-bindings/hashlib/Hash.c b/shared-bindings/hashlib/Hash.c index e27b71ef78..e3cbbc39d3 100644 --- a/shared-bindings/hashlib/Hash.c +++ b/shared-bindings/hashlib/Hash.c @@ -33,25 +33,25 @@ //| class Hash: //| """In progress hash algorithm. This object is always created by a `hashlib.new()`. It has no -//| user-visible constructor.""" +//| user-visible constructor.""" //| //| digest_size: int //| """Digest size in bytes""" -//| -STATIC mp_obj_t hashlib_hash_get_digest_size(mp_obj_t self_in) { +STATIC mp_obj_t hashlib_hash_digest_size_get(mp_obj_t self_in) { mp_check_self(mp_obj_is_type(self_in, &hashlib_hash_type)); hashlib_hash_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_hashlib_hash_get_digest_size(self)); } -MP_PROPERTY_GETTER(hashlib_hash_digest_size_obj, hashlib_hash_get_digest_size); +MP_DEFINE_CONST_FUN_OBJ_1(hashlib_hash_digest_size_get_obj, hashlib_hash_digest_size_get); +MP_PROPERTY_GETTER(hashlib_hash_digest_size_obj, (mp_obj_t)&hashlib_hash_digest_size_get_obj); //| def update(self, data: ReadableBuffer) -> None: //| """Update the hash with the given bytes. //| -//| :param ~circuitpython_typing.ReadableBuffer data: Update the hash from data in this buffer""" +//| :param ~circuitpython_typing.ReadableBuffer data: Update the hash from data in this buffer +//| """ //| ... -//| mp_obj_t hashlib_hash_update(mp_obj_t self_in, mp_obj_t buf_in) { mp_check_self(mp_obj_is_type(self_in, &hashlib_hash_type)); hashlib_hash_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/hashlib/__init__.c b/shared-bindings/hashlib/__init__.c index 4b5be0165b..424159f84c 100644 --- a/shared-bindings/hashlib/__init__.c +++ b/shared-bindings/hashlib/__init__.c @@ -38,7 +38,7 @@ //| |see_cpython_module| :mod:`cpython:hashlib`. //| """ //| -//| def new(name, data=b"") -> hashlib.Hash: +//| def new(name: str, data: bytes = b"") -> hashlib.Hash: //| """Returns a Hash object setup for the named algorithm. Raises ValueError when the named //| algorithm is unsupported. //| diff --git a/shared-bindings/i2cperipheral/I2CPeripheral.c b/shared-bindings/i2cperipheral/I2CPeripheral.c deleted file mode 100644 index b63e8a891b..0000000000 --- a/shared-bindings/i2cperipheral/I2CPeripheral.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Noralf Trønnes - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/i2cperipheral/I2CPeripheral.h" -#include "shared-bindings/time/__init__.h" -#include "shared-bindings/util.h" - -#include "shared/runtime/buffer_helper.h" -#include "shared/runtime/context_manager_helpers.h" -#include "shared/runtime/interrupt_char.h" - -#include "py/mperrno.h" -#include "py/mphal.h" -#include "py/obj.h" -#include "py/objproperty.h" -#include "py/runtime.h" - -STATIC mp_obj_t mp_obj_new_i2cperipheral_i2c_peripheral_request(i2cperipheral_i2c_peripheral_obj_t *peripheral, uint8_t address, bool is_read, bool is_restart) { - i2cperipheral_i2c_peripheral_request_obj_t *self = m_new_obj(i2cperipheral_i2c_peripheral_request_obj_t); - self->base.type = &i2cperipheral_i2c_peripheral_request_type; - self->peripheral = peripheral; - self->address = address; - self->is_read = is_read; - self->is_restart = is_restart; - return (mp_obj_t)self; -} - -//| class I2CPeripheral: -//| """Two wire serial protocol peripheral""" -//| -//| def __init__(self, scl: microcontroller.Pin, sda: microcontroller.Pin, addresses: Sequence[int], smbus: bool = False) -> None: -//| """I2C is a two-wire protocol for communicating between devices. -//| This implements the peripheral (sensor, secondary) side. -//| -//| :param ~microcontroller.Pin scl: The clock pin -//| :param ~microcontroller.Pin sda: The data pin -//| :param addresses: The I2C addresses to respond to (how many is hw dependent). -//| :type addresses: list[int] -//| :param bool smbus: Use SMBUS timings if the hardware supports it""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - i2cperipheral_i2c_peripheral_obj_t *self = m_new_obj(i2cperipheral_i2c_peripheral_obj_t); - self->base.type = &i2cperipheral_i2c_peripheral_type; - enum { ARG_scl, ARG_sda, ARG_addresses, ARG_smbus }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_addresses, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_smbus, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj); - const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj); - - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(args[ARG_addresses].u_obj, &iter_buf); - mp_obj_t item; - uint8_t *addresses = NULL; - unsigned int i = 0; - while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - mp_int_t value; - if (!mp_obj_get_int_maybe(item, &value)) { - mp_raise_TypeError_varg(translate("can't convert %q to %q"), MP_QSTR_address, MP_QSTR_int); - } - if (value < 0x00 || value > 0x7f) { - mp_raise_ValueError(translate("address out of bounds")); - } - addresses = m_renew(uint8_t, addresses, i, i + 1); - addresses[i++] = value; - } - if (i == 0) { - mp_raise_ValueError(translate("addresses is empty")); - } - - common_hal_i2cperipheral_i2c_peripheral_construct(self, scl, sda, addresses, i, args[ARG_smbus].u_bool); - return (mp_obj_t)self; -} - -//| def deinit(self) -> None: -//| """Releases control of the underlying hardware so other classes can use it.""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_obj_deinit(mp_obj_t self_in) { - mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_type)); - i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_i2cperipheral_i2c_peripheral_deinit(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(i2cperipheral_i2c_peripheral_deinit_obj, i2cperipheral_i2c_peripheral_obj_deinit); - -//| def __enter__(self) -> I2CPeripheral: -//| """No-op used in Context Managers.""" -//| ... -//| -// Provided by context manager helper. - -//| def __exit__(self) -> None: -//| """Automatically deinitializes the hardware on context exit. See -//| :ref:`lifetime-and-contextmanagers` for more info.""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_obj___exit__(size_t n_args, const mp_obj_t *args) { - mp_check_self(mp_obj_is_type(args[0], &i2cperipheral_i2c_peripheral_type)); - i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(args[0]); - common_hal_i2cperipheral_i2c_peripheral_deinit(self); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral___exit___obj, 4, 4, i2cperipheral_i2c_peripheral_obj___exit__); - -//| def request(self, timeout: float = -1) -> I2CPeripheralRequest: -//| """Wait for an I2C request. -//| -//| :param float timeout: Timeout in seconds. Zero means wait forever, a negative value means check once -//| :return: I2C Slave Request or None if timeout=-1 and there's no request -//| :rtype: ~i2cperipheral.I2CPeripheralRequest""" -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_check_self(mp_obj_is_type(pos_args[0], &i2cperipheral_i2c_peripheral_type)); - i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - if (common_hal_i2cperipheral_i2c_peripheral_deinited(self)) { - raise_deinited_error(); - } - enum { ARG_timeout }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - #if MICROPY_PY_BUILTINS_FLOAT - float f = mp_obj_get_float(args[ARG_timeout].u_obj) * 1000; - int timeout_ms = (int)f; - #else - int timeout_ms = mp_obj_get_int(args[ARG_timeout].u_obj) * 1000; - #endif - - bool forever = false; - uint64_t timeout_end = 0; - if (timeout_ms == 0) { - forever = true; - } else if (timeout_ms > 0) { - timeout_end = common_hal_time_monotonic_ms() + timeout_ms; - } - - int last_error = 0; - - do { - uint8_t address; - bool is_read; - bool is_restart; - - RUN_BACKGROUND_TASKS; - if (mp_hal_is_interrupted()) { - return mp_const_none; - } - - int status = common_hal_i2cperipheral_i2c_peripheral_is_addressed(self, &address, &is_read, &is_restart); - if (status < 0) { - // On error try one more time before bailing out - if (last_error) { - mp_raise_OSError(last_error); - } - last_error = -status; - mp_hal_delay_ms(10); - continue; - } - - last_error = 0; - - if (status == 0) { - mp_hal_delay_us(10); - continue; - } - - return mp_obj_new_i2cperipheral_i2c_peripheral_request(self, address, is_read, is_restart); - } while (forever || common_hal_time_monotonic_ms() < timeout_end); - - if (timeout_ms > 0) { - mp_raise_OSError(MP_ETIMEDOUT); - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(i2cperipheral_i2c_peripheral_request_obj, 1, i2cperipheral_i2c_peripheral_request); - -STATIC const mp_rom_map_elem_t i2cperipheral_i2c_peripheral_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cperipheral_i2c_peripheral___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_request), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_obj) }, - -}; - -STATIC MP_DEFINE_CONST_DICT(i2cperipheral_i2c_peripheral_locals_dict, i2cperipheral_i2c_peripheral_locals_dict_table); - -const mp_obj_type_t i2cperipheral_i2c_peripheral_type = { - { &mp_type_type }, - .name = MP_QSTR_I2CPeripheral, - .make_new = i2cperipheral_i2c_peripheral_make_new, - .locals_dict = (mp_obj_dict_t *)&i2cperipheral_i2c_peripheral_locals_dict, -}; - -//| class I2CPeripheralRequest: -//| -//| def __init__(self, peripheral: i2cperipheral.I2CPeripheral, address: int, is_read: bool, is_restart: bool) -> None: -//| """Information about an I2C transfer request -//| This cannot be instantiated directly, but is returned by :py:meth:`I2CPeripheral.request`. -//| -//| :param peripheral: The I2CPeripheral object receiving this request -//| :param address: I2C address -//| :param is_read: True if the main peripheral is requesting data -//| :param is_restart: Repeated Start Condition""" -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 4, 4, false); - return mp_obj_new_i2cperipheral_i2c_peripheral_request(args[0], mp_obj_get_int(args[1]), mp_obj_is_true(args[2]), mp_obj_is_true(args[3])); -} - -//| def __enter__(self) -> I2CPeripheralRequest: -//| """No-op used in Context Managers.""" -//| ... -//| -// Provided by context manager helper. - -//| def __exit__(self) -> None: -//| """Close the request.""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_obj___exit__(size_t n_args, const mp_obj_t *args) { - mp_check_self(mp_obj_is_type(args[0], &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); - common_hal_i2cperipheral_i2c_peripheral_close(self->peripheral); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral_request___exit___obj, 4, 4, i2cperipheral_i2c_peripheral_request_obj___exit__); - -//| address: int -//| """The I2C address of the request.""" -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_address(mp_obj_t self_in) { - mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(self->address); -} -MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_address_obj, i2cperipheral_i2c_peripheral_request_get_address); - -//| is_read: bool -//| """The I2C main controller is reading from this peripheral.""" -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_is_read(mp_obj_t self_in) { - mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(self->is_read); -} -MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_is_read_obj, i2cperipheral_i2c_peripheral_request_get_is_read); - -//| is_restart: bool -//| """Is Repeated Start Condition.""" -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_is_restart(mp_obj_t self_in) { - mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(self->is_restart); -} -MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_is_restart_obj, i2cperipheral_i2c_peripheral_request_get_is_restart); - -//| def read(self, n: int = -1, ack: bool = True) -> bytearray: -//| """Read data. -//| If ack=False, the caller is responsible for calling :py:meth:`I2CPeripheralRequest.ack`. -//| -//| :param n: Number of bytes to read (negative means all) -//| :param ack: Whether or not to send an ACK after the n'th byte -//| :return: Bytes read""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_check_self(mp_obj_is_type(pos_args[0], &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - enum { ARG_n, ARG_ack }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_n, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_ack, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - if (self->is_read) { - mp_raise_OSError(MP_EACCES); - } - - int n = args[ARG_n].u_int; - if (n == 0) { - return mp_obj_new_bytearray(0, NULL); - } - bool ack = args[ARG_ack].u_bool; - - int i = 0; - uint8_t *buffer = NULL; - uint64_t timeout_end = common_hal_time_monotonic_ms() + 10 * 1000; - while (common_hal_time_monotonic_ms() < timeout_end) { - RUN_BACKGROUND_TASKS; - if (mp_hal_is_interrupted()) { - break; - } - - uint8_t data; - int num = common_hal_i2cperipheral_i2c_peripheral_read_byte(self->peripheral, &data); - if (num == 0) { - break; - } - - buffer = m_renew(uint8_t, buffer, i, i + 1); - buffer[i++] = data; - if (i == n) { - if (ack) { - common_hal_i2cperipheral_i2c_peripheral_ack(self->peripheral, true); - } - break; - } - common_hal_i2cperipheral_i2c_peripheral_ack(self->peripheral, true); - } - - return mp_obj_new_bytearray(i, buffer); -} -MP_DEFINE_CONST_FUN_OBJ_KW(i2cperipheral_i2c_peripheral_request_read_obj, 1, i2cperipheral_i2c_peripheral_request_read); - -//| def write(self, buffer: ReadableBuffer) -> int: -//| """Write the data contained in buffer. -//| -//| :param ~circuitpython_typing.ReadableBuffer buffer: Write out the data in this buffer -//| :return: Number of bytes written""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_write(mp_obj_t self_in, mp_obj_t buf_in) { - mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (!self->is_read) { - mp_raise_OSError(MP_EACCES); - } - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); - - for (size_t i = 0; i < bufinfo.len; i++) { - RUN_BACKGROUND_TASKS; - if (mp_hal_is_interrupted()) { - break; - } - - int num = common_hal_i2cperipheral_i2c_peripheral_write_byte(self->peripheral, ((uint8_t *)(bufinfo.buf))[i]); - if (num == 0) { - return mp_obj_new_int(i); - } - } - - return mp_obj_new_int(bufinfo.len); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(i2cperipheral_i2c_peripheral_request_write_obj, i2cperipheral_i2c_peripheral_request_write); - -//| def ack(self, ack: bool = True) -> None: -//| """Acknowledge or Not Acknowledge last byte received. -//| Use together with :py:meth:`I2CPeripheralRequest.read` ack=False. -//| -//| :param ack: Whether to send an ACK or NACK""" -//| ... -//| -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_ack(uint n_args, const mp_obj_t *args) { - mp_check_self(mp_obj_is_type(args[0], &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); - bool ack = (n_args == 1) ? true : mp_obj_is_true(args[1]); - - if (self->is_read) { - mp_raise_OSError(MP_EACCES); - } - - common_hal_i2cperipheral_i2c_peripheral_ack(self->peripheral, ack); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral_request_ack_obj, 1, 2, i2cperipheral_i2c_peripheral_request_ack); - -STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_close(mp_obj_t self_in) { - mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_request_type)); - i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); - - common_hal_i2cperipheral_i2c_peripheral_close(self->peripheral); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(i2cperipheral_i2c_peripheral_request_close_obj, i2cperipheral_i2c_peripheral_request_close); - -STATIC const mp_rom_map_elem_t i2cperipheral_i2c_peripheral_request_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_address_obj) }, - { MP_ROM_QSTR(MP_QSTR_is_read), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_is_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_is_restart), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_is_restart_obj) }, - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_ack), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_ack_obj) }, - { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_request_close_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(i2cperipheral_i2c_peripheral_request_locals_dict, i2cperipheral_i2c_peripheral_request_locals_dict_table); - -const mp_obj_type_t i2cperipheral_i2c_peripheral_request_type = { - { &mp_type_type }, - .name = MP_QSTR_I2CPeripheralRequest, - .make_new = i2cperipheral_i2c_peripheral_request_make_new, - .locals_dict = (mp_obj_dict_t *)&i2cperipheral_i2c_peripheral_request_locals_dict, -}; diff --git a/shared-bindings/i2ctarget/I2CTarget.c b/shared-bindings/i2ctarget/I2CTarget.c new file mode 100644 index 0000000000..a07d038c6f --- /dev/null +++ b/shared-bindings/i2ctarget/I2CTarget.c @@ -0,0 +1,425 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Noralf Trønnes + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/i2ctarget/I2CTarget.h" +#include "shared-bindings/time/__init__.h" +#include "shared-bindings/util.h" + +#include "shared/runtime/buffer_helper.h" +#include "shared/runtime/context_manager_helpers.h" +#include "shared/runtime/interrupt_char.h" + +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +STATIC mp_obj_t mp_obj_new_i2ctarget_i2c_target_request(i2ctarget_i2c_target_obj_t *target, uint8_t address, bool is_read, bool is_restart) { + i2ctarget_i2c_target_request_obj_t *self = m_new_obj(i2ctarget_i2c_target_request_obj_t); + self->base.type = &i2ctarget_i2c_target_request_type; + self->target = target; + self->address = address; + self->is_read = is_read; + self->is_restart = is_restart; + return (mp_obj_t)self; +} + +//| class I2CTarget: +//| """Two wire serial protocol target""" +//| +//| def __init__( +//| self, +//| scl: microcontroller.Pin, +//| sda: microcontroller.Pin, +//| addresses: Sequence[int], +//| smbus: bool = False, +//| ) -> None: +//| """I2C is a two-wire protocol for communicating between devices. +//| This implements the target (peripheral, sensor, secondary) side. +//| +//| :param ~microcontroller.Pin scl: The clock pin +//| :param ~microcontroller.Pin sda: The data pin +//| :param addresses: The I2C addresses to respond to (how many is hardware dependent). +//| :type addresses: list[int] +//| :param bool smbus: Use SMBUS timings if the hardware supports it""" +//| ... +STATIC mp_obj_t i2ctarget_i2c_target_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + i2ctarget_i2c_target_obj_t *self = m_new_obj(i2ctarget_i2c_target_obj_t); + self->base.type = &i2ctarget_i2c_target_type; + enum { ARG_scl, ARG_sda, ARG_addresses, ARG_smbus }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_addresses, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_smbus, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj, MP_QSTR_scl); + const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj, MP_QSTR_sda); + + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(args[ARG_addresses].u_obj, &iter_buf); + mp_obj_t item; + uint8_t *addresses = NULL; + unsigned int i = 0; + while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + mp_uint_t value = mp_arg_validate_int_range(mp_obj_get_int(item), 0x00, 0x7f, MP_QSTR_address); + addresses = m_renew(uint8_t, addresses, i, i + 1); + addresses[i++] = value; + } + if (i == 0) { + mp_raise_ValueError(translate("addresses is empty")); + } + + common_hal_i2ctarget_i2c_target_construct(self, scl, sda, addresses, i, args[ARG_smbus].u_bool); + return (mp_obj_t)self; +} + +//| def deinit(self) -> None: +//| """Releases control of the underlying hardware so other classes can use it.""" +//| ... +STATIC mp_obj_t i2ctarget_i2c_target_obj_deinit(mp_obj_t self_in) { + mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_type)); + i2ctarget_i2c_target_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_i2ctarget_i2c_target_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(i2ctarget_i2c_target_deinit_obj, i2ctarget_i2c_target_obj_deinit); + +//| def __enter__(self) -> I2CTarget: +//| """No-op used in Context Managers.""" +//| ... +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware on context exit. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +STATIC mp_obj_t i2ctarget_i2c_target_obj___exit__(size_t n_args, const mp_obj_t *args) { + mp_check_self(mp_obj_is_type(args[0], &i2ctarget_i2c_target_type)); + i2ctarget_i2c_target_obj_t *self = MP_OBJ_TO_PTR(args[0]); + common_hal_i2ctarget_i2c_target_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2ctarget_i2c_target___exit___obj, 4, 4, i2ctarget_i2c_target_obj___exit__); + +//| def request(self, *, timeout: float = -1) -> I2CTargetRequest: +//| """Wait for an I2C request. +//| +//| :param float timeout: Timeout in seconds. Zero means wait forever, a negative value means check once +//| :return: I2CTargetRequest or None if timeout=-1 and there's no request +//| :rtype: ~i2ctarget.I2CTargetRequest""" +//| +STATIC mp_obj_t i2ctarget_i2c_target_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_check_self(mp_obj_is_type(pos_args[0], &i2ctarget_i2c_target_type)); + i2ctarget_i2c_target_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if (common_hal_i2ctarget_i2c_target_deinited(self)) { + raise_deinited_error(); + } + enum { ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + #if MICROPY_PY_BUILTINS_FLOAT + float f = mp_obj_get_float(args[ARG_timeout].u_obj) * 1000; + int timeout_ms = (int)f; + #else + int timeout_ms = mp_obj_get_int(args[ARG_timeout].u_obj) * 1000; + #endif + + bool forever = false; + uint64_t timeout_end = 0; + if (timeout_ms == 0) { + forever = true; + } else if (timeout_ms > 0) { + timeout_end = common_hal_time_monotonic_ms() + timeout_ms; + } + + int last_error = 0; + + do { + uint8_t address; + bool is_read; + bool is_restart; + + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + return mp_const_none; + } + + int status = common_hal_i2ctarget_i2c_target_is_addressed(self, &address, &is_read, &is_restart); + if (status < 0) { + // On error try one more time before bailing out + if (last_error) { + mp_raise_OSError(last_error); + } + last_error = -status; + mp_hal_delay_ms(10); + continue; + } + + last_error = 0; + + if (status == 0) { + mp_hal_delay_us(10); + continue; + } + + return mp_obj_new_i2ctarget_i2c_target_request(self, address, is_read, is_restart); + } while (forever || common_hal_time_monotonic_ms() < timeout_end); + + if (timeout_ms > 0) { + mp_raise_OSError(MP_ETIMEDOUT); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(i2ctarget_i2c_target_request_obj, 1, i2ctarget_i2c_target_request); + +STATIC const mp_rom_map_elem_t i2ctarget_i2c_target_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2ctarget_i2c_target_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2ctarget_i2c_target___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_request), MP_ROM_PTR(&i2ctarget_i2c_target_request_obj) }, + +}; + +STATIC MP_DEFINE_CONST_DICT(i2ctarget_i2c_target_locals_dict, i2ctarget_i2c_target_locals_dict_table); + +const mp_obj_type_t i2ctarget_i2c_target_type = { + { &mp_type_type }, + .name = MP_QSTR_I2CTarget, + .make_new = i2ctarget_i2c_target_make_new, + .locals_dict = (mp_obj_dict_t *)&i2ctarget_i2c_target_locals_dict, +}; + +//| class I2CTargetRequest: +//| def __init__( +//| self, target: i2ctarget.I2CTarget, address: int, is_read: bool, is_restart: bool +//| ) -> None: +//| """Information about an I2C transfer request +//| This cannot be instantiated directly, but is returned by :py:meth:`I2CTarget.request`. +//| +//| :param target: The I2CTarget object receiving this request +//| :param address: I2C address +//| :param is_read: True if the main target is requesting data +//| :param is_restart: Repeated Start Condition""" +STATIC mp_obj_t i2ctarget_i2c_target_request_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 4, 4, false); + return mp_obj_new_i2ctarget_i2c_target_request(args[0], mp_obj_get_int(args[1]), mp_obj_is_true(args[2]), mp_obj_is_true(args[3])); +} + +//| def __enter__(self) -> I2CTargetRequest: +//| """No-op used in Context Managers.""" +//| ... +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Close the request.""" +//| ... +STATIC mp_obj_t i2ctarget_i2c_target_request_obj___exit__(size_t n_args, const mp_obj_t *args) { + mp_check_self(mp_obj_is_type(args[0], &i2ctarget_i2c_target_request_type)); + i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); + common_hal_i2ctarget_i2c_target_close(self->target); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2ctarget_i2c_target_request___exit___obj, 4, 4, i2ctarget_i2c_target_request_obj___exit__); + +//| address: int +//| """The I2C address of the request.""" +STATIC mp_obj_t i2ctarget_i2c_target_request_get_address(mp_obj_t self_in) { + mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_request_type)); + i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int(self->address); +} +MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_address_obj, i2ctarget_i2c_target_request_get_address); + +//| is_read: bool +//| """The I2C main controller is reading from this target.""" +STATIC mp_obj_t i2ctarget_i2c_target_request_get_is_read(mp_obj_t self_in) { + mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_request_type)); + i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(self->is_read); +} +MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_read_obj, i2ctarget_i2c_target_request_get_is_read); + +//| is_restart: bool +//| """Is Repeated Start Condition.""" +STATIC mp_obj_t i2ctarget_i2c_target_request_get_is_restart(mp_obj_t self_in) { + mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_request_type)); + i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(self->is_restart); +} +MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_restart_obj, i2ctarget_i2c_target_request_get_is_restart); + +//| def read(self, n: int = -1, ack: bool = True) -> bytearray: +//| """Read data. +//| If ack=False, the caller is responsible for calling :py:meth:`I2CTargetRequest.ack`. +//| +//| :param n: Number of bytes to read (negative means all) +//| :param ack: Whether or not to send an ACK after the n'th byte +//| :return: Bytes read""" +//| ... +STATIC mp_obj_t i2ctarget_i2c_target_request_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_check_self(mp_obj_is_type(pos_args[0], &i2ctarget_i2c_target_request_type)); + i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + enum { ARG_n, ARG_ack }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_n, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_ack, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if (self->is_read) { + mp_raise_OSError(MP_EACCES); + } + + int n = args[ARG_n].u_int; + if (n == 0) { + return mp_obj_new_bytearray(0, NULL); + } + bool ack = args[ARG_ack].u_bool; + + int i = 0; + uint8_t *buffer = NULL; + uint64_t timeout_end = common_hal_time_monotonic_ms() + 10 * 1000; + while (common_hal_time_monotonic_ms() < timeout_end) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + break; + } + + uint8_t data; + int num = common_hal_i2ctarget_i2c_target_read_byte(self->target, &data); + if (num == 0) { + break; + } + + buffer = m_renew(uint8_t, buffer, i, i + 1); + buffer[i++] = data; + if (i == n) { + if (ack) { + common_hal_i2ctarget_i2c_target_ack(self->target, true); + } + break; + } + common_hal_i2ctarget_i2c_target_ack(self->target, true); + } + + return mp_obj_new_bytearray(i, buffer); +} +MP_DEFINE_CONST_FUN_OBJ_KW(i2ctarget_i2c_target_request_read_obj, 1, i2ctarget_i2c_target_request_read); + +//| def write(self, buffer: ReadableBuffer) -> int: +//| """Write the data contained in buffer. +//| +//| :param ~circuitpython_typing.ReadableBuffer buffer: Write out the data in this buffer +//| :return: Number of bytes written""" +//| ... +STATIC mp_obj_t i2ctarget_i2c_target_request_write(mp_obj_t self_in, mp_obj_t buf_in) { + mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_request_type)); + i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (!self->is_read) { + mp_raise_OSError(MP_EACCES); + } + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + + for (size_t i = 0; i < bufinfo.len; i++) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + break; + } + + int num = common_hal_i2ctarget_i2c_target_write_byte(self->target, ((uint8_t *)(bufinfo.buf))[i]); + if (num == 0) { + return mp_obj_new_int(i); + } + } + + return mp_obj_new_int(bufinfo.len); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(i2ctarget_i2c_target_request_write_obj, i2ctarget_i2c_target_request_write); + +//| def ack(self, ack: bool = True) -> None: +//| """Acknowledge or Not Acknowledge last byte received. +//| Use together with :py:meth:`I2CTargetRequest.read` ack=False. +//| +//| :param ack: Whether to send an ACK or NACK""" +//| ... +//| +STATIC mp_obj_t i2ctarget_i2c_target_request_ack(uint n_args, const mp_obj_t *args) { + mp_check_self(mp_obj_is_type(args[0], &i2ctarget_i2c_target_request_type)); + i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); + bool ack = (n_args == 1) ? true : mp_obj_is_true(args[1]); + + if (self->is_read) { + mp_raise_OSError(MP_EACCES); + } + + common_hal_i2ctarget_i2c_target_ack(self->target, ack); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2ctarget_i2c_target_request_ack_obj, 1, 2, i2ctarget_i2c_target_request_ack); + +STATIC mp_obj_t i2ctarget_i2c_target_request_close(mp_obj_t self_in) { + mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_request_type)); + i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_i2ctarget_i2c_target_close(self->target); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(i2ctarget_i2c_target_request_close_obj, i2ctarget_i2c_target_request_close); + +STATIC const mp_rom_map_elem_t i2ctarget_i2c_target_request_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2ctarget_i2c_target_request___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&i2ctarget_i2c_target_request_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_is_read), MP_ROM_PTR(&i2ctarget_i2c_target_request_is_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_is_restart), MP_ROM_PTR(&i2ctarget_i2c_target_request_is_restart_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&i2ctarget_i2c_target_request_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&i2ctarget_i2c_target_request_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_ack), MP_ROM_PTR(&i2ctarget_i2c_target_request_ack_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&i2ctarget_i2c_target_request_close_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(i2ctarget_i2c_target_request_locals_dict, i2ctarget_i2c_target_request_locals_dict_table); + +const mp_obj_type_t i2ctarget_i2c_target_request_type = { + { &mp_type_type }, + .name = MP_QSTR_I2CTargetRequest, + .make_new = i2ctarget_i2c_target_request_make_new, + .locals_dict = (mp_obj_dict_t *)&i2ctarget_i2c_target_request_locals_dict, +}; diff --git a/shared-bindings/i2cperipheral/I2CPeripheral.h b/shared-bindings/i2ctarget/I2CTarget.h similarity index 54% rename from shared-bindings/i2cperipheral/I2CPeripheral.h rename to shared-bindings/i2ctarget/I2CTarget.h index d3db1b96c9..e9c9714dee 100644 --- a/shared-bindings/i2cperipheral/I2CPeripheral.h +++ b/shared-bindings/i2ctarget/I2CTarget.h @@ -24,37 +24,37 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_TARGET_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_TARGET_H #include "py/obj.h" #include "common-hal/microcontroller/Pin.h" -#include "common-hal/i2cperipheral/I2CPeripheral.h" +#include "common-hal/i2ctarget/I2CTarget.h" typedef struct { mp_obj_base_t base; - i2cperipheral_i2c_peripheral_obj_t *peripheral; + i2ctarget_i2c_target_obj_t *target; uint16_t address; bool is_read; bool is_restart; -} i2cperipheral_i2c_peripheral_request_obj_t; +} i2ctarget_i2c_target_request_obj_t; -extern const mp_obj_type_t i2cperipheral_i2c_peripheral_request_type; +extern const mp_obj_type_t i2ctarget_i2c_target_request_type; -extern const mp_obj_type_t i2cperipheral_i2c_peripheral_type; +extern const mp_obj_type_t i2ctarget_i2c_target_type; -extern void common_hal_i2cperipheral_i2c_peripheral_construct(i2cperipheral_i2c_peripheral_obj_t *self, +extern void common_hal_i2ctarget_i2c_target_construct(i2ctarget_i2c_target_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint8_t *addresses, unsigned int num_addresses, bool smbus); -extern void common_hal_i2cperipheral_i2c_peripheral_deinit(i2cperipheral_i2c_peripheral_obj_t *self); -extern bool common_hal_i2cperipheral_i2c_peripheral_deinited(i2cperipheral_i2c_peripheral_obj_t *self); +extern void common_hal_i2ctarget_i2c_target_deinit(i2ctarget_i2c_target_obj_t *self); +extern bool common_hal_i2ctarget_i2c_target_deinited(i2ctarget_i2c_target_obj_t *self); -extern int common_hal_i2cperipheral_i2c_peripheral_is_addressed(i2cperipheral_i2c_peripheral_obj_t *self, +extern int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart); -extern int common_hal_i2cperipheral_i2c_peripheral_read_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t *data); -extern int common_hal_i2cperipheral_i2c_peripheral_write_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t data); -extern void common_hal_i2cperipheral_i2c_peripheral_ack(i2cperipheral_i2c_peripheral_obj_t *self, bool ack); -extern void common_hal_i2cperipheral_i2c_peripheral_close(i2cperipheral_i2c_peripheral_obj_t *self); +extern int common_hal_i2ctarget_i2c_target_read_byte(i2ctarget_i2c_target_obj_t *self, uint8_t *data); +extern int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self, uint8_t data); +extern void common_hal_i2ctarget_i2c_target_ack(i2ctarget_i2c_target_obj_t *self, bool ack); +extern void common_hal_i2ctarget_i2c_target_close(i2ctarget_i2c_target_obj_t *self); -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_SLAVE_H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_TARGET_H diff --git a/shared-bindings/i2cperipheral/__init__.c b/shared-bindings/i2ctarget/__init__.c similarity index 73% rename from shared-bindings/i2cperipheral/__init__.c rename to shared-bindings/i2ctarget/__init__.c index fde7002daf..0fa7e50dd6 100644 --- a/shared-bindings/i2cperipheral/__init__.c +++ b/shared-bindings/i2ctarget/__init__.c @@ -30,24 +30,24 @@ #include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" -// #include "shared-bindings/i2cperipheral/__init__.h" -#include "shared-bindings/i2cperipheral/I2CPeripheral.h" +// #include "shared-bindings/i2ctarget/__init__.h" +#include "shared-bindings/i2ctarget/I2CTarget.h" #include "py/runtime.h" -//| """Two wire serial protocol peripheral +//| """Two wire serial protocol target //| -//| The `i2cperipheral` module contains classes to support an I2C peripheral. +//| The `i2ctarget` module contains classes to support an I2C target. //| -//| Example emulating a peripheral with 2 addresses (read and write):: +//| Example emulating a target with 2 addresses (read and write):: //| //| import board -//| from i2cperipheral import I2CPeripheral +//| from i2ctarget import I2CTarget //| //| regs = [0] * 16 //| index = 0 //| -//| with I2CPeripheral(board.SCL, board.SDA, (0x40, 0x41)) as device: +//| with I2CTarget(board.SCL, board.SDA, (0x40, 0x41)) as device: //| while True: //| r = device.request() //| if not r: @@ -84,25 +84,29 @@ //| 0xaa //| //| .. warning:: -//| I2CPeripheral makes use of clock stretching in order to slow down +//| I2CTarget makes use of clock stretching in order to slow down //| the host. //| Make sure the I2C host supports this. //| //| Raspberry Pi in particular does not support this with its I2C hw block. //| This can be worked around by using the ``i2c-gpio`` bit banging driver. //| Since the RPi firmware uses the hw i2c, it's not possible to emulate a HAT eeprom.""" -//| -STATIC const mp_rom_map_elem_t i2cperipheral_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_i2cperipheral) }, - { MP_ROM_QSTR(MP_QSTR_I2CPeripheral), MP_ROM_PTR(&i2cperipheral_i2c_peripheral_type) }, +STATIC const mp_rom_map_elem_t i2ctarget_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_i2ctarget) }, + { MP_ROM_QSTR(MP_QSTR_I2CTarget), MP_ROM_PTR(&i2ctarget_i2c_target_type) }, + // TODO: Remove for CircuitPython 9.0.0 + { MP_ROM_QSTR(MP_QSTR_I2CPeripheral), MP_ROM_PTR(&i2ctarget_i2c_target_type) }, }; -STATIC MP_DEFINE_CONST_DICT(i2cperipheral_module_globals, i2cperipheral_module_globals_table); +STATIC MP_DEFINE_CONST_DICT(i2ctarget_module_globals, i2ctarget_module_globals_table); -const mp_obj_module_t i2cperipheral_module = { +const mp_obj_module_t i2ctarget_module = { .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&i2cperipheral_module_globals, + .globals = (mp_obj_dict_t *)&i2ctarget_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_i2cperipheral, i2cperipheral_module, CIRCUITPY_I2CPERIPHERAL); +MP_REGISTER_MODULE(MP_QSTR_i2ctarget, i2ctarget_module, CIRCUITPY_I2CTARGET); + +// TODO: Remove for CircuitPython 9.0.0 +MP_REGISTER_MODULE(MP_QSTR_i2cperipheral, i2ctarget_module, CIRCUITPY_I2CTARGET); diff --git a/shared-bindings/imagecapture/ParallelImageCapture.c b/shared-bindings/imagecapture/ParallelImageCapture.c index 7f90f0923b..d568da158f 100644 --- a/shared-bindings/imagecapture/ParallelImageCapture.c +++ b/shared-bindings/imagecapture/ParallelImageCapture.c @@ -47,13 +47,14 @@ //| ) -> None: //| """Create a parallel image capture object //| +//| This object is usually used with a camera-specific wrapper library such as `adafruit_ov5640 `_. +//| //| :param List[microcontroller.Pin] data_pins: The data pins. //| :param microcontroller.Pin clock: The pixel clock input. //| :param microcontroller.Pin vsync: The vertical sync input, which has a negative-going pulse at the beginning of each frame. //| :param microcontroller.Pin href: The horizontal reference input, which is high whenever the camera is transmitting valid pixel information. //| """ //| ... -//| STATIC mp_obj_t imagecapture_parallelimagecapture_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_data_pins, ARG_clock, ARG_vsync, ARG_href, NUM_ARGS }; @@ -71,9 +72,9 @@ STATIC mp_obj_t imagecapture_parallelimagecapture_make_new(const mp_obj_type_t * uint8_t pin_count; validate_pins(MP_QSTR_data, pins, MP_ARRAY_SIZE(pins), args[ARG_data_pins].u_obj, &pin_count); - const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj); - const mcu_pin_obj_t *vsync = validate_obj_is_free_pin_or_none(args[ARG_vsync].u_obj); - const mcu_pin_obj_t *href = validate_obj_is_free_pin_or_none(args[ARG_href].u_obj); + const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock); + const mcu_pin_obj_t *vsync = validate_obj_is_free_pin_or_none(args[ARG_vsync].u_obj, MP_QSTR_vsync); + const mcu_pin_obj_t *href = validate_obj_is_free_pin_or_none(args[ARG_href].u_obj, MP_QSTR_href); imagecapture_parallelimagecapture_obj_t *self = m_new_obj(imagecapture_parallelimagecapture_obj_t); self->base.type = &imagecapture_parallelimagecapture_type; @@ -88,7 +89,6 @@ STATIC mp_obj_t imagecapture_parallelimagecapture_make_new(const mp_obj_type_t * //| //| This will stop a continuous-mode capture, if one is in progress.""" //| ... -//| STATIC mp_obj_t imagecapture_parallelimagecapture_capture(mp_obj_t self_in, mp_obj_t buffer) { imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in; common_hal_imagecapture_parallelimagecapture_singleshot_capture(self, buffer); @@ -97,7 +97,9 @@ STATIC mp_obj_t imagecapture_parallelimagecapture_capture(mp_obj_t self_in, mp_o } STATIC MP_DEFINE_CONST_FUN_OBJ_2(imagecapture_parallelimagecapture_capture_obj, imagecapture_parallelimagecapture_capture); -//| def continuous_capture_start(self, buffer1: WriteableBuffer, buffer2: WriteableBuffer, /) -> None: +//| def continuous_capture_start( +//| self, buffer1: WriteableBuffer, buffer2: WriteableBuffer, / +//| ) -> None: //| """Begin capturing into the given buffers in the background. //| //| Call `continuous_capture_get_frame` to get the next available @@ -107,7 +109,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(imagecapture_parallelimagecapture_capture_obj, //| `ParallelImageCapture` object keeps references to ``buffer1`` and //| ``buffer2``, so the objects will not be garbage collected.""" //| ... -//| STATIC mp_obj_t imagecapture_parallelimagecapture_continuous_capture_start(mp_obj_t self_in, mp_obj_t buffer1, mp_obj_t buffer2) { imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in; common_hal_imagecapture_parallelimagecapture_continuous_capture_start(self, buffer1, buffer2); @@ -119,7 +120,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(imagecapture_parallelimagecapture_continuous_ca //| def continuous_capture_get_frame(self) -> WriteableBuffer: //| """Return the next available frame, one of the two buffers passed to `continuous_capture_start`""" //| ... -//| STATIC mp_obj_t imagecapture_parallelimagecapture_continuous_capture_get_frame(mp_obj_t self_in) { imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in; return common_hal_imagecapture_parallelimagecapture_continuous_capture_get_frame(self); @@ -135,7 +135,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(imagecapture_parallelimagecapture_continuous_ca //| references to the buffers passed to `continuous_capture_start`, //| potentially allowing the objects to be garbage collected.""" //| ... -//| STATIC mp_obj_t imagecapture_parallelimagecapture_continuous_capture_stop(mp_obj_t self_in) { imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in; common_hal_imagecapture_parallelimagecapture_continuous_capture_stop(self); @@ -150,7 +149,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(imagecapture_parallelimagecapture_continuous_ca //| def deinit(self) -> None: //| """Deinitialize this instance""" //| ... -//| STATIC mp_obj_t imagecapture_parallelimagecapture_deinit(mp_obj_t self_in) { imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in; common_hal_imagecapture_parallelimagecapture_deinit(self); @@ -162,7 +160,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(imagecapture_parallelimagecapture_deinit_obj, i //| def __enter__(self) -> ParallelImageCapture: //| """No-op used in Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: diff --git a/shared-bindings/imagecapture/__init__.c b/shared-bindings/imagecapture/__init__.c index 0e5092aee8..71d0b9125b 100644 --- a/shared-bindings/imagecapture/__init__.c +++ b/shared-bindings/imagecapture/__init__.c @@ -31,9 +31,13 @@ #include "shared-bindings/imagecapture/ParallelImageCapture.h" -//| """Support for "Parallel capture" interfaces""" +//| """Support for "Parallel capture" interfaces //| - +//| .. seealso:: +//| +//| Espressif microcontrollers use the `espcamera` module together. +//| +//| """ STATIC const mp_rom_map_elem_t imagecapture_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_imagecapture) }, { MP_ROM_QSTR(MP_QSTR_ParallelImageCapture), MP_ROM_PTR(&imagecapture_parallelimagecapture_type) }, diff --git a/shared-bindings/ipaddress/IPv4Address.c b/shared-bindings/ipaddress/IPv4Address.c index 23204329d3..b9a2363e09 100644 --- a/shared-bindings/ipaddress/IPv4Address.c +++ b/shared-bindings/ipaddress/IPv4Address.c @@ -42,9 +42,8 @@ //| def __init__(self, address: Union[int, str, bytes]) -> None: //| """Create a new IPv4Address object encapsulating the address value. //| -//| The value itself can either be bytes or a string formatted address.""" +//| The value itself can either be bytes or a string formatted address.""" //| ... -//| STATIC mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_address }; static const mp_arg_t allowed_args[] = { @@ -88,7 +87,6 @@ STATIC mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t //| packed: bytes //| """The bytes that make up the address (read-only).""" -//| STATIC mp_obj_t ipaddress_ipv4address_get_packed(mp_obj_t self_in) { ipaddress_ipv4address_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -101,7 +99,6 @@ MP_PROPERTY_GETTER(ipaddress_ipv4address_packed_obj, //| version: int //| """4 for IPv4, 6 for IPv6""" -//| STATIC mp_obj_t ipaddress_ipv4address_get_version(mp_obj_t self_in) { ipaddress_ipv4address_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t buf_info; @@ -122,7 +119,6 @@ MP_PROPERTY_GETTER(ipaddress_ipv4address_version_obj, //| def __eq__(self, other: object) -> bool: //| """Two Address objects are equal if their addresses and address types are equal.""" //| ... -//| STATIC mp_obj_t ipaddress_ipv4address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { switch (op) { // Two Addresses are equal if their address bytes and address_type are equal diff --git a/shared-bindings/is31fl3741/FrameBuffer.c b/shared-bindings/is31fl3741/FrameBuffer.c index e1a87e8ee0..f907a1dcd3 100644 --- a/shared-bindings/is31fl3741/FrameBuffer.c +++ b/shared-bindings/is31fl3741/FrameBuffer.c @@ -40,8 +40,17 @@ //| class IS31FL3741_FrameBuffer: //| """Creates an in-memory framebuffer for a IS31FL3741 device.""" //| -//| def __init__(self, is31: is31fl3741.IS31FL3741, width: int, height: int, mapping: Tuple[int, ...], *, -//| framebuffer: Optional[WriteableBuffer] = None, scale: bool = False, gamma: bool = False) -> None: +//| def __init__( +//| self, +//| is31: is31fl3741.IS31FL3741, +//| width: int, +//| height: int, +//| mapping: Tuple[int, ...], +//| *, +//| framebuffer: Optional[WriteableBuffer] = None, +//| scale: bool = False, +//| gamma: bool = False +//| ) -> None: //| """Create a IS31FL3741_FrameBuffer object with the given attributes. //| //| The framebuffer is in "RGB888" format using 4 bytes per pixel. @@ -62,7 +71,6 @@ //| :param bool scale: if True display is scaled down by 3 when displayed //| :param bool gamma: if True apply gamma correction to all LEDs""" //| ... -//| STATIC mp_obj_t is31fl3741_FrameBuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_is31, ARG_width, ARG_height, ARG_mapping, ARG_framebuffer, ARG_scale, ARG_gamma }; static const mp_arg_t allowed_args[] = { @@ -123,7 +131,6 @@ STATIC mp_obj_t is31fl3741_FrameBuffer_make_new(const mp_obj_type_t *type, size_ //| IS31FL3741 instance. After deinitialization, no further operations //| may be performed.""" //| ... -//| STATIC mp_obj_t is31fl3741_FrameBuffer_deinit(mp_obj_t self_in) { is31fl3741_FrameBuffer_obj_t *self = (is31fl3741_FrameBuffer_obj_t *)self_in; common_hal_is31fl3741_FrameBuffer_deinit(self); @@ -140,7 +147,6 @@ static void check_for_deinit(is31fl3741_FrameBuffer_obj_t *self) { //| brightness: float //| """In the current implementation, 0.0 turns the display off entirely //| and any other value up to 1.0 turns the display on fully.""" -//| STATIC mp_obj_t is31fl3741_FrameBuffer_get_brightness(mp_obj_t self_in) { is31fl3741_FrameBuffer_obj_t *self = (is31fl3741_FrameBuffer_obj_t *)self_in; check_for_deinit(self); @@ -174,7 +180,6 @@ MP_PROPERTY_GETSET(is31fl3741_FrameBuffer_brightness_obj, //| """Transmits the color data in the buffer to the pixels so that //| they are shown.""" //| ... -//| STATIC mp_obj_t is31fl3741_FrameBuffer_refresh(mp_obj_t self_in) { is31fl3741_FrameBuffer_obj_t *self = (is31fl3741_FrameBuffer_obj_t *)self_in; check_for_deinit(self); @@ -185,7 +190,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_FrameBuffer_refresh_obj, is31fl3741_FrameBu //| width: int //| """The width of the display, in pixels""" -//| STATIC mp_obj_t is31fl3741_FrameBuffer_get_width(mp_obj_t self_in) { is31fl3741_FrameBuffer_obj_t *self = (is31fl3741_FrameBuffer_obj_t *)self_in; check_for_deinit(self); diff --git a/shared-bindings/is31fl3741/IS31FL3741.c b/shared-bindings/is31fl3741/IS31FL3741.c index 46a7f8ac86..17b12da67a 100644 --- a/shared-bindings/is31fl3741/IS31FL3741.c +++ b/shared-bindings/is31fl3741/IS31FL3741.c @@ -46,7 +46,6 @@ //| :param ~busio.I2C i2c: I2C bus the IS31FL3741 is on //| :param int addr: device address""" //| ... -//| STATIC mp_obj_t is31fl3741_IS31FL3741_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_i2c, ARG_addr }; static const mp_arg_t allowed_args[] = { @@ -142,8 +141,10 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(is31fl3741_IS31FL3741_set_led_obj, 4, 4, is3 //| """Write buf out on the I2C bus to the IS31FL3741. //| //| :param ~Tuple[int, ...] mapping: map the pixels in the buffer to the order addressed by the driver chip -//| :param ~_typing.ReadableBuffer buf: The bytes to clock out. No assumption is made about color order""" +//| :param ~_typing.ReadableBuffer buf: The bytes to clock out. No assumption is made about color order +//| """ //| ... +//| STATIC mp_obj_t is31fl3741_IS31FL3741_write(mp_obj_t self_in, mp_obj_t mapping, mp_obj_t buffer) { is31fl3741_IS31FL3741_obj_t *self = MP_OBJ_TO_PTR(self_in); if (!mp_obj_is_tuple_compatible(mapping)) { diff --git a/shared-bindings/is31fl3741/IS31FL3741.h b/shared-bindings/is31fl3741/IS31FL3741.h index 2b81b01617..62302a3ac2 100644 --- a/shared-bindings/is31fl3741/IS31FL3741.h +++ b/shared-bindings/is31fl3741/IS31FL3741.h @@ -46,4 +46,4 @@ void common_hal_is31fl3741_send_reset(is31fl3741_IS31FL3741_obj_t *self); void common_hal_is31fl3741_set_current(is31fl3741_IS31FL3741_obj_t *self, uint8_t current); uint8_t common_hal_is31fl3741_get_current(is31fl3741_IS31FL3741_obj_t *self); void common_hal_is31fl3741_set_led(is31fl3741_IS31FL3741_obj_t *self, uint16_t led, uint8_t level, uint8_t page); -void common_hal_is31fl3741_draw_pixel(is31fl3741_IS31FL3741_obj_t *self, int16_t x, int16_t y, uint32_t color, uint16_t *mapping); +void common_hal_is31fl3741_draw_pixel(is31fl3741_IS31FL3741_obj_t *self, int16_t x, int16_t y, uint32_t color, uint16_t *mapping, uint8_t display_height); diff --git a/shared-bindings/keypad/Event.c b/shared-bindings/keypad/Event.c index 380b6b5b41..c8d24294f8 100644 --- a/shared-bindings/keypad/Event.c +++ b/shared-bindings/keypad/Event.c @@ -33,7 +33,10 @@ //| class Event: //| """A key transition event.""" -//| def __init__(self, key_number: int=0, pressed: bool=True, timestamp:Optional[int]=None) -> None: +//| +//| def __init__( +//| self, key_number: int = 0, pressed: bool = True, timestamp: Optional[int] = None +//| ) -> None: //| """Create a key transition event, which reports a key-pressed or key-released transition. //| //| :param int key_number: The key number. @@ -41,7 +44,6 @@ //| :param int timestamp: The time in milliseconds that the keypress occurred in the `supervisor.ticks_ms` time system. If specified as None, the current value of `supervisor.ticks_ms` is used. //| """ //| ... -//| STATIC mp_obj_t keypad_event_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { keypad_event_obj_t *self = m_new_obj(keypad_event_obj_t); self->base.type = &keypad_event_type; @@ -69,7 +71,6 @@ STATIC mp_obj_t keypad_event_make_new(const mp_obj_type_t *type, size_t n_args, //| key_number: int //| """The key number.""" -//| STATIC mp_obj_t keypad_event_get_key_number(mp_obj_t self_in) { keypad_event_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_keypad_event_get_key_number(self)); @@ -83,7 +84,6 @@ MP_PROPERTY_GETTER(keypad_event_key_number_obj, //| """``True`` if the event represents a key down (pressed) transition. //| The opposite of `released`. //| """ -//| STATIC mp_obj_t keypad_event_get_pressed(mp_obj_t self_in) { keypad_event_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_keypad_event_get_pressed(self)); @@ -97,7 +97,6 @@ MP_PROPERTY_GETTER(keypad_event_pressed_obj, //| """``True`` if the event represents a key up (released) transition. //| The opposite of `pressed`. //| """ -//| STATIC mp_obj_t keypad_event_get_released(mp_obj_t self_in) { keypad_event_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_keypad_event_get_released(self)); @@ -109,7 +108,6 @@ MP_PROPERTY_GETTER(keypad_event_released_obj, //| timestamp: int //| """The timestamp.""" -//| STATIC mp_obj_t keypad_event_get_timestamp(mp_obj_t self_in) { keypad_event_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_keypad_event_get_timestamp(self); @@ -126,7 +124,6 @@ MP_PROPERTY_GETTER(keypad_event_timestamp_obj, //| Note that this does not compare the event timestamps. //| """ //| ... -//| STATIC mp_obj_t keypad_event_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { switch (op) { case MP_BINARY_OP_EQUAL: @@ -151,7 +148,8 @@ STATIC mp_obj_t keypad_event_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_ob //| def __hash__(self) -> int: //| """Returns a hash for the `Event`, so it can be used in dictionaries, etc.. //| -//| Note that as events with different timestamps compare equal, they also hash to the same value.""" +//| Note that as events with different timestamps compare equal, they also hash to the same value. +//| """ //| ... //| STATIC mp_obj_t keypad_event_unary_op(mp_unary_op_t op, mp_obj_t self_in) { diff --git a/shared-bindings/keypad/EventQueue.c b/shared-bindings/keypad/EventQueue.c index 8e45f7ad1d..d09d5db129 100644 --- a/shared-bindings/keypad/EventQueue.c +++ b/shared-bindings/keypad/EventQueue.c @@ -24,8 +24,11 @@ * THE SOFTWARE. */ +#include "py/stream.h" +#include "py/mperrno.h" #include "py/objproperty.h" #include "py/runtime.h" +#include "py/stream.h" #include "shared-bindings/keypad/Event.h" #include "shared-bindings/keypad/EventQueue.h" @@ -35,6 +38,7 @@ //| You cannot create an instance of `EventQueue` directly. Each scanner creates an //| instance when it is created. //| """ +//| //| ... //| def get(self) -> Optional[Event]: @@ -49,7 +53,6 @@ //| :rtype: Optional[Event] //| """ //| ... -//| STATIC mp_obj_t keypad_eventqueue_get(mp_obj_t self_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -72,7 +75,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_get_obj, keypad_eventqueue_get); //| :rtype: bool //| """ //| ... -//| STATIC mp_obj_t keypad_eventqueue_get_into(mp_obj_t self_in, mp_obj_t event_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -83,10 +85,8 @@ STATIC mp_obj_t keypad_eventqueue_get_into(mp_obj_t self_in, mp_obj_t event_in) MP_DEFINE_CONST_FUN_OBJ_2(keypad_eventqueue_get_into_obj, keypad_eventqueue_get_into); //| def clear(self) -> None: -//| """Clear any queued key transition events. Also sets `overflowed` to ``False``. -//| """ +//| """Clear any queued key transition events. Also sets `overflowed` to ``False``.""" //| ... -//| STATIC mp_obj_t keypad_eventqueue_clear(mp_obj_t self_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -100,11 +100,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_clear_obj, keypad_eventqueue_clear); //| This is an easy way to check if the queue is empty. //| """ //| ... -//| //| def __len__(self) -> int: //| """Return the number of events currently in the queue. Used to implement ``len()``.""" //| ... -//| STATIC mp_obj_t keypad_eventqueue_unary_op(mp_unary_op_t op, mp_obj_t self_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); uint16_t len = common_hal_keypad_eventqueue_get_length(self); @@ -141,12 +139,41 @@ STATIC const mp_rom_map_elem_t keypad_eventqueue_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(keypad_eventqueue_locals_dict, keypad_eventqueue_locals_dict_table); +#if MICROPY_PY_USELECT +STATIC mp_uint_t eventqueue_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + (void)errcode; + keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); + switch (request) { + case MP_STREAM_POLL: { + mp_uint_t flags = arg; + mp_uint_t ret = 0; + if ((flags & MP_STREAM_POLL_RD) && common_hal_keypad_eventqueue_get_length(self)) { + ret |= MP_STREAM_POLL_RD; + } + return ret; + } + default: + *errcode = MP_EINVAL; + return MP_STREAM_ERROR; + } +} + +STATIC const mp_stream_p_t eventqueue_p = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) + .ioctl = eventqueue_ioctl, +}; +#endif + + const mp_obj_type_t keypad_eventqueue_type = { { &mp_type_type }, .flags = MP_TYPE_FLAG_EXTENDED, .name = MP_QSTR_EventQueue, MP_TYPE_EXTENDED_FIELDS( .unary_op = keypad_eventqueue_unary_op, + #if MICROPY_PY_USELECT + .protocol = &eventqueue_p, + #endif ), .locals_dict = (mp_obj_t)&keypad_eventqueue_locals_dict, }; diff --git a/shared-bindings/keypad/KeyMatrix.c b/shared-bindings/keypad/KeyMatrix.c index 9e65471a2b..49723dbb9e 100644 --- a/shared-bindings/keypad/KeyMatrix.c +++ b/shared-bindings/keypad/KeyMatrix.c @@ -37,7 +37,14 @@ //| class KeyMatrix: //| """Manage a 2D matrix of keys with row and column pins.""" //| -//| def __init__(self, row_pins: Sequence[microcontroller.Pin], column_pins: Sequence[microcontroller.Pin], columns_to_anodes: bool = True, interval: float = 0.020, max_events: int = 64) -> None: +//| def __init__( +//| self, +//| row_pins: Sequence[microcontroller.Pin], +//| column_pins: Sequence[microcontroller.Pin], +//| columns_to_anodes: bool = True, +//| interval: float = 0.020, +//| max_events: int = 64, +//| ) -> None: //| """ //| Create a `Keys` object that will scan the key matrix attached to the given row and column pins. //| There should not be any external pull-ups or pull-downs on the matrix: @@ -95,13 +102,13 @@ STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_ar for (size_t row = 0; row < num_row_pins; row++) { const mcu_pin_obj_t *pin = - validate_obj_is_free_pin(mp_obj_subscr(row_pins, MP_OBJ_NEW_SMALL_INT(row), MP_OBJ_SENTINEL)); + validate_obj_is_free_pin(mp_obj_subscr(row_pins, MP_OBJ_NEW_SMALL_INT(row), MP_OBJ_SENTINEL), MP_QSTR_pin); row_pins_array[row] = pin; } for (size_t column = 0; column < num_column_pins; column++) { const mcu_pin_obj_t *pin = - validate_obj_is_free_pin(mp_obj_subscr(column_pins, MP_OBJ_NEW_SMALL_INT(column), MP_OBJ_SENTINEL)); + validate_obj_is_free_pin(mp_obj_subscr(column_pins, MP_OBJ_NEW_SMALL_INT(column), MP_OBJ_SENTINEL), MP_QSTR_pin); column_pins_array[column] = pin; } @@ -112,7 +119,6 @@ STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Stop scanning and release the pins.""" //| ... -//| STATIC mp_obj_t keypad_keymatrix_deinit(mp_obj_t self_in) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_keypad_keymatrix_deinit(self); @@ -123,14 +129,12 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_keymatrix_deinit_obj, keypad_keymatrix_deinit); //| def __enter__(self) -> KeyMatrix: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t keypad_keymatrix___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_keypad_keymatrix_deinit(args[0]); @@ -150,12 +154,10 @@ STATIC void check_for_deinit(keypad_keymatrix_obj_t *self) { //| a new key-pressed event to occur. //| """ //| ... -//| //| key_count: int //| """The number of keys that are being scanned. (read-only) //| """ -//| //| def key_number_to_row_column(self, key_number: int) -> Tuple[int]: //| """Return the row and column for the given key number. @@ -166,7 +168,6 @@ STATIC void check_for_deinit(keypad_keymatrix_obj_t *self) { //| :rtype: Tuple[int] //| """ //| ... -//| STATIC mp_obj_t keypad_keymatrix_key_number_to_row_column(mp_obj_t self_in, mp_obj_t key_number_in) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -193,7 +194,6 @@ MP_DEFINE_CONST_FUN_OBJ_2(keypad_keymatrix_key_number_to_row_column_obj, keypad_ //| The key number is ``row * len(column_pins) + column``. //| """ //| ... -//| STATIC mp_obj_t keypad_keymatrix_row_column_to_key_number(mp_obj_t self_in, mp_obj_t row_in, mp_obj_t column_in) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/keypad/Keys.c b/shared-bindings/keypad/Keys.c index 6ac705eba6..10519958c7 100644 --- a/shared-bindings/keypad/Keys.c +++ b/shared-bindings/keypad/Keys.c @@ -37,7 +37,15 @@ //| class Keys: //| """Manage a set of independent keys.""" //| -//| def __init__(self, pins: Sequence[microcontroller.Pin], *, value_when_pressed: bool, pull: bool = True, interval: float = 0.020, max_events: int = 64) -> None: +//| def __init__( +//| self, +//| pins: Sequence[microcontroller.Pin], +//| *, +//| value_when_pressed: bool, +//| pull: bool = True, +//| interval: float = 0.020, +//| max_events: int = 64 +//| ) -> None: //| """ //| Create a `Keys` object that will scan keys attached to the given sequence of pins. //| Each key is independent and attached to its own pin. @@ -92,7 +100,7 @@ STATIC mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, s for (mp_uint_t i = 0; i < num_pins; i++) { pins_array[i] = - validate_obj_is_free_pin(mp_obj_subscr(pins, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL)); + validate_obj_is_free_pin(mp_obj_subscr(pins, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL), MP_QSTR_pin); } common_hal_keypad_keys_construct(self, num_pins, pins_array, value_when_pressed, args[ARG_pull].u_bool, interval, max_events); @@ -103,7 +111,6 @@ STATIC mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, s //| def deinit(self) -> None: //| """Stop scanning and release the pins.""" //| ... -//| STATIC mp_obj_t keypad_keys_deinit(mp_obj_t self_in) { keypad_keys_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -115,14 +122,12 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_keys_deinit_obj, keypad_keys_deinit); //| def __enter__(self) -> Keys: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t keypad_keys___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_keypad_keys_deinit(args[0]); @@ -137,12 +142,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(keypad_keys___exit___obj, 4, 4, keypa //| a new key-pressed event to occur. //| """ //| ... -//| //| key_count: int //| """The number of keys that are being scanned. (read-only) //| """ -//| //| events: EventQueue //| """The `EventQueue` associated with this `Keys` object. (read-only) diff --git a/shared-bindings/keypad/ShiftRegisterKeys.c b/shared-bindings/keypad/ShiftRegisterKeys.c index 14ab87436b..9113be33d2 100644 --- a/shared-bindings/keypad/ShiftRegisterKeys.c +++ b/shared-bindings/keypad/ShiftRegisterKeys.c @@ -37,7 +37,18 @@ //| class ShiftRegisterKeys: //| """Manage a set of keys attached to an incoming shift register.""" //| -//| def __init__(self, *, clock: microcontroller.Pin, data: microcontroller.Pin, latch: microcontroller.Pin, value_to_latch: bool = True, key_count: int, value_when_pressed: bool, interval: float = 0.020, max_events: int = 64) -> None: +//| def __init__( +//| self, +//| *, +//| clock: microcontroller.Pin, +//| data: microcontroller.Pin, +//| latch: microcontroller.Pin, +//| value_to_latch: bool = True, +//| key_count: int, +//| value_when_pressed: bool, +//| interval: float = 0.020, +//| max_events: int = 64 +//| ) -> None: //| """ //| Create a `Keys` object that will scan keys attached to a parallel-in serial-out shift register //| like the 74HC165 or CD4021. @@ -87,9 +98,9 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj); - const mcu_pin_obj_t *data = validate_obj_is_free_pin(args[ARG_data].u_obj); - const mcu_pin_obj_t *latch = validate_obj_is_free_pin(args[ARG_latch].u_obj); + const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock); + const mcu_pin_obj_t *data = validate_obj_is_free_pin(args[ARG_data].u_obj, MP_QSTR_data); + const mcu_pin_obj_t *latch = validate_obj_is_free_pin(args[ARG_latch].u_obj, MP_QSTR_latch); const bool value_to_latch = args[ARG_value_to_latch].u_bool; const size_t key_count = (size_t)mp_arg_validate_int_min(args[ARG_key_count].u_int, 1, MP_QSTR_key_count); @@ -107,7 +118,6 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz //| def deinit(self) -> None: //| """Stop scanning and release the pins.""" //| ... -//| STATIC mp_obj_t keypad_shiftregisterkeys_deinit(mp_obj_t self_in) { keypad_shiftregisterkeys_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -119,14 +129,12 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_shiftregisterkeys_deinit_obj, keypad_shiftregis //| def __enter__(self) -> Keys: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t keypad_shiftregisterkeys___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_keypad_shiftregisterkeys_deinit(args[0]); @@ -140,12 +148,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(keypad_shiftregisterkeys___exit___obj //| a new key-pressed event to occur. //| """ //| ... -//| //| key_count: int //| """The number of keys that are being scanned. (read-only) //| """ -//| //| events: EventQueue //| """The `EventQueue` associated with this `Keys` object. (read-only) diff --git a/shared-bindings/keypad/__init__.c b/shared-bindings/keypad/__init__.c index 3822b8ea53..7dd76c1947 100644 --- a/shared-bindings/keypad/__init__.c +++ b/shared-bindings/keypad/__init__.c @@ -90,7 +90,6 @@ const mp_obj_property_t keypad_generic_events_obj = { //| For more information about working with the `keypad` module in CircuitPython, //| see `this Learn guide `_. //| """ -//| STATIC mp_rom_map_elem_t keypad_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_keypad) }, diff --git a/shared-bindings/math/__init__.c b/shared-bindings/math/__init__.c index f5fb45cb4d..8aee44ffb8 100644 --- a/shared-bindings/math/__init__.c +++ b/shared-bindings/math/__init__.c @@ -45,7 +45,6 @@ //| //| |see_cpython_module| :mod:`cpython:math`. //| """ -//| STATIC NORETURN void math_error(void) { mp_raise_ValueError(translate("math domain error")); @@ -373,7 +372,7 @@ STATIC mp_obj_t mp_math_log(size_t n_args, const mp_obj_t *args) { #pragma GCC diagnostic ignored "-Wfloat-equal" } else if (base == (mp_float_t)1.0) { #pragma GCC diagnostic pop - mp_raise_msg(&mp_type_ZeroDivisionError, translate("division by zero")); + math_error(); } return mp_obj_new_float(l / MICROPY_FLOAT_C_FUN(log)(base)); } diff --git a/shared-bindings/mdns/RemoteService.c b/shared-bindings/mdns/RemoteService.c index 49eda58557..c1d7b25783 100644 --- a/shared-bindings/mdns/RemoteService.c +++ b/shared-bindings/mdns/RemoteService.c @@ -40,11 +40,9 @@ //| def __init__(self) -> None: //| """Cannot be instantiated directly. Use `mdns.Server.find`.""" //| ... -//| //| hostname: str //| """The hostname of the device (read-only),.""" -//| STATIC mp_obj_t mdns_remoteservice_get_hostname(mp_obj_t self_in) { mdns_remoteservice_obj_t *self = MP_OBJ_TO_PTR(self_in); const char *hostname = common_hal_mdns_remoteservice_get_hostname(self); @@ -57,7 +55,6 @@ MP_PROPERTY_GETTER(mdns_remoteservice_hostname_obj, //| instance_name: str //| """The human readable instance name for the service. (read-only)""" -//| STATIC mp_obj_t remoteservice_get_instance_name(mp_obj_t self_in) { mdns_remoteservice_obj_t *self = MP_OBJ_TO_PTR(self_in); const char *instance_name = common_hal_mdns_remoteservice_get_instance_name(self); @@ -70,7 +67,6 @@ MP_PROPERTY_GETTER(mdns_remoteservice_instance_name_obj, //| service_type: str //| """The service type string such as ``_http``. (read-only)""" -//| STATIC mp_obj_t remoteservice_get_service_type(mp_obj_t self_in) { mdns_remoteservice_obj_t *self = MP_OBJ_TO_PTR(self_in); const char *service_type = common_hal_mdns_remoteservice_get_service_type(self); @@ -83,7 +79,6 @@ MP_PROPERTY_GETTER(mdns_remoteservice_service_type_obj, //| protocol: str //| """The protocol string such as ``_tcp``. (read-only)""" -//| STATIC mp_obj_t remoteservice_get_protocol(mp_obj_t self_in) { mdns_remoteservice_obj_t *self = MP_OBJ_TO_PTR(self_in); const char *protocol = common_hal_mdns_remoteservice_get_protocol(self); @@ -96,7 +91,6 @@ MP_PROPERTY_GETTER(mdns_remoteservice_protocol_obj, //| port: int //| """Port number used for the service. (read-only)""" -//| STATIC mp_obj_t remoteservice_get_port(mp_obj_t self_in) { mdns_remoteservice_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_mdns_remoteservice_get_port(self)); @@ -108,7 +102,6 @@ MP_PROPERTY_GETTER(mdns_remoteservice_port_obj, //| ipv4_address: Optional[ipaddress.IPv4Address] //| """IP v4 Address of the remote service. None if no A records are found.""" -//| STATIC mp_obj_t _mdns_remoteservice_get_ipv4_address(mp_obj_t self) { return common_hal_mdns_remoteservice_get_ipv4_address(self); diff --git a/shared-bindings/mdns/Server.c b/shared-bindings/mdns/Server.c index 97574ff0e2..0d06d67f0d 100644 --- a/shared-bindings/mdns/Server.c +++ b/shared-bindings/mdns/Server.c @@ -33,9 +33,13 @@ #include "shared-bindings/mdns/Server.h" #include "shared-bindings/util.h" +#if CIRCUITPY_WEB_WORKFLOW +#include "supervisor/shared/web_workflow/web_workflow.h" +#endif + //| class Server: //| """The MDNS Server responds to queries for this device's information and allows for querying -//| other devices.""" +//| other devices.""" //| //| def __init__(self, network_interface: wifi.Radio) -> None: @@ -44,7 +48,6 @@ //| may already be using it.) Only native interfaces are currently supported. //| """ //| ... -//| STATIC mp_obj_t mdns_server_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_network_interface }; static const mp_arg_t allowed_args[] = { @@ -54,7 +57,14 @@ STATIC mp_obj_t mdns_server_make_new(const mp_obj_type_t *type, size_t n_args, s mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - mdns_server_obj_t *self = m_new_obj(mdns_server_obj_t); + #if CIRCUITPY_WEB_WORKFLOW + mdns_server_obj_t *web_workflow_mdns = supervisor_web_workflow_mdns(args[ARG_network_interface].u_obj); + if (web_workflow_mdns != NULL) { + return web_workflow_mdns; + } + #endif + + mdns_server_obj_t *self = m_new_obj_with_finaliser(mdns_server_obj_t); self->base.type = &mdns_server_type; common_hal_mdns_server_construct(self, args[ARG_network_interface].u_obj); @@ -64,7 +74,6 @@ STATIC mp_obj_t mdns_server_make_new(const mp_obj_type_t *type, size_t n_args, s //| def deinit(self) -> None: //| """Stops the server""" //| ... -//| STATIC mp_obj_t mdns_server_obj_deinit(mp_obj_t self_in) { mdns_server_obj_t *self = (mdns_server_obj_t *)self_in; common_hal_mdns_server_deinit(self); @@ -78,12 +87,10 @@ STATIC void check_for_deinit(mdns_server_obj_t *self) { } } -//| //| hostname: str //| """Hostname resolvable as ``.local`` in addition to ``circuitpython.local``. Make //| sure this is unique across all devices on the network. It defaults to ``cpy-######`` //| where ``######`` is the hex digits of the last three bytes of the mac address.""" -//| STATIC mp_obj_t mdns_server_get_hostname(mp_obj_t self) { check_for_deinit(self); const char *hostname = common_hal_mdns_server_get_hostname(self); @@ -105,7 +112,6 @@ MP_PROPERTY_GETSET(mdns_server_hostname_obj, //| instance_name: str //| """Human readable name to describe the device.""" -//| STATIC mp_obj_t mdns_server_get_instance_name(mp_obj_t self) { check_for_deinit(self); const char *instance_name = common_hal_mdns_server_get_instance_name(self); @@ -125,7 +131,9 @@ MP_PROPERTY_GETSET(mdns_server_instance_name_obj, (mp_obj_t)&mdns_server_set_instance_name_obj); -//| def find(self, service_type: str, protocol: str, *, timeout: float = 1) -> Tuple[RemoteService]: +//| def find( +//| self, service_type: str, protocol: str, *, timeout: float = 1 +//| ) -> Tuple[RemoteService]: //| """Find all locally available remote services with the given service type and protocol. //| //| This doesn't allow for direct hostname lookup. To do that, use @@ -135,7 +143,6 @@ MP_PROPERTY_GETSET(mdns_server_instance_name_obj, //| :param str protocol: The service protocol such as "_tcp" //| :param float/int timeout: Time to wait for responses""" //| ... -//| STATIC mp_obj_t _mdns_server_find(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mdns_server_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); @@ -158,9 +165,12 @@ STATIC mp_obj_t _mdns_server_find(mp_uint_t n_args, const mp_obj_t *pos_args, mp } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mdns_server_find_obj, 1, _mdns_server_find); -//| def advertise_service(self, *, service_type: str, protocol: str, port: int) -> None: +//| def advertise_service(self, *, service_type: str, protocol: str, port: int) -> None: //| """Respond to queries for the given service with the given port. //| +//| ``service_type`` and ``protocol`` can only occur on one port. Any call after the first +//| will update the entry's port. +//| //| :param str service_type: The service type such as "_http" //| :param str protocol: The service protocol such as "_tcp" //| :param int port: The port used by the service""" @@ -195,6 +205,7 @@ STATIC const mp_rom_map_elem_t mdns_server_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_find), MP_ROM_PTR(&mdns_server_find_obj) }, { MP_ROM_QSTR(MP_QSTR_advertise_service), MP_ROM_PTR(&mdns_server_advertise_service_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mdns_server_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mdns_server_deinit_obj) }, }; diff --git a/shared-bindings/mdns/__init__.c b/shared-bindings/mdns/__init__.c index 9752a3b7ff..73bd71c65c 100644 --- a/shared-bindings/mdns/__init__.c +++ b/shared-bindings/mdns/__init__.c @@ -38,7 +38,6 @@ //| Basic use provides hostname resolution under the .local TLD. This module //| also supports DNS Service Discovery that allows for discovering other hosts //| that provide a desired service.""" -//| STATIC const mp_rom_map_elem_t mdns_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mdns) }, diff --git a/shared-bindings/memorymap/AddressRange.c b/shared-bindings/memorymap/AddressRange.c new file mode 100644 index 0000000000..fb55c07efe --- /dev/null +++ b/shared-bindings/memorymap/AddressRange.c @@ -0,0 +1,207 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/memorymap/AddressRange.h" +#include "supervisor/shared/translate/translate.h" + +//| class AddressRange: +//| r"""Presents a range of addresses as a bytearray. +//| +//| The addresses may access memory or memory mapped peripherals. +//| +//| Some address ranges may be protected by CircuitPython to prevent errors. +//| An exception will be raised when constructing an AddressRange for an +//| invalid or protected address. +//| +//| Multiple AddressRanges may overlap. There is no "claiming" of addresses. +//| +//| Example usage on ESP32-S2:: +//| +//| import memorymap +//| rtc_slow_mem = memorymap.AddressRange(start=0x50000000, length=0x2000) +//| rtc_slow_mem[0:3] = b"\xcc\x10\x00" +//| """ + +//| def __init__(self, *, start, length) -> None: +//| """Constructs an address range starting at ``start`` and ending at +//| ``start + length``. An exception will be raised if any of the +//| addresses are invalid or protected.""" +//| ... +STATIC mp_obj_t memorymap_addressrange_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_start, ARG_length }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_length, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + size_t start = + mp_arg_validate_int_min(args[ARG_start].u_int, 0, MP_QSTR_start); + size_t length = + mp_arg_validate_int_min(args[ARG_length].u_int, 1, MP_QSTR_length); + + + memorymap_addressrange_obj_t *self = m_new_obj(memorymap_addressrange_obj_t); + self->base.type = &memorymap_addressrange_type; + + common_hal_memorymap_addressrange_construct(self, (uint8_t *)start, length); + + return MP_OBJ_FROM_PTR(self); +} + +//| def __bool__(self) -> bool: ... +//| def __len__(self) -> int: +//| """Return the length. This is used by (`len`)""" +//| ... +STATIC mp_obj_t memorymap_addressrange_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + memorymap_addressrange_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint16_t len = common_hal_memorymap_addressrange_get_length(self); + switch (op) { + case MP_UNARY_OP_BOOL: + return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: + return MP_OBJ_NEW_SMALL_INT(len); + default: + return MP_OBJ_NULL; // op not supported + } +} + +STATIC const mp_rom_map_elem_t memorymap_addressrange_locals_dict_table[] = { +}; + +STATIC MP_DEFINE_CONST_DICT(memorymap_addressrange_locals_dict, memorymap_addressrange_locals_dict_table); + +//| @overload +//| def __getitem__(self, index: slice) -> bytearray: ... +//| @overload +//| def __getitem__(self, index: int) -> int: +//| """Returns the value(s) at the given index. +//| +//| 1, 2, 4 and 8 byte aligned reads will be done in one transaction. +//| All others may use multiple transactions.""" +//| ... +//| @overload +//| def __setitem__(self, index: slice, value: ReadableBuffer) -> None: ... +//| @overload +//| def __setitem__(self, index: int, value: int) -> None: +//| """Set the value(s) at the given index. +//| +//| 1, 2, 4 and 8 byte aligned writes will be done in one transaction. +//| All others may use multiple transactions.""" +//| ... +//| +STATIC mp_obj_t memorymap_addressrange_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { + if (value == MP_OBJ_NULL) { + // delete item + // slice deletion + return MP_OBJ_NULL; // op not supported + } else { + memorymap_addressrange_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (0) { + #if MICROPY_PY_BUILTINS_SLICE + } else if (mp_obj_is_type(index_in, &mp_type_slice)) { + mp_bound_slice_t slice; + if (!mp_seq_get_fast_slice_indexes(common_hal_memorymap_addressrange_get_length(self), index_in, &slice)) { + mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); + } + if (value != MP_OBJ_SENTINEL) { + #if MICROPY_PY_ARRAY_SLICE_ASSIGN + // Assign + size_t src_len = slice.stop - slice.start; + uint8_t *src_items; + if (mp_obj_is_type(value, &mp_type_array) || + mp_obj_is_type(value, &mp_type_bytearray) || + mp_obj_is_type(value, &mp_type_memoryview) || + mp_obj_is_type(value, &mp_type_bytes)) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_READ); + if (bufinfo.len != src_len) { + mp_raise_ValueError(translate("Slice and value different lengths.")); + } + src_len = bufinfo.len; + src_items = bufinfo.buf; + if (1 != mp_binary_get_size('@', bufinfo.typecode, NULL)) { + mp_raise_ValueError(translate("Array values should be single bytes.")); + } + } else { + mp_raise_NotImplementedError(translate("array/bytes required on right side")); + } + + if (!common_hal_memorymap_addressrange_set_bytes(self, slice.start, src_items, src_len)) { + mp_raise_RuntimeError(translate("Unable to write to address.")); + } + return mp_const_none; + #else + return MP_OBJ_NULL; // op not supported + #endif + } else { + // Read slice. + size_t len = slice.stop - slice.start; + uint8_t *items = m_new(uint8_t, len); + common_hal_memorymap_addressrange_get_bytes(self, slice.start, len, items); + return mp_obj_new_bytearray_by_ref(len, items); + } + #endif + } else { + // Single index rather than slice. + size_t index = mp_get_index(self->base.type, common_hal_memorymap_addressrange_get_length(self), + index_in, false); + if (value == MP_OBJ_SENTINEL) { + // load + uint8_t value_out; + common_hal_memorymap_addressrange_get_bytes(self, index, 1, &value_out); + return MP_OBJ_NEW_SMALL_INT(value_out); + } else { + // store + mp_int_t byte_value = mp_obj_get_int(value); + mp_arg_validate_int_range(byte_value, 0, 255, MP_QSTR_bytes); + + uint8_t short_value = byte_value; + if (!common_hal_memorymap_addressrange_set_bytes(self, index, &short_value, 1)) { + mp_raise_RuntimeError(translate("Unable to write to address.")); + } + return mp_const_none; + } + } + } +} + +const mp_obj_type_t memorymap_addressrange_type = { + { &mp_type_type }, + .flags = MP_TYPE_FLAG_EXTENDED, + .name = MP_QSTR_AddressRange, + .make_new = memorymap_addressrange_make_new, + .locals_dict = (mp_obj_t)&memorymap_addressrange_locals_dict, + MP_TYPE_EXTENDED_FIELDS( + .subscr = memorymap_addressrange_subscr, + .unary_op = memorymap_addressrange_unary_op, + ), +}; diff --git a/shared-bindings/memorymap/AddressRange.h b/shared-bindings/memorymap/AddressRange.h new file mode 100644 index 0000000000..74a214d949 --- /dev/null +++ b/shared-bindings/memorymap/AddressRange.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMAP_ADDRESSRANGE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMAP_ADDRESSRANGE_H + +#include "common-hal/memorymap/AddressRange.h" + +extern const mp_obj_type_t memorymap_addressrange_type; + +void common_hal_memorymap_addressrange_construct(memorymap_addressrange_obj_t *self, uint8_t *start_address, size_t length); + +uint32_t common_hal_memorymap_addressrange_get_length(const memorymap_addressrange_obj_t *self); + +bool common_hal_memorymap_addressrange_set_bytes(const memorymap_addressrange_obj_t *self, + uint32_t start_index, uint8_t *values, uint32_t len); + +// len and values are intentionally swapped to signify values is an output and +// also leverage the compiler to validate uses are expected. +void common_hal_memorymap_addressrange_get_bytes(const memorymap_addressrange_obj_t *self, + uint32_t start_index, uint32_t len, uint8_t *values); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMAP_ADDRESSRANGE_H diff --git a/shared-module/multiterminal/__init__.c b/shared-bindings/memorymap/__init__.c similarity index 57% rename from shared-module/multiterminal/__init__.c rename to shared-bindings/memorymap/__init__.c index 361a6dcc7a..576c7f1e1d 100644 --- a/shared-module/multiterminal/__init__.c +++ b/shared-bindings/memorymap/__init__.c @@ -3,7 +3,6 @@ * * The MIT License (MIT) * - * Copyright (c) 2016 Paul Sokolovsky * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -25,26 +24,29 @@ * THE SOFTWARE. */ -#include "py/mpstate.h" +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" -#include "shared-bindings/multiterminal/__init__.h" +#include "shared-bindings/memorymap/__init__.h" +#include "shared-bindings/memorymap/AddressRange.h" -mp_obj_t shared_module_multiterminal_get_secondary_terminal() { - if (MP_STATE_VM(dupterm_objs[0]) == MP_OBJ_NULL) { - return mp_const_none; - } else { - return MP_STATE_VM(dupterm_objs[0]); - } -} +//| """Raw memory map access +//| +//| The `memorymap` module allows you to read and write memory addresses in the +//| address space seen from the processor running CircuitPython. It is usually +//| the physical address space. +//| """ +STATIC const mp_rom_map_elem_t memorymap_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_memorymap) }, + { MP_ROM_QSTR(MP_QSTR_AddressRange), MP_ROM_PTR(&memorymap_addressrange_type) }, +}; -void shared_module_multiterminal_set_secondary_terminal(mp_obj_t secondary_terminal) { - MP_STATE_VM(dupterm_objs[0]) = secondary_terminal; - if (MP_STATE_PORT(dupterm_arr_obj) == MP_OBJ_NULL) { - MP_STATE_PORT(dupterm_arr_obj) = mp_obj_new_bytearray(1, ""); - } -} +STATIC MP_DEFINE_CONST_DICT(memorymap_module_globals, memorymap_module_globals_table); -void shared_module_multiterminal_clear_secondary_terminal() { - MP_STATE_VM(dupterm_objs[0]) = MP_OBJ_NULL; - MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL; -} +const mp_obj_module_t memorymap_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&memorymap_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_memorymap, memorymap_module, CIRCUITPY_MEMORYMAP); diff --git a/shared-module/dotenv/__init__.h b/shared-bindings/memorymap/__init__.h similarity index 88% rename from shared-module/dotenv/__init__.h rename to shared-bindings/memorymap/__init__.h index 6cfb209324..f4e6c51481 100644 --- a/shared-module/dotenv/__init__.h +++ b/shared-bindings/memorymap/__init__.h @@ -24,5 +24,7 @@ * THE SOFTWARE. */ -// Allocation free version that returns the full length of the value. -mp_int_t dotenv_get_key(const char *path, const char *key, char *value, mp_int_t value_len); +#ifndef SHARED_BINDINGS_MEMORYMAP_H +#define SHARED_BINDINGS_MEMORYMAP_H + +#endif // SHARED_BINDINGS_MEMORYMAP_H diff --git a/shared-bindings/memorymonitor/AllocationAlarm.c b/shared-bindings/memorymonitor/AllocationAlarm.c index 45e7019912..e279fa6854 100644 --- a/shared-bindings/memorymonitor/AllocationAlarm.c +++ b/shared-bindings/memorymonitor/AllocationAlarm.c @@ -34,7 +34,6 @@ #include "supervisor/shared/translate/translate.h" //| class AllocationAlarm: -//| //| def __init__(self, *, minimum_block_count: int = 1) -> None: //| """Throw an exception when an allocation of ``minimum_block_count`` or more blocks //| occurs while active. @@ -55,7 +54,6 @@ //| //| """ //| ... -//| STATIC mp_obj_t memorymonitor_allocationalarm_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) { enum { ARG_minimum_block_count }; static const mp_arg_t allowed_args[] = { @@ -78,16 +76,15 @@ STATIC mp_obj_t memorymonitor_allocationalarm_make_new(const mp_obj_type_t *type //| def ignore(self, count: int) -> AllocationAlarm: //| """Sets the number of applicable allocations to ignore before raising the exception. -//| Automatically set back to zero at context exit. +//| Automatically set back to zero at context exit. //| -//| Use it within a ``with`` block:: +//| Use it within a ``with`` block:: //| -//| # Will not alarm because the bytearray allocation will be ignored. -//| with aa.ignore(2): -//| x = bytearray(20) -//| """ +//| # Will not alarm because the bytearray allocation will be ignored. +//| with aa.ignore(2): +//| x = bytearray(20) +//| """ //| ... -//| STATIC mp_obj_t memorymonitor_allocationalarm_obj_ignore(mp_obj_t self_in, mp_obj_t count_obj) { mp_int_t count = mp_obj_get_int(count_obj); mp_arg_validate_int_min(count, 0, MP_QSTR_count); @@ -100,7 +97,6 @@ MP_DEFINE_CONST_FUN_OBJ_2(memorymonitor_allocationalarm_ignore_obj, memorymonito //| def __enter__(self) -> AllocationAlarm: //| """Enables the alarm.""" //| ... -//| STATIC mp_obj_t memorymonitor_allocationalarm_obj___enter__(mp_obj_t self_in) { common_hal_memorymonitor_allocationalarm_resume(self_in); return self_in; diff --git a/shared-bindings/memorymonitor/AllocationSize.c b/shared-bindings/memorymonitor/AllocationSize.c index ed8252b67a..dd3a1e03cf 100644 --- a/shared-bindings/memorymonitor/AllocationSize.c +++ b/shared-bindings/memorymonitor/AllocationSize.c @@ -34,7 +34,6 @@ #include "supervisor/shared/translate/translate.h" //| class AllocationSize: -//| //| def __init__(self) -> None: //| """Tracks the number of allocations in power of two buckets. //| @@ -62,7 +61,6 @@ //| //| """ //| ... -//| STATIC mp_obj_t memorymonitor_allocationsize_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) { memorymonitor_allocationsize_obj_t *self = m_new_obj(memorymonitor_allocationsize_obj_t); self->base.type = &memorymonitor_allocationsize_type; @@ -75,7 +73,6 @@ STATIC mp_obj_t memorymonitor_allocationsize_make_new(const mp_obj_type_t *type, //| def __enter__(self) -> AllocationSize: //| """Clears counts and resumes tracking.""" //| ... -//| STATIC mp_obj_t memorymonitor_allocationsize_obj___enter__(mp_obj_t self_in) { common_hal_memorymonitor_allocationsize_clear(self_in); common_hal_memorymonitor_allocationsize_resume(self_in); @@ -87,7 +84,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationsize___enter___obj, memorymoni //| """Automatically pauses allocation tracking when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t memorymonitor_allocationsize_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_memorymonitor_allocationsize_pause(args[0]); @@ -97,7 +93,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(memorymonitor_allocationsize___exit__ //| bytes_per_block: int //| """Number of bytes per block""" -//| STATIC mp_obj_t memorymonitor_allocationsize_obj_get_bytes_per_block(mp_obj_t self_in) { memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -116,7 +111,6 @@ MP_PROPERTY_GETTER(memorymonitor_allocationsize_bytes_per_block_obj, //| mm = memorymonitor.AllocationSize() //| print(len(mm))""" //| ... -//| STATIC mp_obj_t memorymonitor_allocationsize_unary_op(mp_unary_op_t op, mp_obj_t self_in) { memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); uint16_t len = common_hal_memorymonitor_allocationsize_get_len(self); diff --git a/shared-bindings/memorymonitor/__init__.c b/shared-bindings/memorymonitor/__init__.c index 64a3a6a77f..7b05acd095 100644 --- a/shared-bindings/memorymonitor/__init__.c +++ b/shared-bindings/memorymonitor/__init__.c @@ -38,7 +38,9 @@ //| class AllocationError(Exception): //| """Catchall exception for allocation related errors.""" +//| //| ... +//| MP_DEFINE_MEMORYMONITOR_EXCEPTION(AllocationError, Exception) NORETURN void mp_raise_memorymonitor_AllocationError(const compressed_string_t *fmt, ...) { diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c index 840f468e2a..ea27df9812 100644 --- a/shared-bindings/microcontroller/Pin.c +++ b/shared-bindings/microcontroller/Pin.c @@ -41,7 +41,6 @@ //| hardware so they cannot be constructed on demand. Instead, use //| :mod:`board` or :mod:`microcontroller.pin` to reference the desired pin.""" //| ... -//| //| def __hash__(self) -> int: //| """Returns a hash for the Pin.""" @@ -70,7 +69,7 @@ static void get_pin_name(const mcu_pin_obj_t *self, qstr *package, qstr *module, } } -STATIC void mcu_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { +void shared_bindings_microcontroller_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { mcu_pin_obj_t *self = MP_OBJ_TO_PTR(self_in); qstr package = MP_QSTR_Pin; qstr module; @@ -88,29 +87,30 @@ const mp_obj_type_t mcu_pin_type = { { &mp_type_type }, .flags = MP_TYPE_FLAG_EXTENDED, .name = MP_QSTR_Pin, - .print = mcu_pin_print, + .print = shared_bindings_microcontroller_pin_print, MP_TYPE_EXTENDED_FIELDS( .unary_op = mp_generic_unary_op, ) }; -const mcu_pin_obj_t *validate_obj_is_pin(mp_obj_t obj) { - if (!mp_obj_is_type(obj, &mcu_pin_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), mcu_pin_type.name); - } - return MP_OBJ_TO_PTR(obj); +const mcu_pin_obj_t *validate_obj_is_pin(mp_obj_t obj, qstr arg_name) { + return MP_OBJ_TO_PTR(mp_arg_validate_type(obj, &mcu_pin_type, arg_name)); +} + +const mcu_pin_obj_t *validate_obj_is_pin_in(mp_obj_t obj, qstr arg_name) { + return MP_OBJ_TO_PTR(mp_arg_validate_type_in(obj, &mcu_pin_type, arg_name)); } // Validate that the obj is a pin or None. Return an mcu_pin_obj_t* or NULL, correspondingly. -const mcu_pin_obj_t *validate_obj_is_pin_or_none(mp_obj_t obj) { +const mcu_pin_obj_t *validate_obj_is_pin_or_none(mp_obj_t obj, qstr arg_name) { if (obj == mp_const_none) { return NULL; } - return validate_obj_is_pin(obj); + return validate_obj_is_pin(obj, arg_name); } -const mcu_pin_obj_t *validate_obj_is_free_pin(mp_obj_t obj) { - const mcu_pin_obj_t *pin = validate_obj_is_pin(obj); +const mcu_pin_obj_t *validate_obj_is_free_pin(mp_obj_t obj, qstr arg_name) { + const mcu_pin_obj_t *pin = validate_obj_is_pin(obj, arg_name); assert_pin_free(pin); return pin; } @@ -121,11 +121,11 @@ void validate_no_duplicate_pins(mp_obj_t seq, qstr arg_name) { for (size_t pin_cnt = 0; pin_cnt < num_pins; pin_cnt++) { mp_obj_t pin1_obj = mp_obj_subscr(seq, MP_OBJ_NEW_SMALL_INT(pin_cnt), MP_OBJ_SENTINEL); - const mcu_pin_obj_t *pin1 = validate_obj_is_pin(pin1_obj); + const mcu_pin_obj_t *pin1 = validate_obj_is_pin_in(pin1_obj, arg_name); for (size_t pin_cnt_2 = pin_cnt + 1; pin_cnt_2 < num_pins; pin_cnt_2++) { mp_obj_t pin2_obj = mp_obj_subscr(seq, MP_OBJ_NEW_SMALL_INT(pin_cnt_2), MP_OBJ_SENTINEL); - const mcu_pin_obj_t *pin2 = validate_obj_is_pin(pin2_obj); + const mcu_pin_obj_t *pin2 = validate_obj_is_pin_in(pin2_obj, arg_name); if (pin1 == pin2) { mp_raise_TypeError_varg(translate("%q contains duplicate pins"), arg_name); } @@ -142,11 +142,11 @@ void validate_no_duplicate_pins_2(mp_obj_t seq1, mp_obj_t seq2, qstr arg_name1, for (size_t pin_cnt_1 = 0; pin_cnt_1 < num_pins_1; pin_cnt_1++) { mp_obj_t pin1_obj = mp_obj_subscr(seq1, MP_OBJ_NEW_SMALL_INT(pin_cnt_1), MP_OBJ_SENTINEL); - const mcu_pin_obj_t *pin1 = validate_obj_is_pin(pin1_obj); + const mcu_pin_obj_t *pin1 = validate_obj_is_pin_in(pin1_obj, arg_name1); for (size_t pin_cnt_2 = 0; pin_cnt_2 < num_pins_2; pin_cnt_2++) { mp_obj_t pin2_obj = mp_obj_subscr(seq2, MP_OBJ_NEW_SMALL_INT(pin_cnt_2), MP_OBJ_SENTINEL); - const mcu_pin_obj_t *pin2 = validate_obj_is_pin(pin2_obj); + const mcu_pin_obj_t *pin2 = validate_obj_is_pin_in(pin2_obj, arg_name2); if (pin1 == pin2) { mp_raise_TypeError_varg(translate("%q and %q contain duplicate pins"), arg_name1, arg_name2); } @@ -157,21 +157,21 @@ void validate_no_duplicate_pins_2(mp_obj_t seq1, mp_obj_t seq2, qstr arg_name1, // Validate every element in the list to be a free pin. void validate_list_is_free_pins(qstr what, const mcu_pin_obj_t **pins_out, mp_int_t max_pins, mp_obj_t seq, uint8_t *count_out) { mp_int_t len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(seq)); - if (len > max_pins) { - mp_raise_ValueError_varg(translate("At most %d %q may be specified (not %d)"), max_pins, what, len); - } + mp_arg_validate_length_max(len, max_pins, what); *count_out = len; for (mp_int_t i = 0; i < len; i++) { - pins_out[i] = validate_obj_is_free_pin(mp_obj_subscr(seq, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL)); + pins_out[i] = + validate_obj_is_pin_in(mp_obj_subscr(seq, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL), what); + assert_pin_free(pins_out[i]); } } // Validate that the obj is a free pin or None. Return an mcu_pin_obj_t* or NULL, correspondingly. -const mcu_pin_obj_t *validate_obj_is_free_pin_or_none(mp_obj_t obj) { +const mcu_pin_obj_t *validate_obj_is_free_pin_or_none(mp_obj_t obj, qstr arg_name) { if (obj == mp_const_none) { return NULL; } - const mcu_pin_obj_t *pin = validate_obj_is_pin(obj); + const mcu_pin_obj_t *pin = validate_obj_is_pin(obj, arg_name); assert_pin_free(pin); return pin; } diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h index 12ff422a4a..28d0949042 100644 --- a/shared-bindings/microcontroller/Pin.h +++ b/shared-bindings/microcontroller/Pin.h @@ -33,10 +33,11 @@ // Type object used in Python. Should be shared between ports. extern const mp_obj_type_t mcu_pin_type; -const mcu_pin_obj_t *validate_obj_is_pin(mp_obj_t obj); -const mcu_pin_obj_t *validate_obj_is_pin_or_none(mp_obj_t obj); -const mcu_pin_obj_t *validate_obj_is_free_pin(mp_obj_t obj); -const mcu_pin_obj_t *validate_obj_is_free_pin_or_none(mp_obj_t obj); +const mcu_pin_obj_t *validate_obj_is_pin(mp_obj_t obj, qstr arg_name); +const mcu_pin_obj_t *validate_obj_is_pin_in(mp_obj_t obj, qstr arg_name); +const mcu_pin_obj_t *validate_obj_is_pin_or_none(mp_obj_t obj, qstr arg_name); +const mcu_pin_obj_t *validate_obj_is_free_pin(mp_obj_t obj, qstr arg_name); +const mcu_pin_obj_t *validate_obj_is_free_pin_or_none(mp_obj_t obj, qstr arg_name); void validate_no_duplicate_pins(mp_obj_t seq, qstr arg_name); void validate_no_duplicate_pins_2(mp_obj_t seq1, mp_obj_t seq2, qstr arg_name1, qstr arg_name2); void validate_list_is_free_pins(qstr what, const mcu_pin_obj_t **pins_out, mp_int_t max_pins, mp_obj_t seq, uint8_t *count_out); @@ -55,6 +56,8 @@ void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin); void common_hal_mcu_pin_claim_number(uint8_t pin_no); void common_hal_mcu_pin_reset_number(uint8_t pin_no); +void shared_bindings_microcontroller_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); + #define COMMON_HAL_MCU_NO_PIN ((uint8_t)0xff) #endif // MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H diff --git a/shared-bindings/microcontroller/Processor.c b/shared-bindings/microcontroller/Processor.c index 067d6b0097..986f81ea53 100644 --- a/shared-bindings/microcontroller/Processor.c +++ b/shared-bindings/microcontroller/Processor.c @@ -63,23 +63,23 @@ //| """You cannot create an instance of `microcontroller.Processor`. //| Use `microcontroller.cpu` to access the sole instance available.""" //| ... -//| //| frequency: int -//| """The CPU operating frequency in Hertz. (read-only)""" +//| """The CPU operating frequency in Hertz. //| +//| **Limitations:** Setting the ``frequency`` is possible only on some i.MX boards. +//| On most boards, ``frequency`` is read-only. +//| """ +#if CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY STATIC mp_obj_t mcu_processor_set_frequency(mp_obj_t self, mp_obj_t freq) { - #if CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY uint32_t value_of_freq = (uint32_t)mp_arg_validate_int_min(mp_obj_get_int(freq), 0, MP_QSTR_frequency); common_hal_mcu_processor_set_frequency(self, value_of_freq); - #else - mp_raise_msg(&mp_type_NotImplementedError,translate("frequency is read-only for this board")); - #endif return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(mcu_processor_set_frequency_obj, mcu_processor_set_frequency); +#endif STATIC mp_obj_t mcu_processor_get_frequency(mp_obj_t self) { @@ -88,13 +88,17 @@ STATIC mp_obj_t mcu_processor_get_frequency(mp_obj_t self) { MP_DEFINE_CONST_FUN_OBJ_1(mcu_processor_get_frequency_obj, mcu_processor_get_frequency); +#if CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY MP_PROPERTY_GETSET(mcu_processor_frequency_obj, (mp_obj_t)&mcu_processor_get_frequency_obj, (mp_obj_t)&mcu_processor_set_frequency_obj); +#else +MP_PROPERTY_GETTER(mcu_processor_frequency_obj, + (mp_obj_t)&mcu_processor_get_frequency_obj); +#endif //| reset_reason: microcontroller.ResetReason //| """The reason the microcontroller started up from reset state.""" -//| STATIC mp_obj_t mcu_processor_get_reset_reason(mp_obj_t self) { return cp_enum_find(&mcu_reset_reason_type, common_hal_mcu_processor_get_reset_reason()); } @@ -107,8 +111,11 @@ MP_PROPERTY_GETTER(mcu_processor_reset_reason_obj, //| temperature: Optional[float] //| """The on-chip temperature, in Celsius, as a float. (read-only) //| -//| Is `None` if the temperature is not available.""" +//| Is `None` if the temperature is not available. //| +//| **Limitations:** Not available on ESP32 or ESP32-S3. On small SAMD21 builds without external flash, +//| the reported temperature has reduced accuracy and precision, to save code space. +//| """ STATIC mp_obj_t mcu_processor_get_temperature(mp_obj_t self) { float temperature = common_hal_mcu_processor_get_temperature(); return isnan(temperature) ? mp_const_none : mp_obj_new_float(temperature); @@ -121,7 +128,6 @@ MP_PROPERTY_GETTER(mcu_processor_temperature_obj, //| uid: bytearray //| """The unique id (aka serial number) of the chip as a `bytearray`. (read-only)""" -//| STATIC mp_obj_t mcu_processor_get_uid(mp_obj_t self) { uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; common_hal_mcu_processor_get_uid(raw_id); diff --git a/shared-bindings/microcontroller/ResetReason.c b/shared-bindings/microcontroller/ResetReason.c index 905c19f83f..13a8f25e6d 100644 --- a/shared-bindings/microcontroller/ResetReason.c +++ b/shared-bindings/microcontroller/ResetReason.c @@ -42,7 +42,7 @@ MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESCUE_DEBUG, RESET_REASON_ //| """The reason the microntroller was last reset""" //| //| POWER_ON: object -//| """The microntroller was started from power off.""" +//| """The microcontroller was started from power off.""" //| //| BROWNOUT: object //| """The microntroller was reset due to too low a voltage.""" diff --git a/shared-bindings/microcontroller/RunMode.c b/shared-bindings/microcontroller/RunMode.c index 477168dda0..b29670576b 100644 --- a/shared-bindings/microcontroller/RunMode.c +++ b/shared-bindings/microcontroller/RunMode.c @@ -32,7 +32,6 @@ //| def __init__(self) -> None: //| """Enum-like class to define the run mode of the microcontroller and //| CircuitPython.""" -//| //| NORMAL: RunMode //| """Run CircuitPython as normal. //| diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index 46382dc3e6..2c1fdd5b58 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -55,7 +55,6 @@ //| """CPU information and control, such as ``cpu.temperature`` and ``cpu.frequency`` //| (clock frequency). //| This object is an instance of `microcontroller.Processor`.""" -//| //| cpus: Processor //| """CPU information and control, such as ``cpus[0].temperature`` and ``cpus[1].frequency`` @@ -147,12 +146,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_reset_obj, mcu_reset); //| This object is the sole instance of `nvm.ByteArray` when available or ``None`` otherwise. //| //| :type: nvm.ByteArray or None""" -//| //| watchdog: Optional[WatchDogTimer] //| """Available watchdog timer. //| This object is the sole instance of `watchdog.WatchDogTimer` when available or ``None`` otherwise.""" -//| const mp_obj_module_t mcu_pin_module = { .base = { &mp_type_module }, diff --git a/shared-bindings/msgpack/ExtType.c b/shared-bindings/msgpack/ExtType.c index 94c699d469..7bfe3bd8bd 100644 --- a/shared-bindings/msgpack/ExtType.c +++ b/shared-bindings/msgpack/ExtType.c @@ -31,11 +31,11 @@ //| class ExtType: //| """ExtType represents ext type in msgpack.""" +//| //| def __init__(self, code: int, data: bytes) -> None: //| """Constructor //| :param int code: type code in range 0~127. //| :param bytes data: representation.""" -//| STATIC mp_obj_t mod_msgpack_exttype_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mod_msgpack_extype_obj_t *self = m_new_obj(mod_msgpack_extype_obj_t); self->base.type = &mod_msgpack_exttype_type; @@ -60,7 +60,6 @@ STATIC mp_obj_t mod_msgpack_exttype_make_new(const mp_obj_type_t *type, size_t n //| code: int //| """The type code, in range 0~127.""" //| ... -//| STATIC mp_obj_t mod_msgpack_exttype_get_code(mp_obj_t self_in) { mod_msgpack_extype_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(self->code); diff --git a/shared-bindings/msgpack/__init__.c b/shared-bindings/msgpack/__init__.c index e13fb28819..7773d6d190 100644 --- a/shared-bindings/msgpack/__init__.c +++ b/shared-bindings/msgpack/__init__.c @@ -86,7 +86,12 @@ //| """ //| -//| def pack(obj: object, stream: circuitpython_typing.ByteStream, *, default: Union[Callable[[object], None], None] = None) -> None: +//| def pack( +//| obj: object, +//| stream: circuitpython_typing.ByteStream, +//| *, +//| default: Union[Callable[[object], None], None] = None +//| ) -> None: //| """Output object to stream in msgpack format. //| //| :param object obj: Object to convert to msgpack format. @@ -118,7 +123,12 @@ STATIC mp_obj_t mod_msgpack_pack(size_t n_args, const mp_obj_t *pos_args, mp_map MP_DEFINE_CONST_FUN_OBJ_KW(mod_msgpack_pack_obj, 0, mod_msgpack_pack); -//| def unpack(stream: circuitpython_typing.ByteStream, *, ext_hook: Union[Callable[[int, bytes], object], None] = None, use_list: bool=True) -> object: +//| def unpack( +//| stream: circuitpython_typing.ByteStream, +//| *, +//| ext_hook: Union[Callable[[int, bytes], object], None] = None, +//| use_list: bool = True +//| ) -> object: //| """Unpack and return one object from stream. //| //| :param ~circuitpython_typing.ByteStream stream: stream to read from diff --git a/shared-bindings/multiterminal/__init__.c b/shared-bindings/multiterminal/__init__.c deleted file mode 100644 index 8726e9a655..0000000000 --- a/shared-bindings/multiterminal/__init__.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "shared-bindings/multiterminal/__init__.h" - -#include "py/obj.h" -#include "py/mphal.h" -#include "py/runtime.h" -#include "supervisor/shared/translate/translate.h" - -//| """Manage additional terminal sources -//| -//| The `multiterminal` module allows you to configure an additional serial -//| terminal source. Incoming characters are accepted from both the internal -//| serial connection and the optional secondary connection.""" -//| - -//| def get_secondary_terminal() -> Optional[typing.BinaryIO]: -//| """Returns the current secondary terminal.""" -//| ... -//| -STATIC mp_obj_t multiterminal_obj_get_secondary_terminal() { - return common_hal_multiterminal_get_secondary_terminal(); -} -MP_DEFINE_CONST_FUN_OBJ_0(multiterminal_get_secondary_terminal_obj, multiterminal_obj_get_secondary_terminal); - -//| def set_secondary_terminal(stream: typing.BinaryIO) -> None: -//| """Read additional input from the given stream and write out back to it. -//| This doesn't replace the core stream (usually UART or native USB) but is -//| mixed in instead. -//| -//| :param stream stream: secondary stream""" -//| ... -//| -STATIC mp_obj_t multiterminal_obj_set_secondary_terminal(mp_obj_t secondary_terminal) { - mp_obj_t write_m[3]; - mp_load_method_maybe(secondary_terminal, MP_QSTR_write, write_m); - mp_obj_t readinto_m[3]; - mp_load_method_maybe(secondary_terminal, MP_QSTR_readinto, readinto_m); - if (write_m[0] == MP_OBJ_NULL || readinto_m[0] == MP_OBJ_NULL) { - mp_raise_ValueError(translate("Stream missing readinto() or write() method.")); - return mp_const_none; - } - common_hal_multiterminal_set_secondary_terminal(secondary_terminal); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(multiterminal_set_secondary_terminal_obj, multiterminal_obj_set_secondary_terminal); - -//| def clear_secondary_terminal() -> None: -//| """Clears the secondary terminal.""" -//| ... -//| -STATIC mp_obj_t multiterminal_obj_clear_secondary_terminal() { - common_hal_multiterminal_clear_secondary_terminal(); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_0(multiterminal_clear_secondary_terminal_obj, multiterminal_obj_clear_secondary_terminal); - -//| def schedule_secondary_terminal_read(socket: socket.socket) -> None: -//| """In cases where the underlying OS is doing task scheduling, this notifies -//| the OS when more data is available on the socket to read. This is useful -//| as a callback for lwip sockets.""" -//| ... -//| -// TODO(tannewt): This is a funny API. Replace it with a direct call into the OS -// by the lwip object. -STATIC mp_obj_t multiterminal_obj_schedule_secondary_terminal_read(mp_obj_t socket) { - common_hal_multiterminal_schedule_secondary_terminal_read(socket); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(multiterminal_schedule_secondary_terminal_read_obj, multiterminal_obj_schedule_secondary_terminal_read); - -// TODO(tannewt): Expose the internal serial connection as `primary_terminal` - -STATIC const mp_rom_map_elem_t multiterminal_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_multiterminal) }, - { MP_ROM_QSTR(MP_QSTR_get_secondary_terminal), MP_ROM_PTR(&multiterminal_get_secondary_terminal_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_secondary_terminal), MP_ROM_PTR(&multiterminal_set_secondary_terminal_obj) }, - { MP_ROM_QSTR(MP_QSTR_clear_secondary_terminal), MP_ROM_PTR(&multiterminal_clear_secondary_terminal_obj) }, - { MP_ROM_QSTR(MP_QSTR_schedule_secondary_terminal_read), MP_ROM_PTR(&multiterminal_schedule_secondary_terminal_read_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(multiterminal_module_globals, multiterminal_module_globals_table); - -const mp_obj_module_t multiterminal_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&multiterminal_module_globals, -}; diff --git a/shared-bindings/neopixel_write/__init__.c b/shared-bindings/neopixel_write/__init__.c index e45e970179..cc0e2a041a 100644 --- a/shared-bindings/neopixel_write/__init__.c +++ b/shared-bindings/neopixel_write/__init__.c @@ -109,15 +109,13 @@ STATIC void check_for_deinit(digitalio_digitalinout_obj_t *self) { //| """Write buf out on the given DigitalInOut. //| //| :param ~digitalio.DigitalInOut digitalinout: the DigitalInOut to output with -//| :param ~circuitpython_typing.ReadableBuffer buf: The bytes to clock out. No assumption is made about color order""" +//| :param ~circuitpython_typing.ReadableBuffer buf: The bytes to clock out. No assumption is made about color order +//| """ //| ... +//| STATIC mp_obj_t neopixel_write_neopixel_write_(mp_obj_t digitalinout_obj, mp_obj_t buf) { - if (!mp_obj_is_type(digitalinout_obj, &digitalio_digitalinout_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), digitalio_digitalinout_type.name); - } - - // Convert parameters into expected types. - const digitalio_digitalinout_obj_t *digitalinout = MP_OBJ_TO_PTR(digitalinout_obj); + const digitalio_digitalinout_obj_t *digitalinout = + mp_arg_validate_type(digitalinout_obj, &digitalio_digitalinout_type, MP_QSTR_digitalinout); // Check to see if the NeoPixel has been deinited before writing to it. check_for_deinit(digitalinout_obj); diff --git a/shared-bindings/nvm/ByteArray.c b/shared-bindings/nvm/ByteArray.c index 936e3bcee5..e7c3fc37e8 100644 --- a/shared-bindings/nvm/ByteArray.c +++ b/shared-bindings/nvm/ByteArray.c @@ -43,20 +43,15 @@ //| import microcontroller //| microcontroller.nvm[0:3] = b"\xcc\x10\x00" //| """ -//| //| def __init__(self) -> None: //| """Not currently dynamically supported. Access the sole instance through `microcontroller.nvm`.""" //| ... -//| -//| def __bool__(self) -> bool: -//| ... -//| +//| def __bool__(self) -> bool: ... //| def __len__(self) -> int: //| """Return the length. This is used by (`len`)""" //| ... -//| STATIC mp_obj_t nvm_bytearray_unary_op(mp_unary_op_t op, mp_obj_t self_in) { nvm_bytearray_obj_t *self = MP_OBJ_TO_PTR(self_in); uint16_t len = common_hal_nvm_bytearray_get_length(self); @@ -81,7 +76,6 @@ STATIC MP_DEFINE_CONST_DICT(nvm_bytearray_locals_dict, nvm_bytearray_locals_dict //| def __getitem__(self, index: int) -> int: //| """Returns the value at the given index.""" //| ... -//| //| @overload //| def __setitem__(self, index: slice, value: ReadableBuffer) -> None: ... //| @overload diff --git a/shared-bindings/nvm/__init__.c b/shared-bindings/nvm/__init__.c index dffc4cda89..0ecadd9880 100644 --- a/shared-bindings/nvm/__init__.c +++ b/shared-bindings/nvm/__init__.c @@ -39,7 +39,6 @@ //| Note that this module can't be imported and used directly. The sole //| instance of :class:`ByteArray` is available at //| :attr:`microcontroller.nvm`.""" -//| STATIC const mp_rom_map_elem_t nvm_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_nvm) }, { MP_ROM_QSTR(MP_QSTR_ByteArray), MP_ROM_PTR(&nvm_bytearray_type) }, @@ -51,3 +50,5 @@ const mp_obj_module_t nvm_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&nvm_module_globals, }; + +MP_REGISTER_MODULE(MP_QSTR_nvm, nvm_module, CIRCUITPY_NVM); diff --git a/shared-bindings/onewireio/OneWire.c b/shared-bindings/onewireio/OneWire.c index a167c86cc8..3f0dc87722 100644 --- a/shared-bindings/onewireio/OneWire.c +++ b/shared-bindings/onewireio/OneWire.c @@ -38,25 +38,21 @@ //| def __init__(self, pin: microcontroller.Pin) -> None: //| """Create a OneWire object associated with the given pin. //| -//| The object implements the lowest level timing-sensitive bits of the protocol. +//| The object implements the lowest level timing-sensitive bits of the protocol. //| -//| :param ~microcontroller.Pin pin: Pin connected to the OneWire bus +//| :param ~microcontroller.Pin pin: Pin connected to the OneWire bus //| -//| .. note:: The OneWire class is available on `busio` and `bitbangio` in CircuitPython -//| 7.x for backwards compatibility but will be removed in CircuitPython 8.0.0. +//| Read a short series of pulses:: //| -//| Read a short series of pulses:: +//| import onewireio +//| import board //| -//| import onewireio -//| import board -//| -//| onewire = onewireio.OneWire(board.D7) -//| onewire.reset() -//| onewire.write_bit(True) -//| onewire.write_bit(False) -//| print(onewire.read_bit())""" +//| onewire = onewireio.OneWire(board.D7) +//| onewire.reset() +//| onewire.write_bit(True) +//| onewire.write_bit(False) +//| print(onewire.read_bit())""" //| ... -//| STATIC mp_obj_t onewireio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pin }; static const mp_arg_t allowed_args[] = { @@ -64,7 +60,7 @@ STATIC mp_obj_t onewireio_onewire_make_new(const mp_obj_type_t *type, size_t n_a }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); onewireio_onewire_obj_t *self = m_new_obj(onewireio_onewire_obj_t); self->base.type = &onewireio_onewire_type; @@ -76,7 +72,6 @@ STATIC mp_obj_t onewireio_onewire_make_new(const mp_obj_type_t *type, size_t n_a //| def deinit(self) -> None: //| """Deinitialize the OneWire bus and release any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t onewireio_onewire_deinit(mp_obj_t self_in) { onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_onewireio_onewire_deinit(self); @@ -93,14 +88,12 @@ STATIC void check_for_deinit(onewireio_onewire_obj_t *self) { //| def __enter__(self) -> OneWire: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t onewireio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_onewireio_onewire_deinit(args[0]); @@ -114,7 +107,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(onewireio_onewire___exit___obj, 4, 4, //| :returns: False when at least one device is present //| :rtype: bool""" //| ... -//| STATIC mp_obj_t onewireio_onewire_obj_reset(mp_obj_t self_in) { onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -129,7 +121,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(onewireio_onewire_reset_obj, onewireio_onewire_obj_res //| :returns: bit state read //| :rtype: bool""" //| ... -//| STATIC mp_obj_t onewireio_onewire_obj_read_bit(mp_obj_t self_in) { onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/onewireio/__init__.c b/shared-bindings/onewireio/__init__.c index 45d78b250a..81b2d605d7 100644 --- a/shared-bindings/onewireio/__init__.c +++ b/shared-bindings/onewireio/__init__.c @@ -38,7 +38,6 @@ //| """Low-level bit primitives for Maxim (formerly Dallas Semi) one-wire protocol. //| //| Protocol definition is here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126""" -//| STATIC const mp_rom_map_elem_t onewireio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_onewireio) }, diff --git a/shared-bindings/os/__init__.c b/shared-bindings/os/__init__.c index 4c249c368e..b2fb8ff095 100644 --- a/shared-bindings/os/__init__.c +++ b/shared-bindings/os/__init__.c @@ -44,6 +44,7 @@ //| """ //| //| import typing +//| //| def uname() -> _Uname: //| """Returns a named tuple of operating specific and CircuitPython port @@ -87,10 +88,11 @@ MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd); //| def getenv(key: str, default: Optional[str] = None) -> Optional[str]: //| """Get the environment variable value for the given key or return ``default``. //| -//| This may load values from disk so cache the result instead of calling this often.""" +//| This may load values from disk so cache the result instead of calling this often.""" //| ... //| STATIC mp_obj_t os_getenv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + #if CIRCUITPY_OS_GETENV enum { ARG_key, ARG_default }; static const mp_arg_t allowed_args[] = { { MP_QSTR_key, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -100,6 +102,9 @@ STATIC mp_obj_t os_getenv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); return common_hal_os_getenv(mp_obj_str_get_str(args[ARG_key].u_obj), args[ARG_default].u_obj); + #else + return mp_const_none; + #endif } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(os_getenv_obj, 1, os_getenv); @@ -166,6 +171,20 @@ MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir); //| def stat(path: str) -> Tuple[int, int, int, int, int, int, int, int, int, int]: //| """Get the status of a file or directory. //| +//| Returns a tuple with the status of a file or directory in the following order: +//| +//| +//| * ``st_mode`` -- File type, regular or directory +//| * ``st_ino`` -- Set to 0 +//| * ``st_dev`` -- Set to 0 +//| * ``st_nlink`` -- Set to 0 +//| * ``st_uid`` -- Set to 0 +//| * ``st_gid`` -- Set to 0 +//| * ``st_size`` -- Size of the file in bytes +//| * ``st_atime`` -- Time of most recent access expressed in seconds +//| * ``st_mtime`` -- Time of most recent content modification expressed in seconds. +//| * ``st_ctime`` -- Time of most recent content modification expressed in seconds. +//| //| .. note:: On builds without long integers, the number of seconds //| for contemporary dates will not fit in a small integer. //| So the time fields return 946684800, @@ -220,7 +239,10 @@ MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync); //| def urandom(size: int) -> str: //| """Returns a string of *size* random bytes based on a hardware True Random -//| Number Generator. When not available, it will raise a NotImplementedError.""" +//| Number Generator. When not available, it will raise a NotImplementedError. +//| +//| **Limitations:** Not yet available on nRF. Not available on SAMD21 due to lack of hardware. +//| """ //| ... //| STATIC mp_obj_t os_urandom(mp_obj_t size_in) { @@ -233,6 +255,17 @@ STATIC mp_obj_t os_urandom(mp_obj_t size_in) { } MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); +//| def utime(path: str, times: Tuple[int, int]) -> None: +//| """Change the timestamp of a file.""" +//| ... +//| +STATIC mp_obj_t os_utime(mp_obj_t path_in, mp_obj_t times_in) { + const char *path = mp_obj_str_get_str(path_in); + common_hal_os_utime(path, times_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(os_utime_obj, os_utime); + STATIC const mp_rom_map_elem_t os_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_os) }, @@ -249,15 +282,14 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&os_stat_obj) }, { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&os_statvfs_obj) }, { MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&os_remove_obj) }, // unlink aliases to remove + { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&os_utime_obj) }, { MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&os_sync_obj) }, { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&os_urandom_obj) }, -//| //| sep: str //| """Separator used to delineate path components such as folder and file names.""" -//| { MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) }, }; diff --git a/shared-bindings/os/__init__.h b/shared-bindings/os/__init__.h index 5a27f309b4..49b12cd52a 100644 --- a/shared-bindings/os/__init__.h +++ b/shared-bindings/os/__init__.h @@ -38,6 +38,8 @@ mp_obj_t common_hal_os_uname(void); void common_hal_os_chdir(const char *path); mp_obj_t common_hal_os_getcwd(void); mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_); +mp_obj_t common_hal_os_getenv_path(const char *path, const char *key, mp_obj_t default_); + mp_obj_t common_hal_os_listdir(const char *path); void common_hal_os_mkdir(const char *path); void common_hal_os_remove(const char *path); @@ -45,6 +47,7 @@ void common_hal_os_rename(const char *old_path, const char *new_path); void common_hal_os_rmdir(const char *path); mp_obj_t common_hal_os_stat(const char *path); mp_obj_t common_hal_os_statvfs(const char *path); +void common_hal_os_utime(const char *path, mp_obj_t times); // Returns true if data was correctly sourced from a true random number generator. bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length); diff --git a/shared-bindings/paralleldisplay/ParallelBus.c b/shared-bindings/paralleldisplay/ParallelBus.c index a8b37fa956..42b4c788c7 100644 --- a/shared-bindings/paralleldisplay/ParallelBus.c +++ b/shared-bindings/paralleldisplay/ParallelBus.c @@ -42,7 +42,17 @@ //| protocol may be refered to as 8080-I Series Parallel Interface in datasheets. It doesn't handle //| display initialization.""" //| -//| def __init__(self, *, data0: microcontroller.Pin, command: microcontroller.Pin, chip_select: microcontroller.Pin, write: microcontroller.Pin, read: Optional[microcontroller.Pin], reset: Optional[microcontroller.Pin] = None, frequency: int = 30_000_000) -> None: +//| def __init__( +//| self, +//| *, +//| data0: microcontroller.Pin, +//| command: microcontroller.Pin, +//| chip_select: microcontroller.Pin, +//| write: microcontroller.Pin, +//| read: Optional[microcontroller.Pin], +//| reset: Optional[microcontroller.Pin] = None, +//| frequency: int = 30_000_000, +//| ) -> None: //| """Create a ParallelBus object associated with the given pins. The bus is inferred from data0 //| by implying the next 7 additional pins on a given GPIO port. //| @@ -60,7 +70,6 @@ //| :param microcontroller.Pin reset: Reset pin, optional //| :param int frequency: The communication frequency in Hz for the display on the bus""" //| ... -//| STATIC mp_obj_t paralleldisplay_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_data0, ARG_data_pins, ARG_command, ARG_chip_select, ARG_write, ARG_read, ARG_reset, ARG_frequency }; static const mp_arg_t allowed_args[] = { @@ -76,11 +85,11 @@ STATIC mp_obj_t paralleldisplay_parallelbus_make_new(const mp_obj_type_t *type, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *command = validate_obj_is_free_pin(args[ARG_command].u_obj); - const mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj); - const mcu_pin_obj_t *write = validate_obj_is_free_pin(args[ARG_write].u_obj); - const mcu_pin_obj_t *read = validate_obj_is_free_pin_or_none(args[ARG_read].u_obj); - const mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj); + const mcu_pin_obj_t *command = validate_obj_is_free_pin(args[ARG_command].u_obj, MP_QSTR_command); + const mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj, MP_QSTR_chip_select); + const mcu_pin_obj_t *write = validate_obj_is_free_pin(args[ARG_write].u_obj, MP_QSTR_write); + const mcu_pin_obj_t *read = validate_obj_is_free_pin_or_none(args[ARG_read].u_obj, MP_QSTR_read); + const mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj, MP_QSTR_reset); paralleldisplay_parallelbus_obj_t *self = &allocate_display_bus_or_raise()->parallel_bus; self->base.type = ¶lleldisplay_parallelbus_type; @@ -93,7 +102,7 @@ STATIC mp_obj_t paralleldisplay_parallelbus_make_new(const mp_obj_type_t *type, } if (specified_data0) { - const mcu_pin_obj_t *data0 = validate_obj_is_free_pin(args[ARG_data0].u_obj); + const mcu_pin_obj_t *data0 = validate_obj_is_free_pin(args[ARG_data0].u_obj, MP_QSTR_data0); common_hal_paralleldisplay_parallelbus_construct(self, data0, command, chip_select, write, read, reset, args[ARG_frequency].u_int); } else { uint8_t num_pins; @@ -108,7 +117,6 @@ STATIC mp_obj_t paralleldisplay_parallelbus_make_new(const mp_obj_type_t *type, //| """Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin //| is available.""" //| ... -//| STATIC mp_obj_t paralleldisplay_parallelbus_obj_reset(mp_obj_t self_in) { paralleldisplay_parallelbus_obj_t *self = self_in; diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c index d84e788de5..67cffc9f7b 100644 --- a/shared-bindings/ps2io/Ps2.c +++ b/shared-bindings/ps2io/Ps2.c @@ -66,7 +66,6 @@ //| print(kbd.sendcmd(0xed)) //| print(kbd.sendcmd(0x01))""" //| ... -//| STATIC mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_data_pin, ARG_clock_pin }; static const mp_arg_t allowed_args[] = { @@ -76,8 +75,8 @@ STATIC mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *clock_pin = validate_obj_is_free_pin(args[ARG_clock_pin].u_obj); - const mcu_pin_obj_t *data_pin = validate_obj_is_free_pin(args[ARG_data_pin].u_obj); + const mcu_pin_obj_t *clock_pin = validate_obj_is_free_pin(args[ARG_clock_pin].u_obj, MP_QSTR_clock_pin); + const mcu_pin_obj_t *data_pin = validate_obj_is_free_pin(args[ARG_data_pin].u_obj, MP_QSTR_data_pin); ps2io_ps2_obj_t *self = m_new_obj(ps2io_ps2_obj_t); self->base.type = &ps2io_ps2_type; @@ -90,7 +89,6 @@ STATIC mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, siz //| def deinit(self) -> None: //| """Deinitialises the Ps2 and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t ps2io_ps2_deinit(mp_obj_t self_in) { ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_ps2io_ps2_deinit(self); @@ -107,14 +105,12 @@ STATIC void check_for_deinit(ps2io_ps2_obj_t *self) { //| def __enter__(self) -> Ps2: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t ps2io_ps2_obj___exit__(size_t n_args, const mp_obj_t *args) { mp_check_self(mp_obj_is_type(args[0], &ps2io_ps2_type)); ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(args[0]); @@ -127,7 +123,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ps2io_ps2___exit___obj, 4, 4, ps2io_p //| """Removes and returns the oldest received byte. When buffer //| is empty, raises an IndexError exception.""" //| ... -//| STATIC mp_obj_t ps2io_ps2_obj_popleft(mp_obj_t self_in) { ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -152,7 +147,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_popleft_obj, ps2io_ps2_obj_popleft); //| //| :param int byte: byte value of the command""" //| ... -//| STATIC mp_obj_t ps2io_ps2_obj_sendcmd(mp_obj_t self_in, mp_obj_t ob) { ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -194,7 +188,6 @@ MP_DEFINE_CONST_FUN_OBJ_2(ps2io_ps2_sendcmd_obj, ps2io_ps2_obj_sendcmd); //| //| 0x2000: device didn't send a response byte in time""" //| ... -//| STATIC mp_obj_t ps2io_ps2_obj_clear_errors(mp_obj_t self_in) { ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -204,7 +197,6 @@ STATIC mp_obj_t ps2io_ps2_obj_clear_errors(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_clear_errors_obj, ps2io_ps2_obj_clear_errors); //| def __bool__(self) -> bool: ... -//| //| def __len__(self) -> int: //| """Returns the number of received bytes in buffer, available //| to :py:func:`popleft()`.""" diff --git a/shared-bindings/ps2io/__init__.c b/shared-bindings/ps2io/__init__.c index 517816dbcf..6857744036 100644 --- a/shared-bindings/ps2io/__init__.c +++ b/shared-bindings/ps2io/__init__.c @@ -37,16 +37,13 @@ //| //| The `ps2io` module contains classes to provide PS/2 communication. //| - //| .. warning:: This module is not available in some SAMD21 builds. See the //| :ref:`module-support-matrix` for more info. //| - //| All classes change hardware state and should be deinitialized when they //| are no longer needed if the program continues after use. To do so, either //| call :py:meth:`!deinit` or use a context manager. See //| :ref:`lifetime-and-contextmanagers` for more info.""" -//| STATIC const mp_rom_map_elem_t ps2io_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ps2io) }, diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 1769f5c7a8..81edc48bfd 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -37,10 +37,12 @@ //| class PulseIn: //| """Measure a series of active and idle pulses. This is commonly used in infrared receivers -//| and low cost temperature sensors (DHT). The pulsed signal consists of timed active and -//| idle periods. Unlike PWM, there is no set duration for active and idle pairs.""" +//| and low cost temperature sensors (DHT). The pulsed signal consists of timed active and +//| idle periods. Unlike PWM, there is no set duration for active and idle pairs.""" //| -//| def __init__(self, pin: microcontroller.Pin, maxlen: int = 2, *, idle_state: bool = False) -> None: +//| def __init__( +//| self, pin: microcontroller.Pin, maxlen: int = 2, *, idle_state: bool = False +//| ) -> None: //| """Create a PulseIn object associated with the given pin. The object acts as //| a read-only sequence of pulse lengths with a given max length. When it is //| active, new pulse lengths are added to the end of the list. When there is @@ -75,7 +77,6 @@ //| # Resume with an 80 microsecond active pulse //| pulses.resume(80)""" //| ... -//| STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pin, ARG_maxlen, ARG_idle_state }; static const mp_arg_t allowed_args[] = { @@ -85,9 +86,10 @@ STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_arg }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); - pulseio_pulsein_obj_t *self = m_new_obj(pulseio_pulsein_obj_t); + // Make object long-lived to avoid moving between imports + pulseio_pulsein_obj_t *self = m_new_ll_obj(pulseio_pulsein_obj_t); self->base.type = &pulseio_pulsein_type; common_hal_pulseio_pulsein_construct(self, pin, args[ARG_maxlen].u_int, @@ -99,7 +101,6 @@ STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_arg //| def deinit(self) -> None: //| """Deinitialises the PulseIn and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t pulseio_pulsein_deinit(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_pulseio_pulsein_deinit(self); @@ -116,14 +117,12 @@ STATIC void check_for_deinit(pulseio_pulsein_obj_t *self) { //| def __enter__(self) -> PulseIn: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t pulseio_pulsein_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_pulseio_pulsein_deinit(args[0]); @@ -134,7 +133,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulsein___exit___obj, 4, 4, p //| def pause(self) -> None: //| """Pause pulse capture""" //| ... -//| STATIC mp_obj_t pulseio_pulsein_obj_pause(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -154,7 +152,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_pause_obj, pulseio_pulsein_obj_pause); //| //| :param int trigger_duration: trigger pulse duration in microseconds""" //| ... -//| STATIC mp_obj_t pulseio_pulsein_obj_resume(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_trigger_duration }; static const mp_arg_t allowed_args[] = { @@ -174,7 +171,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pulseio_pulsein_resume_obj, 1, pulseio_pulsein_obj_re //| def clear(self) -> None: //| """Clears all captured pulses""" //| ... -//| STATIC mp_obj_t pulseio_pulsein_obj_clear(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -187,7 +183,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_clear_obj, pulseio_pulsein_obj_clear); //| def popleft(self) -> int: //| """Removes and returns the oldest read pulse.""" //| ... -//| STATIC mp_obj_t pulseio_pulsein_obj_popleft(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -199,7 +194,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_popleft_obj, pulseio_pulsein_obj_pople //| maxlen: int //| """The maximum length of the PulseIn. When len() is equal to maxlen, //| it is unclear which pulses are active and which are idle.""" -//| STATIC mp_obj_t pulseio_pulsein_obj_get_maxlen(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -214,7 +208,6 @@ MP_PROPERTY_GETTER(pulseio_pulsein_maxlen_obj, //| paused: bool //| """True when pulse capture is paused as a result of :py:func:`pause` or an error during capture //| such as a signal that is too fast.""" -//| STATIC mp_obj_t pulseio_pulsein_obj_get_paused(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -227,7 +220,6 @@ MP_PROPERTY_GETTER(pulseio_pulsein_paused_obj, (mp_obj_t)&pulseio_pulsein_get_paused_obj); //| def __bool__(self) -> bool: ... -//| //| def __len__(self) -> int: //| """Returns the number of pulse durations currently stored. //| @@ -236,7 +228,6 @@ MP_PROPERTY_GETTER(pulseio_pulsein_paused_obj, //| pulses = pulseio.PulseIn(pin) //| print(len(pulses))""" //| ... -//| STATIC mp_obj_t pulsein_unary_op(mp_unary_op_t op, mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c index 3de2176ffc..2af07a46d8 100644 --- a/shared-bindings/pulseio/PulseOut.c +++ b/shared-bindings/pulseio/PulseOut.c @@ -38,19 +38,18 @@ //| class PulseOut: //| """Pulse PWM "carrier" output on and off. This is commonly used in infrared remotes. The -//| pulsed signal consists of timed on and off periods. Unlike PWM, there is no set duration -//| for on and off pairs.""" +//| pulsed signal consists of timed on and off periods. Unlike PWM, there is no set duration +//| for on and off pairs.""" //| -//| def __init__(self, pin: microcontroller.Pin, *, frequency: int = 38000, duty_cycle: int = 1 << 15) -> None: +//| def __init__( +//| self, pin: microcontroller.Pin, *, frequency: int = 38000, duty_cycle: int = 1 << 15 +//| ) -> None: //| """Create a PulseOut object associated with the given pin. //| //| :param ~microcontroller.Pin pin: Signal output pin //| :param int frequency: Carrier signal frequency in Hertz //| :param int duty_cycle: 16-bit duty cycle of carrier frequency (0 - 65536) //| -//| For backwards compatibility, ``pin`` may be a PWMOut object used as the carrier. This -//| compatibility will be removed in CircuitPython 8.0.0. -//| //| Send a short series of pulses:: //| //| import array @@ -68,7 +67,6 @@ //| pulses[0] = 200 //| pulse.send(pulses)""" //| ... -//| STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pin, ARG_frequency, ARG_duty_cycle}; static const mp_arg_t allowed_args[] = { @@ -79,18 +77,10 @@ STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_ar mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *pin = args[ARG_pin].u_obj; + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); mp_int_t frequency = args[ARG_frequency].u_int; mp_int_t duty_cycle = args[ARG_duty_cycle].u_int; - if (mp_obj_is_type(args[ARG_pin].u_obj, &pwmio_pwmout_type)) { - pwmio_pwmout_obj_t *pwmout = args[ARG_pin].u_obj; - duty_cycle = common_hal_pwmio_pwmout_get_duty_cycle(pwmout); - frequency = common_hal_pwmio_pwmout_get_frequency(pwmout); - pin = common_hal_pwmio_pwmout_get_pin(pwmout); - // Deinit the pin so we can use it. - common_hal_pwmio_pwmout_deinit(pwmout); - } - validate_obj_is_free_pin(MP_OBJ_FROM_PTR(pin)); + pulseio_pulseout_obj_t *self = m_new_obj(pulseio_pulseout_obj_t); self->base.type = &pulseio_pulseout_type; common_hal_pulseio_pulseout_construct(self, pin, frequency, duty_cycle); @@ -100,7 +90,6 @@ STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the PulseOut and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t pulseio_pulseout_deinit(mp_obj_t self_in) { pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_pulseio_pulseout_deinit(self); @@ -111,14 +100,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulseout_deinit_obj, pulseio_pulseout_d //| def __enter__(self) -> PulseOut: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t pulseio_pulseout_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_pulseio_pulseout_deinit(args[0]); diff --git a/shared-bindings/pulseio/__init__.c b/shared-bindings/pulseio/__init__.c index 0dba6ffad6..c062cedd11 100644 --- a/shared-bindings/pulseio/__init__.c +++ b/shared-bindings/pulseio/__init__.c @@ -44,7 +44,6 @@ //| are no longer needed if the program continues after use. To do so, either //| call :py:meth:`!deinit` or use a context manager. See //| :ref:`lifetime-and-contextmanagers` for more info.""" -//| STATIC const mp_rom_map_elem_t pulseio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pulseio) }, diff --git a/shared-bindings/pwmio/PWMOut.c b/shared-bindings/pwmio/PWMOut.c index 4acb2a6a8a..24c0097c0c 100644 --- a/shared-bindings/pwmio/PWMOut.c +++ b/shared-bindings/pwmio/PWMOut.c @@ -69,9 +69,36 @@ void common_hal_pwmio_pwmout_raise_error(pwmout_result_t result) { } //| class PWMOut: -//| """Output a Pulse Width Modulated signal on a given pin.""" +//| """Output a Pulse Width Modulated signal on a given pin. //| -//| def __init__(self, pin: microcontroller.Pin, *, duty_cycle: int = 0, frequency: int = 500, variable_frequency: bool = False) -> None: +//| .. note:: The exact frequencies possible depend on the specific microcontroller. +//| If the requested frequency is within the available range, one of the two +//| nearest possible frequencies to the requested one is selected. +//| +//| If the requested frequency is outside the range, either (A) a ValueError +//| may be raised or (B) the highest or lowest frequency is selected. This +//| behavior is microcontroller-dependent, and may depend on whether it's the +//| upper or lower bound that is exceeded. +//| +//| In any case, the actual frequency (rounded to 1Hz) is available in the +//| ``frequency`` property after construction. +//| +//| .. note:: The frequency is calculated based on a nominal CPU frequency. +//| However, depending on the board, the error between the nominal and +//| actual CPU frequency can be large (several hundred PPM in the case of +//| crystal oscillators and up to ten percent in the case of RC +//| oscillators) +//| +//| """ +//| +//| def __init__( +//| self, +//| pin: microcontroller.Pin, +//| *, +//| duty_cycle: int = 0, +//| frequency: int = 500, +//| variable_frequency: bool = False +//| ) -> None: //| """Create a PWM object associated with the given pin. This allows you to //| write PWM signals out on the given pin. Frequency is fixed after init //| unless ``variable_frequency`` is True. @@ -127,9 +154,10 @@ void common_hal_pwmio_pwmout_raise_error(pwmout_result_t result) { //| pwm = pwmio.PWMOut(board.D13, duty_cycle=2 ** 15, frequency=440, variable_frequency=True) //| time.sleep(0.2) //| pwm.frequency = 880 -//| time.sleep(0.1)""" -//| ... +//| time.sleep(0.1) //| +//| """ +//| ... STATIC mp_obj_t pwmio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { enum { ARG_pin, ARG_duty_cycle, ARG_frequency, ARG_variable_frequency }; static const mp_arg_t allowed_args[] = { @@ -141,7 +169,7 @@ STATIC mp_obj_t pwmio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args); - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(parsed_args[ARG_pin].u_obj); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(parsed_args[ARG_pin].u_obj, MP_QSTR_pin); uint16_t duty_cycle = parsed_args[ARG_duty_cycle].u_int; uint32_t frequency = parsed_args[ARG_frequency].u_int; @@ -159,7 +187,6 @@ STATIC mp_obj_t pwmio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, //| def deinit(self) -> None: //| """Deinitialises the PWMOut and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t pwmio_pwmout_deinit(mp_obj_t self_in) { pwmio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_pwmio_pwmout_deinit(self); @@ -176,14 +203,12 @@ STATIC void check_for_deinit(pwmio_pwmout_obj_t *self) { //| def __enter__(self) -> PWMOut: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t pwmio_pwmout_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_pwmio_pwmout_deinit(args[0]); @@ -200,7 +225,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pwmio_pwmout___exit___obj, 4, 4, pwmi //| representation for duty cycle might have less than 16 bits of resolution. //| Reading this property will return the value from the internal representation, //| so it may differ from the value set.""" -//| STATIC mp_obj_t pwmio_pwmout_obj_get_duty_cycle(mp_obj_t self_in) { pwmio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -232,7 +256,8 @@ MP_PROPERTY_GETSET(pwmio_pwmout_duty_cycle_obj, //| for the PWM's duty cycle may need to be recalculated when the frequency //| changes. In these cases, the duty cycle is automatically recalculated //| from the original duty cycle value. This should happen without any need -//| to manually re-set the duty cycle.""" +//| to manually re-set the duty cycle. However, an output glitch may occur during the adjustment. +//| """ //| STATIC mp_obj_t pwmio_pwmout_obj_get_frequency(mp_obj_t self_in) { pwmio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/pwmio/__init__.c b/shared-bindings/pwmio/__init__.c index 90aff45819..6aeaf9c3c8 100644 --- a/shared-bindings/pwmio/__init__.c +++ b/shared-bindings/pwmio/__init__.c @@ -37,7 +37,6 @@ //| //| The `pwmio` module contains classes to provide access to basic pulse IO. //| - //| All classes change hardware state and should be deinitialized when they //| are no longer needed if the program continues after use. To do so, either //| call :py:meth:`!deinit` or use a context manager. See @@ -62,7 +61,6 @@ //| For the essentials of `pwmio`, see the `CircuitPython Essentials //| Learn guide `_. //| """ -//| STATIC const mp_rom_map_elem_t pwmio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pwmio) }, diff --git a/shared-bindings/qrio/PixelPolicy.c b/shared-bindings/qrio/PixelPolicy.c index 6887081b24..deb164d02d 100644 --- a/shared-bindings/qrio/PixelPolicy.c +++ b/shared-bindings/qrio/PixelPolicy.c @@ -34,18 +34,28 @@ //| """The input buffer to `QRDecoder.decode` consists of greyscale values in every byte""" //| //| EVEN_BYTES: PixelPolicy -//| """The input buffer to `QRDecoder.decode` consists of greyscale values in positions 0, 2, …, and ignored bytes in positions 1, 3, …. This can decode directly from YUV images where the even bytes hold the Y (luminance) data.""" +//| """The input buffer to `QRDecoder.decode` consists of greyscale values in positions 0, 2, …, and ignored bytes in positions 1, 3, …. This can decode directly from YUV images where the even bytes hold the Y (luminance) data.""" //| //| ODD_BYTES: PixelPolicy -//| """The input buffer to `QRDecoder.decode` consists of greyscale values in positions 1, 3, …, and ignored bytes in positions 0, 2, …. This can decode directly from YUV images where the odd bytes hold the Y (luminance) data""" +//| """The input buffer to `QRDecoder.decode` consists of greyscale values in positions 1, 3, …, and ignored bytes in positions 0, 2, …. This can decode directly from YUV images where the odd bytes hold the Y (luminance) data""" +//| +//| RGB565_SWAPPED: PixelPolicy +//| """The input buffer to `QRDecoder.decode` consists of RGB565 values in byte-swapped order. Most cameras produce data in byte-swapped order. The green component is used.""" +//| +//| RGB565: PixelPolicy +//| """The input buffer to `QRDecoder.decode` consists of RGB565 values in native order. The green component is used.""" //| MAKE_ENUM_VALUE(qrio_pixel_policy_type, qrio_pixel_policy, EVERY_BYTE, QRIO_EVERY_BYTE); +MAKE_ENUM_VALUE(qrio_pixel_policy_type, qrio_pixel_policy, RGB565, QRIO_RGB565); +MAKE_ENUM_VALUE(qrio_pixel_policy_type, qrio_pixel_policy, RGB565_SWAPPED, QRIO_RGB565_SWAPPED); MAKE_ENUM_VALUE(qrio_pixel_policy_type, qrio_pixel_policy, EVEN_BYTES, QRIO_EVEN_BYTES); MAKE_ENUM_VALUE(qrio_pixel_policy_type, qrio_pixel_policy, ODD_BYTES, QRIO_EVEN_BYTES); MAKE_ENUM_MAP(qrio_pixel_policy) { MAKE_ENUM_MAP_ENTRY(qrio_pixel_policy, EVERY_BYTE), + MAKE_ENUM_MAP_ENTRY(qrio_pixel_policy, RGB565), + MAKE_ENUM_MAP_ENTRY(qrio_pixel_policy, RGB565_SWAPPED), MAKE_ENUM_MAP_ENTRY(qrio_pixel_policy, EVEN_BYTES), MAKE_ENUM_MAP_ENTRY(qrio_pixel_policy, ODD_BYTES), }; diff --git a/shared-bindings/qrio/PixelPolicy.h b/shared-bindings/qrio/PixelPolicy.h index 8be5dde1cc..36c1d271fd 100644 --- a/shared-bindings/qrio/PixelPolicy.h +++ b/shared-bindings/qrio/PixelPolicy.h @@ -33,7 +33,7 @@ extern const mp_obj_type_t qrio_pixel_policy_type; typedef enum { - QRIO_EVERY_BYTE, QRIO_EVEN_BYTES, QRIO_ODD_BYTES + QRIO_EVERY_BYTE, QRIO_EVEN_BYTES, QRIO_ODD_BYTES, QRIO_RGB565, QRIO_RGB565_SWAPPED } qrio_pixel_policy_t; extern const cp_enum_obj_t qrio_pixel_policy_EVERY_BYTE_obj; diff --git a/shared-bindings/qrio/QRDecoder.c b/shared-bindings/qrio/QRDecoder.c index d2d4785ed8..b37a14fd8f 100644 --- a/shared-bindings/qrio/QRDecoder.c +++ b/shared-bindings/qrio/QRDecoder.c @@ -33,7 +33,6 @@ #include "py/enum.h" //| class QRDecoder: -//| //| def __init__(self, width: int, height: int) -> None: //| """Construct a QRDecoder object //| @@ -58,9 +57,10 @@ STATIC mp_obj_t qrio_qrdecoder_make_new(const mp_obj_type_t *type, size_t n_args return self; } -//| def decode(self, buffer: ReadableBuffer, pixel_policy: PixelPolicy = PixelPolicy.EVERY_BYTE) -> List[QRInfo]: +//| def decode( +//| self, buffer: ReadableBuffer, pixel_policy: PixelPolicy = PixelPolicy.EVERY_BYTE +//| ) -> List[QRInfo]: //| """Decode zero or more QR codes from the given image. The size of the buffer must be at least ``length``×``width`` bytes for `EVERY_BYTE`, and 2×``length``×``width`` bytes for `EVEN_BYTES` or `ODD_BYTES`.""" -//| STATIC mp_obj_t qrio_qrdecoder_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { qrio_qrdecoder_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -80,7 +80,7 @@ STATIC mp_obj_t qrio_qrdecoder_decode(size_t n_args, const mp_obj_t *pos_args, m // verify that the buffer is big enough int sz = width * height; - qrio_pixel_policy_t policy = cp_enum_value(&qrio_pixel_policy_type, args[ARG_pixel_policy].u_obj); + qrio_pixel_policy_t policy = cp_enum_value(&qrio_pixel_policy_type, args[ARG_pixel_policy].u_obj, MP_QSTR_pixel_policy); if (policy != QRIO_EVERY_BYTE) { sz *= 2; } @@ -92,7 +92,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(qrio_qrdecoder_decode_obj, 1, qrio_qrdecoder_decode); //| width: int //| """The width of image the decoder expects""" -//| STATIC mp_obj_t qrio_qrdecoder_get_width(mp_obj_t self_in) { qrio_qrdecoder_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(shared_module_qrio_qrdecoder_get_width(self)); diff --git a/shared-bindings/qrio/QRInfo.c b/shared-bindings/qrio/QRInfo.c index 8eb03874ef..d53e638f81 100644 --- a/shared-bindings/qrio/QRInfo.c +++ b/shared-bindings/qrio/QRInfo.c @@ -37,6 +37,7 @@ //| //| data_type: Union[str, int] //| """The encoding of the payload as a string (if a standard encoding) or int (if not standard)""" +//| const mp_obj_namedtuple_type_t qrio_qrinfo_type_obj = { .base = { diff --git a/shared-bindings/qrio/__init__.c b/shared-bindings/qrio/__init__.c index 04c86fd1ee..18c74b9a88 100644 --- a/shared-bindings/qrio/__init__.c +++ b/shared-bindings/qrio/__init__.c @@ -40,7 +40,6 @@ //| .. note:: This module only handles decoding QR codes. If you are looking //| to generate a QR code, use the //| `adafruit_miniqr library `_""" -//| STATIC const mp_rom_map_elem_t qrio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_qrio) }, diff --git a/shared-bindings/rainbowio/__init__.c b/shared-bindings/rainbowio/__init__.c index 0dfdcd3a45..324f43198e 100644 --- a/shared-bindings/rainbowio/__init__.c +++ b/shared-bindings/rainbowio/__init__.c @@ -33,7 +33,8 @@ //| //| def colorwheel(n: float) -> int: //| """C implementation of the common colorwheel() function found in many examples. -//| Returns the colorwheel RGB value as an integer value for n (usable in neopixel and dotstar).""" +//| Returns the colorwheel RGB value as an integer value for n (usable in neopixel and dotstar). +//| """ //| ... //| STATIC mp_obj_t rainbowio_colorwheel(mp_obj_t n) { diff --git a/shared-bindings/random/__init__.c b/shared-bindings/random/__init__.c index eee574d29e..33cd9e90d0 100644 --- a/shared-bindings/random/__init__.c +++ b/shared-bindings/random/__init__.c @@ -45,7 +45,8 @@ //| bytes from `os.urandom` directly for true randomness.""" //| //| from typing import TypeVar -//| _T = TypeVar('_T') +//| +//| _T = TypeVar("_T") //| //| def seed(seed: int) -> None: @@ -108,7 +109,7 @@ STATIC mp_obj_t random_randrange(size_t n_args, const mp_obj_t *args) { } else if (step < 0) { n = (stop - start + step + 1) / step; } else { - mp_raise_ValueError(translate("step must be non-zero")); + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q step cannot be zero"), MP_QSTR_randrange); } if (n <= 0) { mp_raise_ValueError(translate("invalid step")); diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c index fc9f438766..f2877531bb 100644 --- a/shared-bindings/rgbmatrix/RGBMatrix.c +++ b/shared-bindings/rgbmatrix/RGBMatrix.c @@ -44,8 +44,8 @@ extern Protomatter_core *_PM_protoPtr; -STATIC uint8_t validate_pin(mp_obj_t obj) { - const mcu_pin_obj_t *result = validate_obj_is_free_pin(obj); +STATIC uint8_t validate_pin(mp_obj_t obj, qstr arg_name) { + const mcu_pin_obj_t *result = validate_obj_is_free_pin(obj, arg_name); return common_hal_mcu_pin_number(result); } @@ -132,15 +132,22 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ } } -//| def __init__(self, *, width: int, bit_depth: int, -//| rgb_pins: Sequence[digitalio.DigitalInOut], -//| addr_pins: Sequence[digitalio.DigitalInOut], -//| clock_pin: digitalio.DigitalInOut, -//| latch_pin: digitalio.DigitalInOut, -//| output_enable_pin: digitalio.DigitalInOut, -//| doublebuffer: bool = True, -//| framebuffer: Optional[WriteableBuffer] = None, -//| height: int = 0, tile: int = 1, serpentine: bool = True) -> None: +//| def __init__( +//| self, +//| *, +//| width: int, +//| bit_depth: int, +//| rgb_pins: Sequence[digitalio.DigitalInOut], +//| addr_pins: Sequence[digitalio.DigitalInOut], +//| clock_pin: digitalio.DigitalInOut, +//| latch_pin: digitalio.DigitalInOut, +//| output_enable_pin: digitalio.DigitalInOut, +//| doublebuffer: bool = True, +//| framebuffer: Optional[WriteableBuffer] = None, +//| height: int = 0, +//| tile: int = 1, +//| serpentine: bool = True +//| ) -> None: //| """Create a RGBMatrix object with the given attributes. The height of //| the display is determined by the number of rgb and address pins and the number of tiles: //| ``len(rgb_pins) // 3 * 2 ** len(address_pins) * abs(tile)``. With 6 RGB pins, 4 @@ -176,7 +183,6 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ //| //| A RGBMatrix is often used in conjunction with a //| `framebufferio.FramebufferDisplay`.""" -//| STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_width, ARG_bit_depth, ARG_rgb_list, ARG_addr_list, @@ -204,9 +210,9 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n uint8_t rgb_count, addr_count; uint8_t rgb_pins[MP_ARRAY_SIZE(self->rgb_pins)]; uint8_t addr_pins[MP_ARRAY_SIZE(self->addr_pins)]; - uint8_t clock_pin = validate_pin(args[ARG_clock_pin].u_obj); - uint8_t latch_pin = validate_pin(args[ARG_latch_pin].u_obj); - uint8_t output_enable_pin = validate_pin(args[ARG_output_enable_pin].u_obj); + uint8_t clock_pin = validate_pin(args[ARG_clock_pin].u_obj, MP_QSTR_clock_pin); + uint8_t latch_pin = validate_pin(args[ARG_latch_pin].u_obj, MP_QSTR_latch_pin); + uint8_t output_enable_pin = validate_pin(args[ARG_output_enable_pin].u_obj, MP_QSTR_output_enable_pin); mp_int_t bit_depth = mp_arg_validate_int_range(args[ARG_bit_depth].u_int, 1, 6, MP_QSTR_bit_depth); validate_pins(MP_QSTR_rgb_pins, rgb_pins, MP_ARRAY_SIZE(self->rgb_pins), args[ARG_rgb_list].u_obj, &rgb_count); @@ -259,7 +265,6 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n //| rgbmatrix instance. After deinitialization, no further operations //| may be performed.""" //| ... -//| STATIC mp_obj_t rgbmatrix_rgbmatrix_deinit(mp_obj_t self_in) { rgbmatrix_rgbmatrix_obj_t *self = (rgbmatrix_rgbmatrix_obj_t *)self_in; common_hal_rgbmatrix_rgbmatrix_deinit(self); @@ -277,7 +282,6 @@ static void check_for_deinit(rgbmatrix_rgbmatrix_obj_t *self) { //| brightness: float //| """In the current implementation, 0.0 turns the display off entirely //| and any other value up to 1.0 turns the display on fully.""" -//| STATIC mp_obj_t rgbmatrix_rgbmatrix_get_brightness(mp_obj_t self_in) { rgbmatrix_rgbmatrix_obj_t *self = (rgbmatrix_rgbmatrix_obj_t *)self_in; check_for_deinit(self); @@ -306,7 +310,6 @@ MP_PROPERTY_GETSET(rgbmatrix_rgbmatrix_brightness_obj, //| """Transmits the color data in the buffer to the pixels so that //| they are shown.""" //| ... -//| STATIC mp_obj_t rgbmatrix_rgbmatrix_refresh(mp_obj_t self_in) { rgbmatrix_rgbmatrix_obj_t *self = (rgbmatrix_rgbmatrix_obj_t *)self_in; check_for_deinit(self); @@ -317,7 +320,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(rgbmatrix_rgbmatrix_refresh_obj, rgbmatrix_rgbmatrix_r //| width: int //| """The width of the display, in pixels""" -//| STATIC mp_obj_t rgbmatrix_rgbmatrix_get_width(mp_obj_t self_in) { rgbmatrix_rgbmatrix_obj_t *self = (rgbmatrix_rgbmatrix_obj_t *)self_in; check_for_deinit(self); diff --git a/shared-bindings/rgbmatrix/__init__.c b/shared-bindings/rgbmatrix/__init__.c index a7da7089f5..1e9099adb6 100644 --- a/shared-bindings/rgbmatrix/__init__.c +++ b/shared-bindings/rgbmatrix/__init__.c @@ -32,7 +32,6 @@ #include "shared-bindings/rgbmatrix/RGBMatrix.h" //| """Low-level routines for bitbanged LED matrices""" -//| STATIC const mp_rom_map_elem_t rgbmatrix_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_rgbmatrix) }, diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c index 0fe22be262..fae55db317 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.c +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -37,7 +37,9 @@ //| class IncrementalEncoder: //| """IncrementalEncoder determines the relative rotational position based on two series of pulses.""" //| -//| def __init__(self, pin_a: microcontroller.Pin, pin_b: microcontroller.Pin, divisor: int = 4) -> None: +//| def __init__( +//| self, pin_a: microcontroller.Pin, pin_b: microcontroller.Pin, divisor: int = 4 +//| ) -> None: //| """Create an IncrementalEncoder object associated with the given pins. It tracks the positional //| state of an incremental rotary encoder (also known as a quadrature encoder.) Position is //| relative to the position when the object is contructed. @@ -60,7 +62,6 @@ //| print(position) //| last_position = position""" //| ... -//| STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pin_a, ARG_pin_b, ARG_divisor }; static const mp_arg_t allowed_args[] = { @@ -71,10 +72,11 @@ STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *pin_a = validate_obj_is_free_pin(args[ARG_pin_a].u_obj); - const mcu_pin_obj_t *pin_b = validate_obj_is_free_pin(args[ARG_pin_b].u_obj); + const mcu_pin_obj_t *pin_a = validate_obj_is_free_pin(args[ARG_pin_a].u_obj, MP_QSTR_pin_a); + const mcu_pin_obj_t *pin_b = validate_obj_is_free_pin(args[ARG_pin_b].u_obj, MP_QSTR_pin_b); - rotaryio_incrementalencoder_obj_t *self = m_new_obj(rotaryio_incrementalencoder_obj_t); + // Make long-lived because some implementations use a pointer to the object as interrupt-handler data. + rotaryio_incrementalencoder_obj_t *self = m_new_ll_obj(rotaryio_incrementalencoder_obj_t); self->base.type = &rotaryio_incrementalencoder_type; common_hal_rotaryio_incrementalencoder_construct(self, pin_a, pin_b); @@ -86,7 +88,6 @@ STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, //| def deinit(self) -> None: //| """Deinitializes the IncrementalEncoder and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t rotaryio_incrementalencoder_deinit(mp_obj_t self_in) { rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_rotaryio_incrementalencoder_deinit(self); @@ -103,14 +104,12 @@ STATIC void check_for_deinit(rotaryio_incrementalencoder_obj_t *self) { //| def __enter__(self) -> IncrementalEncoder: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t rotaryio_incrementalencoder_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_rotaryio_incrementalencoder_deinit(args[0]); @@ -123,7 +122,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rotaryio_incrementalencoder___exit___ //| """The divisor of the quadrature signal. Use 1 for encoders without //| detents, or encoders with 4 detents per cycle. Use 2 for encoders with 2 //| detents per cycle. Use 4 for encoders with 1 detent per cycle.""" -//| STATIC mp_obj_t rotaryio_incrementalencoder_obj_get_divisor(mp_obj_t self_in) { rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/rotaryio/__init__.c b/shared-bindings/rotaryio/__init__.c index 43a884e9a1..e549ecc75e 100644 --- a/shared-bindings/rotaryio/__init__.c +++ b/shared-bindings/rotaryio/__init__.c @@ -39,11 +39,13 @@ //| `Wikipedia's Rotary Encoder page `_ for more //| background. //| +//| For more information on working with rotary encoders using this library, see +//| `this Learn Guide `_. +//| //| All classes change hardware state and should be deinitialized when they //| are no longer needed if the program continues after use. To do so, either //| call :py:meth:`!deinit` or use a context manager. See //| :ref:`lifetime-and-contextmanagers` for more info.""" -//| STATIC const mp_rom_map_elem_t rotaryio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_rotaryio) }, diff --git a/shared-bindings/rtc/RTC.c b/shared-bindings/rtc/RTC.c index 9e75576487..bf2b0915c4 100644 --- a/shared-bindings/rtc/RTC.c +++ b/shared-bindings/rtc/RTC.c @@ -44,7 +44,6 @@ const rtc_rtc_obj_t rtc_rtc_obj = {{&rtc_rtc_type}}; //| def __init__(self) -> None: //| """This class represents the onboard Real Time Clock. It is a singleton and will always return the same instance.""" //| ... -//| STATIC mp_obj_t rtc_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // No arguments mp_arg_check_num(n_args, n_kw, 0, 0, false); @@ -71,7 +70,6 @@ STATIC mp_obj_t rtc_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_ //| current_time = r.datetime //| print(current_time) //| # struct_time(tm_year=2019, tm_month=5, ...)""" -//| STATIC mp_obj_t rtc_rtc_obj_get_datetime(mp_obj_t self_in) { timeutils_struct_time_t tm; common_hal_rtc_get_time(&tm); @@ -95,6 +93,9 @@ MP_PROPERTY_GETSET(rtc_rtc_datetime_obj, //| """The RTC calibration value as an `int`. //| //| A positive value speeds up the clock and a negative value slows it down. +//| +//| **Limitations:** Calibration not supported on SAMD, nRF, RP240, Spresense, and STM. +//| //| Range and value is hardware specific, but one step is often approximately 1 ppm:: //| //| import rtc diff --git a/shared-bindings/sdcardio/SDCard.c b/shared-bindings/sdcardio/SDCard.c index 5afca798f6..ce67834774 100644 --- a/shared-bindings/sdcardio/SDCard.c +++ b/shared-bindings/sdcardio/SDCard.c @@ -44,7 +44,9 @@ //| `busio.SPI`, not `bitbangio.SPI`. Usually an SDCard object is used //| with ``storage.VfsFat`` to allow file I/O to an SD card.""" //| -//| def __init__(self, bus: busio.SPI, cs: microcontroller.Pin, baudrate: int = 8000000) -> None: +//| def __init__( +//| self, bus: busio.SPI, cs: microcontroller.Pin, baudrate: int = 8000000 +//| ) -> None: //| """Construct an SPI SD Card object with the given properties //| //| :param busio.SPI spi: The SPI bus @@ -87,8 +89,8 @@ STATIC mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi].u_obj); - const mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj); + busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi].u_obj, MP_QSTR_spi); + const mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj, MP_QSTR_cs); sdcardio_sdcard_obj_t *self = m_new_obj(sdcardio_sdcard_obj_t); self->base.type = &sdcardio_SDCard_type; @@ -105,7 +107,6 @@ STATIC mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_arg //| Due to technical limitations, this is a function and not a property. //| //| :return: The number of 512-byte blocks, as a number""" -//| STATIC mp_obj_t sdcardio_sdcard_count(mp_obj_t self_in) { sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; return mp_obj_new_int_from_ull(common_hal_sdcardio_sdcard_get_blockcount(self)); @@ -116,7 +117,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_count_obj, sdcardio_sdcard_count); //| """Disable permanently. //| //| :return: None""" -//| STATIC mp_obj_t sdcardio_sdcard_deinit(mp_obj_t self_in) { sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; common_hal_sdcardio_sdcard_deinit(self); @@ -126,14 +126,12 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_deinit_obj, sdcardio_sdcard_deinit); //| def readblocks(self, start_block: int, buf: WriteableBuffer) -> None: -//| //| """Read one or more blocks from the card //| //| :param int start_block: The block to start reading from //| :param ~circuitpython_typing.WriteableBuffer buf: The buffer to write into. Length must be multiple of 512. //| //| :return: None""" -//| STATIC mp_obj_t sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { uint32_t start_block = mp_obj_get_int(start_block_in); @@ -167,7 +165,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_sync_obj, sdcardio_sdcard_sync); //| def writeblocks(self, start_block: int, buf: ReadableBuffer) -> None: -//| //| """Write one or more blocks to the card //| //| :param int start_block: The block to start writing from diff --git a/shared-bindings/sdioio/SDCard.c b/shared-bindings/sdioio/SDCard.c index dbeb50ddf3..776b20fafe 100644 --- a/shared-bindings/sdioio/SDCard.c +++ b/shared-bindings/sdioio/SDCard.c @@ -49,7 +49,13 @@ //| 25MHz. Usually an SDCard object is used with ``storage.VfsFat`` //| to allow file I/O to an SD card.""" //| -//| def __init__(self, clock: microcontroller.Pin, command: microcontroller.Pin, data: Sequence[microcontroller.Pin], frequency: int) -> None: +//| def __init__( +//| self, +//| clock: microcontroller.Pin, +//| command: microcontroller.Pin, +//| data: Sequence[microcontroller.Pin], +//| frequency: int, +//| ) -> None: //| """Construct an SDIO SD Card object with the given properties //| //| :param ~microcontroller.Pin clock: the pin to use for the clock. @@ -76,7 +82,6 @@ //| storage.mount(vfs, '/sd') //| os.listdir('/sd')""" //| ... -//| STATIC mp_obj_t sdioio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { sdioio_sdcard_obj_t *self = m_new_obj(sdioio_sdcard_obj_t); @@ -93,8 +98,8 @@ STATIC mp_obj_t sdioio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj); - const mcu_pin_obj_t *command = validate_obj_is_free_pin(args[ARG_command].u_obj); + const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock); + const mcu_pin_obj_t *command = validate_obj_is_free_pin(args[ARG_command].u_obj, MP_QSTR_command); const mcu_pin_obj_t *data_pins[4]; uint8_t num_data; validate_list_is_free_pins(MP_QSTR_data, data_pins, MP_ARRAY_SIZE(data_pins), args[ARG_data].u_obj, &num_data); @@ -116,7 +121,6 @@ STATIC void check_for_deinit(sdioio_sdcard_obj_t *self) { //| :param int width: the number of data lines to use. Must be 1 or 4 and must also not exceed the number of data lines at construction //| //| .. note:: Leaving a value unspecified or 0 means the current setting is kept""" -//| STATIC mp_obj_t sdioio_sdcard_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_frequency, ARG_width, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -148,7 +152,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(sdioio_sdcard_configure_obj, 1, sdioio_sdcard_configu //| Due to technical limitations, this is a function and not a property. //| //| :return: The number of 512-byte blocks, as a number""" -//| STATIC mp_obj_t sdioio_sdcard_count(mp_obj_t self_in) { sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -157,7 +160,6 @@ STATIC mp_obj_t sdioio_sdcard_count(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_count_obj, sdioio_sdcard_count); //| def readblocks(self, start_block: int, buf: WriteableBuffer) -> None: -//| //| """Read one or more blocks from the card //| //| :param int start_block: The block to start reading from @@ -179,14 +181,12 @@ STATIC mp_obj_t sdioio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_ MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_readblocks_obj, sdioio_sdcard_readblocks); //| def writeblocks(self, start_block: int, buf: ReadableBuffer) -> None: -//| //| """Write one or more blocks to the card //| //| :param int start_block: The block to start writing from //| :param ~circuitpython_typing.ReadableBuffer buf: The buffer to read from. Length must be multiple of 512. //| //| :return: None""" -//| STATIC mp_obj_t sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { uint32_t start_block = mp_obj_get_int(start_block_in); mp_buffer_info_t bufinfo; @@ -201,12 +201,9 @@ STATIC mp_obj_t sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_writeblocks_obj, sdioio_sdcard_writeblocks); -//| @property -//| def frequency(self) -> int: -//| """The actual SDIO bus frequency. This may not match the frequency -//| requested due to internal limitations.""" -//| ... -//| +//| frequency: int +//| """The actual SDIO bus frequency. This may not match the frequency +//| requested due to internal limitations.""" STATIC mp_obj_t sdioio_sdcard_obj_get_frequency(mp_obj_t self_in) { sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -217,11 +214,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_get_frequency_obj, sdioio_sdcard_obj_get MP_PROPERTY_GETTER(sdioio_sdcard_frequency_obj, (mp_obj_t)&sdioio_sdcard_get_frequency_obj); -//| @property -//| def width(self) -> int: -//| """The actual SDIO bus width, in bits""" -//| ... -//| +//| width: int +//| """The actual SDIO bus width, in bits""" STATIC mp_obj_t sdioio_sdcard_obj_get_width(mp_obj_t self_in) { sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -247,7 +241,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_deinit_obj, sdioio_sdcard_obj_deinit); //| """No-op used by Context Managers. //| Provided by context manager helper.""" //| ... -//| //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See diff --git a/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c index 35e06b7838..d9643495ba 100644 --- a/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c +++ b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c @@ -33,27 +33,55 @@ #include "shared-module/displayio/__init__.h" #include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" +//| class SharpMemoryFramebuffer: +//| """A framebuffer for a memory-in-pixel display. Sharp makes monochrome displays and JDI used +//| to make 8-color displays. +//| +//| This initializes a display and connects it into CircuitPython. Unlike other +//| objects in CircuitPython, Display objects live until `displayio.release_displays()` +//| is called. This is done so that CircuitPython can use the display itself.""" +//| +//| def __init__( +//| self, +//| spi_bus: busio.SPI, +//| chip_select: microcontroller.Pin, +//| width: int, +//| height: int, +//| baudrate: int = 2000000, +//| jdi_display: bool = False, +//| ) -> None: +//| """Create a framebuffer for the memory-in-pixel display. +//| +//| :param busio.SPI spi_bus: The SPI bus that the display is connected to +//| :param microcontroller.Pin chip_select: The pin connect to the display's chip select line +//| :param int width: The width of the display in pixels +//| :param int height: The height of the display in pixels +//| :param int baudrate: The baudrate to communicate with the screen at +//| :param bool jdi_display: When True, work with an 8-color JDI display. Otherwise, a monochrome Sharp display. +//| """ +//| ... STATIC mp_obj_t sharpdisplay_framebuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - enum { ARG_spi_bus, ARG_chip_select, ARG_width, ARG_height, ARG_baudrate, NUM_ARGS }; + enum { ARG_spi_bus, ARG_chip_select, ARG_width, ARG_height, ARG_baudrate, ARG_jdi_display, NUM_ARGS }; static const mp_arg_t allowed_args[] = { { MP_QSTR_spi_bus, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} }, { MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} }, { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 2000000} }, + { MP_QSTR_jdi_display, MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; MP_STATIC_ASSERT(MP_ARRAY_SIZE(allowed_args) == NUM_ARGS); mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj); - busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi_bus].u_obj); + const mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj, MP_QSTR_chip_select); + busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi_bus].u_obj, MP_QSTR_spi_bus); sharpdisplay_framebuffer_obj_t *self = &allocate_display_bus_or_raise()->sharpdisplay; self->base.type = &sharpdisplay_framebuffer_type; - common_hal_sharpdisplay_framebuffer_construct(self, spi, chip_select, args[ARG_baudrate].u_int, args[ARG_width].u_int, args[ARG_height].u_int); + common_hal_sharpdisplay_framebuffer_construct(self, spi, chip_select, args[ARG_baudrate].u_int, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_jdi_display].u_bool); return MP_OBJ_FROM_PTR(self); } @@ -69,6 +97,12 @@ STATIC mp_int_t sharpdisplay_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer_ return 0; } +//| def deinit(self) -> None: +//| """Free the resources (pins, timers, etc.) associated with this +//| SharpMemoryFramebuffer instance. After deinitialization, no further operations +//| may be performed.""" +//| ... +//| STATIC mp_obj_t sharpdisplay_framebuffer_deinit(mp_obj_t self_in) { sharpdisplay_framebuffer_obj_t *self = (sharpdisplay_framebuffer_obj_t *)self_in; common_hal_sharpdisplay_framebuffer_deinit(self); diff --git a/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h index 30f1b867b1..b2c15ac499 100644 --- a/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h +++ b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h @@ -26,9 +26,18 @@ #pragma once -// #include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" -// #include "shared-module/framebufferio/FramebufferDisplay.h" - #include "py/objtype.h" +#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" + extern const mp_obj_type_t sharpdisplay_framebuffer_type; + +void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *chip_select, int baudrate, int width, int height, bool jdi_display); +void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask); +void common_hal_sharpdisplay_framebuffer_deinit(sharpdisplay_framebuffer_obj_t *self); +void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_obj_t *self, mp_buffer_info_t *bufinfo); +int common_hal_sharpdisplay_framebuffer_get_height(sharpdisplay_framebuffer_obj_t *self); +int common_hal_sharpdisplay_framebuffer_get_width(sharpdisplay_framebuffer_obj_t *self); +void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask); +void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *self); +void common_hal_sharpdisplay_framebuffer_reconstruct(sharpdisplay_framebuffer_obj_t *self); diff --git a/shared-bindings/sharpdisplay/__init__.c b/shared-bindings/sharpdisplay/__init__.c index a7e0bff77d..4726e6ea1c 100644 --- a/shared-bindings/sharpdisplay/__init__.c +++ b/shared-bindings/sharpdisplay/__init__.c @@ -36,7 +36,6 @@ //| For more information about working with Sharp Memory Displays, //| see `this Learn guide `_. //| """ -//| STATIC const mp_rom_map_elem_t sharpdisplay_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sharpdisplay) }, { MP_ROM_QSTR(MP_QSTR_SharpMemoryFramebuffer), MP_ROM_PTR(&sharpdisplay_framebuffer_type) }, diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index 716ff673ee..9d439b5bd4 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -30,39 +30,38 @@ #include #include -#include "shared/runtime/context_manager_helpers.h" -#include "py/objtuple.h" -#include "py/objlist.h" -#include "py/runtime.h" #include "py/mperrno.h" +#include "py/objlist.h" +#include "py/objtuple.h" +#include "py/runtime.h" +#include "py/stream.h" #include "shared/netutils/netutils.h" +#include "shared/runtime/context_manager_helpers.h" +#include "shared/runtime/interrupt_char.h" //| class Socket: //| """TCP, UDP and RAW socket. Cannot be created directly. Instead, call -//| `SocketPool.socket()`. +//| `SocketPool.socket()`. //| -//| Provides a subset of CPython's `socket.socket` API. It only implements the versions of -//| recv that do not allocate bytes objects.""" +//| Provides a subset of CPython's `socket.socket` API. It only implements the versions of +//| recv that do not allocate bytes objects.""" //| //| def __hash__(self) -> int: //| """Returns a hash for the Socket.""" //| ... -//| // Provided by mp_generic_unary_op(). //| def __enter__(self) -> Socket: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically closes the Socket when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t socketpool_socket___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_socketpool_socket_close(args[0]); @@ -74,7 +73,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4, //| """Accept a connection on a listening socket of type SOCK_STREAM, //| creating a new socket of type SOCK_STREAM. //| Returns a tuple of (new_socket, remote_address)""" -//| STATIC mp_obj_t _socketpool_socket_accept(mp_obj_t self_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); uint8_t ip[4]; @@ -94,7 +92,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, _socketpool_socke //| //| :param ~tuple address: tuple of (remote_address, remote_port)""" //| ... -//| STATIC mp_obj_t socketpool_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -119,7 +116,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_bind_obj, socketpool_socket_b //| def close(self) -> None: //| """Closes this Socket and makes its resources available to its SocketPool.""" -//| STATIC mp_obj_t _socketpool_socket_close(mp_obj_t self_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_socketpool_socket_close(self); @@ -132,7 +128,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, _socketpool_socket //| //| :param ~tuple address: tuple of (remote_address, remote_port)""" //| ... -//| STATIC mp_obj_t socketpool_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -157,7 +152,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_connect_obj, socketpool_socke //| //| :param ~int backlog: length of backlog queue for waiting connections""" //| ... -//| STATIC mp_obj_t socketpool_socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -177,14 +171,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_listen_obj, socketpool_socket //| //| :param object buffer: buffer to read into""" //| ... -//| STATIC mp_obj_t socketpool_socket_recvfrom_into(mp_obj_t self_in, mp_obj_t data_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t bufinfo; mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_WRITE); byte ip[4]; - mp_uint_t port; + uint32_t port; mp_int_t ret = common_hal_socketpool_socket_recvfrom_into(self, (byte *)bufinfo.buf, bufinfo.len, ip, &port); mp_obj_t tuple_contents[2]; @@ -207,7 +200,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_recvfrom_into_obj, socketpool //| :param bytearray buffer: buffer to receive into //| :param int bufsize: optionally, a maximum number of bytes to read.""" //| ... -//| STATIC mp_obj_t _socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (common_hal_socketpool_socket_get_closed(self)) { @@ -246,7 +238,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_recv_into_obj, 2, 3 //| //| :param ~bytes bytes: some bytes to send""" //| ... -//| STATIC mp_obj_t _socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (common_hal_socketpool_socket_get_closed(self)) { @@ -266,6 +257,46 @@ STATIC mp_obj_t _socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, _socketpool_socket_send); +//| def sendall(self, bytes: ReadableBuffer) -> None: +//| """Send some bytes to the connected remote address. +//| Suits sockets of type SOCK_STREAM +//| +//| This calls send() repeatedly until all the data is sent or an error +//| occurs. If an error occurs, it's impossible to tell how much data +//| has been sent. +//| +//| :param ~bytes bytes: some bytes to send""" +//| ... +STATIC mp_obj_t _socketpool_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) { + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (common_hal_socketpool_socket_get_closed(self)) { + // Bad file number. + mp_raise_OSError(MP_EBADF); + } + if (!common_hal_socketpool_socket_get_connected(self)) { + mp_raise_BrokenPipeError(); + } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); + while (bufinfo.len > 0) { + mp_int_t ret = common_hal_socketpool_socket_send(self, bufinfo.buf, bufinfo.len); + if (ret == -1) { + mp_raise_BrokenPipeError(); + } + bufinfo.len -= ret; + bufinfo.buf += ret; + if (bufinfo.len > 0) { + RUN_BACKGROUND_TASKS; + // Allow user to break out of sendall with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + return 0; + } + } + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_sendall_obj, _socketpool_socket_sendall); + //| def sendto(self, bytes: ReadableBuffer, address: Tuple[str, int]) -> int: //| """Send some bytes to a specific address. //| Suits sockets of type SOCK_DGRAM @@ -273,7 +304,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, _socketpool_socket_ //| :param ~bytes bytes: some bytes to send //| :param ~tuple address: tuple of (remote_address, remote_port)""" //| ... -//| STATIC mp_obj_t socketpool_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -302,7 +332,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(socketpool_socket_sendto_obj, socketpool_socket //| //| :param ~bool flag: False means non-blocking, True means block indefinitely.""" //| ... -//| // method socket.setblocking(flag) STATIC mp_obj_t socketpool_socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -315,44 +344,43 @@ STATIC mp_obj_t socketpool_socket_setblocking(mp_obj_t self_in, mp_obj_t blockin } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_setblocking_obj, socketpool_socket_setblocking); -// //| def setsockopt(self, level: int, optname: int, value: int) -> None: -// //| """Sets socket options""" -// //| ... -// //| -// STATIC mp_obj_t socketpool_socket_setsockopt(size_t n_args, const mp_obj_t *args) { -// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); +//| def setsockopt(self, level: int, optname: int, value: int) -> None: +//| """Sets socket options""" +//| ... +STATIC mp_obj_t socketpool_socket_setsockopt(size_t n_args, const mp_obj_t *args) { + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); + mp_int_t level = mp_obj_get_int(args[1]); + mp_int_t opt = mp_obj_get_int(args[2]); -// // mp_int_t level = mp_obj_get_int(args[1]); -// // mp_int_t opt = mp_obj_get_int(args[2]); + const void *optval; + mp_uint_t optlen; + mp_int_t val; + if (mp_obj_is_integer(args[3])) { + val = mp_obj_get_int_truncated(args[3]); + optval = &val; + optlen = sizeof(val); + } else { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); + optval = bufinfo.buf; + optlen = bufinfo.len; + } -// // const void *optval; -// // mp_uint_t optlen; -// // mp_int_t val; -// // if (mp_obj_is_integer(args[3])) { -// // val = mp_obj_get_int_truncated(args[3]); -// // optval = &val; -// // optlen = sizeof(val); -// // } else { -// // mp_buffer_info_t bufinfo; -// // mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); -// // optval = bufinfo.buf; -// // optlen = bufinfo.len; -// // } + int _errno = common_hal_socketpool_socket_setsockopt(self, level, opt, optval, optlen); + if (_errno < 0) { + mp_raise_OSError(-_errno); + } -// // int _errno; -// // if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) { -// // mp_raise_OSError(_errno); -// // } - -// return mp_const_none; -// } -// STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, 4, socketpool_socket_setsockopt); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, 4, socketpool_socket_setsockopt); //| def settimeout(self, value: int) -> None: //| """Set the timeout value for this socket. //| -//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely.""" +//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely. +//| """ //| ... //| STATIC mp_obj_t socketpool_socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { @@ -385,14 +413,40 @@ STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_recvfrom_into), MP_ROM_PTR(&socketpool_socket_recvfrom_into_obj) }, { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socketpool_socket_recv_into_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socketpool_socket_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_sendall), MP_ROM_PTR(&socketpool_socket_sendall_obj) }, { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socketpool_socket_sendto_obj) }, { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socketpool_socket_setblocking_obj) }, - // { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socketpool_socket_setsockopt_obj) }, + { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socketpool_socket_setsockopt_obj) }, { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socketpool_socket_settimeout_obj) }, }; STATIC MP_DEFINE_CONST_DICT(socketpool_socket_locals_dict, socketpool_socket_locals_dict_table); +STATIC mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + if (request == MP_STREAM_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_STREAM_POLL_RD) && common_hal_socketpool_readable(self) > 0) { + ret |= MP_STREAM_POLL_RD; + } + if ((flags & MP_STREAM_POLL_WR) && common_hal_socketpool_writable(self)) { + ret |= MP_STREAM_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +STATIC const mp_stream_p_t socket_stream_p = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) + .ioctl = socket_ioctl, + .is_text = false, +}; + const mp_obj_type_t socketpool_socket_type = { { &mp_type_type }, .flags = MP_TYPE_FLAG_EXTENDED, @@ -400,5 +454,6 @@ const mp_obj_type_t socketpool_socket_type = { .locals_dict = (mp_obj_dict_t *)&socketpool_socket_locals_dict, MP_TYPE_EXTENDED_FIELDS( .unary_op = mp_generic_unary_op, + .protocol = &socket_stream_p, ) }; diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index c6c2a66630..690c9f8363 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -46,12 +46,22 @@ mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t *self, const mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t *self, const char *host, size_t hostlen, uint32_t port, const uint8_t *buf, uint32_t len); void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint32_t timeout_ms); +int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen); +bool common_hal_socketpool_readable(socketpool_socket_obj_t *self); +bool common_hal_socketpool_writable(socketpool_socket_obj_t *self); // Non-allocating versions for internal use. -int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port); +int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port, socketpool_socket_obj_t *accepted); void socketpool_socket_close(socketpool_socket_obj_t *self); int socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len); int socketpool_socket_recv_into(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len); +// Moves self to sock without closing the real socket. self will think its closed afterwards. +void socketpool_socket_move(socketpool_socket_obj_t *self, socketpool_socket_obj_t *sock); + +// Resets the socket object state so it appears closed and disconnected. This only works on +// uninitialized memory. +void socketpool_socket_reset(socketpool_socket_obj_t *self); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c index 447d2d7d78..3023721378 100644 --- a/shared-bindings/socketpool/SocketPool.c +++ b/shared-bindings/socketpool/SocketPool.c @@ -38,12 +38,21 @@ //| class SocketPool: //| """A pool of socket resources available for the given radio. Only one -//| SocketPool can be created for each radio. +//| SocketPool can be created for each radio. //| -//| SocketPool should be used in place of CPython's socket which provides -//| a pool of sockets provided by the underlying OS.""" +//| SocketPool should be used in place of CPython's socket which provides +//| a pool of sockets provided by the underlying OS. +//| """ +//| +//| def __init__(self, radio: wifi.Radio) -> None: +//| """Create a new SocketPool object for the provided radio +//| +//| :param wifi.Radio radio: The (connected) network hardware to associate +//| with this SocketPool; currently, this will always be the object +//| returned by :py:attr:`wifi.radio` +//| """ +//| ... //| - STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); @@ -56,12 +65,23 @@ STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t return MP_OBJ_FROM_PTR(s); } +//| class gaierror(OSError): +//| """Errors raised by getaddrinfo""" +//| +MP_DEFINE_EXCEPTION(gaierror, OSError) + +//| //| AF_INET: int //| AF_INET6: int +//| //| SOCK_STREAM: int //| SOCK_DGRAM: int //| SOCK_RAW: int +//| EAI_NONAME: int //| +//| TCP_NODELAY: int +//| +//| IPPROTO_TCP: int //| def socket(self, family: int = AF_INET, type: int = SOCK_STREAM) -> socketpool.Socket: //| """Create a new socket //| @@ -72,7 +92,6 @@ STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t //| in CPython are not supported. //| """ //| ... -//| STATIC mp_obj_t socketpool_socketpool_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_family, ARG_type }; static const mp_arg_t allowed_args[] = { @@ -91,7 +110,15 @@ STATIC mp_obj_t socketpool_socketpool_socket(size_t n_args, const mp_obj_t *pos_ } MP_DEFINE_CONST_FUN_OBJ_KW(socketpool_socketpool_socket_obj, 1, socketpool_socketpool_socket); -//| def getaddrinfo(self, host: str, port: int, family: int = 0, type: int = 0, proto: int = 0, flags: int = 0) -> Tuple[int, int, int, str, Tuple[str, int]]: +//| def getaddrinfo( +//| self, +//| host: str, +//| port: int, +//| family: int = 0, +//| type: int = 0, +//| proto: int = 0, +//| flags: int = 0, +//| ) -> Tuple[int, int, int, str, Tuple[str, int]]: //| """Gets the address information for a hostname and port //| //| Returns the appropriate family, socket type, socket protocol and @@ -123,11 +150,7 @@ STATIC mp_obj_t socketpool_socketpool_getaddrinfo(size_t n_args, const mp_obj_t } if (ip_str == mp_const_none) { - ip_str = common_hal_socketpool_socketpool_gethostbyname(self, host); - } - - if (ip_str == mp_const_none) { - mp_raise_OSError(-2); // socket.EAI_NONAME from CPython + ip_str = common_hal_socketpool_socketpool_gethostbyname_raise(self, host); } mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL)); @@ -146,6 +169,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(socketpool_socketpool_getaddrinfo_obj, 1, sock STATIC const mp_rom_map_elem_t socketpool_socketpool_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socketpool_socketpool_socket_obj) }, { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&socketpool_socketpool_getaddrinfo_obj) }, + { MP_ROM_QSTR(MP_QSTR_gaierror), MP_ROM_PTR(&mp_type_gaierror) }, // class constants { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(SOCKETPOOL_AF_INET) }, @@ -154,6 +178,12 @@ STATIC const mp_rom_map_elem_t socketpool_socketpool_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(SOCKETPOOL_SOCK_STREAM) }, { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(SOCKETPOOL_SOCK_DGRAM) }, { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(SOCKETPOOL_SOCK_RAW) }, + + { MP_ROM_QSTR(MP_QSTR_TCP_NODELAY), MP_ROM_INT(SOCKETPOOL_TCP_NODELAY) }, + + { MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(SOCKETPOOL_IPPROTO_TCP) }, + + { MP_ROM_QSTR(MP_QSTR_EAI_NONAME), MP_ROM_INT(SOCKETPOOL_EAI_NONAME) }, }; STATIC MP_DEFINE_CONST_DICT(socketpool_socketpool_locals_dict, socketpool_socketpool_locals_dict_table); @@ -164,3 +194,26 @@ const mp_obj_type_t socketpool_socketpool_type = { .make_new = socketpool_socketpool_make_new, .locals_dict = (mp_obj_dict_t *)&socketpool_socketpool_locals_dict, }; + +MP_WEAK +mp_obj_t common_hal_socketpool_socketpool_gethostbyname_raise(socketpool_socketpool_obj_t *self, const char *host) { + mp_obj_t ip_str = common_hal_socketpool_socketpool_gethostbyname(self, host); + if (ip_str == mp_const_none) { + common_hal_socketpool_socketpool_raise_gaierror_noname(); + } + return ip_str; +} + +MP_WEAK NORETURN +void common_hal_socketpool_socketpool_raise_gaierror_noname(void) { + vstr_t vstr; + mp_print_t print; + vstr_init_print(&vstr, 64, &print); + mp_printf(&print, "%S", translate("Name or service not known")); + + mp_obj_t exc_args[] = { + MP_OBJ_NEW_SMALL_INT(SOCKETPOOL_EAI_NONAME), + mp_obj_new_str_from_vstr(&mp_type_str, &vstr), + }; + nlr_raise(mp_obj_new_exception_args(&mp_type_gaierror, MP_ARRAY_SIZE(exc_args), exc_args)); +} diff --git a/shared-bindings/socketpool/SocketPool.h b/shared-bindings/socketpool/SocketPool.h index 92382078e1..6409f8c763 100644 --- a/shared-bindings/socketpool/SocketPool.h +++ b/shared-bindings/socketpool/SocketPool.h @@ -34,16 +34,28 @@ extern const mp_obj_type_t socketpool_socketpool_type; typedef enum { - SOCKETPOOL_SOCK_STREAM, - SOCKETPOOL_SOCK_DGRAM, - SOCKETPOOL_SOCK_RAW + SOCKETPOOL_SOCK_STREAM = 1, + SOCKETPOOL_SOCK_DGRAM = 2, + SOCKETPOOL_SOCK_RAW = 3 } socketpool_socketpool_sock_t; typedef enum { - SOCKETPOOL_AF_INET, - SOCKETPOOL_AF_INET6 + SOCKETPOOL_AF_INET = 2, + SOCKETPOOL_AF_INET6 = 10 } socketpool_socketpool_addressfamily_t; +typedef enum { + SOCKETPOOL_IPPROTO_TCP = 6, +} socketpool_socketpool_ipproto_t; + +typedef enum { + SOCKETPOOL_TCP_NODELAY = 1, +} socketpool_socketpool_tcpopt_t; + +typedef enum { + SOCKETPOOL_EAI_NONAME = -2, +} socketpool_eai_t; + void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *self, mp_obj_t radio); socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_t *self, @@ -51,6 +63,9 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_ mp_obj_t common_hal_socketpool_socketpool_gethostbyname(socketpool_socketpool_obj_t *self, const char *host); +// raises an exception instead of returning mp_const_none in the case of error +mp_obj_t common_hal_socketpool_socketpool_gethostbyname_raise(socketpool_socketpool_obj_t *self, + const char *host); // Non-allocating version for internal use. These sockets are not registered and, therefore, not // closed automatically. @@ -58,4 +73,6 @@ bool socketpool_socket(socketpool_socketpool_obj_t *self, socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type, socketpool_socket_obj_t *sock); +NORETURN void common_hal_socketpool_socketpool_raise_gaierror_noname(void); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKETPOOL_H diff --git a/shared-bindings/socketpool/__init__.c b/shared-bindings/socketpool/__init__.c index fee81f2820..48cc00245f 100644 --- a/shared-bindings/socketpool/__init__.c +++ b/shared-bindings/socketpool/__init__.c @@ -39,7 +39,6 @@ //| For more information about the `socket` module, see the CPython documentation: //| https://docs.python.org/3/library/socket.html //| """ -//| STATIC const mp_rom_map_elem_t socketpool_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_socketpool) }, diff --git a/shared-bindings/ssl/SSLContext.c b/shared-bindings/ssl/SSLContext.c index 5dfa5e599f..ac5f7ad42d 100644 --- a/shared-bindings/ssl/SSLContext.c +++ b/shared-bindings/ssl/SSLContext.c @@ -27,6 +27,7 @@ #include #include +#include "extmod/vfs.h" #include "py/objtuple.h" #include "py/objlist.h" #include "py/objproperty.h" @@ -37,8 +38,8 @@ //| class SSLContext: //| """Settings related to SSL that can be applied to a socket by wrapping it. -//| This is useful to provide SSL certificates to specific connections -//| rather than all of them.""" +//| This is useful to provide SSL certificates to specific connections +//| rather than all of them.""" //| STATIC mp_obj_t ssl_sslcontext_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { @@ -52,10 +53,50 @@ STATIC mp_obj_t ssl_sslcontext_make_new(const mp_obj_type_t *type, size_t n_args return MP_OBJ_FROM_PTR(s); } +//| def load_cert_chain(self, certfile: str, keyfile: str) -> None: +//| """Load a private key and the corresponding certificate. +//| +//| The certfile string must be the path to a single file in PEM format +//| containing the certificate as well as any number of CA certificates +//| needed to establish the certificate's authenticity. The keyfile string +//| must point to a file containing the private key. +//| """ + +STATIC void get_file_contents(mp_obj_t name_obj, mp_buffer_info_t *bufinfo) { + mp_obj_t file = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), name_obj, MP_OBJ_NEW_QSTR(MP_QSTR_rb)); + mp_obj_t dest[2]; + mp_load_method(file, MP_QSTR_read, dest); + mp_obj_t result = mp_call_method_n_kw(0, 0, dest); + mp_get_buffer_raise(result, bufinfo, MP_BUFFER_READ); +} + +STATIC mp_obj_t ssl_sslcontext_load_cert_chain(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_certfile, ARG_keyfile }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_certfile, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_keyfile, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + ssl_sslcontext_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t cert_buf, key_buf; + get_file_contents(args[ARG_certfile].u_obj, &cert_buf); + if (args[ARG_keyfile].u_obj != mp_const_none) { + get_file_contents(args[ARG_keyfile].u_obj, &key_buf); + } else { + key_buf = cert_buf; + } + + common_hal_ssl_sslcontext_load_cert_chain(self, &cert_buf, &key_buf); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ssl_sslcontext_load_cert_chain_obj, 1, ssl_sslcontext_load_cert_chain); + //| def load_verify_locations(self, cadata: Optional[str] = None) -> None: //| """Load a set of certification authority (CA) certificates used to validate -//| other peers' certificates.""" -//| +//| other peers' certificates.""" STATIC mp_obj_t ssl_sslcontext_load_verify_locations(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_cadata }; @@ -76,7 +117,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ssl_sslcontext_load_verify_locations_obj, 1, s //| def set_default_verify_paths(self) -> None: //| """Load a set of default certification authority (CA) certificates.""" -//| STATIC mp_obj_t ssl_sslcontext_set_default_verify_paths(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { ssl_sslcontext_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -88,7 +128,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ssl_sslcontext_set_default_verify_paths_obj, 1 //| check_hostname: bool //| """Whether to match the peer certificate's hostname.""" -//| STATIC mp_obj_t ssl_sslcontext_get_check_hostname(mp_obj_t self_in) { ssl_sslcontext_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -109,9 +148,15 @@ MP_PROPERTY_GETSET(ssl_sslcontext_check_hostname_obj, (mp_obj_t)&ssl_sslcontext_get_check_hostname_obj, (mp_obj_t)&ssl_sslcontext_set_check_hostname_obj); -//| def wrap_socket(self, sock: socketpool.Socket, *, server_side: bool = False, server_hostname: Optional[str] = None) -> ssl.SSLSocket: +//| def wrap_socket( +//| self, +//| sock: socketpool.Socket, +//| *, +//| server_side: bool = False, +//| server_hostname: Optional[str] = None +//| ) -> ssl.SSLSocket: //| """Wraps the socket into a socket-compatible class that handles SSL negotiation. -//| The socket must be of type SOCK_STREAM.""" +//| The socket must be of type SOCK_STREAM.""" //| STATIC mp_obj_t ssl_sslcontext_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -143,6 +188,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ssl_sslcontext_wrap_socket_obj, 1, ssl_sslcont STATIC const mp_rom_map_elem_t ssl_sslcontext_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&ssl_sslcontext_wrap_socket_obj) }, + { MP_ROM_QSTR(MP_QSTR_load_cert_chain), MP_ROM_PTR(&ssl_sslcontext_load_cert_chain_obj) }, { MP_ROM_QSTR(MP_QSTR_load_verify_locations), MP_ROM_PTR(&ssl_sslcontext_load_verify_locations_obj) }, { MP_ROM_QSTR(MP_QSTR_set_default_verify_paths), MP_ROM_PTR(&ssl_sslcontext_set_default_verify_paths_obj) }, { MP_ROM_QSTR(MP_QSTR_check_hostname), MP_ROM_PTR(&ssl_sslcontext_check_hostname_obj) }, diff --git a/shared-bindings/ssl/SSLContext.h b/shared-bindings/ssl/SSLContext.h index ef04f25d43..9f40badd85 100644 --- a/shared-bindings/ssl/SSLContext.h +++ b/shared-bindings/ssl/SSLContext.h @@ -46,5 +46,6 @@ void common_hal_ssl_sslcontext_set_default_verify_paths(ssl_sslcontext_obj_t *se bool common_hal_ssl_sslcontext_get_check_hostname(ssl_sslcontext_obj_t *self); void common_hal_ssl_sslcontext_set_check_hostname(ssl_sslcontext_obj_t *self, bool value); +void common_hal_ssl_sslcontext_load_cert_chain(ssl_sslcontext_obj_t *self, mp_buffer_info_t *cert_buf, mp_buffer_info_t *key_buf); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SSL_SSLCONTEXT_H diff --git a/shared-bindings/ssl/SSLSocket.c b/shared-bindings/ssl/SSLSocket.c index 630ab28c68..e0e7911715 100644 --- a/shared-bindings/ssl/SSLSocket.c +++ b/shared-bindings/ssl/SSLSocket.c @@ -39,29 +39,26 @@ //| class SSLSocket: //| """Implements TLS security on a subset of `socketpool.Socket` functions. Cannot be created -//| directly. Instead, call `wrap_socket` on an existing socket object. +//| directly. Instead, call `wrap_socket` on an existing socket object. //| -//| Provides a subset of CPython's `ssl.SSLSocket` API. It only implements the versions of -//| recv that do not allocate bytes objects.""" +//| Provides a subset of CPython's `ssl.SSLSocket` API. It only implements the versions of +//| recv that do not allocate bytes objects.""" //| //| def __hash__(self) -> int: //| """Returns a hash for the Socket.""" //| ... -//| // Provided by mp_generic_unary_op(). //| def __enter__(self) -> SSLSocket: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically closes the Socket when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t ssl_sslsocket___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_ssl_sslsocket_close(args[0]); @@ -73,7 +70,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket___exit___obj, 4, 4, ssl //| """Accept a connection on a listening socket of type SOCK_STREAM, //| creating a new socket of type SOCK_STREAM. //| Returns a tuple of (new_socket, remote_address)""" -//| STATIC mp_obj_t ssl_sslsocket_accept(mp_obj_t self_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); uint8_t ip[4]; @@ -93,7 +89,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(ssl_sslsocket_accept_obj, ssl_sslsocket_accept) //| //| :param ~tuple address: tuple of (remote_address, remote_port)""" //| ... -//| STATIC mp_obj_t ssl_sslsocket_bind(mp_obj_t self_in, mp_obj_t addr_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -118,7 +113,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_bind_obj, ssl_sslsocket_bind); //| def close(self) -> None: //| """Closes this Socket""" -//| STATIC mp_obj_t ssl_sslsocket_close(mp_obj_t self_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_ssl_sslsocket_close(self); @@ -131,7 +125,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(ssl_sslsocket_close_obj, ssl_sslsocket_close); //| //| :param ~tuple address: tuple of (remote_address, remote_port)""" //| ... -//| STATIC mp_obj_t ssl_sslsocket_connect(mp_obj_t self_in, mp_obj_t addr_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -156,7 +149,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_connect_obj, ssl_sslsocket_connec //| //| :param ~int backlog: length of backlog queue for waiting connetions""" //| ... -//| STATIC mp_obj_t ssl_sslsocket_listen(mp_obj_t self_in, mp_obj_t backlog_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -180,7 +172,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_listen_obj, ssl_sslsocket_listen) //| :param bytearray buffer: buffer to receive into //| :param int bufsize: optionally, a maximum number of bytes to read.""" //| ... -//| STATIC mp_obj_t ssl_sslsocket_recv_into(size_t n_args, const mp_obj_t *args) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (common_hal_ssl_sslsocket_get_closed(self)) { @@ -219,7 +210,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket_recv_into_obj, 2, 3, ss //| //| :param ~bytes bytes: some bytes to send""" //| ... -//| STATIC mp_obj_t ssl_sslsocket_send(mp_obj_t self_in, mp_obj_t buf_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (common_hal_ssl_sslsocket_get_closed(self)) { @@ -250,9 +240,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_send_obj, ssl_sslsocket_send); //| def settimeout(self, value: int) -> None: //| """Set the timeout value for this socket. //| -//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely.""" +//| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely. +//| """ //| ... -//| STATIC mp_obj_t ssl_sslsocket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t timeout_ms; diff --git a/shared-bindings/ssl/SSLSocket.h b/shared-bindings/ssl/SSLSocket.h index d6519340d9..0c303e44c7 100644 --- a/shared-bindings/ssl/SSLSocket.h +++ b/shared-bindings/ssl/SSLSocket.h @@ -38,7 +38,7 @@ void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, const char *hos bool common_hal_ssl_sslsocket_get_closed(ssl_sslsocket_obj_t *self); bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t *self); bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog); -mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t *self, const uint8_t *buf, uint32_t len); +mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t *self, uint8_t *buf, uint32_t len); mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t *buf, uint32_t len); void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t *self, uint32_t timeout_ms); diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c index baf91a35c1..8e2eee6511 100644 --- a/shared-bindings/storage/__init__.c +++ b/shared-bindings/storage/__init__.c @@ -34,6 +34,7 @@ #include "py/runtime.h" #include "shared-bindings/storage/__init__.h" #include "supervisor/shared/translate/translate.h" +#include "supervisor/flash.h" //| """Storage management //| @@ -41,13 +42,12 @@ //| unmounting which is typically handled by the operating system hosting Python. //| CircuitPython does not have an OS, so this module provides this functionality //| directly. - +//| //| For more information regarding using the `storage` module, refer to the `CircuitPython //| Essentials Learn guide //| `_. //| """ //| - //| def mount(filesystem: VfsFat, mount_path: str, *, readonly: bool = False) -> None: //| """Mounts the given filesystem object at the given path. //| @@ -107,15 +107,20 @@ STATIC mp_obj_t storage_umount(mp_obj_t mnt_in) { } MP_DEFINE_CONST_FUN_OBJ_1(storage_umount_obj, storage_umount); -//| def remount(mount_path: str, readonly: bool = False, *, disable_concurrent_write_protection: bool = False) -> None: +//| def remount( +//| mount_path: str, +//| readonly: bool = False, +//| *, +//| disable_concurrent_write_protection: bool = False +//| ) -> None: //| """Remounts the given path with new parameters. //| -//| :param str mount_path: The path to remount. -//| :param bool readonly: True when the filesystem should be readonly to CircuitPython. -//| :param bool disable_concurrent_write_protection: When True, the check that makes sure the -//| underlying filesystem data is written by one computer is disabled. Disabling the protection -//| allows CircuitPython and a host to write to the same filesystem with the risk that the -//| filesystem will be corrupted.""" +//| :param str mount_path: The path to remount. +//| :param bool readonly: True when the filesystem should be readonly to CircuitPython. +//| :param bool disable_concurrent_write_protection: When True, the check that makes sure the +//| underlying filesystem data is written by one computer is disabled. Disabling the protection +//| allows CircuitPython and a host to write to the same filesystem with the risk that the +//| filesystem will be corrupted.""" //| ... //| STATIC mp_obj_t storage_remount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -146,7 +151,7 @@ STATIC mp_obj_t storage_getmount(const mp_obj_t mnt_in) { } MP_DEFINE_CONST_FUN_OBJ_1(storage_getmount_obj, storage_getmount); -//| def erase_filesystem() -> None: +//| def erase_filesystem(extended: Optional[bool] = None) -> None: //| """Erase and re-create the ``CIRCUITPY`` filesystem. //| //| On boards that present USB-visible ``CIRCUITPY`` drive (e.g., SAMD21 and SAMD51), @@ -156,16 +161,41 @@ MP_DEFINE_CONST_FUN_OBJ_1(storage_getmount_obj, storage_getmount); //| This function can be called from the REPL when ``CIRCUITPY`` //| has become corrupted. //| +//| :param bool extended: On boards that support ``dualbank`` module +//| and the ``extended`` parameter, the ``CIRCUITPY`` storage can be +//| extended by setting this to `True`. If this isn't provided or +//| set to `None` (default), the existing configuration will be used. +//| +//| .. note:: New firmware starts with storage extended. In case of an existing +//| filesystem (e.g. uf2 load), the existing extension setting is preserved. +//| //| .. warning:: All the data on ``CIRCUITPY`` will be lost, and -//| CircuitPython will restart on certain boards.""" +//| CircuitPython will restart on certain boards.""" //| ... //| -STATIC mp_obj_t storage_erase_filesystem(void) { - common_hal_storage_erase_filesystem(); +STATIC mp_obj_t storage_erase_filesystem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_extended }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_extended, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + #if CIRCUITPY_STORAGE_EXTEND + bool extended = (args[ARG_extended].u_obj == mp_const_none) ? supervisor_flash_get_extended() : mp_obj_is_true(args[ARG_extended].u_obj); + common_hal_storage_erase_filesystem(extended); + #else + if (mp_obj_is_true(args[ARG_extended].u_obj)) { + mp_raise_NotImplementedError_varg(translate("%q=%q"), MP_QSTR_extended, MP_QSTR_True); + } + common_hal_storage_erase_filesystem(false); + #endif + return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_0(storage_erase_filesystem_obj, storage_erase_filesystem); +MP_DEFINE_CONST_FUN_OBJ_KW(storage_erase_filesystem_obj, 0, storage_erase_filesystem); //| def disable_usb_drive() -> None: //| """Disable presenting ``CIRCUITPY`` as a USB mass storage device. @@ -226,46 +256,43 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = { //| """Create a new VfsFat filesystem around the given block device. //| //| :param block_device: Block device the the filesystem lives on""" -//| //| label: str //| """The filesystem label, up to 11 case-insensitive bytes. Note that //| this property can only be set when the device is writable by the //| microcontroller.""" //| ... +//| readonly: bool +//| """``True`` when the device is mounted as readonly by the microcontroller. +//| This property cannot be changed, use `storage.remount` instead.""" +//| ... //| //| def mkfs(self) -> None: //| """Format the block device, deleting any data that may have been there""" //| ... -//| //| def open(self, path: str, mode: str) -> None: //| """Like builtin ``open()``""" //| ... -//| -//| def ilistdir(self, path: str) -> Iterator[Union[Tuple[AnyStr, int, int, int], Tuple[AnyStr, int, int]]]: +//| def ilistdir( +//| self, path: str +//| ) -> Iterator[Union[Tuple[AnyStr, int, int, int], Tuple[AnyStr, int, int]]]: //| """Return an iterator whose values describe files and folders within //| ``path``""" //| ... -//| //| def mkdir(self, path: str) -> None: //| """Like `os.mkdir`""" //| ... -//| //| def rmdir(self, path: str) -> None: //| """Like `os.rmdir`""" //| ... -//| //| def stat(self, path: str) -> Tuple[int, int, int, int, int, int, int, int, int, int]: //| """Like `os.stat`""" //| ... -//| //| def statvfs(self, path: int) -> Tuple[int, int, int, int, int, int, int, int, int, int]: //| """Like `os.statvfs`""" //| ... -//| //| def mount(self, readonly: bool, mkfs: VfsFat) -> None: //| """Don't call this directly, call `storage.mount`.""" //| ... -//| //| def umount(self) -> None: //| """Don't call this directly, call `storage.umount`.""" //| ... diff --git a/shared-bindings/storage/__init__.h b/shared-bindings/storage/__init__.h index fbf492efab..ffe68c17c8 100644 --- a/shared-bindings/storage/__init__.h +++ b/shared-bindings/storage/__init__.h @@ -37,7 +37,7 @@ void common_hal_storage_umount_path(const char *path); void common_hal_storage_umount_object(mp_obj_t vfs_obj); void common_hal_storage_remount(const char *path, bool readonly, bool disable_concurrent_write_protection); mp_obj_t common_hal_storage_getmount(const char *path); -void common_hal_storage_erase_filesystem(void); +void common_hal_storage_erase_filesystem(bool extended); bool common_hal_storage_disable_usb_drive(void); bool common_hal_storage_enable_usb_drive(void); diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 55217ec97a..db3d8d1e4d 100644 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -32,6 +32,12 @@ #include "shared-bindings/supervisor/RunReason.h" #include "shared-bindings/supervisor/Runtime.h" +#include "shared-bindings/supervisor/SafeModeReason.h" + +#include "supervisor/shared/reload.h" +#include "supervisor/shared/stack.h" +#include "supervisor/shared/status_leds.h" +#include "supervisor/shared/bluetooth/bluetooth.h" #if (CIRCUITPY_USB) #include "tusb.h" @@ -55,11 +61,9 @@ STATIC supervisor_run_reason_t _run_reason; //| """You cannot create an instance of `supervisor.Runtime`. //| Use `supervisor.runtime` to access the sole instance available.""" //| ... -//| //| usb_connected: bool //| """Returns the USB enumeration status (read-only).""" -//| STATIC mp_obj_t supervisor_runtime_get_usb_connected(mp_obj_t self) { #if CIRCUITPY_USB return mp_obj_new_bool(tud_ready()); @@ -74,7 +78,6 @@ MP_PROPERTY_GETTER(supervisor_runtime_usb_connected_obj, //| serial_connected: bool //| """Returns the USB serial communication status (read-only).""" -//| STATIC mp_obj_t supervisor_runtime_get_serial_connected(mp_obj_t self) { return mp_obj_new_bool(common_hal_supervisor_runtime_get_serial_connected()); } @@ -87,7 +90,6 @@ MP_PROPERTY_GETTER(supervisor_runtime_serial_connected_obj, //| """Returns the whether any bytes are available to read //| on the USB serial input. Allows for polling to see whether //| to call the built-in input() or wait. (read-only)""" -//| STATIC mp_obj_t supervisor_runtime_get_serial_bytes_available(mp_obj_t self) { return mp_obj_new_bool(common_hal_supervisor_runtime_get_serial_bytes_available()); } @@ -105,8 +107,7 @@ void supervisor_set_run_reason(supervisor_run_reason_t run_reason) { } //| run_reason: RunReason -//| """Returns why CircuitPython started running this particular time.""" -//| +//| """Why CircuitPython started running this particular time (read-only).""" STATIC mp_obj_t supervisor_runtime_get_run_reason(mp_obj_t self) { return cp_enum_find(&supervisor_run_reason_type, _run_reason); } @@ -115,11 +116,131 @@ MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_run_reason_obj, supervisor_runt MP_PROPERTY_GETTER(supervisor_runtime_run_reason_obj, (mp_obj_t)&supervisor_runtime_get_run_reason_obj); +//| safe_mode_reason: SafeModeReason +//| """Why CircuitPython went into safe mode this particular time (read-only). +//| +//| **Limitations**: Raises ``NotImplementedError`` on builds that do not implement ``safemode.py``. +//| """ +STATIC mp_obj_t supervisor_runtime_get_safe_mode_reason(mp_obj_t self) { + #if CIRCUITPY_SAFEMODE_PY + return cp_enum_find(&supervisor_safe_mode_reason_type, get_safe_mode()); + #else + mp_raise_NotImplementedError(NULL); + #endif +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_safe_mode_reason_obj, supervisor_runtime_get_safe_mode_reason); + +MP_PROPERTY_GETTER(supervisor_runtime_safe_mode_reason_obj, + (mp_obj_t)&supervisor_runtime_get_safe_mode_reason_obj); + +//| autoreload: bool +//| """Whether CircuitPython may autoreload based on workflow writes to the filesystem.""" +//| +STATIC mp_obj_t supervisor_runtime_get_autoreload(mp_obj_t self) { + return mp_obj_new_bool(autoreload_is_enabled()); +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_autoreload_obj, supervisor_runtime_get_autoreload); + +STATIC mp_obj_t supervisor_runtime_set_autoreload(mp_obj_t self, mp_obj_t state_in) { + if (mp_obj_is_true(state_in)) { + autoreload_enable(); + } else { + autoreload_disable(); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(supervisor_runtime_set_autoreload_obj, supervisor_runtime_set_autoreload); + +MP_PROPERTY_GETSET(supervisor_runtime_autoreload_obj, + (mp_obj_t)&supervisor_runtime_get_autoreload_obj, + (mp_obj_t)&supervisor_runtime_set_autoreload_obj); + +//| ble_workflow: bool +//| """Enable/Disable ble workflow until a reset. This prevents BLE advertising outside of the VM and +//| the services used for it.""" +//| +STATIC mp_obj_t supervisor_runtime_get_ble_workflow(mp_obj_t self) { + #if CIRCUITPY_BLE_FILE_SERVICE && CIRCUITPY_SERIAL_BLE + return mp_obj_new_bool(supervisor_bluetooth_workflow_is_enabled()); + #else + return mp_const_false; + #endif +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_ble_workflow_obj, supervisor_runtime_get_ble_workflow); + +STATIC mp_obj_t supervisor_runtime_set_ble_workflow(mp_obj_t self, mp_obj_t state_in) { + #if CIRCUITPY_BLE_FILE_SERVICE && CIRCUITPY_SERIAL_BLE + if (mp_obj_is_true(state_in)) { + supervisor_bluetooth_enable_workflow(); + } else { + supervisor_bluetooth_disable_workflow(); + } + #else + mp_raise_NotImplementedError(NULL); + #endif + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(supervisor_runtime_set_ble_workflow_obj, supervisor_runtime_set_ble_workflow); + +MP_PROPERTY_GETSET(supervisor_runtime_ble_workflow_obj, + (mp_obj_t)&supervisor_runtime_get_ble_workflow_obj, + (mp_obj_t)&supervisor_runtime_set_ble_workflow_obj); + +//| next_stack_limit: int +//| """The size of the stack for the next vm run. If its too large, the default will be used.""" +//| +STATIC mp_obj_t supervisor_runtime_get_next_stack_limit(mp_obj_t self) { + return mp_obj_new_int(get_next_stack_size()); +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_next_stack_limit_obj, supervisor_runtime_get_next_stack_limit); + +STATIC mp_obj_t supervisor_runtime_set_next_stack_limit(mp_obj_t self, mp_obj_t size_obj) { + mp_int_t size = mp_obj_get_int(size_obj); + mp_arg_validate_int_min(size, 256, MP_QSTR_size); + set_next_stack_size(size); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(supervisor_runtime_set_next_stack_limit_obj, supervisor_runtime_set_next_stack_limit); + +MP_PROPERTY_GETSET(supervisor_runtime_next_stack_limit_obj, + (mp_obj_t)&supervisor_runtime_get_next_stack_limit_obj, + (mp_obj_t)&supervisor_runtime_set_next_stack_limit_obj); + +//| rgb_status_brightness: int +//| """Set brightness of status RGB LED from 0-255. This will take effect +//| after the current code finishes and the status LED is used to show +//| the finish state.""" +//| +STATIC mp_obj_t supervisor_runtime_get_rgb_status_brightness(mp_obj_t self) { + return MP_OBJ_NEW_SMALL_INT(get_status_brightness()); +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_rgb_status_brightness_obj, supervisor_runtime_get_rgb_status_brightness); + +STATIC mp_obj_t supervisor_runtime_set_rgb_status_brightness(mp_obj_t self, mp_obj_t lvl) { + #if CIRCUITPY_STATUS_LED + // This must be int. If cast to uint8_t first, will never raise a ValueError. + set_status_brightness((uint8_t)mp_arg_validate_int_range(mp_obj_get_int(lvl), 0, 255, MP_QSTR_brightness)); + #else + mp_raise_NotImplementedError(NULL); + #endif + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(supervisor_runtime_set_rgb_status_brightness_obj, supervisor_runtime_set_rgb_status_brightness); + +MP_PROPERTY_GETSET(supervisor_runtime_rgb_status_brightness_obj, + (mp_obj_t)&supervisor_runtime_get_rgb_status_brightness_obj, + (mp_obj_t)&supervisor_runtime_set_rgb_status_brightness_obj); + STATIC const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_usb_connected), MP_ROM_PTR(&supervisor_runtime_usb_connected_obj) }, { MP_ROM_QSTR(MP_QSTR_serial_connected), MP_ROM_PTR(&supervisor_runtime_serial_connected_obj) }, { MP_ROM_QSTR(MP_QSTR_serial_bytes_available), MP_ROM_PTR(&supervisor_runtime_serial_bytes_available_obj) }, { MP_ROM_QSTR(MP_QSTR_run_reason), MP_ROM_PTR(&supervisor_runtime_run_reason_obj) }, + { MP_ROM_QSTR(MP_QSTR_safe_mode_reason), MP_ROM_PTR(&supervisor_runtime_safe_mode_reason_obj) }, + { MP_ROM_QSTR(MP_QSTR_autoreload), MP_ROM_PTR(&supervisor_runtime_autoreload_obj) }, + { MP_ROM_QSTR(MP_QSTR_ble_workflow), MP_ROM_PTR(&supervisor_runtime_ble_workflow_obj) }, + { MP_ROM_QSTR(MP_QSTR_next_stack_limit), MP_ROM_PTR(&supervisor_runtime_next_stack_limit_obj) }, + { MP_ROM_QSTR(MP_QSTR_rgb_status_brightness), MP_ROM_PTR(&supervisor_runtime_rgb_status_brightness_obj) }, }; STATIC MP_DEFINE_CONST_DICT(supervisor_runtime_locals_dict, supervisor_runtime_locals_dict_table); diff --git a/shared-bindings/supervisor/Runtime.h b/shared-bindings/supervisor/Runtime.h index debc5ec79c..3c3e2611f6 100644 --- a/shared-bindings/supervisor/Runtime.h +++ b/shared-bindings/supervisor/Runtime.h @@ -31,12 +31,16 @@ #include "py/obj.h" #include "shared-bindings/supervisor/RunReason.h" +#include "shared-bindings/supervisor/SafeModeReason.h" extern const mp_obj_type_t supervisor_runtime_type; supervisor_run_reason_t supervisor_get_run_reason(void); void supervisor_set_run_reason(supervisor_run_reason_t run_reason); +safe_mode_t supervisor_get_safe_mode(void); +void supervisor_set_safe_mode(safe_mode_t safe_mode); + bool common_hal_supervisor_runtime_get_serial_connected(void); bool common_hal_supervisor_runtime_get_serial_bytes_available(void); diff --git a/shared-bindings/supervisor/SafeModeReason.c b/shared-bindings/supervisor/SafeModeReason.c new file mode 100644 index 0000000000..2da03bdced --- /dev/null +++ b/shared-bindings/supervisor/SafeModeReason.c @@ -0,0 +1,158 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/enum.h" + +#include "shared-bindings/supervisor/SafeModeReason.h" + +// Reuse the non-Python safe_mode_t enum +#include "supervisor/shared/safe_mode.h" + +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, NONE, SAFE_MODE_NONE); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, BROWNOUT, SAFE_MODE_BROWNOUT); +// alphabetical from here down +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, FLASH_WRITE_FAIL, SAFE_MODE_FLASH_WRITE_FAIL); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, GC_ALLOC_OUTSIDE_VM, SAFE_MODE_GC_ALLOC_OUTSIDE_VM); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, HARD_FAULT, SAFE_MODE_HARD_FAULT); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, INTERRUPT_ERROR, SAFE_MODE_INTERRUPT_ERROR); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, NLR_JUMP_FAIL, SAFE_MODE_NLR_JUMP_FAIL); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, NO_CIRCUITPY, SAFE_MODE_NO_CIRCUITPY); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, NO_HEAP, SAFE_MODE_NO_HEAP); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, PROGRAMMATIC, SAFE_MODE_PROGRAMMATIC); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, SDK_FATAL_ERROR, SAFE_MODE_SDK_FATAL_ERROR); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, STACK_OVERFLOW, SAFE_MODE_STACK_OVERFLOW); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, USB_BOOT_DEVICE_NOT_INTERFACE_ZERO, SAFE_MODE_USB_BOOT_DEVICE_NOT_INTERFACE_ZERO); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, USB_TOO_MANY_ENDPOINTS, SAFE_MODE_USB_TOO_MANY_ENDPOINTS); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, USB_TOO_MANY_INTERFACE_NAMES, SAFE_MODE_USB_TOO_MANY_INTERFACE_NAMES); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, USER, SAFE_MODE_USER); +MAKE_ENUM_VALUE(supervisor_safe_mode_reason_type, safe_mode_reason, WATCHDOG, SAFE_MODE_WATCHDOG); + + +//| class SafeModeReason: +//| """The reason that CircuitPython went into safe mode. +//| +//| **Limitations**: Class not available on builds that do not implement ``safemode.py``. +//| """ +//| +MAKE_ENUM_MAP(supervisor_safe_mode_reason) { + +//| NONE: object +//| """CircuitPython is not in safe mode.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, NONE), + +//| BROWNOUT: object +//| """The microcontroller voltage dropped too low.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, BROWNOUT), + +// alphabetical from here down + +//| FLASH_WRITE_FAIL: object +//| """Could not write to flash memory.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, FLASH_WRITE_FAIL), + +//| GC_ALLOC_OUTSIDE_VM: object +//| """CircuitPython tried to allocate storage when its virtual machine was not running.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, GC_ALLOC_OUTSIDE_VM), + +//| HARD_FAULT: object +//| """The microcontroller detected a fault, such as an out-of-bounds memory write.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, HARD_FAULT), + +//| INTERRUPT_ERROR: object +//| """Internal error related to interrupts.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, INTERRUPT_ERROR), + +//| NLR_JUMP_FAIL: object +//| """An error occurred during exception handling, possibly due to memory corruption.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, NLR_JUMP_FAIL), + +//| NO_CIRCUITPY: object +//| """The CIRCUITPY drive was not available.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, NO_CIRCUITPY), + +//| NO_HEAP: object +//| """Heap storage was not present.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, NO_HEAP), + +//| PROGRAMMATIC: object +//| """The program entered safe mode using the `supervisor` module.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, PROGRAMMATIC), + +//| SDK_FATAL_ERROR: object +//| """Third party firmware reported a fatal error.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, SDK_FATAL_ERROR), + +//| STACK_OVERFLOW: object +//| """The CircuitPython heap was corrupted because the stack was too small.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, STACK_OVERFLOW), + +//| USB_BOOT_DEVICE_NOT_INTERFACE_ZERO: object +//| """The USB HID boot device was not set up to be the first device, on interface #0.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, USB_BOOT_DEVICE_NOT_INTERFACE_ZERO), + +//| USB_TOO_MANY_ENDPOINTS: object +//| """USB devices need more endpoints than are available.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, USB_TOO_MANY_ENDPOINTS), + +//| USB_TOO_MANY_INTERFACE_NAMES: object +//| """USB devices specify too many interface names.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, USB_TOO_MANY_INTERFACE_NAMES), + +//| USER: object +//| """The user pressed one or more buttons to enter safe mode. +//| This safe mode does **not** cause ``safemode.py`` to be run, since its purpose +//| is to prevent all user code from running. +//| This allows errors in ``safemode.py`` to be corrected easily. +//| """ +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, USER), + +//| SAFE_MODE_WATCHDOG: object +//| """An internal watchdog timer expired.""" +//| + MAKE_ENUM_MAP_ENTRY(safe_mode_reason, WATCHDOG), +}; + +STATIC MP_DEFINE_CONST_DICT(supervisor_safe_mode_reason_locals_dict, supervisor_safe_mode_reason_locals_table); + +MAKE_PRINTER(supervisor, supervisor_safe_mode_reason); + +MAKE_ENUM_TYPE(supervisor, SafeModeReason, supervisor_safe_mode_reason); diff --git a/shared-bindings/supervisor/SafeModeReason.h b/shared-bindings/supervisor/SafeModeReason.h new file mode 100644 index 0000000000..d061d75154 --- /dev/null +++ b/shared-bindings/supervisor/SafeModeReason.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "supervisor/shared/safe_mode.h" + +extern const mp_obj_type_t supervisor_safe_mode_reason_type; diff --git a/shared-bindings/supervisor/StatusBar.c b/shared-bindings/supervisor/StatusBar.c new file mode 100644 index 0000000000..8db1906f5e --- /dev/null +++ b/shared-bindings/supervisor/StatusBar.c @@ -0,0 +1,125 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 by Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "py/obj.h" +#include "py/enum.h" +#include "py/runtime.h" +#include "py/objproperty.h" +#include "shared-bindings/supervisor/StatusBar.h" + +//| class StatusBar: +//| """Current status of runtime objects. +//| +//| Usage:: +//| +//| import supervisor +//| +//| supervisor.status_bar.console = False +//| """ +//| + +//| def __init__(self) -> None: +//| """You cannot create an instance of `supervisor.StatusBar`. +//| Use `supervisor.status_bar` to access the sole instance available.""" +//| ... + +//| console: bool +//| """Whether status bar information is sent over the console (REPL) serial connection, +//| using OSC terminal escape codes that change the terminal's title. Default is ``True``. +//| If set to ``False``, status bar will be cleared and then disabled. +//| May be set in ``boot.py`` or later. Persists across soft restarts. +//| """ +STATIC mp_obj_t supervisor_status_bar_get_console(mp_obj_t self_in) { + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(shared_module_supervisor_status_bar_get_console(self)); + #else + mp_raise_NotImplementedError(NULL); + #endif +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_status_bar_get_console_obj, supervisor_status_bar_get_console); + +STATIC mp_obj_t supervisor_status_bar_set_console(mp_obj_t self_in, mp_obj_t state_in) { + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_obj_t *self = MP_OBJ_TO_PTR(self_in); + shared_module_supervisor_status_bar_set_console(self, mp_obj_is_true(state_in)); + return mp_const_none; + #else + mp_raise_NotImplementedError(NULL); + #endif +} +MP_DEFINE_CONST_FUN_OBJ_2(supervisor_status_bar_set_console_obj, supervisor_status_bar_set_console); + +MP_PROPERTY_GETSET(supervisor_status_bar_console_obj, + (mp_obj_t)&supervisor_status_bar_get_console_obj, + (mp_obj_t)&supervisor_status_bar_set_console_obj); + +//| display: bool +//| """Whether status bar information is displayed on the top line of the display. +//| Default is ``True``. If set to ``False``, status bar will be cleared and then disabled. +//| May be set in ``boot.py`` or later. Persists across soft restarts. +//| Not available if `terminalio` is not available. +//| """ +//| +STATIC mp_obj_t supervisor_status_bar_get_display(mp_obj_t self_in) { + #if CIRCUITPY_STATUS_BAR && CIRCUITPY_TERMINALIO + supervisor_status_bar_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(shared_module_supervisor_status_bar_get_display(self)); + #else + mp_raise_NotImplementedError(NULL); + #endif +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_status_bar_get_display_obj, supervisor_status_bar_get_display); + +STATIC mp_obj_t supervisor_status_bar_set_display(mp_obj_t self_in, mp_obj_t state_in) { + #if CIRCUITPY_STATUS_BAR && CIRCUITPY_TERMINALIO + supervisor_status_bar_obj_t *self = MP_OBJ_TO_PTR(self_in); + shared_module_supervisor_status_bar_set_display(self, mp_obj_is_true(state_in)); + return mp_const_none; + #else + mp_raise_NotImplementedError(NULL); + #endif +} +MP_DEFINE_CONST_FUN_OBJ_2(supervisor_status_bar_set_display_obj, supervisor_status_bar_set_display); + +MP_PROPERTY_GETSET(supervisor_status_bar_display_obj, + (mp_obj_t)&supervisor_status_bar_get_display_obj, + (mp_obj_t)&supervisor_status_bar_set_display_obj); + + +STATIC const mp_rom_map_elem_t supervisor_status_bar_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_console), MP_ROM_PTR(&supervisor_status_bar_console_obj) }, + { MP_ROM_QSTR(MP_QSTR_display), MP_ROM_PTR(&supervisor_status_bar_display_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(supervisor_status_bar_locals_dict, supervisor_status_bar_locals_dict_table); + +const mp_obj_type_t supervisor_status_bar_type = { + .base = { &mp_type_type }, + .name = MP_QSTR_Status_Bar, + .locals_dict = (mp_obj_dict_t *)&supervisor_status_bar_locals_dict, +}; diff --git a/shared-bindings/supervisor/StatusBar.h b/shared-bindings/supervisor/StatusBar.h new file mode 100644 index 0000000000..12b337ea84 --- /dev/null +++ b/shared-bindings/supervisor/StatusBar.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 by Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_STATUS_BAR_STATUS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_STATUS_BAR_STATUS_H + +#include +#include "py/obj.h" +#include "shared-module/supervisor/StatusBar.h" + +extern const mp_obj_type_t supervisor_status_bar_type; + +bool shared_module_supervisor_status_bar_get_console(supervisor_status_bar_obj_t *self); +void shared_module_supervisor_status_bar_set_console(supervisor_status_bar_obj_t *self, bool enabled); + +bool shared_module_supervisor_status_bar_get_display(supervisor_status_bar_obj_t *self); +void shared_module_supervisor_status_bar_set_display(supervisor_status_bar_obj_t *self, bool enabled); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SUPERVISOR_STATUS_BAR_H diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index cad8ccdeec..491cac2f17 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -30,64 +30,36 @@ #include "py/objstr.h" #include "shared/runtime/interrupt_char.h" -#include "supervisor/shared/bluetooth/bluetooth.h" #include "supervisor/shared/display.h" -#include "supervisor/shared/status_leds.h" #include "supervisor/shared/reload.h" -#include "supervisor/shared/stack.h" #include "supervisor/shared/traceback.h" #include "supervisor/shared/translate/translate.h" #include "supervisor/shared/workflow.h" +#if CIRCUITPY_USB_IDENTIFICATION +#include "supervisor/usb.h" +#endif + #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/supervisor/__init__.h" #include "shared-bindings/time/__init__.h" #include "shared-bindings/supervisor/Runtime.h" +#include "shared-bindings/supervisor/StatusBar.h" //| """Supervisor settings""" -//| //| runtime: Runtime //| """Runtime information, such as ``runtime.serial_connected`` //| (USB serial connection status). //| This object is the sole instance of `supervisor.Runtime`.""" -//| -//| def enable_autoreload() -> None: -//| """Enable autoreload based on USB file write activity.""" -//| ... +//| status_bar: StatusBar +//| """The status bar, shown on an attached display, and also sent to +//| an attached terminal via OSC escape codes over the REPL serial connection. +//| The status bar reports the current IP or BLE connection, what file is running, +//| the last exception name and location, and firmware version information. +//| This object is the sole instance of `supervisor.StatusBar`.""" //| -STATIC mp_obj_t supervisor_enable_autoreload(void) { - autoreload_enable(); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_0(supervisor_enable_autoreload_obj, supervisor_enable_autoreload); - -//| def disable_autoreload() -> None: -//| """Disable autoreload based on USB file write activity until -//| `enable_autoreload` is called.""" -//| ... -//| -STATIC mp_obj_t supervisor_disable_autoreload(void) { - autoreload_disable(); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_0(supervisor_disable_autoreload_obj, supervisor_disable_autoreload); - -//| def set_rgb_status_brightness(brightness: int) -> None: -//| """Set brightness of status RGB LED from 0-255. This will take effect -//| after the current code finishes and the status LED is used to show -//| the finish state.""" -//| ... -//| -STATIC mp_obj_t supervisor_set_rgb_status_brightness(mp_obj_t lvl) { - // This must be int. If cast to uint8_t first, will never raise a ValueError. - int brightness_int = mp_obj_get_int(lvl); - mp_arg_validate_int_range(brightness_int, 0, 255, MP_QSTR_brightness); - set_status_brightness((uint8_t)brightness_int); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_rgb_status_brightness_obj, supervisor_set_rgb_status_brightness); //| def reload() -> None: //| """Reload the main Python code and run it (equivalent to hitting Ctrl-D at the REPL).""" @@ -99,22 +71,15 @@ STATIC mp_obj_t supervisor_reload(void) { } MP_DEFINE_CONST_FUN_OBJ_0(supervisor_reload_obj, supervisor_reload); -//| def set_next_stack_limit(size: int) -> None: -//| """Set the size of the stack for the next vm run. If its too large, the default will be used.""" -//| ... -//| -STATIC mp_obj_t supervisor_set_next_stack_limit(mp_obj_t size_obj) { - mp_int_t size = mp_obj_get_int(size_obj); - - mp_arg_validate_int_min(size, 256, MP_QSTR_size); - - set_next_stack_size(size); - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_next_stack_limit_obj, supervisor_set_next_stack_limit); - -//| def set_next_code_file(filename: Optional[str], *, reload_on_success : bool = False, reload_on_error: bool = False, sticky_on_success: bool = False, sticky_on_error: bool = False, sticky_on_reload: bool = False) -> None: +//| def set_next_code_file( +//| filename: Optional[str], +//| *, +//| reload_on_success: bool = False, +//| reload_on_error: bool = False, +//| sticky_on_success: bool = False, +//| sticky_on_error: bool = False, +//| sticky_on_reload: bool = False +//| ) -> None: //| """Set what file to run on the next vm run. //| //| When not ``None``, the given ``filename`` is inserted at the front of the usual ['code.py', @@ -233,7 +198,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(supervisor_set_next_code_file_obj, 0, supervisor_set_ //| //| def ticks_add(ticks, delta): //| "Add a delta to a base number of ticks, performing wraparound at 2**29ms." -//| return (a + b) % _TICKS_PERIOD +//| return (ticks + delta) % _TICKS_PERIOD //| //| def ticks_diff(ticks1, ticks2): //| "Compute the signed difference between two ticks values, assuming that they are within 2**28 ticks" @@ -247,6 +212,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(supervisor_set_next_code_file_obj, 0, supervisor_set_ //| //| """ //| ... +//| mp_obj_t supervisor_ticks_ms(void) { uint64_t ticks_ms = common_hal_time_monotonic_ms(); return mp_obj_new_int((ticks_ms + 0x1fff0000) % (1 << 29)); @@ -280,21 +246,6 @@ STATIC mp_obj_t supervisor_get_previous_traceback(void) { } MP_DEFINE_CONST_FUN_OBJ_0(supervisor_get_previous_traceback_obj, supervisor_get_previous_traceback); -//| def disable_ble_workflow() -> None: -//| """Disable ble workflow until a reset. This prevents BLE advertising outside of the VM and -//| the services used for it.""" -//| ... -//| -STATIC mp_obj_t supervisor_disable_ble_workflow(void) { - #if !CIRCUITPY_BLE_FILE_SERVICE && !CIRCUITPY_SERIAL_BLE - mp_raise_NotImplementedError(NULL); - #else - supervisor_bluetooth_disable_workflow(); - #endif - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_0(supervisor_disable_ble_workflow_obj, supervisor_disable_ble_workflow); - //| def reset_terminal(x_pixels: int, y_pixels: int) -> None: //| """Reset the CircuitPython serial terminal with new dimensions.""" //| ... @@ -310,20 +261,92 @@ STATIC mp_obj_t supervisor_reset_terminal(mp_obj_t x_pixels, mp_obj_t y_pixels) } MP_DEFINE_CONST_FUN_OBJ_2(supervisor_reset_terminal_obj, supervisor_reset_terminal); +//| def set_usb_identification( +//| manufacturer: Optional[str] = None, +//| product: Optional[str] = None, +//| vid: int = -1, +//| pid: int = -1, +//| ) -> None: +//| """Override identification constants in the USB Device Descriptor. +//| +//| If passed, `manufacturer` and `product` must be ASCII strings (or buffers) of at most 126 +//| characters. Any omitted arguments will be left at their default values. +//| +//| This method must be called in boot.py to have any effect. +//| +//| Not available on boards without native USB support. +//| """ +//| ... +//| +STATIC mp_obj_t supervisor_set_usb_identification(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + #if CIRCUITPY_USB_IDENTIFICATION + static const mp_arg_t allowed_args[] = { + { MP_QSTR_manufacturer, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_product, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_vid, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_pid, MP_ARG_INT, {.u_int = -1} }, + }; + struct { + mp_arg_val_t manufacturer; + mp_arg_val_t product; + mp_arg_val_t vid; + mp_arg_val_t pid; + } args; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args); + + if (!usb_identification_allocation) { + usb_identification_allocation = allocate_memory(sizeof(usb_identification_t), false, true); + } + usb_identification_t *identification = (usb_identification_t *)usb_identification_allocation->ptr; + + mp_arg_validate_int_range(args.vid.u_int, -1, (1 << 16) - 1, MP_QSTR_vid); + mp_arg_validate_int_range(args.pid.u_int, -1, (1 << 16) - 1, MP_QSTR_pid); + + identification->vid = args.vid.u_int > -1 ? args.vid.u_int : USB_VID; + identification->pid = args.pid.u_int > -1 ? args.pid.u_int : USB_PID; + + mp_buffer_info_t info; + if (args.manufacturer.u_obj != mp_const_none) { + mp_get_buffer_raise(args.manufacturer.u_obj, &info, MP_BUFFER_READ); + mp_arg_validate_length_range(info.len, 0, 126, MP_QSTR_manufacturer); + memcpy(identification->manufacturer_name, info.buf, info.len); + identification->manufacturer_name[info.len] = 0; + } else { + strcpy(identification->manufacturer_name, USB_MANUFACTURER); + } + + if (args.product.u_obj != mp_const_none) { + mp_get_buffer_raise(args.product.u_obj, &info, MP_BUFFER_READ); + mp_arg_validate_length_range(info.len, 0, 126, MP_QSTR_product); + memcpy(identification->product_name, info.buf, info.len); + identification->product_name[info.len] = 0; + } else { + strcpy(identification->product_name, USB_PRODUCT); + } + + return mp_const_none; + #else + mp_raise_NotImplementedError(NULL); + #endif +} +MP_DEFINE_CONST_FUN_OBJ_KW(supervisor_set_usb_identification_obj, 0, supervisor_set_usb_identification); + STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_supervisor) }, - { MP_ROM_QSTR(MP_QSTR_enable_autoreload), MP_ROM_PTR(&supervisor_enable_autoreload_obj) }, - { MP_ROM_QSTR(MP_QSTR_disable_autoreload), MP_ROM_PTR(&supervisor_disable_autoreload_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_rgb_status_brightness), MP_ROM_PTR(&supervisor_set_rgb_status_brightness_obj) }, { MP_ROM_QSTR(MP_QSTR_runtime), MP_ROM_PTR(&common_hal_supervisor_runtime_obj) }, { MP_ROM_QSTR(MP_QSTR_reload), MP_ROM_PTR(&supervisor_reload_obj) }, { MP_ROM_QSTR(MP_QSTR_RunReason), MP_ROM_PTR(&supervisor_run_reason_type) }, - { MP_ROM_QSTR(MP_QSTR_set_next_stack_limit), MP_ROM_PTR(&supervisor_set_next_stack_limit_obj) }, + #if CIRCUITPY_SAFEMODE_PY + { MP_ROM_QSTR(MP_QSTR_SafeModeReason), MP_ROM_PTR(&supervisor_safe_mode_reason_type) }, + #else + { MP_ROM_QSTR(MP_QSTR_SafeModeReason), MP_ROM_NONE }, + #endif { MP_ROM_QSTR(MP_QSTR_set_next_code_file), MP_ROM_PTR(&supervisor_set_next_code_file_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&supervisor_ticks_ms_obj) }, { MP_ROM_QSTR(MP_QSTR_get_previous_traceback), MP_ROM_PTR(&supervisor_get_previous_traceback_obj) }, - { MP_ROM_QSTR(MP_QSTR_disable_ble_workflow), MP_ROM_PTR(&supervisor_disable_ble_workflow_obj) }, { MP_ROM_QSTR(MP_QSTR_reset_terminal), MP_ROM_PTR(&supervisor_reset_terminal_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_usb_identification), MP_ROM_PTR(&supervisor_set_usb_identification_obj) }, + { MP_ROM_QSTR(MP_QSTR_status_bar), MP_ROM_PTR(&shared_module_supervisor_status_bar_obj) }, }; STATIC MP_DEFINE_CONST_DICT(supervisor_module_globals, supervisor_module_globals_table); diff --git a/shared-bindings/supervisor/__init__.h b/shared-bindings/supervisor/__init__.h index 40a1e73932..4b4dc4fc57 100644 --- a/shared-bindings/supervisor/__init__.h +++ b/shared-bindings/supervisor/__init__.h @@ -31,8 +31,10 @@ #include "py/obj.h" #include "common-hal/supervisor/Runtime.h" +#include "shared-module/supervisor/StatusBar.h" extern const super_runtime_obj_t common_hal_supervisor_runtime_obj; +extern supervisor_status_bar_obj_t shared_module_supervisor_status_bar_obj; extern mp_obj_t supervisor_ticks_ms(void); diff --git a/shared-bindings/support_matrix.rst b/shared-bindings/support_matrix.rst index e007e27b47..3d5e544ea0 100644 --- a/shared-bindings/support_matrix.rst +++ b/shared-bindings/support_matrix.rst @@ -6,6 +6,11 @@ Module Support Matrix - Which Modules Are Available on Which Boards The following table lists the available built-in modules for each CircuitPython capable board, as well as each :term:`frozen module` included on it. +You can filter this list by typing one or more module names or partial names into the search box. +Only those boards that provide those modules will be listed. +To exclude boards that provide a module, type a "-" in front of the module name. +You can also type a regular expression as a filter. + .. raw:: html

(all)

@@ -21,9 +26,9 @@ capable board, as well as each :term:`frozen module` included on it. {% for key, value in support_matrix|dictsort %} {{ '.. _' ~ key|replace(" ", "-") ~ ':' }} * - {{ key }} - - {{ ':py:mod:`' ~ value[0]|join("`, :py:mod:`") ~ '`' }} + - {{ ':py:mod:`' ~ value.modules|join("`, :py:mod:`") ~ '`' }} - {% for module in value[1] %}\ + {% for module in value.frozen_libraries %}\ {% if loop.index == 1 %}**Frozen Modules:** {% endif %}\ {% if loop.index > 1 %}, {% endif %}\ {% if module[1] %}{{ '`' ~ module[0] ~ ' <' ~ module[1] ~ '>`__' }}\ diff --git a/shared-bindings/synthio/MidiTrack.c b/shared-bindings/synthio/MidiTrack.c index e27ff903c6..b987337eaa 100644 --- a/shared-bindings/synthio/MidiTrack.c +++ b/shared-bindings/synthio/MidiTrack.c @@ -37,7 +37,9 @@ //| class MidiTrack: //| """Simple square-wave MIDI synth""" //| -//| def __init__(self, buffer: ReadableBuffer, tempo: int, *, sample_rate: int = 11025) -> None: +//| def __init__( +//| self, buffer: ReadableBuffer, tempo: int, *, sample_rate: int = 11025 +//| ) -> None: //| """Create a MidiTrack from the given stream of MIDI events. Only "Note On" and "Note Off" events //| are supported; channel numbers and key velocities are ignored. Up to two notes may be on at the //| same time. @@ -62,7 +64,6 @@ //| pass //| print("stopped")""" //| ... -//| STATIC mp_obj_t synthio_miditrack_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_buffer, ARG_tempo, ARG_sample_rate }; static const mp_arg_t allowed_args[] = { @@ -90,7 +91,6 @@ STATIC mp_obj_t synthio_miditrack_make_new(const mp_obj_type_t *type, size_t n_a //| def deinit(self) -> None: //| """Deinitialises the MidiTrack and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t synthio_miditrack_deinit(mp_obj_t self_in) { synthio_miditrack_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_synthio_miditrack_deinit(self); @@ -107,14 +107,12 @@ STATIC void check_for_deinit(synthio_miditrack_obj_t *self) { //| def __enter__(self) -> MidiTrack: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t synthio_miditrack_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_synthio_miditrack_deinit(args[0]); diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c index 605ee2727f..46e171ff7e 100644 --- a/shared-bindings/terminalio/Terminal.c +++ b/shared-bindings/terminalio/Terminal.c @@ -29,7 +29,7 @@ #include "shared-bindings/terminalio/Terminal.h" #include "shared-bindings/util.h" -#include "py/ioctl.h" +#include "py/stream.h" #include "py/objproperty.h" #include "py/objstr.h" #include "py/runtime.h" @@ -40,42 +40,47 @@ //| class Terminal: //| """Display a character stream with a TileGrid //| -//| ASCII control: -//| * ``\\r`` - Move cursor to column 1 -//| * ``\\n`` - Move cursor down a row -//| * ``\\b`` - Move cursor left one if possible +//| ASCII control: +//| * ``\\r`` - Move cursor to column 1 +//| * ``\\n`` - Move cursor down a row +//| * ``\\b`` - Move cursor left one if possible //| -//| OSC control sequences: -//| * ``ESC ] 0; ESC \\`` - Set title bar to -//| * ``ESC ] ####; ESC \\`` - Ignored +//| OSC control sequences: +//| * ``ESC ] 0; ESC \\`` - Set title bar to +//| * ``ESC ] ####; ESC \\`` - Ignored //| -//| VT100 control sequences: -//| * ``ESC [ K`` - Clear the remainder of the line -//| * ``ESC [ #### D`` - Move the cursor to the left by #### -//| * ``ESC [ 2 J`` - Erase the entire display -//| * ``ESC [ nnnn ; mmmm H`` - Move the cursor to mmmm, nnnn. +//| VT100 control sequences: +//| * ``ESC [ K`` - Clear the remainder of the line +//| * ``ESC [ #### D`` - Move the cursor to the left by #### +//| * ``ESC [ 2 J`` - Erase the entire display +//| * ``ESC [ nnnn ; mmmm H`` - Move the cursor to mmmm, nnnn. //| """ //| -//| def __init__(self, scroll_area: displayio.TileGrid, font: fontio.BuiltinFont, *, title_bar: displayio.TileGrid = None) -> None: +//| def __init__( +//| self, +//| scroll_area: displayio.TileGrid, +//| font: fontio.BuiltinFont, +//| *, +//| status_bar: Optional[displayio.TileGrid] = None +//| ) -> None: //| """Terminal manages tile indices and cursor position based on VT100 commands. The font should be //| a `fontio.BuiltinFont` and the TileGrid's bitmap should match the font's bitmap.""" //| ... -//| STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - enum { ARG_scroll_area, ARG_font, ARG_title_bar }; + enum { ARG_scroll_area, ARG_font, ARG_status_bar }; static const mp_arg_t allowed_args[] = { { MP_QSTR_scroll_area, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_font, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_title_bar, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } }, + { MP_QSTR_status_bar, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); displayio_tilegrid_t *scroll_area = mp_arg_validate_type(args[ARG_scroll_area].u_obj, &displayio_tilegrid_type, MP_QSTR_scroll_area); - displayio_tilegrid_t *title_bar = NULL; - if (args[ARG_title_bar].u_obj != mp_const_none) { - title_bar = mp_arg_validate_type(args[ARG_title_bar].u_obj, &displayio_tilegrid_type, MP_QSTR_title_bar); + displayio_tilegrid_t *status_bar = NULL; + if (args[ARG_status_bar].u_obj != mp_const_none) { + status_bar = mp_arg_validate_type(args[ARG_status_bar].u_obj, &displayio_tilegrid_type, MP_QSTR_status_bar); } fontio_builtinfont_t *font = mp_arg_validate_type(args[ARG_font].u_obj, &fontio_builtinfont_type, MP_QSTR_font); @@ -83,7 +88,7 @@ STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n terminalio_terminal_obj_t *self = m_new_obj(terminalio_terminal_obj_t); self->base.type = &terminalio_terminal_type; - common_hal_terminalio_terminal_construct(self, scroll_area, font, title_bar); + common_hal_terminalio_terminal_construct(self, scroll_area, font, status_bar); return MP_OBJ_FROM_PTR(self); } @@ -106,11 +111,11 @@ STATIC mp_uint_t terminalio_terminal_write(mp_obj_t self_in, const void *buf_in, STATIC mp_uint_t terminalio_terminal_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { terminalio_terminal_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret; - if (request == MP_IOCTL_POLL) { + if (request == MP_STREAM_POLL) { mp_uint_t flags = arg; ret = 0; - if ((flags & MP_IOCTL_POLL_WR) && common_hal_terminalio_terminal_ready_to_tx(self)) { - ret |= MP_IOCTL_POLL_WR; + if ((flags & MP_STREAM_POLL_WR) && common_hal_terminalio_terminal_ready_to_tx(self)) { + ret |= MP_STREAM_POLL_WR; } } else { *errcode = MP_EINVAL; diff --git a/shared-bindings/terminalio/Terminal.h b/shared-bindings/terminalio/Terminal.h index 64609b49b1..fda1c29bdd 100644 --- a/shared-bindings/terminalio/Terminal.h +++ b/shared-bindings/terminalio/Terminal.h @@ -34,7 +34,7 @@ extern const mp_obj_type_t terminalio_terminal_type; extern void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, - displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font, displayio_tilegrid_t *title_bar); + displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font, displayio_tilegrid_t *status_bar); // Write characters. len is in characters NOT bytes! extern size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, diff --git a/shared-bindings/terminalio/__init__.c b/shared-bindings/terminalio/__init__.c index 5fd1a2751a..a5980a8b9b 100644 --- a/shared-bindings/terminalio/__init__.c +++ b/shared-bindings/terminalio/__init__.c @@ -47,7 +47,6 @@ //| //| FONT: fontio.BuiltinFont //| """The built in font""" -//| STATIC const mp_rom_map_elem_t terminalio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_terminalio) }, { MP_ROM_QSTR(MP_QSTR_Terminal), MP_OBJ_FROM_PTR(&terminalio_terminal_type) }, diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 096c80d382..d02923f162 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -97,9 +97,7 @@ STATIC mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, s size_t len; mp_obj_t *items; mp_obj_get_array(args[0], &len, &items); - if (len != 9) { - mp_raise_TypeError(translate("time.struct_time() takes a 9-sequence")); - } + mp_arg_validate_length(len, 9, MP_QSTR_value); return namedtuple_make_new(type, len, 0, items); } diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index 729cf94d5d..7f26149b00 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -57,14 +57,13 @@ //| //| :param ~microcontroller.Pin pin: the pin to read from""" //| ... -//| STATIC mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // check number of arguments mp_arg_check_num(n_args, n_kw, 1, 1, false); // 1st argument is the pin - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0], MP_QSTR_pin); touchio_touchin_obj_t *self = m_new_obj(touchio_touchin_obj_t); self->base.type = &touchio_touchin_type; @@ -76,7 +75,6 @@ STATIC mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, //| def deinit(self) -> None: //| """Deinitialises the TouchIn and releases any hardware resources for reuse.""" //| ... -//| STATIC mp_obj_t touchio_touchin_deinit(mp_obj_t self_in) { touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_touchio_touchin_deinit(self); @@ -93,14 +91,12 @@ STATIC void check_for_deinit(touchio_touchin_obj_t *self) { //| def __enter__(self) -> TouchIn: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -//| STATIC mp_obj_t touchio_touchin_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_touchio_touchin_deinit(args[0]); @@ -112,7 +108,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(touchio_touchin___exit___obj, 4, 4, t //| """Whether the touch pad is being touched or not. (read-only) //| //| True when `raw_value` > `threshold`.""" -//| STATIC mp_obj_t touchio_touchin_obj_get_value(mp_obj_t self_in) { touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -126,7 +121,6 @@ MP_PROPERTY_GETTER(touchio_touchin_value_obj, //| raw_value: int //| """The raw touch measurement as an `int`. (read-only)""" -//| STATIC mp_obj_t touchio_touchin_obj_get_raw_value(mp_obj_t self_in) { touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -165,10 +159,7 @@ STATIC mp_obj_t touchio_touchin_obj_set_threshold(mp_obj_t self_in, mp_obj_t thr touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); uint32_t new_threshold = mp_obj_get_int(threshold_obj); - if (new_threshold < 0 || new_threshold > UINT16_MAX) { - // I would use MP_STRINGIFY(UINT16_MAX), but that prints "0xffff" instead of 65536. - mp_raise_ValueError(translate("threshold must be in the range 0-65536")); - } + mp_arg_validate_int_range(new_threshold, 0, UINT16_MAX, MP_QSTR_threshold); common_hal_touchio_touchin_set_threshold(self, new_threshold); return mp_const_none; } diff --git a/shared-bindings/touchio/__init__.c b/shared-bindings/touchio/__init__.c index 2d6bf5f31c..8501315ca7 100644 --- a/shared-bindings/touchio/__init__.c +++ b/shared-bindings/touchio/__init__.c @@ -58,7 +58,6 @@ //| //| This example will initialize the the device, and print the //| :py:data:`~touchio.TouchIn.value`.""" -//| STATIC const mp_rom_map_elem_t touchio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_touchio) }, diff --git a/shared-bindings/traceback/__init__.c b/shared-bindings/traceback/__init__.c index 880fe08e85..3ad601eb39 100644 --- a/shared-bindings/traceback/__init__.c +++ b/shared-bindings/traceback/__init__.c @@ -39,7 +39,46 @@ //| ... //| -STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj_t tb_obj, mp_obj_t limit_obj) { +STATIC void traceback_exception_common(bool is_print_exception, mp_print_t *print, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_exc, ARG_value, ARG_tb, ARG_limit, ARG_file, ARG_chain }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_value, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_tb, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_limit, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_file, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_chain, MP_ARG_BOOL, {.u_bool = true} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t value = args[ARG_value].u_obj; + if (value == MP_OBJ_NULL) { + value = args[ARG_exc].u_obj; + } + mp_obj_t tb_obj = args[ARG_tb].u_obj; + mp_obj_t limit_obj = args[ARG_limit].u_obj; + bool chain = args[ARG_chain].u_bool; + + if (args[ARG_file].u_obj != mp_const_none) { + if (!is_print_exception) { + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE + mp_arg_error_terse_mismatch(); + #else + mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("unexpected keyword argument '%q'"), MP_QSTR_file); + #endif + + } + #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES + mp_get_stream_raise(args[ARG_file].u_obj, MP_STREAM_OP_WRITE); + print->data = MP_OBJ_TO_PTR(args[ARG_file].u_obj); + print->print_strn = mp_stream_write_adaptor; + #else + mp_raise_NotImplementedError(translate("file write is not available")); + #endif + } + if (!mp_obj_is_exception_instance(value)) { mp_raise_TypeError(translate("invalid exception")); } @@ -53,8 +92,19 @@ STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj mp_obj_exception_t *exc = mp_obj_exception_get_native(value); mp_obj_traceback_t *trace_backup = exc->traceback; + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + mp_obj_exception_t *context_backup = exc->context; + mp_obj_exception_t *cause_backup = exc->cause; - if (tb_obj != mp_const_none && print_tb) { + if (!chain) { + exc->context = NULL; + exc->cause = NULL; + } + #endif + + if (tb_obj == MP_OBJ_NULL) { + /* Print the traceback's exception as is */ + } else if (tb_obj != mp_const_none && print_tb) { exc->traceback = mp_arg_validate_type(tb_obj, &mp_type_traceback, MP_QSTR_tb); } else { exc->traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; @@ -62,98 +112,92 @@ STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj shared_module_traceback_print_exception(MP_OBJ_TO_PTR(value), print, limit); exc->traceback = trace_backup; + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + exc->context = context_backup; + exc->cause = cause_backup; + #endif } -//| def format_exception(etype: Type[BaseException], value: BaseException, tb: TracebackType, -//| limit: Optional[int] = None, chain: Optional[bool] = True) -> None: +//| def format_exception( +//| exc: BaseException | Type[BaseException], +//| /, +//| value: Optional[BaseException] = None, +//| tb: Optional[TracebackType] = None, +//| limit: Optional[int] = None, +//| chain: Optional[bool] = True, +//| ) -> List[str]: //| """Format a stack trace and the exception information. //| +//| If the exception value is passed in ``exc``, then this exception value and its +//| associated traceback are used. This is compatible with CPython 3.10 and newer. +//| +//| If the exception value is passed in ``value``, then any value passed in for +//| ``exc`` is ignored. ``value`` is used as the exception value and the +//| traceback in the ``tb`` argument is used. In this case, if ``tb`` is None, +//| no traceback will be shown. This is compatible with CPython 3.5 and +//| newer. +//| //| The arguments have the same meaning as the corresponding arguments //| to print_exception(). The return value is a list of strings, each //| ending in a newline and some containing internal newlines. When //| these lines are concatenated and printed, exactly the same text is //| printed as does print_exception(). //| -//| .. note:: Setting ``chain`` will have no effect as chained exceptions are not yet implemented. -//| -//| :param Type[BaseException] etype: This is ignored and inferred from the type of ``value``. -//| :param BaseException value: The exception. Must be an instance of `BaseException`. -//| :param TracebackType tb: The traceback object. If `None`, the traceback will not be printed. +//| :param exc: The exception. Must be an instance of `BaseException`. Unused if value is specified. +//| :param value: If specified, is used in place of ``exc``. +//| :param TracebackType tb: When value is alsp specified, ``tb`` is used in place of the exception's own traceback. If `None`, the traceback will not be printed. //| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive. //| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed. -//| :param bool chain: If `True` then chained exceptions will be printed (note: not yet implemented). -//| +//| :param bool chain: If `True` then chained exceptions will be printed. //| """ -//| ... //| STATIC mp_obj_t traceback_format_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_etype, ARG_value, ARG_tb, ARG_limit, ARG_chain }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_etype, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_value, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_tb, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_limit, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_chain, MP_ARG_BOOL, {.u_bool = true} }, - }; - - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - mp_print_t print; vstr_t vstr; vstr_init_print(&vstr, 0, &print); - traceback_exception_common(&print, args[ARG_value].u_obj, args[ARG_tb].u_obj, args[ARG_limit].u_obj); - return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + traceback_exception_common(false, &print, n_args, pos_args, kw_args); + mp_obj_t output = mp_obj_new_str_from_vstr(&mp_type_str, &vstr); + return mp_obj_new_list(1, &output); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_format_exception_obj, 0, traceback_format_exception); -//| def print_exception(etype: Type[BaseException], value: BaseException, tb: TracebackType, -//| limit: Optional[int] = None, file: Optional[io.FileIO] = None, chain: Optional[bool] = True) -> None: -//| +//| def print_exception( +//| exc: BaseException | Type[BaseException], +//| /, +//| value: Optional[BaseException] = None, +//| tb: Optional[TracebackType] = None, +//| limit: Optional[int] = None, +//| file: Optional[io.FileIO] = None, +//| chain: Optional[bool] = True, +//| ) -> None: //| """Prints exception information and stack trace entries. //| -//| .. note:: Setting ``chain`` will have no effect as chained exceptions are not yet implemented. +//| If the exception value is passed in ``exc``, then this exception value and its +//| associated traceback are used. This is compatible with CPython 3.10 and newer. //| -//| :param Type[BaseException] etype: This is ignored and inferred from the type of ``value``. -//| :param BaseException value: The exception. Must be an instance of `BaseException`. -//| :param TracebackType tb: The traceback object. If `None`, the traceback will not be printed. +//| If the exception value is passed in ``value``, then any value passed in for +//| ``exc`` is ignored. ``value`` is used as the exception value and the +//| traceback in the ``tb`` argument is used. In this case, if ``tb`` is None, +//| no traceback will be shown. This is compatible with CPython 3.5 and +//| newer. +//| +//| :param exc: The exception. Must be an instance of `BaseException`. Unused if value is specified. +//| :param value: If specified, is used in place of ``exc``. +//| :param tb: When value is alsp specified, ``tb`` is used in place of the exception's own traceback. If `None`, the traceback will not be printed. //| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive. //| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed. //| :param io.FileIO file: If file is omitted or `None`, the output goes to `sys.stderr`; otherwise it should be an open //| file or file-like object to receive the output. -//| :param bool chain: If `True` then chained exceptions will be printed (note: not yet implemented). +//| :param bool chain: If `True` then chained exceptions will be printed. //| //| """ //| ... //| STATIC mp_obj_t traceback_print_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_etype, ARG_value, ARG_tb, ARG_limit, ARG_file, ARG_chain }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_etype, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_value, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_tb, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_limit, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_file, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_chain, MP_ARG_BOOL, {.u_bool = true} }, - }; - - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - mp_print_t print = mp_plat_print; - if (args[ARG_file].u_obj != mp_const_none) { - #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES - mp_get_stream_raise(args[ARG_file].u_obj, MP_STREAM_OP_WRITE); - print.data = MP_OBJ_TO_PTR(args[ARG_file].u_obj); - print.print_strn = mp_stream_write_adaptor; - #else - mp_raise_NotImplementedError(translate("file write is not available")); - #endif - } - - traceback_exception_common(&print, args[ARG_value].u_obj, args[ARG_tb].u_obj, args[ARG_limit].u_obj); + traceback_exception_common(true, &print, n_args, pos_args, kw_args); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_print_exception_obj, 0, traceback_print_exception); diff --git a/shared-bindings/usb/__init__.c b/shared-bindings/usb/__init__.c index bae72da1f7..443d5cf788 100644 --- a/shared-bindings/usb/__init__.c +++ b/shared-bindings/usb/__init__.c @@ -35,7 +35,6 @@ //| //| The `usb` is a subset of PyUSB that allows you to communicate to USB devices. //| """ -//| STATIC mp_rom_map_elem_t usb_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_usb) }, diff --git a/shared-bindings/usb/core/Device.c b/shared-bindings/usb/core/Device.c index 3a9e9bb421..40bb01dc08 100644 --- a/shared-bindings/usb/core/Device.c +++ b/shared-bindings/usb/core/Device.c @@ -62,17 +62,14 @@ #include "py/runtime.h" //| class Device: -//| //| def __init__(self) -> None: //| """User code cannot create Device objects. Instead, get them from -//| `usb.core.find`. +//| `usb.core.find`. //| """ //| ... -//| //| idVendor: int //| """The USB vendor ID of the device""" -//| STATIC mp_obj_t usb_core_device_obj_get_idVendor(mp_obj_t self_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_usb_core_device_get_idVendor(self)); @@ -84,7 +81,6 @@ MP_PROPERTY_GETTER(usb_core_device_idVendor_obj, //| idProduct: int //| """The USB product ID of the device""" -//| STATIC mp_obj_t usb_core_device_obj_get_idProduct(mp_obj_t self_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_usb_core_device_get_idProduct(self)); @@ -96,7 +92,6 @@ MP_PROPERTY_GETTER(usb_core_device_idProduct_obj, //| serial_number: str //| """The USB device's serial number string.""" -//| STATIC mp_obj_t usb_core_device_obj_get_serial_number(mp_obj_t self_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_usb_core_device_get_serial_number(self); @@ -108,7 +103,6 @@ MP_PROPERTY_GETTER(usb_core_device_serial_number_obj, //| product: str //| """The USB device's product string.""" -//| STATIC mp_obj_t usb_core_device_obj_get_product(mp_obj_t self_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_usb_core_device_get_product(self); @@ -120,7 +114,6 @@ MP_PROPERTY_GETTER(usb_core_device_product_obj, //| manufacturer: str //| """The USB device's manufacturer string.""" -//| STATIC mp_obj_t usb_core_device_obj_get_manufacturer(mp_obj_t self_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_usb_core_device_get_manufacturer(self); @@ -130,16 +123,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_get_manufacturer_obj, usb_core_device_ MP_PROPERTY_GETTER(usb_core_device_manufacturer_obj, (mp_obj_t)&usb_core_device_get_manufacturer_obj); -//| def write(self, endpoint: int, data: ReadableBuffer, timeout = None) -> int: +//| def write(self, endpoint: int, data: ReadableBuffer, timeout: Optional[int] = None) -> int: //| """Write data to a specific endpoint on the device. //| -//| :param int endpoint: the bEndpointAddress you want to communicate with. -//| :param ReadableBuffer data: the data to send -//| :param int timeout: Time to wait specified in milliseconds. (Different from most CircuitPython!) -//| :returns: the number of bytes written +//| :param int endpoint: the bEndpointAddress you want to communicate with. +//| :param ReadableBuffer data: the data to send +//| :param int timeout: Time to wait specified in milliseconds. (Different from most CircuitPython!) +//| :returns: the number of bytes written //| """ //| ... -//| STATIC mp_obj_t usb_core_device_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_endpoint, ARG_data, ARG_timeout }; static const mp_arg_t allowed_args[] = { @@ -159,13 +151,15 @@ STATIC mp_obj_t usb_core_device_write(size_t n_args, const mp_obj_t *pos_args, m MP_DEFINE_CONST_FUN_OBJ_KW(usb_core_device_write_obj, 2, usb_core_device_write); -//| def read(self, endpoint: int, size_or_buffer: array.array, timeout = None) -> int: +//| def read( +//| self, endpoint: int, size_or_buffer: array.array, timeout: Optional[int] = None +//| ) -> int: //| """Read data from the endpoint. //| -//| :param int endpoint: the bEndpointAddress you want to communicate with. -//| :param array.array size_or_buffer: the array to read data into. PyUSB also allows size but CircuitPython only support array to force deliberate memory use. -//| :param int timeout: Time to wait specified in milliseconds. (Different from most CircuitPython!) -//| :returns: the number of bytes read +//| :param int endpoint: the bEndpointAddress you want to communicate with. +//| :param array.array size_or_buffer: the array to read data into. PyUSB also allows size but CircuitPython only support array to force deliberate memory use. +//| :param int timeout: Time to wait specified in milliseconds. (Different from most CircuitPython!) +//| :returns: the number of bytes read //| """ //| ... STATIC mp_obj_t usb_core_device_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -186,27 +180,33 @@ STATIC mp_obj_t usb_core_device_read(size_t n_args, const mp_obj_t *pos_args, mp } MP_DEFINE_CONST_FUN_OBJ_KW(usb_core_device_read_obj, 2, usb_core_device_read); -//| def ctrl_transfer(self, bmRequestType, bRequest, wValue=0, wIndex=0, -//| data_or_wLength: array.array = None, timeout = None) -> int: +//| def ctrl_transfer( +//| self, +//| bmRequestType: int, +//| bRequest: int, +//| wValue: int = 0, +//| wIndex: int = 0, +//| data_or_wLength: Optional[array.array] = None, +//| timeout: Optional[int] = None, +//| ) -> int: //| """Do a control transfer on the endpoint 0. The parameters bmRequestType, -//| bRequest, wValue and wIndex are the same of the USB Standard Control -//| Request format. +//| bRequest, wValue and wIndex are the same of the USB Standard Control +//| Request format. //| -//| Control requests may or may not have a data payload to write/read. -//| In cases which it has, the direction bit of the bmRequestType -//| field is used to infer the desired request direction. +//| Control requests may or may not have a data payload to write/read. +//| In cases which it has, the direction bit of the bmRequestType +//| field is used to infer the desired request direction. //| -//| For host to device requests (OUT), data_or_wLength parameter is -//| the data payload to send, and it must be a sequence type convertible -//| to an array object. In this case, the return value is the number -//| of bytes written in the data payload. +//| For host to device requests (OUT), data_or_wLength parameter is +//| the data payload to send, and it must be a sequence type convertible +//| to an array object. In this case, the return value is the number +//| of bytes written in the data payload. //| -//| For device to host requests (IN), data_or_wLength is an array -//| object which the data will be read to, and the return value is the -//| number of bytes read. -//| """ +//| For device to host requests (IN), data_or_wLength is an array +//| object which the data will be read to, and the return value is the +//| number of bytes read. +//| """ //| ... -//| STATIC mp_obj_t usb_core_device_ctrl_transfer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bmRequestType, ARG_bRequest, ARG_wValue, ARG_wIndex, ARG_data_or_wLength, ARG_timeout }; static const mp_arg_t allowed_args[] = { @@ -240,12 +240,11 @@ MP_DEFINE_CONST_FUN_OBJ_KW(usb_core_device_ctrl_transfer_obj, 2, usb_core_device //| def is_kernel_driver_active(self, interface: int) -> bool: //| """Determine if CircuitPython is using the interface. If it is, the -//| object will be unable to perform I/O. +//| object will be unable to perform I/O. //| -//| :param int interface: the device interface number to check -//| """ +//| :param int interface: the device interface number to check +//| """ //| ... -//| STATIC mp_obj_t usb_core_device_is_kernel_driver_active(mp_obj_t self_in, mp_obj_t interface_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_int_t interface = mp_obj_get_int(interface_in); @@ -254,15 +253,14 @@ STATIC mp_obj_t usb_core_device_is_kernel_driver_active(mp_obj_t self_in, mp_obj } MP_DEFINE_CONST_FUN_OBJ_2(usb_core_device_is_kernel_driver_active_obj, usb_core_device_is_kernel_driver_active); -//| def detach_kernel_driver(self, interface: int): +//| def detach_kernel_driver(self, interface: int) -> None: //| """Stop CircuitPython from using the interface. If successful, you -//| will then be able to perform I/O. CircuitPython will automatically -//| re-start using the interface on reload. +//| will then be able to perform I/O. CircuitPython will automatically +//| re-start using the interface on reload. //| -//| :param int interface: the device interface number to stop CircuitPython on +//| :param int interface: the device interface number to stop CircuitPython on //| """ //| ... -//| STATIC mp_obj_t usb_core_device_detach_kernel_driver(mp_obj_t self_in, mp_obj_t interface_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_int_t interface = mp_obj_get_int(interface_in); @@ -271,10 +269,10 @@ STATIC mp_obj_t usb_core_device_detach_kernel_driver(mp_obj_t self_in, mp_obj_t } MP_DEFINE_CONST_FUN_OBJ_2(usb_core_device_detach_kernel_driver_obj, usb_core_device_detach_kernel_driver); -//| def attach_kernel_driver(self, interface: int): +//| def attach_kernel_driver(self, interface: int) -> None: //| """Allow CircuitPython to use the interface if it wants to. //| -//| :param int interface: the device interface number to allow CircuitPython to use +//| :param int interface: the device interface number to allow CircuitPython to use //| """ //| ... //| diff --git a/shared-bindings/usb/core/__init__.c b/shared-bindings/usb/core/__init__.c index 0e0d409ede..faeef23a88 100644 --- a/shared-bindings/usb/core/__init__.c +++ b/shared-bindings/usb/core/__init__.c @@ -44,7 +44,9 @@ //| class USBError(OSError): //| """Catchall exception for USB related errors.""" +//| //| ... +//| MP_DEFINE_USB_CORE_EXCEPTION(USBError, OSError) NORETURN void mp_raise_usb_core_USBError(const compressed_string_t *fmt, ...) { va_list argptr; @@ -56,6 +58,7 @@ NORETURN void mp_raise_usb_core_USBError(const compressed_string_t *fmt, ...) { //| class USBTimeoutError(USBError): //| """Raised when a USB transfer times out.""" +//| //| ... //| MP_DEFINE_USB_CORE_EXCEPTION(USBTimeoutError, usb_core_USBError) @@ -64,12 +67,14 @@ NORETURN void mp_raise_usb_core_USBTimeoutError(void) { } -//| def find(find_all=False, *, idVendor=None, idProduct=None): -//| """Find the first device that matches the given requirements or, if -//| find_all is True, return a generator of all matching devices. +//| def find( +//| find_all: bool = False, *, idVendor: Optional[int] = None, idProduct: Optional[int] = None +//| ) -> Device: +//| """Find the first device that matches the given requirements or, if +//| find_all is True, return a generator of all matching devices. //| -//| Returns None if no device matches. -//| """ +//| Returns None if no device matches. +//| """ //| typedef struct { mp_obj_base_t base; diff --git a/shared-bindings/usb_cdc/Serial.c b/shared-bindings/usb_cdc/Serial.c index 8a74380be3..9fe6cafd5f 100644 --- a/shared-bindings/usb_cdc/Serial.c +++ b/shared-bindings/usb_cdc/Serial.c @@ -29,7 +29,7 @@ #include "shared-bindings/usb_cdc/Serial.h" #include "shared-bindings/util.h" -#include "py/ioctl.h" +#include "py/stream.h" #include "py/objproperty.h" #include "py/runtime.h" #include "py/stream.h" @@ -42,7 +42,6 @@ //| """You cannot create an instance of `usb_cdc.Serial`. //| The available instances are in the ``usb_cdc.serials`` tuple.""" //| ... -//| //| def read(self, size: int = 1) -> bytes: //| """Read at most ``size`` bytes. If ``size`` exceeds the internal buffer size //| only the bytes in the buffer will be read. If `timeout` is > 0 or ``None``, @@ -52,15 +51,14 @@ //| :return: Data read //| :rtype: bytes""" //| ... -//| //| def readinto(self, buf: WriteableBuffer) -> int: -//| """Read bytes into the ``buf``. If ``nbytes`` is specified then read at most -//| that many bytes, subject to `timeout`. Otherwise, read at most ``len(buf)`` bytes. +//| """Read bytes into the ``buf``. Read at most ``len(buf)`` bytes. If `timeout` +//| is > 0 or ``None``, keep waiting until the timeout expires or ``len(buf)`` +//| bytes are available. //| //| :return: number of bytes read and stored into ``buf`` -//| :rtype: bytes""" +//| :rtype: int""" //| ... -//| //| def readline(self, size: int = -1) -> Optional[bytes]: //| r"""Read a line ending in a newline character ("\\n"), including the newline. //| Return everything readable if no newline is found and ``timeout`` is 0. @@ -73,7 +71,6 @@ //| :return: the line read //| :rtype: bytes or None""" //| ... -//| //| def readlines(self) -> List[Optional[bytes]]: //| """Read multiple lines as a list, using `readline()`. //| @@ -83,18 +80,15 @@ //| :return: a list of the line read //| :rtype: list""" //| ... -//| //| def write(self, buf: ReadableBuffer) -> int: //| """Write as many bytes as possible from the buffer of bytes. //| //| :return: the number of bytes written //| :rtype: int""" //| ... -//| //| def flush(self) -> None: //| """Force out any unwritten bytes, waiting until they are written.""" //| ... -//| // These three methods are used by the shared stream methods. STATIC mp_uint_t usb_cdc_serial_read_stream(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { @@ -120,14 +114,14 @@ STATIC mp_uint_t usb_cdc_serial_ioctl_stream(mp_obj_t self_in, mp_uint_t request usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret = 0; switch (request) { - case MP_IOCTL_POLL: { + case MP_STREAM_POLL: { mp_uint_t flags = arg; ret = 0; - if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_cdc_serial_get_in_waiting(self) > 0) { - ret |= MP_IOCTL_POLL_RD; + if ((flags & MP_STREAM_POLL_RD) && common_hal_usb_cdc_serial_get_in_waiting(self) > 0) { + ret |= MP_STREAM_POLL_RD; } - if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_cdc_serial_get_out_waiting(self) == 0) { - ret |= MP_IOCTL_POLL_WR; + if ((flags & MP_STREAM_POLL_WR) && common_hal_usb_cdc_serial_get_out_waiting(self) == 0) { + ret |= MP_STREAM_POLL_WR; } break; } @@ -150,7 +144,6 @@ STATIC mp_uint_t usb_cdc_serial_ioctl_stream(mp_obj_t self_in, mp_uint_t request //| Most terminal programs and ``pyserial`` assert DTR when opening a serial connection. //| However, the C# ``SerialPort`` API does not. You must set ``SerialPort.DtrEnable``. //| """ -//| STATIC mp_obj_t usb_cdc_serial_get_connected(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_usb_cdc_serial_get_connected(self)); @@ -162,7 +155,6 @@ MP_PROPERTY_GETTER(usb_cdc_serial_connected_obj, //| in_waiting: int //| """Returns the number of bytes waiting to be read on the USB serial input. (read-only)""" -//| STATIC mp_obj_t usb_cdc_serial_get_in_waiting(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_usb_cdc_serial_get_in_waiting(self)); @@ -174,7 +166,6 @@ MP_PROPERTY_GETTER(usb_cdc_serial_in_waiting_obj, //| out_waiting: int //| """Returns the number of bytes waiting to be written on the USB serial output. (read-only)""" -//| STATIC mp_obj_t usb_cdc_serial_get_out_waiting(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_usb_cdc_serial_get_out_waiting(self)); @@ -187,7 +178,6 @@ MP_PROPERTY_GETTER(usb_cdc_serial_out_waiting_obj, //| def reset_input_buffer(self) -> None: //| """Clears any unread bytes.""" //| ... -//| STATIC mp_obj_t usb_cdc_serial_reset_input_buffer(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_usb_cdc_serial_reset_input_buffer(self); @@ -198,7 +188,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_reset_input_buffer_obj, usb_cdc_serial_ //| def reset_output_buffer(self) -> None: //| """Clears any unwritten bytes.""" //| ... -//| STATIC mp_obj_t usb_cdc_serial_reset_output_buffer(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_usb_cdc_serial_reset_output_buffer(self); @@ -209,7 +198,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_reset_output_buffer_obj, usb_cdc_serial //| timeout: Optional[float] //| """The initial value of `timeout` is ``None``. If ``None``, wait indefinitely to satisfy //| the conditions of a read operation. If 0, do not wait. If > 0, wait only ``timeout`` seconds.""" -//| STATIC mp_obj_t usb_cdc_serial_get_timeout(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_float_t timeout = common_hal_usb_cdc_serial_get_timeout(self); diff --git a/shared-bindings/usb_cdc/__init__.c b/shared-bindings/usb_cdc/__init__.c index e23e289309..b4e712e854 100644 --- a/shared-bindings/usb_cdc/__init__.c +++ b/shared-bindings/usb_cdc/__init__.c @@ -62,6 +62,7 @@ //| """A `Serial` object that can be used to send and receive binary data to and from //| the host. //| Note that `data` is *disabled* by default. ``data`` is ``None`` if disabled.""" +//| //| def disable() -> None: //| """Do not present any USB CDC device to the host. diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index f0074f9cac..cb88766b3e 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -32,7 +32,16 @@ //| class Device: //| """HID Device specification""" //| -//| def __init__(self, *, report_descriptor: ReadableBuffer, usage_page: int, usage: int, report_ids: Sequence[int], in_report_lengths: Sequence[int], out_report_lengths: Sequence[int]) -> None: +//| def __init__( +//| self, +//| *, +//| report_descriptor: ReadableBuffer, +//| usage_page: int, +//| usage: int, +//| report_ids: Sequence[int], +//| in_report_lengths: Sequence[int], +//| out_report_lengths: Sequence[int] +//| ) -> None: //| """Create a description of a USB HID device. The actual device is created when you //| pass a `Device` to `usb_hid.enable()`. //| @@ -66,7 +75,6 @@ //| ) //| """ //| ... -//| //| KEYBOARD: Device //| """Standard keyboard device supporting keycodes 0x00-0xDD, modifiers 0xE-0xE7, and five LED indicators. //| Uses Report ID 1 for its IN and OUT reports. @@ -81,7 +89,6 @@ //| CONSUMER_CONTROL: Device //| """Consumer Control device supporting sent values from 1-652, with no rollover. //| Uses Report ID 3 for its IN report.""" -//| STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { usb_hid_device_obj_t *self = m_new_obj(usb_hid_device_obj_t); @@ -148,7 +155,7 @@ STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args } if (report_ids_array[0] == 0 && report_ids_count > 1) { - mp_raise_ValueError_varg(translate("%q with a report ID of 0 must be of length 1"), MP_QSTR_report_ids); + mp_raise_ValueError_varg(translate("%q length must be %d"), MP_QSTR_report_id_space_0, 1); } common_hal_usb_hid_device_construct( @@ -163,7 +170,6 @@ STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args //| Otherwise you must specify which report id to use when sending the report. //| """ //| ... -//| STATIC mp_obj_t usb_hid_device_send_report(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -191,13 +197,13 @@ STATIC mp_obj_t usb_hid_device_send_report(size_t n_args, const mp_obj_t *pos_ar } MP_DEFINE_CONST_FUN_OBJ_KW(usb_hid_device_send_report_obj, 1, usb_hid_device_send_report); -//| def get_last_received_report(self, report_id: Optional[int] = None) -> bytes: +//| def get_last_received_report(self, report_id: Optional[int] = None) -> Optional[bytes]: //| """Get the last received HID OUT or feature report for the given report ID. //| The report ID may be omitted if there is no report ID, or only one report ID. -//| Return `None` if nothing received. +//| Return `None` if nothing received. After returning a report, subsequent calls +//| will return `None` until next report is received. //| """ //| ... -//| STATIC mp_obj_t usb_hid_device_get_last_received_report(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -219,28 +225,8 @@ STATIC mp_obj_t usb_hid_device_get_last_received_report(size_t n_args, const mp_ } MP_DEFINE_CONST_FUN_OBJ_KW(usb_hid_device_get_last_received_report_obj, 1, usb_hid_device_get_last_received_report); -//| last_received_report: bytes -//| """The HID OUT report as a `bytes` (read-only). `None` if nothing received. -//| Same as `get_last_received_report()` with no argument. -//| -//| Deprecated: will be removed in CircutPython 8.0.0. Use `get_last_received_report()` instead. -//| """ -//| -STATIC mp_obj_t usb_hid_device_obj_get_last_received_report_property(mp_obj_t self_in) { - usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // Get the sole report_id, if there is one. - const uint8_t report_id = common_hal_usb_hid_device_validate_report_id(self, -1); - return common_hal_usb_hid_device_get_last_received_report(self, report_id); -} -MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_last_received_report_property_obj, usb_hid_device_obj_get_last_received_report_property); - -MP_PROPERTY_GETTER(usb_hid_device_last_received_report_obj, - (mp_obj_t)&usb_hid_device_get_last_received_report_property_obj); - //| usage_page: int //| """The device usage page identifier, which designates a category of device. (read-only)""" -//| STATIC mp_obj_t usb_hid_device_obj_get_usage_page(mp_obj_t self_in) { usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_usb_hid_device_get_usage_page(self)); @@ -269,7 +255,6 @@ MP_PROPERTY_GETTER(usb_hid_device_usage_obj, STATIC const mp_rom_map_elem_t usb_hid_device_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, { MP_ROM_QSTR(MP_QSTR_get_last_received_report), MP_ROM_PTR(&usb_hid_device_get_last_received_report_obj) }, - { MP_ROM_QSTR(MP_QSTR_last_received_report), MP_ROM_PTR(&usb_hid_device_last_received_report_obj) }, { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj) }, { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj) }, diff --git a/shared-bindings/usb_hid/__init__.c b/shared-bindings/usb_hid/__init__.c index dcdf6933f7..5c61cc52de 100644 --- a/shared-bindings/usb_hid/__init__.c +++ b/shared-bindings/usb_hid/__init__.c @@ -36,7 +36,6 @@ //| """USB Human Interface Device //| //| The `usb_hid` module allows you to output data as a HID device.""" -//| //| devices: Tuple[Device, ...] //| """Tuple of all active HID device interfaces. @@ -125,9 +124,7 @@ STATIC mp_obj_t usb_hid_enable(size_t n_args, const mp_obj_t *pos_args, mp_map_t const mp_int_t len = mp_obj_get_int(mp_obj_len(devices)); for (mp_int_t i = 0; i < len; i++) { mp_obj_t item = mp_obj_subscr(devices, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL); - if (!mp_obj_is_type(item, &usb_hid_device_type)) { - mp_raise_ValueError_varg(translate("non-Device in %q"), MP_QSTR_devices); - } + mp_arg_validate_type(item, &usb_hid_device_type, MP_QSTR___class__); } uint8_t boot_device = diff --git a/shared-bindings/usb_host/Port.c b/shared-bindings/usb_host/Port.c index 8f54246584..53b1fec54f 100644 --- a/shared-bindings/usb_host/Port.c +++ b/shared-bindings/usb_host/Port.c @@ -35,21 +35,20 @@ //| //| def __init__(self, dp: microcontroller.Pin, dm: microcontroller.Pin) -> None: //| """Create a USB host port on the given pins. Access attached devices -//| through the `usb` module. Keep this object referenced while -//| interacting with devices, otherwise they will be disconnected. +//| through the `usb` module. Keep this object referenced while +//| interacting with devices, otherwise they will be disconnected. //| -//| :param ~microcontroller.Pin dp: The data plus pin -//| :param ~microcontroller.Pin dm: The data minus pin +//| :param ~microcontroller.Pin dp: The data plus pin +//| :param ~microcontroller.Pin dm: The data minus pin //| """ //| ... -//| STATIC mp_obj_t usb_host_port_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // check number of arguments mp_arg_check_num(n_args, n_kw, 2, 2, false); - const mcu_pin_obj_t *dp = validate_obj_is_free_pin(args[0]); - const mcu_pin_obj_t *dm = validate_obj_is_free_pin(args[1]); + const mcu_pin_obj_t *dp = validate_obj_is_free_pin(args[0], MP_QSTR_dp); + const mcu_pin_obj_t *dm = validate_obj_is_free_pin(args[1], MP_QSTR_dm); usb_host_port_obj_t *self = m_new_obj(usb_host_port_obj_t); self->base.type = &usb_host_port_type; @@ -61,7 +60,6 @@ STATIC mp_obj_t usb_host_port_make_new(const mp_obj_type_t *type, //| def deinit(self) -> None: //| """Turn off the USB host port and release the pins for other use.""" //| ... -//| STATIC mp_obj_t usb_host_port_obj_deinit(mp_obj_t self_in) { usb_host_port_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_usb_host_port_deinit(self); @@ -72,7 +70,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(usb_host_port_deinit_obj, usb_host_port_obj_deinit); //| def __enter__(self) -> Port: //| """No-op used by Context Managers.""" //| ... -//| // Provided by context manager helper. //| def __exit__(self) -> None: diff --git a/shared-bindings/usb_host/__init__.c b/shared-bindings/usb_host/__init__.c index c689a2521a..5c884b3ec2 100644 --- a/shared-bindings/usb_host/__init__.c +++ b/shared-bindings/usb_host/__init__.c @@ -36,7 +36,6 @@ //| The `usb_host` module allows you to manage USB host ports. To communicate //| with devices use the `usb` module that is a subset of PyUSB's API. //| """ -//| STATIC mp_map_elem_t usb_host_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_usb_host) }, diff --git a/shared-bindings/usb_midi/PortIn.c b/shared-bindings/usb_midi/PortIn.c index 273fa77b35..ca07c8695a 100644 --- a/shared-bindings/usb_midi/PortIn.c +++ b/shared-bindings/usb_midi/PortIn.c @@ -29,7 +29,7 @@ #include "shared-bindings/usb_midi/PortIn.h" #include "shared-bindings/util.h" -#include "py/ioctl.h" +#include "py/stream.h" #include "py/objproperty.h" #include "py/runtime.h" #include "py/stream.h" @@ -44,7 +44,6 @@ //| PortIn objects are constructed for every corresponding entry in the USB //| descriptor and added to the ``usb_midi.ports`` tuple.""" //| ... -//| // These are standard stream methods. Code is in py/stream.c. // @@ -57,7 +56,6 @@ //| :return: Data read //| :rtype: bytes or None""" //| ... -//| //| def readinto(self, buf: WriteableBuffer, nbytes: Optional[int] = None) -> Optional[bytes]: //| """Read bytes into the ``buf``. If ``nbytes`` is specified then read at most //| that many bytes. Otherwise, read at most ``len(buf)`` bytes. @@ -83,11 +81,11 @@ STATIC mp_uint_t usb_midi_portin_read(mp_obj_t self_in, void *buf_in, mp_uint_t STATIC mp_uint_t usb_midi_portin_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret; - if (request == MP_IOCTL_POLL) { + if (request == MP_STREAM_POLL) { mp_uint_t flags = arg; ret = 0; - if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_midi_portin_bytes_available(self) > 0) { - ret |= MP_IOCTL_POLL_RD; + if ((flags & MP_STREAM_POLL_RD) && common_hal_usb_midi_portin_bytes_available(self) > 0) { + ret |= MP_STREAM_POLL_RD; } } else { *errcode = MP_EINVAL; diff --git a/shared-bindings/usb_midi/PortOut.c b/shared-bindings/usb_midi/PortOut.c index d5652be5d4..f1f61f948a 100644 --- a/shared-bindings/usb_midi/PortOut.c +++ b/shared-bindings/usb_midi/PortOut.c @@ -29,7 +29,7 @@ #include "shared-bindings/usb_midi/PortOut.h" #include "shared-bindings/util.h" -#include "py/ioctl.h" +#include "py/stream.h" #include "py/objproperty.h" #include "py/runtime.h" #include "py/stream.h" @@ -43,7 +43,6 @@ //| //| PortOut objects are constructed for every corresponding entry in the USB //| descriptor and added to the ``usb_midi.ports`` tuple.""" -//| // These are standard stream methods. Code is in py/stream.c. // @@ -65,11 +64,11 @@ STATIC mp_uint_t usb_midi_portout_write(mp_obj_t self_in, const void *buf_in, mp STATIC mp_uint_t usb_midi_portout_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret; - if (request == MP_IOCTL_POLL) { + if (request == MP_STREAM_POLL) { mp_uint_t flags = arg; ret = 0; - if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_midi_portout_ready_to_tx(self)) { - ret |= MP_IOCTL_POLL_WR; + if ((flags & MP_STREAM_POLL_WR) && common_hal_usb_midi_portout_ready_to_tx(self)) { + ret |= MP_STREAM_POLL_WR; } } else { *errcode = MP_EINVAL; diff --git a/shared-bindings/vectorio/Circle.c b/shared-bindings/vectorio/Circle.c index f955cd2afe..9896876a8a 100644 --- a/shared-bindings/vectorio/Circle.c +++ b/shared-bindings/vectorio/Circle.c @@ -11,16 +11,21 @@ #include "supervisor/shared/translate/translate.h" //| class Circle: -//| -//| def __init__(self, pixel_shader: Union[displayio.ColorConverter, displayio.Palette], radius: int, x: int, y: int) -> None: +//| def __init__( +//| self, +//| pixel_shader: Union[displayio.ColorConverter, displayio.Palette], +//| radius: int, +//| x: int, +//| y: int, +//| ) -> None: //| """Circle is positioned on screen by its center point. //| -//| :param Union[~displayio.ColorConverter,~displayio.Palette] pixel_shader: The pixel shader that produces colors from values -//| :param int radius: The radius of the circle in pixels -//| :param int x: Initial x position of the axis. -//| :param int y: Initial y position of the axis. -//| :param int color_index: Initial color_index to use when selecting color from the palette.""" -//| +//| :param Union[~displayio.ColorConverter,~displayio.Palette] pixel_shader: The pixel shader that produces colors from values +//| :param int radius: The radius of the circle in pixels +//| :param int x: Initial x position of the axis. +//| :param int y: Initial y position of the axis. +//| :param int color_index: Initial color_index to use when selecting color from the palette. +//| """ static mp_obj_t vectorio_circle_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pixel_shader, ARG_radius, ARG_x, ARG_y, ARG_color_index }; static const mp_arg_t allowed_args[] = { @@ -34,9 +39,7 @@ static mp_obj_t vectorio_circle_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_int_t radius = args[ARG_radius].u_int; - if (radius < 1) { - mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_radius); - } + mp_arg_validate_int_min(radius, 1, MP_QSTR_radius); vectorio_circle_t *self = m_new_obj(vectorio_circle_t); self->base.type = &vectorio_circle_type; @@ -60,9 +63,8 @@ STATIC const vectorio_draw_protocol_t circle_draw_protocol = { }; -//| radius : int +//| radius: int //| """The radius of the circle in pixels.""" -//| STATIC mp_obj_t vectorio_circle_obj_get_radius(mp_obj_t self_in) { vectorio_circle_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_vectorio_circle_get_radius(self)); @@ -80,9 +82,8 @@ MP_PROPERTY_GETSET(vectorio_circle_radius_obj, (mp_obj_t)&vectorio_circle_get_radius_obj, (mp_obj_t)&vectorio_circle_set_radius_obj); -//| color_index : int +//| color_index: int //| """The color_index of the circle as 0 based index of the palette.""" -//| STATIC mp_obj_t vectorio_circle_obj_get_color_index(mp_obj_t self_in) { vectorio_circle_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_vectorio_circle_get_color_index(self)); @@ -103,16 +104,19 @@ MP_PROPERTY_GETSET(vectorio_circle_color_index_obj, // Documentation for properties inherited from VectorShape. -//| x : int +//| x: int //| """X position of the center point of the circle in the parent.""" //| -//| y : int +//| y: int //| """Y position of the center point of the circle in the parent.""" //| -//| location : Tuple[int,int] +//| hidden: bool +//| """Hide the circle or not.""" +//| +//| location: Tuple[int, int] //| """(X,Y) position of the center point of the circle in the parent.""" //| -//| pixel_shader : Union[displayio.ColorConverter,displayio.Palette] +//| pixel_shader: Union[displayio.ColorConverter, displayio.Palette] //| """The pixel shader of the circle.""" //| @@ -123,6 +127,7 @@ STATIC const mp_rom_map_elem_t vectorio_circle_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_radius), MP_ROM_PTR(&vectorio_circle_radius_obj) }, { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_hidden), MP_ROM_PTR(&vectorio_vector_shape_hidden_obj) }, { MP_ROM_QSTR(MP_QSTR_color_index), MP_ROM_PTR(&vectorio_circle_color_index_obj) }, { MP_ROM_QSTR(MP_QSTR_location), MP_ROM_PTR(&vectorio_vector_shape_location_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, diff --git a/shared-bindings/vectorio/Polygon.c b/shared-bindings/vectorio/Polygon.c index 60a4582e5a..b188fc4955 100644 --- a/shared-bindings/vectorio/Polygon.c +++ b/shared-bindings/vectorio/Polygon.c @@ -17,7 +17,13 @@ //| class Polygon: -//| def __init__(self, pixel_shader: Union[displayio.ColorConverter, displayio.Palette], points: List[Tuple[int, int]], x: int, y: int) -> None: +//| def __init__( +//| self, +//| pixel_shader: Union[displayio.ColorConverter, displayio.Palette], +//| points: List[Tuple[int, int]], +//| x: int, +//| y: int, +//| ) -> None: //| """Represents a closed shape by ordered vertices. The path will be treated as //| 'closed', the last point will connect to the first point. //| @@ -26,8 +32,8 @@ //| :param List[Tuple[int,int]] points: Vertices for the polygon //| :param int x: Initial screen x position of the 0,0 origin in the points list. //| :param int y: Initial screen y position of the 0,0 origin in the points list. -//| :param int color_index: Initial color_index to use when selecting color from the palette.""" -//| +//| :param int color_index: Initial color_index to use when selecting color from the palette. +//| """ static mp_obj_t vectorio_polygon_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pixel_shader, ARG_points_list, ARG_x, ARG_y, ARG_color_index }; static const mp_arg_t allowed_args[] = { @@ -67,7 +73,6 @@ STATIC const vectorio_draw_protocol_t polygon_draw_protocol = { //| points: List[Tuple[int, int]] //| """Vertices for the polygon.""" -//| STATIC mp_obj_t vectorio_polygon_obj_get_points(mp_obj_t self_in) { vectorio_polygon_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_vectorio_polygon_get_points(self); @@ -86,9 +91,8 @@ MP_PROPERTY_GETSET(vectorio_polygon_points_obj, (mp_obj_t)&vectorio_polygon_get_points_obj, (mp_obj_t)&vectorio_polygon_set_points_obj); -//| color_index : int +//| color_index: int //| """The color_index of the polygon as 0 based index of the palette.""" -//| STATIC mp_obj_t vectorio_polygon_obj_get_color_index(mp_obj_t self_in) { vectorio_polygon_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_vectorio_polygon_get_color_index(self)); @@ -109,16 +113,19 @@ MP_PROPERTY_GETSET(vectorio_polygon_color_index_obj, // Documentation for properties inherited from VectorShape. -//| x : int +//| x: int //| """X position of the 0,0 origin in the points list.""" //| -//| y : int +//| y: int //| """Y position of the 0,0 origin in the points list.""" //| -//| location : Tuple[int,int] +//| hidden: bool +//| """Hide the polygon or not.""" +//| +//| location: Tuple[int, int] //| """(X,Y) position of the 0,0 origin in the points list.""" //| -//| pixel_shader : Union[displayio.ColorConverter,displayio.Palette] +//| pixel_shader: Union[displayio.ColorConverter, displayio.Palette] //| """The pixel shader of the polygon.""" //| @@ -129,6 +136,7 @@ STATIC const mp_rom_map_elem_t vectorio_polygon_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_points), MP_ROM_PTR(&vectorio_polygon_points_obj) }, { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_hidden), MP_ROM_PTR(&vectorio_vector_shape_hidden_obj) }, { MP_ROM_QSTR(MP_QSTR_color_index), MP_ROM_PTR(&vectorio_polygon_color_index_obj) }, { MP_ROM_QSTR(MP_QSTR_location), MP_ROM_PTR(&vectorio_vector_shape_location_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, diff --git a/shared-bindings/vectorio/Rectangle.c b/shared-bindings/vectorio/Rectangle.c index 34b9e1eabe..ad864f2c2d 100644 --- a/shared-bindings/vectorio/Rectangle.c +++ b/shared-bindings/vectorio/Rectangle.c @@ -10,16 +10,23 @@ #include "supervisor/shared/translate/translate.h" //| class Rectangle: -//| def __init__(self, pixel_shader: Union[displayio.ColorConverter, displayio.Palette], width: int, height: int, x: int, y: int) -> None: +//| def __init__( +//| self, +//| pixel_shader: Union[displayio.ColorConverter, displayio.Palette], +//| width: int, +//| height: int, +//| x: int, +//| y: int, +//| ) -> None: //| """Represents a rectangle by defining its bounds //| -//| :param Union[~displayio.ColorConverter,~displayio.Palette] pixel_shader: The pixel shader that produces colors from values -//| :param int width: The number of pixels wide -//| :param int height: The number of pixels high -//| :param int x: Initial x position of the top left corner. -//| :param int y: Initial y position of the top left corner. -//| :param int color_index: Initial color_index to use when selecting color from the palette.""" -//| +//| :param Union[~displayio.ColorConverter,~displayio.Palette] pixel_shader: The pixel shader that produces colors from values +//| :param int width: The number of pixels wide +//| :param int height: The number of pixels high +//| :param int x: Initial x position of the top left corner. +//| :param int y: Initial y position of the top left corner. +//| :param int color_index: Initial color_index to use when selecting color from the palette. +//| """ static mp_obj_t vectorio_rectangle_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pixel_shader, ARG_width, ARG_height, ARG_x, ARG_y, ARG_color_index }; static const mp_arg_t allowed_args[] = { @@ -34,13 +41,9 @@ static mp_obj_t vectorio_rectangle_make_new(const mp_obj_type_t *type, size_t n_ mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_int_t width = args[ARG_width].u_int; - if (width < 1) { - mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_width); - } + mp_arg_validate_int_min(width, 1, MP_QSTR_width); mp_int_t height = args[ARG_height].u_int; - if (height < 1) { - mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_height); - } + mp_arg_validate_int_min(height, 1, MP_QSTR_height); vectorio_rectangle_t *self = m_new_obj(vectorio_rectangle_t); self->base.type = &vectorio_rectangle_type; @@ -63,9 +66,8 @@ STATIC const vectorio_draw_protocol_t rectangle_draw_protocol = { .draw_protocol_impl = &vectorio_vector_shape_draw_protocol_impl }; -//| width : int +//| width: int //| """The width of the rectangle in pixels.""" -//| STATIC mp_obj_t vectorio_rectangle_obj_get_width(mp_obj_t self_in) { vectorio_rectangle_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_vectorio_rectangle_get_width(self)); @@ -86,9 +88,8 @@ const mp_obj_property_t vectorio_rectangle_width_obj = { MP_ROM_NONE}, }; -//| height : int +//| height: int //| """The height of the rectangle in pixels.""" -//| STATIC mp_obj_t vectorio_rectangle_obj_get_height(mp_obj_t self_in) { vectorio_rectangle_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_vectorio_rectangle_get_height(self)); @@ -109,9 +110,8 @@ const mp_obj_property_t vectorio_rectangle_height_obj = { MP_ROM_NONE}, }; -//| color_index : int +//| color_index: int //| """The color_index of the rectangle in 1 based index of the palette.""" -//| STATIC mp_obj_t vectorio_rectangle_obj_get_color_index(mp_obj_t self_in) { vectorio_rectangle_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_vectorio_rectangle_get_color_index(self)); @@ -134,16 +134,19 @@ const mp_obj_property_t vectorio_rectangle_color_index_obj = { // Documentation for properties inherited from VectorShape. -//| x : int +//| x: int //| """X position of the top left corner of the rectangle in the parent.""" //| -//| y : int +//| y: int //| """Y position of the top left corner of the rectangle in the parent.""" //| -//| location : Tuple[int,int] +//| hidden: bool +//| """Hide the rectangle or not.""" +//| +//| location: Tuple[int, int] //| """(X,Y) position of the top left corner of the rectangle in the parent.""" //| -//| pixel_shader : Union[displayio.ColorConverter,displayio.Palette] +//| pixel_shader: Union[displayio.ColorConverter, displayio.Palette] //| """The pixel shader of the rectangle.""" //| @@ -153,6 +156,7 @@ STATIC const mp_rom_map_elem_t vectorio_rectangle_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_hidden), MP_ROM_PTR(&vectorio_vector_shape_hidden_obj) }, { MP_ROM_QSTR(MP_QSTR_color_index), MP_ROM_PTR(&vectorio_rectangle_color_index_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&vectorio_rectangle_width_obj) }, { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&vectorio_rectangle_height_obj) }, diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index ba55cfb851..e5c806b943 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -181,6 +181,33 @@ MP_PROPERTY_GETSET(vectorio_vector_shape_location_obj, (mp_obj_t)&vectorio_vector_shape_set_location_obj); +// Stub checker does not approve of these shared properties. +// hidden: bool +// """Hide the shape or not.""" +// +STATIC mp_obj_t vectorio_vector_shape_obj_get_hidden(mp_obj_t wrapper_shape) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + return mp_obj_new_bool(common_hal_vectorio_vector_shape_get_hidden(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_hidden_obj, vectorio_vector_shape_obj_get_hidden); + +STATIC mp_obj_t vectorio_vector_shape_obj_set_hidden(mp_obj_t wrapper_shape, mp_obj_t hidden_obj) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + + common_hal_vectorio_vector_shape_set_hidden(self, mp_obj_is_true(hidden_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(vectorio_vector_shape_set_hidden_obj, vectorio_vector_shape_obj_set_hidden); + +MP_PROPERTY_GETSET(vectorio_vector_shape_hidden_obj, + (mp_obj_t)&vectorio_vector_shape_get_hidden_obj, + (mp_obj_t)&vectorio_vector_shape_set_hidden_obj); + + // pixel_shader: Union[ColorConverter, Palette] // """The pixel shader of the shape.""" // diff --git a/shared-bindings/vectorio/VectorShape.h b/shared-bindings/vectorio/VectorShape.h index 13f62922f3..c94476c25a 100644 --- a/shared-bindings/vectorio/VectorShape.h +++ b/shared-bindings/vectorio/VectorShape.h @@ -31,6 +31,9 @@ void common_hal_vectorio_vector_shape_set_location(vectorio_vector_shape_t *self mp_int_t common_hal_vectorio_vector_shape_get_y(vectorio_vector_shape_t *self); void common_hal_vectorio_vector_shape_set_y(vectorio_vector_shape_t *self, mp_int_t y); +mp_int_t common_hal_vectorio_vector_shape_get_hidden(vectorio_vector_shape_t *self); +void common_hal_vectorio_vector_shape_set_hidden(vectorio_vector_shape_t *self, bool hidden); + mp_obj_t common_hal_vectorio_vector_shape_get_pixel_shader(vectorio_vector_shape_t *self); void common_hal_vectorio_vector_shape_set_pixel_shader(vectorio_vector_shape_t *self, mp_obj_t pixel_shader); @@ -40,6 +43,7 @@ void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displ extern vectorio_draw_protocol_impl_t vectorio_vector_shape_draw_protocol_impl; extern const mp_obj_property_getset_t vectorio_vector_shape_x_obj; extern const mp_obj_property_getset_t vectorio_vector_shape_y_obj; +extern const mp_obj_property_getset_t vectorio_vector_shape_hidden_obj; extern const mp_obj_property_getset_t vectorio_vector_shape_location_obj; extern const mp_obj_property_getset_t vectorio_vector_shape_pixel_shader_obj; extern const mp_obj_fun_builtin_fixed_t vectorio_vector_shape_contains_obj; diff --git a/shared-bindings/vectorio/__init__.c b/shared-bindings/vectorio/__init__.c index 6e39f26591..7ad77da681 100644 --- a/shared-bindings/vectorio/__init__.c +++ b/shared-bindings/vectorio/__init__.c @@ -30,7 +30,6 @@ //| group.append(polygon) //| //| """ -//| STATIC const mp_rom_map_elem_t vectorio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_vectorio) }, diff --git a/shared-bindings/watchdog/WatchDogMode.c b/shared-bindings/watchdog/WatchDogMode.c index beea4d0512..c707054d27 100644 --- a/shared-bindings/watchdog/WatchDogMode.c +++ b/shared-bindings/watchdog/WatchDogMode.c @@ -31,10 +31,11 @@ //| //| def __init__(self) -> None: //| """Enum-like class to define the run mode of the watchdog timer.""" -//| //| RAISE: WatchDogMode //| """Raise an exception when the WatchDogTimer expires. //| +//| **Limitations:** ``RAISE`` mode is not supported on SAMD or RP2040. +//| //| :type WatchDogMode:""" //| //| RESET: WatchDogMode diff --git a/shared-bindings/watchdog/WatchDogTimer.c b/shared-bindings/watchdog/WatchDogTimer.c index e00b288080..acfd353c34 100644 --- a/shared-bindings/watchdog/WatchDogTimer.c +++ b/shared-bindings/watchdog/WatchDogTimer.c @@ -42,23 +42,21 @@ //| class WatchDogTimer: //| """Timer that is used to detect code lock ups and automatically reset the microcontroller -//| when one is detected. +//| when one is detected. //| -//| A lock up is detected when the watchdog hasn't been fed after a given duration. So, make -//| sure to call `feed` within the timeout. +//| A lock up is detected when the watchdog hasn't been fed after a given duration. So, make +//| sure to call `feed` within the timeout. //| """ //| //| def __init__(self) -> None: //| """Not currently dynamically supported. Access the sole instance through `microcontroller.watchdog`.""" //| ... -//| //| def feed(self) -> None: //| """Feed the watchdog timer. This must be called regularly, otherwise //| the timer will expire.""" //| ... -//| STATIC mp_obj_t watchdog_watchdogtimer_feed(mp_obj_t self_in) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); watchdog_watchdogmode_t current_mode = common_hal_watchdog_get_mode(self); @@ -76,7 +74,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(watchdog_watchdogtimer_feed_obj, watchdog_watch //| """Stop the watchdog timer. This may raise an error if the watchdog //| timer cannot be disabled on this platform.""" //| ... -//| STATIC mp_obj_t watchdog_watchdogtimer_deinit(mp_obj_t self_in) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_watchdog_deinit(self); @@ -87,7 +84,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(watchdog_watchdogtimer_deinit_obj, watchdog_wat //| timeout: float //| """The maximum number of seconds that can elapse between calls //| to feed()""" -//| STATIC mp_obj_t watchdog_watchdogtimer_obj_get_timeout(mp_obj_t self_in) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_float(common_hal_watchdog_get_timeout(self)); @@ -98,9 +94,7 @@ STATIC mp_obj_t watchdog_watchdogtimer_obj_set_timeout(mp_obj_t self_in, mp_obj_ watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_float_t timeout = mp_obj_get_float(timeout_obj); - if (timeout <= 0) { - mp_raise_ValueError(translate("watchdog timeout must be greater than 0")); - } + mp_arg_validate_int_min((int)timeout, 0, MP_QSTR_timeout); common_hal_watchdog_set_timeout(self, timeout); return mp_const_none; @@ -140,9 +134,7 @@ STATIC mp_obj_t watchdog_watchdogtimer_obj_set_mode(mp_obj_t self_in, mp_obj_t m // When setting the mode, the timeout value must be greater than zero if (new_mode == WATCHDOGMODE_RESET || new_mode == WATCHDOGMODE_RAISE) { - if (current_timeout <= 0) { - mp_raise_ValueError(translate("WatchDogTimer.timeout must be greater than 0")); - } + mp_arg_validate_int_min((int)current_timeout, 0, MP_QSTR_timeout); } // Don't allow changing the mode once the watchdog timer has been started diff --git a/shared-bindings/watchdog/__init__.c b/shared-bindings/watchdog/__init__.c index a0e357e2ac..5281f1c3fc 100644 --- a/shared-bindings/watchdog/__init__.c +++ b/shared-bindings/watchdog/__init__.c @@ -49,6 +49,7 @@ //| w.timeout=2.5 # Set a timeout of 2.5 seconds //| w.mode = WatchDogMode.RAISE //| w.feed()""" +//| //| class WatchDogTimeout(Exception): //| """Exception raised when the watchdog timer is set to @@ -76,6 +77,7 @@ //| //| print("Exited loop") //| """ +//| const mp_obj_type_t mp_type_WatchDogTimeout = { { &mp_type_type }, diff --git a/shared-bindings/wifi/AuthMode.h b/shared-bindings/wifi/AuthMode.h index a1016d6c8a..c514fb2a32 100644 --- a/shared-bindings/wifi/AuthMode.h +++ b/shared-bindings/wifi/AuthMode.h @@ -30,13 +30,13 @@ #include "py/enum.h" typedef enum { - AUTHMODE_OPEN, - AUTHMODE_WEP, - AUTHMODE_WPA, - AUTHMODE_WPA2, - AUTHMODE_WPA3, - AUTHMODE_PSK, - AUTHMODE_ENTERPRISE + AUTHMODE_OPEN = 1 << 0, + AUTHMODE_WEP = 1 << 1, + AUTHMODE_WPA = 1 << 2, + AUTHMODE_WPA2 = 1 << 3, + AUTHMODE_WPA3 = 1 << 4, + AUTHMODE_PSK = 1 << 5, + AUTHMODE_ENTERPRISE = 1 << 6, } wifi_authmode_t; extern const mp_obj_type_t wifi_authmode_type; diff --git a/shared-bindings/wifi/Monitor.c b/shared-bindings/wifi/Monitor.c index 235ec534aa..d087ec587b 100644 --- a/shared-bindings/wifi/Monitor.c +++ b/shared-bindings/wifi/Monitor.c @@ -36,15 +36,14 @@ //| """For monitoring WiFi packets.""" //| -//| def __init__(self, channel: Optional[int] = 1, queue: Optional[int] = 128) -> None: -//| """Initialize `wifi.Monitor` singleton. +//| def __init__(self, channel: Optional[int] = 1, queue: Optional[int] = 128) -> None: +//| """Initialize `wifi.Monitor` singleton. //| -//| :param int channel: The WiFi channel to scan. -//| :param int queue: The queue size for buffering the packet. -//| -//| """ -//| ... +//| :param int channel: The WiFi channel to scan. +//| :param int queue: The queue size for buffering the packet. //| +//| """ +//| ... STATIC mp_obj_t wifi_monitor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_channel, ARG_queue }; static const mp_arg_t allowed_args[] = { @@ -69,9 +68,8 @@ STATIC mp_obj_t wifi_monitor_make_new(const mp_obj_type_t *type, size_t n_args, return MP_OBJ_FROM_PTR(self); } -//| channel: int -//| """The WiFi channel to scan.""" -//| +//| channel: int +//| """The WiFi channel to scan.""" STATIC mp_obj_t wifi_monitor_obj_get_channel(mp_obj_t self_in) { return common_hal_wifi_monitor_get_channel(self_in); } @@ -91,9 +89,8 @@ MP_PROPERTY_GETSET(wifi_monitor_channel_obj, (mp_obj_t)&wifi_monitor_get_channel_obj, (mp_obj_t)&wifi_monitor_set_channel_obj); -//| queue: int -//| """The queue size for buffering the packet.""" -//| +//| queue: int +//| """The queue size for buffering the packet.""" STATIC mp_obj_t wifi_monitor_obj_get_queue(mp_obj_t self_in) { return common_hal_wifi_monitor_get_queue(self_in); } @@ -102,29 +99,26 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_monitor_get_queue_obj, wifi_monitor_obj_get_queue MP_PROPERTY_GETTER(wifi_monitor_queue_obj, (mp_obj_t)&wifi_monitor_get_queue_obj); -//| def deinit(self) -> None: -//| """De-initialize `wifi.Monitor` singleton.""" -//| ... -//| +//| def deinit(self) -> None: +//| """De-initialize `wifi.Monitor` singleton.""" +//| ... STATIC mp_obj_t wifi_monitor_obj_deinit(mp_obj_t self_in) { common_hal_wifi_monitor_deinit(self_in); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(wifi_monitor_deinit_obj, wifi_monitor_obj_deinit); -//| def lost(self) -> int: -//| """Returns the packet loss count. The counter resets after each poll.""" -//| ... -//| +//| def lost(self) -> int: +//| """Returns the packet loss count. The counter resets after each poll.""" +//| ... STATIC mp_obj_t wifi_monitor_obj_get_lost(mp_obj_t self_in) { return common_hal_wifi_monitor_get_lost(self_in); } MP_DEFINE_CONST_FUN_OBJ_1(wifi_monitor_lost_obj, wifi_monitor_obj_get_lost); -//| def queued(self) -> int: -//| """Returns the packet queued count.""" -//| ... -//| +//| def queued(self) -> int: +//| """Returns the packet queued count.""" +//| ... STATIC mp_obj_t wifi_monitor_obj_get_queued(mp_obj_t self_in) { if (common_hal_wifi_monitor_deinited()) { return mp_obj_new_int_from_uint(0); @@ -133,9 +127,9 @@ STATIC mp_obj_t wifi_monitor_obj_get_queued(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(wifi_monitor_queued_obj, wifi_monitor_obj_get_queued); -//| def packet(self) -> dict: -//| """Returns the monitor packet.""" -//| ... +//| def packet(self) -> dict: +//| """Returns the monitor packet.""" +//| ... //| STATIC mp_obj_t wifi_monitor_obj_get_packet(mp_obj_t self_in) { if (common_hal_wifi_monitor_deinited()) { diff --git a/shared-bindings/wifi/Monitor.h b/shared-bindings/wifi/Monitor.h index 38c52a05e7..b828616ddb 100644 --- a/shared-bindings/wifi/Monitor.h +++ b/shared-bindings/wifi/Monitor.h @@ -29,7 +29,7 @@ #include "common-hal/wifi/Monitor.h" -const mp_obj_type_t wifi_monitor_type; +extern const mp_obj_type_t wifi_monitor_type; void common_hal_wifi_monitor_construct(wifi_monitor_obj_t *self, uint8_t channel, size_t queue); diff --git a/shared-bindings/wifi/Network.c b/shared-bindings/wifi/Network.c index 9a457b9499..387b1f587d 100644 --- a/shared-bindings/wifi/Network.c +++ b/shared-bindings/wifi/Network.c @@ -31,19 +31,15 @@ #include "shared-bindings/wifi/Network.h" //| class Network: -//| """A wifi network provided by a nearby access point. -//| -//| """ +//| """A wifi network provided by a nearby access point.""" //| //| def __init__(self) -> None: //| """You cannot create an instance of `wifi.Network`. They are returned by `wifi.Radio.start_scanning_networks`.""" //| ... -//| //| ssid: str //| """String id of the network""" -//| STATIC mp_obj_t wifi_network_get_ssid(mp_obj_t self) { return common_hal_wifi_network_get_ssid(self); @@ -56,7 +52,6 @@ MP_PROPERTY_GETTER(wifi_network_ssid_obj, //| bssid: bytes //| """BSSID of the network (usually the AP's MAC address)""" -//| STATIC mp_obj_t wifi_network_get_bssid(mp_obj_t self) { return common_hal_wifi_network_get_bssid(self); @@ -69,7 +64,6 @@ MP_PROPERTY_GETTER(wifi_network_bssid_obj, //| rssi: int //| """Signal strength of the network""" -//| STATIC mp_obj_t wifi_network_get_rssi(mp_obj_t self) { return common_hal_wifi_network_get_rssi(self); @@ -82,7 +76,6 @@ MP_PROPERTY_GETTER(wifi_network_rssi_obj, //| channel: int //| """Channel number the network is operating on""" -//| STATIC mp_obj_t wifi_network_get_channel(mp_obj_t self) { return common_hal_wifi_network_get_channel(self); @@ -94,7 +87,6 @@ MP_PROPERTY_GETTER(wifi_network_channel_obj, //| country: str //| """String id of the country code""" -//| STATIC mp_obj_t wifi_network_get_country(mp_obj_t self) { return common_hal_wifi_network_get_country(self); diff --git a/shared-bindings/wifi/Network.h b/shared-bindings/wifi/Network.h index 0f07e7b555..574d690f37 100644 --- a/shared-bindings/wifi/Network.h +++ b/shared-bindings/wifi/Network.h @@ -33,7 +33,7 @@ #include "py/objstr.h" -const mp_obj_type_t wifi_network_type; +extern const mp_obj_type_t wifi_network_type; extern mp_obj_t common_hal_wifi_network_get_ssid(wifi_network_obj_t *self); extern mp_obj_t common_hal_wifi_network_get_bssid(wifi_network_obj_t *self); diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index bcd998d806..fc3cc345b8 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -27,7 +27,6 @@ #include "shared-bindings/wifi/__init__.h" #include "shared-bindings/wifi/AuthMode.h" -#include #include #include "py/runtime.h" @@ -35,11 +34,48 @@ #define MAC_ADDRESS_LENGTH 6 +STATIC bool hostname_valid(const char *ptr, size_t len) { + #if 0 // validated by mp_arg_validate_length_range + if (len == 0 || len > 253) { + // at most 253 characters long + return false; + } + #endif + int partlen = 0; + while (len) { + char c = *ptr++; + len--; + if (c == '.') { + if (partlen == 0 || partlen > 63) { + return false; + } + partlen = 0; + continue; + } + partlen++; + if (c == '-') { + if (partlen == 1) { + return false; // part cannot begin with a dash + } + continue; + } else if ( + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9')) { + continue; + } + return false; + } + // check length of last part + return !(partlen > 63); +} + + //| class Radio: //| """Native wifi radio. //| -//| This class manages the station and access point functionality of the native -//| Wifi radio. +//| This class manages the station and access point functionality of the native +//| Wifi radio. //| //| """ //| @@ -48,13 +84,11 @@ //| """You cannot create an instance of `wifi.Radio`. //| Use `wifi.radio` to access the sole instance available.""" //| ... -//| //| enabled: bool //| """``True`` when the wifi radio is enabled. //| If you set the value to ``False``, any open sockets will be closed. //| """ -//| STATIC mp_obj_t wifi_radio_get_enabled(mp_obj_t self) { return mp_obj_new_bool(common_hal_wifi_radio_get_enabled(self)); } @@ -76,7 +110,6 @@ MP_PROPERTY_GETSET(wifi_radio_enabled_obj, //| hostname: Union[str | ReadableBuffer] //| """Hostname for wifi interface. When the hostname is altered after interface started/connected //| the changes would only be reflected once the interface restarts/reconnects.""" -//| STATIC mp_obj_t wifi_radio_get_hostname(mp_obj_t self_in) { wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_wifi_radio_get_hostname(self); @@ -89,14 +122,9 @@ STATIC mp_obj_t wifi_radio_set_hostname(mp_obj_t self_in, mp_obj_t hostname_in) mp_arg_validate_length_range(hostname.len, 1, 253, MP_QSTR_hostname); - #ifndef CONFIG_IDF_TARGET_ESP32C3 - regex_t regex; // validate hostname according to RFC 1123 - regcomp(®ex,"^(([a-z0-9]|[a-z0-9][a-z0-9\\-]{0,61}[a-z0-9])\\.)*([a-z0-9]|[a-z0-9][a-z0-9\\-]{0,61}[a-z0-9])$", REG_EXTENDED | REG_ICASE | REG_NOSUB); - if (regexec(®ex, hostname.buf, 0, NULL, 0)) { + if (!hostname_valid(hostname.buf, hostname.len)) { mp_raise_ValueError(translate("invalid hostname")); } - regfree(®ex); - #endif wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_wifi_radio_set_hostname(self, hostname.buf); @@ -111,14 +139,19 @@ MP_PROPERTY_GETSET(wifi_radio_hostname_obj, //| mac_address: ReadableBuffer //| """MAC address for the station. When the address is altered after interface is connected -//| the changes would only be reflected once the interface reconnects.""" +//| the changes would only be reflected once the interface reconnects. //| -STATIC mp_obj_t wifi_radio_get_mac_address(mp_obj_t self_in) { +//| **Limitations:** Not settable on RP2040 CYW43 boards, such as Pi Pico W. +//| """ + + +STATIC mp_obj_t _wifi_radio_get_mac_address(mp_obj_t self_in) { wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_FROM_PTR(common_hal_wifi_radio_get_mac_address(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_mac_address_obj, wifi_radio_get_mac_address); +MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_mac_address_obj, _wifi_radio_get_mac_address); +#if CIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS STATIC mp_obj_t wifi_radio_set_mac_address(mp_obj_t self_in, mp_obj_t mac_address_in) { mp_buffer_info_t mac_address; mp_get_buffer_raise(mac_address_in, &mac_address, MP_BUFFER_READ); @@ -133,14 +166,19 @@ STATIC mp_obj_t wifi_radio_set_mac_address(mp_obj_t self_in, mp_obj_t mac_addres return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(wifi_radio_set_mac_address_obj, wifi_radio_set_mac_address); +#endif +#if CIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS MP_PROPERTY_GETSET(wifi_radio_mac_address_obj, (mp_obj_t)&wifi_radio_get_mac_address_obj, (mp_obj_t)&wifi_radio_set_mac_address_obj); +#else +MP_PROPERTY_GETTER(wifi_radio_mac_address_obj, + (mp_obj_t)&wifi_radio_get_mac_address_obj); +#endif //| tx_power: float //| """Wifi transmission power, in dBm.""" -//| STATIC mp_obj_t wifi_radio_get_tx_power(mp_obj_t self_in) { wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_float(common_hal_wifi_radio_get_tx_power(self)); @@ -161,14 +199,17 @@ MP_PROPERTY_GETSET(wifi_radio_tx_power_obj, //| mac_address_ap: ReadableBuffer //| """MAC address for the AP. When the address is altered after interface is started -//| the changes would only be reflected once the interface restarts.""" +//| the changes would only be reflected once the interface restarts. //| +//| **Limitations:** Not settable on RP2040 CYW43 boards, such as Pi Pico W. +//| """ STATIC mp_obj_t wifi_radio_get_mac_address_ap(mp_obj_t self_in) { wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_FROM_PTR(common_hal_wifi_radio_get_mac_address_ap(self)); } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_mac_address_ap_obj, wifi_radio_get_mac_address_ap); +#if CIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS STATIC mp_obj_t wifi_radio_set_mac_address_ap(mp_obj_t self_in, mp_obj_t mac_address_in) { mp_buffer_info_t mac_address; mp_get_buffer_raise(mac_address_in, &mac_address, MP_BUFFER_READ); @@ -183,26 +224,56 @@ STATIC mp_obj_t wifi_radio_set_mac_address_ap(mp_obj_t self_in, mp_obj_t mac_add return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(wifi_radio_set_mac_address_ap_obj, wifi_radio_set_mac_address_ap); +#endif +#if CIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS MP_PROPERTY_GETSET(wifi_radio_mac_address_ap_obj, (mp_obj_t)&wifi_radio_get_mac_address_ap_obj, (mp_obj_t)&wifi_radio_set_mac_address_ap_obj); +#else +MP_PROPERTY_GETTER(wifi_radio_mac_address_ap_obj, + (mp_obj_t)&wifi_radio_get_mac_address_ap_obj); +#endif -//| def start_scanning_networks(self, *, start_channel: int = 1, stop_channel: int = 11) -> Iterable[Network]: -//| """Scans for available wifi networks over the given channel range. Make sure the channels are allowed in your country.""" -//| ... +//| def start_scanning_networks( +//| self, *, start_channel: int = 1, stop_channel: int = 11 +//| ) -> Iterable[Network]: +//| """Scans for available wifi networks over the given channel range. Make sure the channels are allowed in your country. //| -STATIC mp_obj_t wifi_radio_start_scanning_networks(mp_obj_t self_in) { - wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); +//| .. note:: +//| +//| In the raspberrypi port (RP2040 CYW43), ``start_channel`` and ``stop_channel`` are ignored. +//| """ +//| ... +STATIC mp_obj_t wifi_radio_start_scanning_networks(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_start_channel, ARG_stop_channel }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_start_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + { MP_QSTR_stop_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 11} }, + }; - return common_hal_wifi_radio_start_scanning_networks(self); + wifi_radio_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + uint8_t start_channel = + (uint8_t)mp_arg_validate_int_range(args[ARG_start_channel].u_int, 1, 14, MP_QSTR_start_channel); + uint8_t stop_channel = + (uint8_t)mp_arg_validate_int_range(args[ARG_stop_channel].u_int, 1, 14, MP_QSTR_stop_channel); + // Swap if in reverse order, without complaining. + if (start_channel > stop_channel) { + uint8_t temp = stop_channel; + stop_channel = start_channel; + start_channel = temp; + } + + return common_hal_wifi_radio_start_scanning_networks(self, start_channel, stop_channel); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_start_scanning_networks_obj, wifi_radio_start_scanning_networks); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_start_scanning_networks_obj, 1, wifi_radio_start_scanning_networks); //| def stop_scanning_networks(self) -> None: //| """Stop scanning for Wifi networks and free any resources used to do it.""" //| ... -//| STATIC mp_obj_t wifi_radio_stop_scanning_networks(mp_obj_t self_in) { wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -215,7 +286,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_scanning_networks_obj, wifi_rad //| def start_station(self) -> None: //| """Starts a Station.""" //| ... -//| STATIC mp_obj_t wifi_radio_start_station(mp_obj_t self) { common_hal_wifi_radio_start_station(self); return mp_const_none; @@ -225,41 +295,42 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_start_station_obj, wifi_radio_start_station //| def stop_station(self) -> None: //| """Stops the Station.""" //| ... -//| STATIC mp_obj_t wifi_radio_stop_station(mp_obj_t self) { common_hal_wifi_radio_stop_station(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_station_obj, wifi_radio_stop_station); -//| def start_ap(self, -//| ssid: Union[str | ReadableBuffer], -//| password: Union[str | ReadableBuffer] = "", -//| *, -//| channel: Optional[int] = 1, -//| authmode: Optional[AuthMode], -//| max_connections: Optional[int] = 4) -> None: +//| def start_ap( +//| self, +//| ssid: Union[str | ReadableBuffer], +//| password: Union[str | ReadableBuffer] = b"", +//| *, +//| channel: int = 1, +//| authmode: Optional[AuthMode] = None, +//| max_connections: Optional[int] = 4 +//| ) -> None: //| """Starts an Access Point with the specified ssid and password. //| -//| If ``channel`` is given, the access point will use that channel unless -//| a station is already operating on a different channel. +//| If ``channel`` is given, the access point will use that channel unless +//| a station is already operating on a different channel. //| -//| If ``authmode`` is given, the access point will use that Authentication -//| mode. If a password is given, ``authmode`` must not be ``OPEN``. -//| If ``authmode`` isn't given, ``OPEN`` will be used when password isn't provided, -//| otherwise ``WPA_WPA2_PSK``. +//| If ``authmode`` is not None, the access point will use that Authentication +//| mode. If a non-empty password is given, ``authmode`` must not be ``OPEN``. +//| If ``authmode`` is not given or is None, +//| ``OPEN`` will be used when the password is the empty string, +//| otherwise ``authmode`` will be ``WPA_WPA2_PSK``. //| -//| If ``max_connections`` is given, the access point will allow up to -//| that number of stations to connect.""" +//| If ``max_connections`` is given, the access point will allow up to +//| that number of stations to connect.""" //| ... -//| STATIC mp_obj_t wifi_radio_start_ap(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_ssid, ARG_password, ARG_channel, ARG_authmode, ARG_max_connections }; static const mp_arg_t allowed_args[] = { { MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_password, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_password, MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} }, { MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, - { MP_QSTR_authmode, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_authmode, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none } }, { MP_QSTR_max_connections, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 4} }, }; @@ -267,12 +338,13 @@ STATIC mp_obj_t wifi_radio_start_ap(size_t n_args, const mp_obj_t *pos_args, mp_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - uint8_t authmode = 0; - if (args[ARG_authmode].u_obj != MP_OBJ_NULL) { + // 0 indicates mode wasn't given. + uint32_t authmodes = 0; + if (args[ARG_authmode].u_obj != mp_const_none) { mp_obj_iter_buf_t iter_buf; mp_obj_t item, iterable = mp_getiter(args[ARG_authmode].u_obj, &iter_buf); while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - authmode |= (1 << (wifi_authmode_t)cp_enum_value(&wifi_authmode_type, item)); + authmodes |= cp_enum_value(&wifi_authmode_type, item, MP_QSTR_authmode); } } @@ -281,20 +353,24 @@ STATIC mp_obj_t wifi_radio_start_ap(size_t n_args, const mp_obj_t *pos_args, mp_ mp_arg_validate_length_range(ssid.len, 1, 32, MP_QSTR_ssid); mp_buffer_info_t password; - password.len = 0; - if (args[ARG_password].u_obj != MP_OBJ_NULL) { - if (authmode == 1) { - mp_raise_ValueError(translate("AuthMode.OPEN is not used with password")); - } else if (authmode == 0) { - authmode = (1 << AUTHMODE_WPA) | (1 << AUTHMODE_WPA2) | (1 << AUTHMODE_PSK); + mp_get_buffer_raise(args[ARG_password].u_obj, &password, MP_BUFFER_READ); + if (authmodes == 0) { + if (password.len == 0) { + authmodes = AUTHMODE_OPEN; + } else { + authmodes = AUTHMODE_WPA | AUTHMODE_WPA2 | AUTHMODE_PSK; } - mp_get_buffer_raise(args[ARG_password].u_obj, &password, MP_BUFFER_READ); - mp_arg_validate_length_range(password.len, 8, 63, MP_QSTR_password); - } else { - authmode = 1; } - common_hal_wifi_radio_start_ap(self, ssid.buf, ssid.len, password.buf, password.len, args[ARG_channel].u_int, authmode, args[ARG_max_connections].u_int); + if (authmodes == AUTHMODE_OPEN && password.len > 0) { + mp_raise_ValueError(translate("AuthMode.OPEN is not used with password")); + } + + if (authmodes != AUTHMODE_OPEN) { + mp_arg_validate_length_range(password.len, 8, 63, MP_QSTR_password); + } + + common_hal_wifi_radio_start_ap(self, ssid.buf, ssid.len, password.buf, password.len, args[ARG_channel].u_int, authmodes, args[ARG_max_connections].u_int); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_start_ap_obj, 1, wifi_radio_start_ap); @@ -302,41 +378,41 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_start_ap_obj, 1, wifi_radio_start_a //| def stop_ap(self) -> None: //| """Stops the Access Point.""" //| ... -//| STATIC mp_obj_t wifi_radio_stop_ap(mp_obj_t self) { common_hal_wifi_radio_stop_ap(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_ap_obj, wifi_radio_stop_ap); -//| def connect(self, -//| ssid: Union[str | ReadableBuffer], -//| password: Union[str | ReadableBuffer] = "", -//| *, -//| channel: Optional[int] = 0, -//| bssid: Optional[Union[str | ReadableBuffer]] = "", -//| timeout: Optional[float] = None) -> None: +//| def connect( +//| self, +//| ssid: Union[str | ReadableBuffer], +//| password: Union[str | ReadableBuffer] = b"", +//| *, +//| channel: int = 0, +//| bssid: Optional[Union[str | ReadableBuffer]] = None, +//| timeout: Optional[float] = None +//| ) -> None: //| """Connects to the given ssid and waits for an ip address. Reconnections are handled -//| automatically once one connection succeeds. +//| automatically once one connection succeeds. //| -//| By default, this will scan all channels and connect to the access point (AP) with the -//| given ``ssid`` and greatest signal strength (rssi). +//| By default, this will scan all channels and connect to the access point (AP) with the +//| given ``ssid`` and greatest signal strength (rssi). //| -//| If ``channel`` is given, the scan will begin with the given channel and connect to -//| the first AP with the given ``ssid``. This can speed up the connection time -//| significantly because a full scan doesn't occur. +//| If ``channel`` is non-zero, the scan will begin with the given channel and connect to +//| the first AP with the given ``ssid``. This can speed up the connection time +//| significantly because a full scan doesn't occur. //| -//| If ``bssid`` is given, the scan will start at the first channel or the one given and -//| connect to the AP with the given ``bssid`` and ``ssid``.""" +//| If ``bssid`` is given and not None, the scan will start at the first channel or the one given and +//| connect to the AP with the given ``bssid`` and ``ssid``.""" //| ... -//| STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_ssid, ARG_password, ARG_channel, ARG_bssid, ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_password, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_password, MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} }, { MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; @@ -356,9 +432,11 @@ STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_m mp_buffer_info_t password; password.len = 0; - if (args[ARG_password].u_obj != MP_OBJ_NULL) { + if (args[ARG_password].u_obj != mp_const_none) { mp_get_buffer_raise(args[ARG_password].u_obj, &password, MP_BUFFER_READ); - mp_arg_validate_length_range(password.len, 8, 63, MP_QSTR_password); + if (password.len != 0) { + mp_arg_validate_length_range(password.len, 8, 63, MP_QSTR_password); + } } #define MAC_ADDRESS_LENGTH 6 @@ -366,7 +444,7 @@ STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_m mp_buffer_info_t bssid; bssid.len = 0; // Should probably make sure bssid is just bytes and not something else too - if (args[ARG_bssid].u_obj != MP_OBJ_NULL) { + if (args[ARG_bssid].u_obj != mp_const_none) { mp_get_buffer_raise(args[ARG_bssid].u_obj, &bssid, MP_BUFFER_READ); if (bssid.len != MAC_ADDRESS_LENGTH) { mp_raise_ValueError(translate("Invalid BSSID")); @@ -388,7 +466,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_connect_obj, 1, wifi_radio_connect) //| ipv4_gateway: Optional[ipaddress.IPv4Address] //| """IP v4 Address of the station gateway when connected to an access point. None otherwise.""" -//| STATIC mp_obj_t wifi_radio_get_ipv4_gateway(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_gateway(self); @@ -400,7 +477,6 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_gateway_obj, //| ipv4_gateway_ap: Optional[ipaddress.IPv4Address] //| """IP v4 Address of the access point gateway, when enabled. None otherwise.""" -//| STATIC mp_obj_t wifi_radio_get_ipv4_gateway_ap(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_gateway_ap(self); @@ -412,7 +488,6 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_gateway_ap_obj, //| ipv4_subnet: Optional[ipaddress.IPv4Address] //| """IP v4 Address of the station subnet when connected to an access point. None otherwise.""" -//| STATIC mp_obj_t wifi_radio_get_ipv4_subnet(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_subnet(self); @@ -424,7 +499,6 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_subnet_obj, //| ipv4_subnet_ap: Optional[ipaddress.IPv4Address] //| """IP v4 Address of the access point subnet, when enabled. None otherwise.""" -//| STATIC mp_obj_t wifi_radio_get_ipv4_subnet_ap(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_subnet_ap(self); @@ -434,9 +508,16 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_subnet_ap_obj, wifi_radio_get_ipv4 MP_PROPERTY_GETTER(wifi_radio_ipv4_subnet_ap_obj, (mp_obj_t)&wifi_radio_get_ipv4_subnet_ap_obj); -//| def set_ipv4_address(self, *, ipv4: ipaddress.IPv4Address, netmask: ipaddress.IPv4Address, gateway: ipaddress.IPv4Address, ipv4_dns: Optional[ipaddress.IPv4Address]) -> None: +//| def set_ipv4_address( +//| self, +//| *, +//| ipv4: ipaddress.IPv4Address, +//| netmask: ipaddress.IPv4Address, +//| gateway: ipaddress.IPv4Address, +//| ipv4_dns: Optional[ipaddress.IPv4Address] +//| ) -> None: //| """Sets the IP v4 address of the station. Must include the netmask and gateway. DNS address is optional. -//| Setting the address manually will stop the DHCP client.""" +//| Setting the address manually will stop the DHCP client.""" //| ... STATIC mp_obj_t wifi_radio_set_ipv4_address(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_ipv4, ARG_netmask, ARG_gateway, ARG_ipv4_dns }; @@ -458,7 +539,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_set_ipv4_address_obj, 1, wifi_radio //| ipv4_address: Optional[ipaddress.IPv4Address] //| """IP v4 Address of the station when connected to an access point. None otherwise.""" -//| STATIC mp_obj_t _wifi_radio_get_ipv4_address(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_address(self); @@ -470,7 +550,6 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_address_obj, //| ipv4_address_ap: Optional[ipaddress.IPv4Address] //| """IP v4 Address of the access point, when enabled. None otherwise.""" -//| STATIC mp_obj_t wifi_radio_get_ipv4_address_ap(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_address_ap(self); @@ -482,7 +561,6 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_address_ap_obj, //| ipv4_dns: ipaddress.IPv4Address //| """IP v4 Address of the DNS server to be used.""" -//| STATIC mp_obj_t wifi_radio_get_ipv4_dns(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_dns(self); @@ -502,7 +580,6 @@ MP_PROPERTY_GETSET(wifi_radio_ipv4_dns_obj, //| ap_info: Optional[Network] //| """Network object containing BSSID, SSID, authmode, channel, country and RSSI when connected to an access point. None otherwise.""" -//| STATIC mp_obj_t wifi_radio_get_ap_info(mp_obj_t self) { return common_hal_wifi_radio_get_ap_info(self); @@ -512,7 +589,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ap_info_obj, wifi_radio_get_ap_info); //| def start_dhcp(self) -> None: //| """Starts the DHCP client.""" //| ... -//| STATIC mp_obj_t wifi_radio_start_dhcp_client(mp_obj_t self) { common_hal_wifi_radio_start_dhcp_client(self); return mp_const_none; @@ -522,7 +598,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_start_dhcp_client_obj, wifi_radio_start_dhc //| def stop_dhcp(self) -> None: //| """Stops the DHCP client. Needed to assign a static IP address.""" //| ... -//| STATIC mp_obj_t wifi_radio_stop_dhcp_client(mp_obj_t self) { common_hal_wifi_radio_stop_dhcp_client(self); return mp_const_none; @@ -532,9 +607,11 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_dhcp_client_obj, wifi_radio_stop_dhcp_ MP_PROPERTY_GETTER(wifi_radio_ap_info_obj, (mp_obj_t)&wifi_radio_get_ap_info_obj); -//| def ping(self, ip: ipaddress.IPv4Address, *, timeout: Optional[float] = 0.5) -> Optional[float]: +//| def ping( +//| self, ip: ipaddress.IPv4Address, *, timeout: Optional[float] = 0.5 +//| ) -> Optional[float]: //| """Ping an IP to test connectivity. Returns echo time in seconds. -//| Returns None when it times out.""" +//| Returns None when it times out.""" //| ... //| STATIC mp_obj_t wifi_radio_ping(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/wifi/Radio.h b/shared-bindings/wifi/Radio.h index 312e9e5395..dbaeb9cce8 100644 --- a/shared-bindings/wifi/Radio.h +++ b/shared-bindings/wifi/Radio.h @@ -33,7 +33,7 @@ #include "py/objstr.h" -const mp_obj_type_t wifi_radio_type; +extern const mp_obj_type_t wifi_radio_type; typedef enum { // 0 is circuitpython-specific; 1-53 are IEEE; 200+ are Espressif @@ -77,6 +77,8 @@ extern void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabl extern mp_obj_t common_hal_wifi_radio_get_hostname(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *hostname); + +extern void wifi_radio_get_mac_address(wifi_radio_obj_t *self, uint8_t *mac); extern mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_set_mac_address(wifi_radio_obj_t *self, const uint8_t *mac); extern mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self); @@ -85,13 +87,13 @@ extern void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, con extern mp_float_t common_hal_wifi_radio_get_tx_power(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_set_tx_power(wifi_radio_obj_t *self, const mp_float_t power); -extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self); +extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, uint8_t start_channel, uint8_t stop_channel); extern void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_start_station(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_stop_station(wifi_radio_obj_t *self); -extern void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint8_t authmode, uint8_t max_connections); +extern void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint32_t authmodes, uint8_t max_connections); extern void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_start_dhcp_client(wifi_radio_obj_t *self); diff --git a/shared-bindings/wifi/ScannedNetworks.c b/shared-bindings/wifi/ScannedNetworks.c index 0706d8f396..a893213719 100644 --- a/shared-bindings/wifi/ScannedNetworks.c +++ b/shared-bindings/wifi/ScannedNetworks.c @@ -50,14 +50,12 @@ STATIC mp_obj_t scannednetworks_iternext(mp_obj_t self_in) { //| def __init__(self) -> None: //| """Cannot be instantiated directly. Use `wifi.Radio.start_scanning_networks`.""" //| ... -//| //| def __iter__(self) -> Iterator[Network]: //| """Returns itself since it is the iterator.""" //| ... -//| //| def __next__(self) -> Network: //| """Returns the next `wifi.Network`. -//| Raises `StopIteration` if scanning is finished and no other results are available.""" +//| Raises `StopIteration` if scanning is finished and no other results are available.""" //| ... //| diff --git a/shared-bindings/wifi/__init__.c b/shared-bindings/wifi/__init__.c index f5bfd3a362..f7b66c68ca 100644 --- a/shared-bindings/wifi/__init__.c +++ b/shared-bindings/wifi/__init__.c @@ -38,7 +38,6 @@ //| radio: Radio //| """Wifi radio used to manage both station and AP modes. //| This object is the sole instance of `wifi.Radio`.""" -//| // Called when wifi is imported. STATIC mp_obj_t wifi___init__(void) { diff --git a/shared-bindings/zlib/__init__.c b/shared-bindings/zlib/__init__.c index e3858d008d..ba02914638 100644 --- a/shared-bindings/zlib/__init__.c +++ b/shared-bindings/zlib/__init__.c @@ -48,7 +48,9 @@ //| (commonly used in zlib library and gzip archiver). Compression is not yet implemented.""" //| -//| def zlib_decompress(data: bytes, wbits: Optional[int] = 0, bufsize: Optional[int] = 0) -> bytes: +//| def zlib_decompress( +//| data: bytes, wbits: Optional[int] = 0, bufsize: Optional[int] = 0 +//| ) -> bytes: //| """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 diff --git a/shared-module/_pixelmap/PixelMap.c b/shared-module/_pixelmap/PixelMap.c new file mode 100644 index 0000000000..5eaad0b2f8 --- /dev/null +++ b/shared-module/_pixelmap/PixelMap.c @@ -0,0 +1,174 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Rose Hooper + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/smallint.h" +#include "py/runtime.h" + +#include "shared-bindings/_pixelmap/PixelMap.h" +#include "shared-bindings/adafruit_pixelbuf/PixelBuf.h" +#include "shared-module/_pixelmap/PixelMap.h" + + +static void pixelmap_set_pixel_rgbw(pixelmap_pixelmap_obj_t *self, size_t i, color_u rgbw) { + mp_arg_validate_index_range(i, 0, self->len - 1, MP_QSTR_index); + + mp_obj_t item = self->items[i]; + if (mp_obj_is_small_int(item)) { + common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(self->pixelbuf, MP_OBJ_SMALL_INT_VALUE(item), rgbw.r, rgbw.g, rgbw.b, rgbw.w); + } else { + size_t len; + mp_obj_t *items; + mp_obj_tuple_get(item, &len, &items); + + for (size_t j = 0; j < len; j++) { + common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(self->pixelbuf, MP_OBJ_SMALL_INT_VALUE(items[j]), rgbw.r, rgbw.g, rgbw.b, rgbw.w); + } + } +} + +static void pixelmap_set_pixel(pixelmap_pixelmap_obj_t *self, size_t i, mp_obj_t color) { + color_u rgbw; + common_hal_adafruit_pixelbuf_pixelbuf_parse_color(self->pixelbuf, color, &rgbw.r, &rgbw.g, &rgbw.b, &rgbw.w); + pixelmap_set_pixel_rgbw(self, i, rgbw); +} + +void shared_module_pixelmap_pixelmap_construct(pixelmap_pixelmap_obj_t *self, mp_obj_t pixelbuf, mp_obj_t indices) { + self->pixelbuf = pixelbuf; + self->indices = indices; + mp_obj_tuple_get(indices, &self->len, &self->items); +} + +static bool auto_write_get_and_clear(pixelmap_pixelmap_obj_t *self) { + bool auto_write = self->auto_write && common_hal_adafruit_pixelbuf_pixelbuf_get_auto_write(self->pixelbuf); + if (auto_write) { + common_hal_adafruit_pixelbuf_pixelbuf_set_auto_write(self->pixelbuf, false); + } + return auto_write; +} + +static void auto_write_reapply(pixelmap_pixelmap_obj_t *self, bool auto_write) { + if (auto_write) { + common_hal_adafruit_pixelbuf_pixelbuf_set_auto_write(self->pixelbuf, true); + common_hal_adafruit_pixelbuf_pixelbuf_show(self->pixelbuf); + } +} + +bool shared_module_pixelmap_pixelmap_auto_write_get(pixelmap_pixelmap_obj_t *self) { + return self->auto_write; +} + +void shared_module_pixelmap_pixelmap_auto_write_set(pixelmap_pixelmap_obj_t *self, bool auto_write) { + self->auto_write = auto_write; +} + +void shared_module_pixelmap_pixelmap_fill(pixelmap_pixelmap_obj_t *self, const mp_obj_t color) { + color_u rgbw; + common_hal_adafruit_pixelbuf_pixelbuf_parse_color(self->pixelbuf, color, &rgbw.r, &rgbw.g, &rgbw.b, &rgbw.w); + bool auto_write = auto_write_get_and_clear(self); + + for (size_t i = 0; i < self->len; i++) { + pixelmap_set_pixel_rgbw(self, i, rgbw); + } + + auto_write_reapply(self, auto_write); +} + +mp_obj_t shared_module_pixelmap_pixelmap_indices(pixelmap_pixelmap_obj_t *self, int index) { + mp_arg_validate_index_range(index, 0, self->len - 1, MP_QSTR_index); + + mp_obj_t item = self->items[index]; + if (mp_obj_is_small_int(item)) { + return mp_obj_new_tuple(1, &item); + } else { + return item; + } +} + +#if MICROPY_PY_BUILTINS_SLICE + +mp_obj_t shared_module_pixelmap_pixelmap_getslice(pixelmap_pixelmap_obj_t *self, mp_bound_slice_t slice, size_t slice_len) { + mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(slice_len, NULL)); + for (uint i = 0; i < slice_len; i++) { + t->items[i] = shared_module_pixelmap_pixelmap_getitem(self, i * slice.step + slice.start); + } + return MP_OBJ_FROM_PTR(t); +} + +void shared_module_pixelmap_pixelmap_setslice(pixelmap_pixelmap_obj_t *self, const mp_obj_t values, mp_bound_slice_t slice, size_t slice_len) { + size_t num_items = mp_obj_get_int(mp_obj_len(values)); + if (num_items != slice_len) { + mp_raise_ValueError_varg(translate("Unmatched number of items on RHS (expected %d, got %d)."), slice_len, num_items); + } + + bool auto_write = auto_write_get_and_clear(self); + + // because we didn't preflight the pixel values, an exception could occur. + // In that case we need to do the auto-write of any pixels that were set + // before re-raising the exception + nlr_buf_t nlr; + + size_t start = slice.start; + mp_int_t step = slice.step; + + if (nlr_push(&nlr) == 0) { + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(values, &iter_buf); + mp_obj_t item; + while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + pixelmap_set_pixel(self, start, item); + start += step; + } + nlr_pop(); + auto_write_reapply(self, auto_write); + } else { + auto_write_reapply(self, auto_write); + // exception converting color value, re-raise + nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val)); + } +} +#endif + +void shared_module_pixelmap_pixelmap_setitem(pixelmap_pixelmap_obj_t *self, mp_int_t i, mp_obj_t color) { + color_u rgbw; + common_hal_adafruit_pixelbuf_pixelbuf_parse_color(self->pixelbuf, color, &rgbw.r, &rgbw.g, &rgbw.b, &rgbw.w); + bool auto_write = auto_write_get_and_clear(self); + pixelmap_set_pixel_rgbw(self, i, rgbw); + auto_write_reapply(self, auto_write); +} + +mp_obj_t shared_module_pixelmap_pixelmap_getitem(pixelmap_pixelmap_obj_t *self, mp_int_t i) { + mp_arg_validate_index_range(i, 0, self->len - 1, MP_QSTR_index); + mp_obj_t item = self->items[i]; + if (mp_obj_is_small_int(item)) { + return common_hal_adafruit_pixelbuf_pixelbuf_get_pixel(self->pixelbuf, MP_OBJ_SMALL_INT_VALUE(item)); + } else { + size_t len; + mp_obj_t *items; + mp_obj_tuple_get(item, &len, &items); + return common_hal_adafruit_pixelbuf_pixelbuf_get_pixel(self->pixelbuf, MP_OBJ_SMALL_INT_VALUE(items[0])); + } +} diff --git a/shared-module/_pixelmap/PixelMap.h b/shared-module/_pixelmap/PixelMap.h new file mode 100644 index 0000000000..192d6a4f9c --- /dev/null +++ b/shared-module/_pixelmap/PixelMap.h @@ -0,0 +1,39 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Rose Hooper + * Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "shared-module/adafruit_pixelbuf/PixelBuf.h" + +typedef struct _pixelmap_pixelmap_obj { + mp_obj_base_t base; + mp_obj_t pixelbuf; + mp_obj_t indices; + size_t len; + mp_obj_t *items; + bool auto_write; +} pixelmap_pixelmap_obj_t; diff --git a/shared-module/_pixelmap/__init__.c b/shared-module/_pixelmap/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/adafruit_pixelbuf/PixelBuf.c b/shared-module/adafruit_pixelbuf/PixelBuf.c index cab97feace..ca8f1c05b0 100644 --- a/shared-module/adafruit_pixelbuf/PixelBuf.c +++ b/shared-module/adafruit_pixelbuf/PixelBuf.c @@ -143,8 +143,10 @@ void common_hal_adafruit_pixelbuf_pixelbuf_set_brightness(mp_obj_t self_in, mp_f STATIC uint8_t _pixelbuf_get_as_uint8(mp_obj_t obj) { if (mp_obj_is_small_int(obj)) { return MP_OBJ_SMALL_INT_VALUE(obj); + #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE } else if (mp_obj_is_int(obj)) { return mp_obj_get_int_truncated(obj); + #endif } else if (mp_obj_is_float(obj)) { return (uint8_t)mp_obj_get_float(obj); } @@ -152,7 +154,7 @@ STATIC uint8_t _pixelbuf_get_as_uint8(mp_obj_t obj) { translate("can't convert %q to %q"), mp_obj_get_type_qstr(obj), MP_QSTR_int); } -STATIC void _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t *self, mp_obj_t color, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *w) { +static void pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t *self, mp_obj_t color, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *w) { pixelbuf_byteorder_details_t *byteorder = &self->byteorder; // w is shared between white in NeoPixels and brightness in dotstars (so that DotStars can have // per-pixel brightness). Set the defaults here in case it isn't set below. @@ -195,7 +197,12 @@ STATIC void _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t *self, mp_obj_t color, } } -STATIC void _pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t *self, size_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { +void common_hal_adafruit_pixelbuf_pixelbuf_parse_color(mp_obj_t self_in, mp_obj_t color, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *w) { + pixelbuf_pixelbuf_obj_t *self = native_pixelbuf(self_in); + pixelbuf_parse_color(self, color, r, g, b, w); +} + +static void pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t *self, size_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { // DotStars don't have white, instead they have 5 bit brightness so pack it into w. Shift right // by three to leave the top five bits. if (self->bytes_per_pixel == 4 && self->byteorder.is_dotstar) { @@ -232,14 +239,18 @@ STATIC void _pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t *self, size_t inde scaled_buffer[rgbw_order->b] = (b * self->scaled_brightness) / 256; } } +void common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(mp_obj_t self_in, size_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { + pixelbuf_pixelbuf_obj_t *self = native_pixelbuf(self_in); + pixelbuf_set_pixel_color(self, index, r, g, b, w); +} STATIC void _pixelbuf_set_pixel(pixelbuf_pixelbuf_obj_t *self, size_t index, mp_obj_t value) { uint8_t r; uint8_t g; uint8_t b; uint8_t w; - _pixelbuf_parse_color(self, value, &r, &g, &b, &w); - _pixelbuf_set_pixel_color(self, index, r, g, b, w); + common_hal_adafruit_pixelbuf_pixelbuf_parse_color(self, value, &r, &g, &b, &w); + common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(self, index, r, g, b, w); } void common_hal_adafruit_pixelbuf_pixelbuf_set_pixels(mp_obj_t self_in, size_t start, mp_int_t step, size_t slice_len, mp_obj_t *values, @@ -322,10 +333,10 @@ void common_hal_adafruit_pixelbuf_pixelbuf_fill(mp_obj_t self_in, mp_obj_t fill_ uint8_t g; uint8_t b; uint8_t w; - _pixelbuf_parse_color(self, fill_color, &r, &g, &b, &w); + common_hal_adafruit_pixelbuf_pixelbuf_parse_color(self, fill_color, &r, &g, &b, &w); for (size_t i = 0; i < self->pixel_count; i++) { - _pixelbuf_set_pixel_color(self, i, r, g, b, w); + common_hal_adafruit_pixelbuf_pixelbuf_set_pixel_color(self, i, r, g, b, w); } if (self->auto_write) { common_hal_adafruit_pixelbuf_pixelbuf_show(self_in); diff --git a/shared-module/adafruit_pixelbuf/PixelBuf.h b/shared-module/adafruit_pixelbuf/PixelBuf.h index b526254f29..a4a753baa0 100644 --- a/shared-module/adafruit_pixelbuf/PixelBuf.h +++ b/shared-module/adafruit_pixelbuf/PixelBuf.h @@ -24,13 +24,11 @@ * THE SOFTWARE. */ +#pragma once #include "py/obj.h" #include "py/objarray.h" -#ifndef PIXELBUF_SHARED_MODULE_H -#define PIXELBUF_SHARED_MODULE_H - typedef struct { uint8_t r; uint8_t g; @@ -68,5 +66,3 @@ typedef struct { #define DOTSTAR_LED_START 0b11100000 #define DOTSTAR_LED_START_FULL_BRIGHT 0xFF - -#endif diff --git a/shared-module/bitmaptools/__init__.c b/shared-module/bitmaptools/__init__.c index 4c73d8fb8e..6818316768 100644 --- a/shared-module/bitmaptools/__init__.c +++ b/shared-module/bitmaptools/__init__.c @@ -384,37 +384,11 @@ void common_hal_bitmaptools_boundary_fill(displayio_bitmap_t *destination, } -void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination, +STATIC void draw_line(displayio_bitmap_t *destination, int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint32_t value) { - // - // adapted from Adafruit_CircuitPython_Display_Shapes.Polygon._line - // - - // update the dirty rectangle - int16_t xbb0, xbb1, ybb0, ybb1; - if (x0 < x1) { - xbb0 = x0; - xbb1 = x1 + 1; - } else { - xbb0 = x1; - xbb1 = x0 + 1; - } - if (y0 < y1) { - ybb0 = y0; - ybb1 = y1 + 1; - } else { - ybb0 = y1; - ybb1 = y0 + 1; - } - displayio_area_t area = { xbb0, ybb0, xbb1, ybb1, NULL }; - displayio_area_t bitmap_area = { 0, 0, destination->width, destination->height, NULL }; - displayio_area_compute_overlap(&area, &bitmap_area, &area); - - displayio_bitmap_set_dirty_area(destination, &area); - int16_t temp, x, y; if (x0 == x1) { // vertical line @@ -423,6 +397,8 @@ void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination, y0 = y1; y1 = temp; } + y0 = MAX(0, y0); // only draw inside bitmap + y1 = MIN(y1, destination->height - 1); for (y = y0; y < (y1 + 1); y++) { // write a horizontal line displayio_bitmap_write_pixel(destination, x0, y, value); } @@ -432,6 +408,8 @@ void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination, x0 = x1; x1 = temp; } + x0 = MAX(0, x0); // only draw inside bitmap + x1 = MIN(x1, destination->width - 1); for (x = x0; x < (x1 + 1); x++) { // write a horizontal line displayio_bitmap_write_pixel(destination, x, y0, value); } @@ -484,6 +462,84 @@ void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination, } } +void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination, + int16_t x0, int16_t y0, + int16_t x1, int16_t y1, + uint32_t value) { + + // + // adapted from Adafruit_CircuitPython_Display_Shapes.Polygon._line + // + + // update the dirty rectangle + int16_t xbb0, xbb1, ybb0, ybb1; + if (x0 < x1) { + xbb0 = x0; + xbb1 = x1 + 1; + } else { + xbb0 = x1; + xbb1 = x0 + 1; + } + if (y0 < y1) { + ybb0 = y0; + ybb1 = y1 + 1; + } else { + ybb0 = y1; + ybb1 = y0 + 1; + } + displayio_area_t area = { xbb0, ybb0, xbb1, ybb1, NULL }; + displayio_area_t bitmap_area = { 0, 0, destination->width, destination->height, NULL }; + displayio_area_compute_overlap(&area, &bitmap_area, &area); + + displayio_bitmap_set_dirty_area(destination, &area); + + draw_line(destination, x0, y0, x1, y1, value); +} + +STATIC int32_t ith(void *data, size_t i, int element_size) { + switch (element_size) { + default: + case 1: + return *((int8_t *)data + i); + case 2: + return *((int16_t *)data + i); + case 4: + return *((int32_t *)data + i); + } +} + +void common_hal_bitmaptools_draw_polygon(displayio_bitmap_t *destination, void *xs, void *ys, size_t points_len, int point_size, uint32_t value, bool close) { + int16_t x0, y0, xmin, xmax, ymin, ymax, xprev, yprev, x, y; + x0 = ith(xs, 0, point_size); + xmin = x0; + xmax = x0; + xprev = x0; + y0 = ith(ys, 0, point_size); + ymin = y0; + ymax = y0; + yprev = y0; + + for (size_t i = 1; i < points_len; i++) { + x = ith(xs, i, point_size); + y = ith(ys, i, point_size); + draw_line(destination, xprev, yprev, x, y, value); + xprev = x; + yprev = y; + xmin = MIN(xmin, x); + xmax = MAX(xmax, x); + ymin = MIN(ymin, y); + ymax = MAX(ymax, y); + } + if (close) { + draw_line(destination, xprev, yprev, x0, y0, value); + } + + displayio_area_t area = { xmin, ymin, xmax, ymax, NULL }; + displayio_area_t bitmap_area = { 0, 0, destination->width, destination->height, NULL }; + displayio_area_compute_overlap(&area, &bitmap_area, &area); + displayio_bitmap_set_dirty_area(destination, &area); +} + void common_hal_bitmaptools_arrayblit(displayio_bitmap_t *self, void *data, int element_size, int x1, int y1, int x2, int y2, bool skip_specified, uint32_t skip_value) { uint32_t mask = (1 << common_hal_displayio_bitmap_get_bits_per_value(self)) - 1; @@ -689,7 +745,7 @@ STATIC void fill_row(displayio_bitmap_t *bitmap, int swap, int16_t *luminance_da static void write_pixels(displayio_bitmap_t *bitmap, int y, bool *data) { if (bitmap->bits_per_value == 1) { uint32_t *pixel_data = (uint32_t *)(bitmap->data + bitmap->stride * y); - for (int i = 0; i < bitmap->stride; i++) { + for (int i = 0; i < bitmap->width; i++) { uint32_t p = 0; for (int j = 0; j < 32; j++) { p = (p << 1); diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 933d3a8227..dc82d04e05 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -30,20 +30,29 @@ #include "py/runtime.h" -void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t width, - uint32_t height, uint32_t bits_per_value) { +enum { ALIGN_BITS = 8 * sizeof(uint32_t) }; + +static int stride(uint32_t width, uint32_t bits_per_value) { uint32_t row_width = width * bits_per_value; // align to uint32_t - uint8_t align_bits = 8 * sizeof(uint32_t); - if (row_width % align_bits != 0) { - self->stride = (row_width / align_bits + 1); - } else { - self->stride = row_width / align_bits; - } + return (row_width + ALIGN_BITS - 1) / ALIGN_BITS; +} + +void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t width, + uint32_t height, uint32_t bits_per_value) { + common_hal_displayio_bitmap_construct_from_buffer(self, width, height, bits_per_value, NULL, false); +} + +void common_hal_displayio_bitmap_construct_from_buffer(displayio_bitmap_t *self, uint32_t width, + uint32_t height, uint32_t bits_per_value, uint32_t *data, bool read_only) { self->width = width; self->height = height; - self->data = m_malloc(self->stride * height * sizeof(uint32_t), false); - self->read_only = false; + self->stride = stride(width, bits_per_value); + if (!data) { + data = m_malloc(self->stride * height * sizeof(uint32_t), false); + } + self->data = data; + self->read_only = read_only; self->bits_per_value = bits_per_value; if (bits_per_value > 8 && bits_per_value != 16 && bits_per_value != 32) { @@ -57,12 +66,12 @@ void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t wi self->x_shift = 0; // Used to divide the index by the number of pixels per word. Its used in a // shift which effectively divides by 2 ** x_shift. uint32_t power_of_two = 1; - while (power_of_two < align_bits / bits_per_value) { + while (power_of_two < ALIGN_BITS / bits_per_value) { self->x_shift++; power_of_two <<= 1; } - self->x_mask = (1 << self->x_shift) - 1; // Used as a modulus on the x value - self->bitmask = (1 << bits_per_value) - 1; + self->x_mask = (1u << self->x_shift) - 1u; // Used as a modulus on the x value + self->bitmask = (1u << bits_per_value) - 1u; self->dirty_area.x1 = 0; self->dirty_area.x2 = width; @@ -70,6 +79,7 @@ void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t wi self->dirty_area.y2 = height; } + uint16_t common_hal_displayio_bitmap_get_height(displayio_bitmap_t *self) { return self->height; } @@ -107,7 +117,7 @@ uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *self, int16_t void displayio_bitmap_set_dirty_area(displayio_bitmap_t *self, const displayio_area_t *dirty_area) { if (self->read_only) { - mp_raise_RuntimeError(translate("Read-only object")); + mp_raise_RuntimeError(translate("Read-only")); } displayio_area_t area = *dirty_area; @@ -121,6 +131,11 @@ void displayio_bitmap_write_pixel(displayio_bitmap_t *self, int16_t x, int16_t y // Writes the color index value into a pixel position // Must update the dirty area separately + // Don't write if out of area + if (0 > x || x >= self->width || 0 > y || y >= self->height) { + return; + } + // Update one pixel of data int32_t row_start = y * self->stride; uint32_t bytes_per_value = self->bits_per_value / 8; diff --git a/shared-module/displayio/ColorConverter.c b/shared-module/displayio/ColorConverter.c index 707601a3e7..7064569e2d 100644 --- a/shared-module/displayio/ColorConverter.c +++ b/shared-module/displayio/ColorConverter.c @@ -45,6 +45,7 @@ void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t *s self->dither = dither; self->transparent_color = NO_TRANSPARENT_COLOR; self->input_colorspace = input_colorspace; + self->output_colorspace.depth = 16; } uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888) { @@ -54,6 +55,13 @@ uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888) { return r5 << 11 | g6 << 5 | b5; } +uint8_t displayio_colorconverter_compute_rgbd(uint32_t color_rgb888) { + uint32_t r1 = (color_rgb888 >> 23) & 0x1; + uint32_t g1 = (color_rgb888 >> 15) & 0x1; + uint32_t b1 = (color_rgb888 >> 7) & 0x1; + return r1 << 3 | g1 << 2 | b1 << 1 /* | dummy */; +} + uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888) { uint32_t r8 = (color_rgb888 >> 16); uint32_t g8 = (color_rgb888 >> 8) & 0xff; @@ -96,6 +104,44 @@ uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888) { return hue; } +uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888) { + // This is DDX=1, the default for the displays. + uint8_t chroma = displayio_colorconverter_compute_chroma(color_rgb888); + if (chroma >= 64) { + uint8_t hue = displayio_colorconverter_compute_hue(color_rgb888); + // Red 0 + if (hue < 10) { + return 0x4; + } + // Orange 21 + if (hue < 21 + 10) { + return 0x6; + } + // Yellow 42 + if (hue < 42 + 21) { + return 0x5; + } + // Green 85 + if (hue < 85 + 42) { + return 0x2; + } + // Blue 170 + if (hue < 170 + 42) { + return 0x3; + } + + // The rest is red to 255 + return 0x4; + } else { + uint8_t luma = displayio_colorconverter_compute_luma(color_rgb888); + if (luma >= 128) { + return 0x1; // White + } else { + return 0x0; // Black + } + } +} + void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color) { int16_t hue_diff = colorspace->tricolor_hue - pixel_hue; @@ -207,18 +253,9 @@ uint32_t displayio_colorconverter_convert_pixel(displayio_colorspace_t colorspac return pixel; } -void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) { +void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dither, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) { uint32_t pixel = input_pixel->pixel; - - if (self->transparent_color == pixel) { - output_color->opaque = false; - return; - } - - pixel = displayio_colorconverter_convert_pixel(self->input_colorspace, pixel); - - - if (self->dither) { + if (dither) { uint8_t randr = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y)); uint8_t randg = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x + 33,input_pixel->tile_y)); uint8_t randb = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y + 33)); @@ -272,10 +309,44 @@ void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _d output_color->pixel = pixel; output_color->opaque = true; return; + } else if (colorspace->depth == 4) { + uint8_t packed; + if (colorspace->sevencolor) { + packed = displayio_colorconverter_compute_sevencolor(pixel); + } else { + packed = displayio_colorconverter_compute_rgbd(pixel); + } + output_color->pixel = packed; + output_color->opaque = true; + return; } output_color->opaque = false; } +void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) { + uint32_t pixel = input_pixel->pixel; + + if (self->transparent_color == pixel) { + output_color->opaque = false; + return; + } + + if (!self->dither && self->cached_colorspace == colorspace && self->cached_input_pixel == input_pixel->pixel) { + output_color->pixel = self->cached_output_color; + return; + } + + displayio_input_pixel_t rgb888_pixel = *input_pixel; + rgb888_pixel.pixel = displayio_colorconverter_convert_pixel(self->input_colorspace, input_pixel->pixel); + displayio_convert_color(colorspace, self->dither, &rgb888_pixel, output_color); + + if (!self->dither) { + self->cached_colorspace = colorspace; + self->cached_input_pixel = input_pixel->pixel; + self->cached_output_color = output_color->pixel; + } +} + // Currently no refresh logic is needed for a ColorConverter. diff --git a/shared-module/displayio/ColorConverter.h b/shared-module/displayio/ColorConverter.h index 7e4e9819ac..c1e46035ca 100644 --- a/shared-module/displayio/ColorConverter.h +++ b/shared-module/displayio/ColorConverter.h @@ -37,7 +37,13 @@ typedef struct displayio_colorconverter { mp_obj_base_t base; bool dither; uint8_t input_colorspace; + _displayio_colorspace_t output_colorspace; uint32_t transparent_color; + + // Cache the last computed color in case the are the same. + const _displayio_colorspace_t *cached_colorspace; + uint32_t cached_input_pixel; + uint32_t cached_output_color; } displayio_colorconverter_t; bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self); @@ -47,10 +53,15 @@ void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _d uint32_t displayio_colorconverter_dither_noise_1(uint32_t n); uint32_t displayio_colorconverter_dither_noise_2(uint32_t x, uint32_t y); +// Convert version that doesn't require a colorconverter object. +void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dither, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color); + uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888); +uint8_t displayio_colorconverter_compute_rgbd(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_chroma(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888); +uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888); void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color); #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_COLORCONVERTER_H diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 9523d068ac..5af97a4144 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -51,7 +51,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t *self, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word, uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, uint8_t *init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t *backlight_pin, - uint16_t brightness_command, mp_float_t brightness, bool auto_brightness, + uint16_t brightness_command, mp_float_t brightness, bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second, bool backlight_on_high, bool SH1107_addressing, uint16_t backlight_pwm_frequency) { @@ -70,7 +70,6 @@ void common_hal_displayio_display_construct(displayio_display_obj_t *self, self->set_row_command = set_row_command; self->write_ram_command = write_ram_command; self->brightness_command = brightness_command; - self->auto_brightness = auto_brightness; self->first_manual_refresh = !auto_refresh; self->data_as_commands = data_as_commands; self->backlight_on_high = backlight_on_high; @@ -132,21 +131,20 @@ void common_hal_displayio_display_construct(displayio_display_obj_t *self, common_hal_never_reset_pin(backlight_pin); #endif } - if (!self->auto_brightness && (self->backlight_inout.base.type != &mp_type_NoneType || - brightness_command != NO_BRIGHTNESS_COMMAND)) { - common_hal_displayio_display_set_brightness(self, brightness); - } else { - self->current_brightness = -1.0; - } + + common_hal_displayio_display_set_brightness(self, brightness); // Set the group after initialization otherwise we may send pixels while we delay in // initialization. - common_hal_displayio_display_show(self, &circuitpython_splash); + common_hal_displayio_display_set_root_group(self, &circuitpython_splash); common_hal_displayio_display_set_auto_refresh(self, auto_refresh); } bool common_hal_displayio_display_show(displayio_display_obj_t *self, displayio_group_t *root_group) { - return displayio_display_core_show(&self->core, root_group); + if (root_group == NULL) { + root_group = &circuitpython_splash; + } + return displayio_display_core_set_root_group(&self->core, root_group); } uint16_t common_hal_displayio_display_get_width(displayio_display_obj_t *self) { @@ -157,20 +155,11 @@ uint16_t common_hal_displayio_display_get_height(displayio_display_obj_t *self) return displayio_display_core_get_height(&self->core); } -bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t *self) { - return self->auto_brightness; -} - -void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t *self, bool auto_brightness) { - self->auto_brightness = auto_brightness; -} - mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t *self) { return self->current_brightness; } bool common_hal_displayio_display_set_brightness(displayio_display_obj_t *self, mp_float_t brightness) { - self->updating_backlight = true; if (!self->backlight_on_high) { brightness = 1.0 - brightness; } @@ -209,7 +198,6 @@ bool common_hal_displayio_display_set_brightness(displayio_display_obj_t *self, } } - self->updating_backlight = false; if (ok) { self->current_brightness = brightness; } @@ -221,6 +209,9 @@ mp_obj_t common_hal_displayio_display_get_bus(displayio_display_obj_t *self) { } mp_obj_t common_hal_displayio_display_get_root_group(displayio_display_obj_t *self) { + if (self->core.current_group == NULL) { + return mp_const_none; + } return self->core.current_group; } @@ -413,23 +404,15 @@ void common_hal_displayio_display_set_auto_refresh(displayio_display_obj_t *self self->auto_refresh = auto_refresh; } -STATIC void _update_backlight(displayio_display_obj_t *self) { - if (!self->auto_brightness || self->updating_backlight) { - return; +mp_obj_t common_hal_displayio_display_set_root_group(displayio_display_obj_t *self, displayio_group_t *root_group) { + bool ok = displayio_display_core_set_root_group(&self->core, root_group); + if (!ok) { + mp_raise_ValueError(translate("Group already used")); } - if (supervisor_ticks_ms64() - self->last_backlight_refresh < 100) { - return; - } - // TODO(tannewt): Fade the backlight based on its existing value and a target value. The target - // should account for ambient light when possible. - common_hal_displayio_display_set_brightness(self, 1.0); - - self->last_backlight_refresh = supervisor_ticks_ms64(); + return mp_const_none; } void displayio_display_background(displayio_display_obj_t *self) { - _update_backlight(self); - if (self->auto_refresh && (supervisor_ticks_ms64() - self->core.last_refresh) > self->native_ms_per_frame) { _refresh_display(self); } @@ -440,7 +423,6 @@ void release_display(displayio_display_obj_t *self) { release_display_core(&self->core); #if (CIRCUITPY_PWMIO) if (self->backlight_pwm.base.type == &pwmio_pwmout_type) { - common_hal_pwmio_pwmout_reset_ok(&self->backlight_pwm); common_hal_pwmio_pwmout_deinit(&self->backlight_pwm); } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); @@ -452,8 +434,10 @@ void release_display(displayio_display_obj_t *self) { void reset_display(displayio_display_obj_t *self) { common_hal_displayio_display_set_auto_refresh(self, true); - self->auto_brightness = true; - common_hal_displayio_display_show(self, NULL); + circuitpython_splash.x = 0; // reset position in case someone moved it. + circuitpython_splash.y = 0; + supervisor_start_terminal(self->core.width, self->core.height); + common_hal_displayio_display_set_root_group(self, &circuitpython_splash); } void displayio_display_collect_ptrs(displayio_display_obj_t *self) { diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h index a0049f00c0..c60adc482f 100644 --- a/shared-module/displayio/Display.h +++ b/shared-module/displayio/Display.h @@ -45,7 +45,6 @@ typedef struct { pwmio_pwmout_obj_t backlight_pwm; #endif }; - uint64_t last_backlight_refresh; uint64_t last_refresh_call; mp_float_t current_brightness; uint16_t brightness_command; @@ -57,8 +56,6 @@ typedef struct { bool auto_refresh; bool first_manual_refresh; bool data_as_commands; - bool auto_brightness; - bool updating_backlight; bool backlight_on_high; // new quirk for sh1107 bool SH1107_addressing; @@ -67,7 +64,6 @@ typedef struct { void displayio_display_background(displayio_display_obj_t *self); void release_display(displayio_display_obj_t *self); void reset_display(displayio_display_obj_t *self); - void displayio_display_collect_ptrs(displayio_display_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H diff --git a/shared-module/displayio/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c index b1e998048e..289fc47a68 100644 --- a/shared-module/displayio/EPaperDisplay.c +++ b/shared-module/displayio/EPaperDisplay.c @@ -28,6 +28,7 @@ #include "py/gc.h" #include "py/runtime.h" +#include "shared/runtime/interrupt_char.h" #include "shared-bindings/displayio/ColorConverter.h" #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/I2CDisplay.h" @@ -47,21 +48,31 @@ #define DELAY 0x80 void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t *self, - mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, + mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, mp_float_t start_up_time, const uint8_t *stop_sequence, uint16_t stop_sequence_len, uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t set_column_window_command, uint16_t set_row_window_command, uint16_t set_current_column_command, uint16_t set_current_row_command, - uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint16_t refresh_display_command, mp_float_t refresh_time, - const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool chip_select, bool grayscale, bool two_byte_sequence_length) { + uint16_t write_black_ram_command, bool black_bits_inverted, + uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, + const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time, + const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, + bool chip_select, bool grayscale, bool acep, bool two_byte_sequence_length) { + uint16_t color_depth = 1; if (highlight_color != 0x000000) { self->core.colorspace.tricolor = true; self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color); self->core.colorspace.tricolor_luma = displayio_colorconverter_compute_luma(highlight_color); } + if (acep) { + self->core.colorspace.sevencolor = true; + color_depth = 4; // bits. 7 colors + clean + self->acep = acep; + grayscale = false; + } - displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, 1, true, true, 1, true, true); + displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, color_depth, grayscale, true, 1, true, true); self->set_column_window_command = set_column_window_command; self->set_row_window_command = set_row_window_command; @@ -71,7 +82,6 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t self->black_bits_inverted = black_bits_inverted; self->write_color_ram_command = write_color_ram_command; self->color_bits_inverted = color_bits_inverted; - self->refresh_display_command = refresh_display_command; self->refresh_time = refresh_time * 1000; self->busy_state = busy_state; self->refreshing = false; @@ -81,8 +91,11 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t self->start_sequence = start_sequence; self->start_sequence_len = start_sequence_len; + self->start_up_time_ms = start_up_time * 1000; self->stop_sequence = stop_sequence; self->stop_sequence_len = stop_sequence_len; + self->refresh_sequence = refresh_sequence; + self->refresh_sequence_len = refresh_sequence_len; self->busy.base.type = &mp_type_NoneType; self->two_byte_sequence_length = two_byte_sequence_length; @@ -103,7 +116,14 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t } bool common_hal_displayio_epaperdisplay_show(displayio_epaperdisplay_obj_t *self, displayio_group_t *root_group) { - return displayio_display_core_show(&self->core, root_group); + if (root_group == NULL) { + root_group = &circuitpython_splash; + } + return displayio_display_core_set_root_group(&self->core, root_group); +} + +bool common_hal_displayio_epaperdisplay_set_root_group(displayio_epaperdisplay_obj_t *self, displayio_group_t *root_group) { + return displayio_display_core_set_root_group(&self->core, root_group); } STATIC const displayio_area_t *displayio_epaperdisplay_get_refresh_areas(displayio_epaperdisplay_obj_t *self) { @@ -186,6 +206,8 @@ STATIC void displayio_epaperdisplay_start_refresh(displayio_epaperdisplay_obj_t // run start sequence self->core.bus_reset(self->core.bus); + common_hal_time_delay_ms(self->start_up_time_ms); + send_command_sequence(self, true, self->start_sequence, self->start_sequence_len); displayio_display_core_start_refresh(&self->core); } @@ -204,9 +226,8 @@ uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaper STATIC void displayio_epaperdisplay_finish_refresh(displayio_epaperdisplay_obj_t *self) { // Actually refresh the display now that all pixel RAM has been updated. - displayio_display_core_begin_transaction(&self->core); - self->core.send(self->core.bus, DISPLAY_COMMAND, self->chip_select, &self->refresh_display_command, 1); - displayio_display_core_end_transaction(&self->core); + send_command_sequence(self, false, self->refresh_sequence, self->refresh_sequence_len); + supervisor_enable_tick(); self->refreshing = true; @@ -239,6 +260,12 @@ uint16_t common_hal_displayio_epaperdisplay_get_rotation(displayio_epaperdisplay return self->core.rotation; } +mp_obj_t common_hal_displayio_epaperdisplay_get_root_group(displayio_epaperdisplay_obj_t *self) { + if (self->core.current_group == NULL) { + return mp_const_none; + } + return self->core.current_group; +} STATIC bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t *self, const displayio_area_t *area) { uint16_t buffer_size = 128; // In uint32_ts @@ -275,7 +302,7 @@ STATIC bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t * uint32_t mask[mask_length]; uint8_t passes = 1; - if (self->core.colorspace.tricolor || self->grayscale) { + if (self->write_color_ram_command != NO_COMMAND) { passes = 2; } for (uint8_t pass = 0; pass < passes; pass++) { @@ -313,16 +340,23 @@ STATIC bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t * memset(mask, 0, mask_length * sizeof(mask[0])); memset(buffer, 0, buffer_size * sizeof(buffer[0])); - self->core.colorspace.grayscale = true; - self->core.colorspace.grayscale_bit = 7; + if (self->grayscale) { + self->core.colorspace.grayscale = true; + self->core.colorspace.grayscale_bit = 7; + } if (pass == 1) { if (self->grayscale) { // 4-color grayscale self->core.colorspace.grayscale_bit = 6; - } else { // Tri-color + displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); + } else if (self->core.colorspace.tricolor) { self->core.colorspace.grayscale = false; + displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); + } else if (self->core.colorspace.sevencolor) { + displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); } + } else { + displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); } - displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); // Invert it all. if ((pass == 1 && self->color_bits_inverted) || @@ -350,6 +384,36 @@ STATIC bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t * return true; } +STATIC bool _clean_area(displayio_epaperdisplay_obj_t *self) { + uint16_t width = displayio_display_core_get_width(&self->core); + uint16_t height = displayio_display_core_get_height(&self->core); + + uint8_t buffer[width / 2]; + memset(buffer, 0x77, width / 2); + + uint8_t write_command = self->write_black_ram_command; + displayio_display_core_begin_transaction(&self->core); + self->core.send(self->core.bus, DISPLAY_COMMAND, self->chip_select, &write_command, 1); + displayio_display_core_end_transaction(&self->core); + + for (uint16_t j = 0; j < height; j++) { + if (!displayio_display_core_begin_transaction(&self->core)) { + // Can't acquire display bus; skip the rest of the data. Try next display. + return false; + } + self->core.send(self->core.bus, DISPLAY_DATA, self->chip_select, buffer, width / 2); + displayio_display_core_end_transaction(&self->core); + + // TODO(tannewt): Make refresh displays faster so we don't starve other + // background tasks. + #if CIRCUITPY_USB + usb_background(); + #endif + } + + return true; +} + bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t *self) { if (self->refreshing && self->busy.base.type == &digitalio_digitalinout_type) { @@ -377,6 +441,18 @@ bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t *s if (current_area == NULL) { return true; } + if (self->acep) { + displayio_epaperdisplay_start_refresh(self); + _clean_area(self); + displayio_epaperdisplay_finish_refresh(self); + while (self->refreshing && !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + } + } + if (mp_hal_is_interrupted()) { + return false; + } + displayio_epaperdisplay_start_refresh(self); while (current_area != NULL) { displayio_epaperdisplay_refresh_area(self, current_area); diff --git a/shared-module/displayio/EPaperDisplay.h b/shared-module/displayio/EPaperDisplay.h index 55feaf964b..f2398398ea 100644 --- a/shared-module/displayio/EPaperDisplay.h +++ b/shared-module/displayio/EPaperDisplay.h @@ -39,9 +39,12 @@ typedef struct { digitalio_digitalinout_obj_t busy; uint32_t milliseconds_per_frame; const uint8_t *start_sequence; - uint32_t start_sequence_len; const uint8_t *stop_sequence; - uint32_t stop_sequence_len; + const uint8_t *refresh_sequence; + uint16_t start_sequence_len; + uint16_t stop_sequence_len; + uint16_t refresh_sequence_len; + uint16_t start_up_time_ms; uint16_t refresh_time; uint16_t set_column_window_command; uint16_t set_row_window_command; @@ -49,15 +52,15 @@ typedef struct { uint16_t set_current_row_command; uint16_t write_black_ram_command; uint16_t write_color_ram_command; - uint8_t refresh_display_command; uint8_t hue; bool busy_state; bool black_bits_inverted; bool color_bits_inverted; bool refreshing; bool grayscale; - display_chip_select_behavior_t chip_select; + bool acep; bool two_byte_sequence_length; + display_chip_select_behavior_t chip_select; } displayio_epaperdisplay_obj_t; void displayio_epaperdisplay_change_refresh_mode_parameters(displayio_epaperdisplay_obj_t *self, diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index ad45852379..7eec72404f 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -310,6 +310,7 @@ static void _remove_layer(displayio_group_t *self, size_t index) { self->members->items[index], &displayio_tilegrid_type); if (layer != MP_OBJ_NULL) { displayio_tilegrid_t *tilegrid = layer; + tilegrid->in_group = false; rendered_last_frame = displayio_tilegrid_get_previous_area(tilegrid, &layer_area); displayio_tilegrid_update_transform(tilegrid, NULL); } @@ -317,6 +318,7 @@ static void _remove_layer(displayio_group_t *self, size_t index) { self->members->items[index], &displayio_group_type); if (layer != MP_OBJ_NULL) { displayio_group_t *group = layer; + group->in_group = false; rendered_last_frame = displayio_group_get_previous_area(group, &layer_area); displayio_group_update_transform(group, NULL); } diff --git a/shared-module/displayio/I2CDisplay.c b/shared-module/displayio/I2CDisplay.c index 8fae5d31fd..f38e4d6296 100644 --- a/shared-module/displayio/I2CDisplay.c +++ b/shared-module/displayio/I2CDisplay.c @@ -54,6 +54,7 @@ void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t *self, // Probe the bus to see if a device acknowledges the given address. if (!common_hal_busio_i2c_probe(i2c, device_address)) { self->base.type = &mp_type_NoneType; + common_hal_displayio_i2cdisplay_deinit(self); mp_raise_ValueError_varg(translate("Unable to find I2C Display at %x"), device_address); } diff --git a/shared-module/displayio/OnDiskBitmap.c b/shared-module/displayio/OnDiskBitmap.c index 2863dffb19..c9a9d7d9f2 100644 --- a/shared-module/displayio/OnDiskBitmap.c +++ b/shared-module/displayio/OnDiskBitmap.c @@ -90,7 +90,7 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, displayio_palette_t *palette = m_new_obj(displayio_palette_t); palette->base.type = &displayio_palette_type; - common_hal_displayio_palette_construct(palette, number_of_colors); + common_hal_displayio_palette_construct(palette, number_of_colors, false); if (number_of_colors > 1) { uint16_t palette_size = number_of_colors * sizeof(uint32_t); diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c index 1bd168b354..a2ddc285fd 100644 --- a/shared-module/displayio/Palette.c +++ b/shared-module/displayio/Palette.c @@ -28,9 +28,18 @@ #include "shared-module/displayio/ColorConverter.h" -void common_hal_displayio_palette_construct(displayio_palette_t *self, uint16_t color_count) { +void common_hal_displayio_palette_construct(displayio_palette_t *self, uint16_t color_count, bool dither) { self->color_count = color_count; self->colors = (_displayio_color_t *)m_malloc(color_count * sizeof(_displayio_color_t), false); + self->dither = dither; +} + +void common_hal_displayio_palette_set_dither(displayio_palette_t *self, bool dither) { + self->dither = dither; +} + +bool common_hal_displayio_palette_get_dither(displayio_palette_t *self) { + return self->dither; } void common_hal_displayio_palette_make_opaque(displayio_palette_t *self, uint32_t palette_index) { @@ -56,12 +65,7 @@ void common_hal_displayio_palette_set_color(displayio_palette_t *self, uint32_t return; } self->colors[palette_index].rgb888 = color; - self->colors[palette_index].luma = displayio_colorconverter_compute_luma(color); - self->colors[palette_index].rgb565 = displayio_colorconverter_compute_rgb565(color); - - uint8_t chroma = displayio_colorconverter_compute_chroma(color); - self->colors[palette_index].chroma = chroma; - self->colors[palette_index].hue = displayio_colorconverter_compute_hue(color); + self->colors[palette_index].cached_colorspace = NULL; self->needs_refresh = true; } @@ -69,40 +73,26 @@ uint32_t common_hal_displayio_palette_get_color(displayio_palette_t *self, uint3 return self->colors[palette_index].rgb888; } -bool displayio_palette_get_color(displayio_palette_t *self, const _displayio_colorspace_t *colorspace, uint32_t palette_index, uint32_t *color) { +void displayio_palette_get_color(displayio_palette_t *self, const _displayio_colorspace_t *colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) { + uint32_t palette_index = input_pixel->pixel; if (palette_index > self->color_count || self->colors[palette_index].transparent) { - return false; // returns transparent + output_color->opaque = false; + return; } - if (colorspace->tricolor) { - uint8_t luma = self->colors[palette_index].luma; - *color = luma >> (8 - colorspace->depth); - // Chroma 0 means the color is a gray and has no hue so never color based on it. - if (self->colors[palette_index].chroma <= 16) { - if (!colorspace->grayscale) { - *color = 0; - } - return true; - } - uint8_t pixel_hue = self->colors[palette_index].hue; - displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, color); - } else if (colorspace->grayscale) { - size_t bitmask = (1 << colorspace->depth) - 1; - *color = (self->colors[palette_index].luma >> colorspace->grayscale_bit) & bitmask; - } else if (colorspace->depth == 16) { - uint16_t packed = self->colors[palette_index].rgb565; - if (colorspace->reverse_bytes_in_word) { - // swap bytes - packed = __builtin_bswap16(packed); - } - *color = packed; - } else if (colorspace->depth == 32) { - *color = self->colors[palette_index].rgb888; - } else { - return false; + // Cache results when not dithering. + if (!self->dither && self->colors[palette_index].cached_colorspace == colorspace) { + output_color->pixel = self->colors[palette_index].cached_color; + return; } - return true; + displayio_input_pixel_t rgb888_pixel = *input_pixel; + rgb888_pixel.pixel = self->colors[palette_index].rgb888; + displayio_convert_color(colorspace, self->dither, &rgb888_pixel, output_color); + if (!self->dither) { + self->colors[palette_index].cached_colorspace = colorspace; + self->colors[palette_index].cached_color = output_color->pixel; + } } bool displayio_palette_needs_refresh(displayio_palette_t *self) { diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h index 49f03b56c7..e9b449c4e7 100644 --- a/shared-module/displayio/Palette.h +++ b/shared-module/displayio/Palette.h @@ -40,6 +40,7 @@ typedef struct { uint8_t grayscale_bit; // The lowest grayscale bit. Normally 8 - depth. bool grayscale; bool tricolor; + bool sevencolor; // Acep e-ink screens. bool pixels_in_byte_share_row; bool reverse_pixels_in_byte; bool reverse_bytes_in_word; @@ -48,10 +49,8 @@ typedef struct { typedef struct { uint32_t rgb888; - uint16_t rgb565; - uint8_t luma; - uint8_t hue; - uint8_t chroma; + const _displayio_colorspace_t *cached_colorspace; + uint32_t cached_color; bool transparent; // This may have additional bits added later for blending. } _displayio_color_t; @@ -74,11 +73,12 @@ typedef struct displayio_palette { _displayio_color_t *colors; uint32_t color_count; bool needs_refresh; + bool dither; } displayio_palette_t; -// Returns false if color fetch did not succeed (out of range or transparent). -// Returns true if color is opaque, and sets color. -bool displayio_palette_get_color(displayio_palette_t *palette, const _displayio_colorspace_t *colorspace, uint32_t palette_index, uint32_t *color); + +void displayio_palette_get_color(displayio_palette_t *palette, const _displayio_colorspace_t *colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color); +; bool displayio_palette_needs_refresh(displayio_palette_t *self); void displayio_palette_finish_refresh(displayio_palette_t *self); diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 769c334ac6..e5573ac34c 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -507,7 +507,7 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, if (self->pixel_shader == mp_const_none) { output_pixel.pixel = input_pixel.pixel; } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { - output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel); + displayio_palette_get_color(self->pixel_shader, colorspace, &input_pixel, &output_pixel); } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel); } diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c index 8b2f0bfdf8..c21d87316d 100644 --- a/shared-module/displayio/display_core.c +++ b/shared-module/displayio/display_core.c @@ -162,17 +162,10 @@ void displayio_display_core_set_rotation(displayio_display_core_t *self, } } -bool displayio_display_core_show(displayio_display_core_t *self, displayio_group_t *root_group) { +bool displayio_display_core_set_root_group(displayio_display_core_t *self, displayio_group_t *root_group) { - if (root_group == NULL) { // set the display to the REPL, reset REPL position and size - circuitpython_splash.in_group = false; - // force the circuit_python_splash out of any group (Note: could cause problems with the parent group) - circuitpython_splash.x = 0; // reset position in case someone moved it. - circuitpython_splash.y = 0; - - supervisor_start_terminal(self->width, self->height); - - root_group = &circuitpython_splash; + if (root_group == NULL) { + // Show nothing on the display } if (root_group == self->current_group) { return true; @@ -366,7 +359,10 @@ void displayio_display_core_collect_ptrs(displayio_display_core_t *self) { } bool displayio_display_core_fill_area(displayio_display_core_t *self, displayio_area_t *area, uint32_t *mask, uint32_t *buffer) { - return displayio_group_fill_area(self->current_group, &self->colorspace, area, mask, buffer); + if (self->current_group != NULL) { + return displayio_group_fill_area(self->current_group,&self->colorspace, area, mask, buffer); + } + return false; } bool displayio_display_core_clip_area(displayio_display_core_t *self, const displayio_area_t *area, displayio_area_t *clipped) { diff --git a/shared-module/displayio/display_core.h b/shared-module/displayio/display_core.h index 8c2ba21b5e..2167683a0d 100644 --- a/shared-module/displayio/display_core.h +++ b/shared-module/displayio/display_core.h @@ -61,7 +61,7 @@ void displayio_display_core_construct(displayio_display_core_t *self, mp_obj_t bus, uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word); -bool displayio_display_core_show(displayio_display_core_t *self, displayio_group_t *root_group); +bool displayio_display_core_set_root_group(displayio_display_core_t *self, displayio_group_t *root_group); uint16_t displayio_display_core_get_width(displayio_display_core_t *self); uint16_t displayio_display_core_get_height(displayio_display_core_t *self); diff --git a/shared-module/dotenv/__init__.c b/shared-module/dotenv/__init__.c deleted file mode 100644 index bd1973366d..0000000000 --- a/shared-module/dotenv/__init__.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "shared-bindings/dotenv/__init__.h" - -#include "extmod/vfs.h" -#include "extmod/vfs_fat.h" -#include "py/mpstate.h" -#include "py/objstr.h" - -STATIC uint8_t consume_spaces(FIL *active_file) { - uint8_t character = ' '; - UINT quantity_read = 1; - while (unichar_isspace(character) && quantity_read > 0) { - f_read(active_file, &character, 1, &quantity_read); - } - return character; -} - -// Starting at the start of a new line, determines if the key matches the given -// key. File pointer is left after the = after the key. -STATIC bool key_matches(FIL *active_file, const char *key) { - uint8_t character = ' '; - UINT quantity_read = 1; - character = consume_spaces(active_file); - bool quoted = false; - if (character == '\'') { - quoted = true; - f_read(active_file, &character, 1, &quantity_read); - } - size_t key_pos = 0; - bool escaped = false; - bool matches = true; - size_t key_len = strlen(key); - while (quantity_read > 0) { - if (character == '\\' && !escaped && quoted) { - escaped = true; - } else if (!escaped && quoted && character == '\'') { - quoted = false; - // Move past the quoted before breaking so we can check the validity of data past it. - f_read(active_file, &character, 1, &quantity_read); - break; - } else if (!quoted && (unichar_isspace(character) || character == '=' || character == '\n' || character == '#')) { - break; - } else { - matches = matches && key[key_pos] == character; - escaped = false; - key_pos++; - } - - f_read(active_file, &character, 1, &quantity_read); - } - if (unichar_isspace(character)) { - character = consume_spaces(active_file); - } - if (character == '=' || character == '\n' || character == '#') { - // Rewind one so the value can find it. - f_lseek(active_file, f_tell(active_file) - 1); - } else { - // We're followed by something else that is invalid syntax. - matches = false; - } - return matches && key_pos == key_len; -} - -STATIC bool next_line(FIL *active_file) { - uint8_t character = ' '; - UINT quantity_read = 1; - bool quoted = false; - bool escaped = false; - // Track comments because they last until the end of the line. - bool comment = false; - FRESULT result = FR_OK; - // Consume all characters while quoted or others up to \n. - while (result == FR_OK && quantity_read > 0 && (quoted || character != '\n')) { - if (character == '#' || comment) { - // Comments consume any escaping. - comment = true; - } else if (!escaped) { - if (character == '\'') { - quoted = !quoted; - } else if (character == '\\') { - escaped = true; - } - } else { - escaped = false; - } - result = f_read(active_file, &character, 1, &quantity_read); - } - return result == FR_OK && quantity_read > 0; -} - -STATIC mp_int_t read_value(FIL *active_file, char *value, size_t value_len) { - uint8_t character = ' '; - UINT quantity_read = 1; - // Consume spaces before = - character = consume_spaces(active_file); - if (character != '=') { - if (character == '#' || character == '\n') { - // Keys without an = after them are valid with the value None. - return 0; - } - // All other characters are invalid. - return -1; - } - character = ' '; - // Consume space after = - while (unichar_isspace(character) && quantity_read > 0) { - f_read(active_file, &character, 1, &quantity_read); - } - bool quoted = false; - if (character == '\'') { - quoted = true; - f_read(active_file, &character, 1, &quantity_read); - } - if (character == '"') { - // We don't support double quoted values. - return -1; - } - // Copy the value over. - size_t value_pos = 0; - bool escaped = false; - // Count trailing spaces so we can ignore them at the end of unquoted - // values. - size_t trailing_spaces = 0; - while (quantity_read > 0) { - // Consume the first \ if the value is quoted. - if (quoted && character == '\\' && !escaped) { - escaped = true; - // Drop this slash by short circuiting the rest of the loop. - f_read(active_file, &character, 1, &quantity_read); - continue; - } - if (quoted && !escaped && character == '\'') { - // trailing ' means the value is done. - break; - } - // Unquoted values are ended by a newline or comment. - if (!quoted && (character == '\n' || character == '#')) { - if (character == '\n') { - // Rewind one so the next_line can find the \n. - f_lseek(active_file, f_tell(active_file) - 1); - } - break; - } - if (!quoted && unichar_isspace(character)) { - trailing_spaces += 1; - } else { - trailing_spaces = 0; - } - escaped = false; - // Only copy the value over if we have space. Otherwise, we'll just - // count the overall length. - if (value_pos < value_len) { - value[value_pos] = character; - } - value_pos++; - f_read(active_file, &character, 1, &quantity_read); - } - - return value_pos - trailing_spaces; -} - -mp_int_t dotenv_get_key(const char *path, const char *key, char *value, mp_int_t value_len) { - FIL active_file; - FATFS *fs = &((fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj)->fatfs; - FRESULT result = f_open(fs, &active_file, path, FA_READ); - if (result != FR_OK) { - return -1; - } - - mp_int_t actual_value_len = -1; - bool read_ok = true; - while (read_ok) { - if (key_matches(&active_file, key)) { - actual_value_len = read_value(&active_file, value, value_len); - } - - read_ok = next_line(&active_file); - } - f_close(&active_file); - return actual_value_len; -} - -mp_obj_t common_hal_dotenv_get_key(const char *path, const char *key) { - // Use the stack for short values. Longer values will require a heap allocation after we know - // the length. - char value[64]; - mp_int_t actual_len = dotenv_get_key(path, key, value, sizeof(value)); - if (actual_len <= 0) { - return mp_const_none; - } - if ((size_t)actual_len >= sizeof(value)) { - mp_obj_str_t *str = MP_OBJ_TO_PTR(mp_obj_new_str_copy(&mp_type_str, NULL, actual_len + 1)); - dotenv_get_key(path, key, (char *)str->data, actual_len + 1); - str->hash = qstr_compute_hash(str->data, actual_len); - return MP_OBJ_FROM_PTR(str); - } - return mp_obj_new_str(value, actual_len); -} diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c index 6f9d9ec6ad..3d66370c04 100644 --- a/shared-module/framebufferio/FramebufferDisplay.c +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -102,7 +102,10 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu } bool common_hal_framebufferio_framebufferdisplay_show(framebufferio_framebufferdisplay_obj_t *self, displayio_group_t *root_group) { - return displayio_display_core_show(&self->core, root_group); + if (root_group == NULL) { + root_group = &circuitpython_splash; + } + return displayio_display_core_set_root_group(&self->core, root_group); } uint16_t common_hal_framebufferio_framebufferdisplay_get_width(framebufferio_framebufferdisplay_obj_t *self) { @@ -113,20 +116,6 @@ uint16_t common_hal_framebufferio_framebufferdisplay_get_height(framebufferio_fr return displayio_display_core_get_height(&self->core); } -bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t *self) { - if (self->framebuffer_protocol->get_auto_brightness) { - return self->framebuffer_protocol->get_auto_brightness(self->framebuffer); - } - return true; -} - -bool common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t *self, bool auto_brightness) { - if (self->framebuffer_protocol->set_auto_brightness) { - return self->framebuffer_protocol->set_auto_brightness(self->framebuffer, auto_brightness); - } - return false; -} - mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t *self) { if (self->framebuffer_protocol->get_brightness) { return self->framebuffer_protocol->get_brightness(self->framebuffer); @@ -374,5 +363,16 @@ void framebufferio_framebufferdisplay_reset(framebufferio_framebufferdisplay_obj } mp_obj_t common_hal_framebufferio_framebufferdisplay_get_root_group(framebufferio_framebufferdisplay_obj_t *self) { + if (self->core.current_group == NULL) { + return mp_const_none; + } return self->core.current_group; } + +mp_obj_t common_hal_framebufferio_framebufferdisplay_set_root_group(framebufferio_framebufferdisplay_obj_t *self, displayio_group_t *root_group) { + bool ok = displayio_display_core_set_root_group(&self->core, root_group); + if (!ok) { + mp_raise_ValueError(translate("Group already used")); + } + return mp_const_none; +} diff --git a/shared-module/framebufferio/FramebufferDisplay.h b/shared-module/framebufferio/FramebufferDisplay.h index b6138e2202..47f31d794f 100644 --- a/shared-module/framebufferio/FramebufferDisplay.h +++ b/shared-module/framebufferio/FramebufferDisplay.h @@ -43,7 +43,6 @@ typedef struct { mp_obj_t framebuffer; const struct _framebuffer_p_t *framebuffer_protocol; mp_buffer_info_t bufinfo; - uint64_t last_backlight_refresh; uint64_t last_refresh_call; uint16_t native_frames_per_second; uint16_t native_ms_per_frame; @@ -61,15 +60,13 @@ void framebufferio_framebufferdisplay_collect_ptrs(framebufferio_framebufferdisp mp_obj_t common_hal_framebufferio_framebufferdisplay_get_framebuffer(framebufferio_framebufferdisplay_obj_t *self); -typedef bool (*framebuffer_get_auto_brightness_fun)(mp_obj_t); typedef bool (*framebuffer_get_reverse_pixels_in_byte_fun)(mp_obj_t); typedef bool (*framebuffer_get_reverse_pixels_in_word_fun)(mp_obj_t); -typedef bool (*framebuffer_set_auto_brightness_fun)(mp_obj_t, bool); typedef bool (*framebuffer_set_brightness_fun)(mp_obj_t, mp_float_t); typedef int (*framebuffer_get_bytes_per_cell_fun)(mp_obj_t); typedef int (*framebuffer_get_color_depth_fun)(mp_obj_t); typedef int (*framebuffer_get_first_pixel_offset_fun)(mp_obj_t); -typedef int (*framebuffer_get_grayscale_fun)(mp_obj_t); +typedef bool (*framebuffer_get_grayscale_fun)(mp_obj_t); typedef int (*framebuffer_get_height_fun)(mp_obj_t); typedef int (*framebuffer_get_native_frames_per_second_fun)(mp_obj_t); typedef bool (*framebuffer_get_pixels_in_byte_share_row_fun)(mp_obj_t); @@ -105,9 +102,6 @@ typedef struct _framebuffer_p_t { framebuffer_get_brightness_fun get_brightness; framebuffer_set_brightness_fun set_brightness; - // Optional -- default is no automatic brightness control - framebuffer_get_auto_brightness_fun get_auto_brightness; - framebuffer_set_auto_brightness_fun set_auto_brightness; } framebuffer_p_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FRAMEBUFFERDISPLAY_H diff --git a/shared-module/gifio/OnDiskGif.c b/shared-module/gifio/OnDiskGif.c new file mode 100644 index 0000000000..234b7f8198 --- /dev/null +++ b/shared-module/gifio/OnDiskGif.c @@ -0,0 +1,204 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Mark Komus + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/gifio/OnDiskGif.h" +#include "shared-bindings/displayio/Bitmap.h" + +#include + +#include "py/mperrno.h" +#include "py/runtime.h" + +static int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen) { + // mp_printf(&mp_plat_print, "GifReadFile len %d ", iLen); + uint32_t iBytesRead; + iBytesRead = iLen; + pyb_file_obj_t *f = pFile->fHandle; + // Note: If you read a file all the way to the last byte, seek() stops working + if ((pFile->iSize - pFile->iPos) < iLen) { + iBytesRead = pFile->iSize - pFile->iPos - 1; // <-- ugly work-around + } + if (iBytesRead <= 0) { + return 0; + } + UINT bytes_read; + if (f_read(&f->fp, pBuf, iBytesRead, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + pFile->iPos = f->fp.fptr; + // mp_printf(&mp_plat_print, " now at %d\n", pFile->iPos); + + return bytes_read; +} /* GIFReadFile() */ + +static int32_t GIFSeekFile(GIFFILE *pFile, int32_t iPosition) { + // mp_printf(&mp_plat_print, "GifSeekFile %d ", iPosition); + pyb_file_obj_t *f = pFile->fHandle; + + f_lseek(&f->fp, iPosition); + pFile->iPos = f->fp.fptr; + // mp_printf(&mp_plat_print, " now at %d\n", pFile->iPos); + return pFile->iPos; +} /* GIFSeekFile() */ + +static void GIFDraw(GIFDRAW *pDraw) { + // Called for every scan line of the image as it decodes + // The pixels delivered are the 8-bit native GIF output + // The palette is either RGB565 or the original 24-bit RGB values + // depending on the pixel type selected with gif.begin() + + displayio_bitmap_t *bitmap = (displayio_bitmap_t *)pDraw->pUser; + + uint8_t *s; + uint16_t *d; + + int iWidth = pDraw->iWidth; + if (iWidth + pDraw->iX > bitmap->width) { + iWidth = bitmap->width - pDraw->iX; + } + + if (pDraw->iY + pDraw->y >= bitmap->height || pDraw->iX >= bitmap->width || iWidth < 1) { + return; + } + + int32_t row_start = (pDraw->y + pDraw->iY) * bitmap->stride; + uint32_t *row = bitmap->data + row_start; + s = pDraw->pPixels; + d = (uint16_t *)row; + + uint16_t *pPal; + pPal = (uint16_t *)pDraw->pPalette; + + if (pDraw->ucDisposalMethod == 2) { // restore to background color + // Not supported currently. Need to reset the area the previous frame occupied + // to the background color before the previous frame was drawn + // See: https://github.com/bitbank2/AnimatedGIF/issues/3 + + // To workaround clear the gif.bitmap object yourself as required. + } + + uint8_t c, ucTransparent = pDraw->ucTransparent; + d += pDraw->iX; + if (pDraw->ucHasTransparency == 1) { + for (int x = 0; x < iWidth; x++) + { + c = *s++; + if (c != ucTransparent) { + *d = pPal[c]; + } + d++; + } + } else { + for (int x = 0; x < iWidth; x++) + { + c = *s++; + *d++ = pPal[c]; + } + } +} + +void common_hal_gifio_ondiskgif_construct(gifio_ondiskgif_t *self, pyb_file_obj_t *file) { + // mp_printf(&mp_plat_print, "Begin OnDiskGif\n"); + self->file = file; + + GIF_begin(&self->gif, GIF_PALETTE_RGB565_BE); + + self->gif.iError = GIF_SUCCESS; + self->gif.pfnRead = GIFReadFile; + self->gif.pfnSeek = GIFSeekFile; + self->gif.pfnDraw = GIFDraw; + self->gif.pfnClose = NULL; + self->gif.pfnOpen = NULL; + self->gif.GIFFile.fHandle = self->file; + + f_rewind(&self->file->fp); + self->gif.GIFFile.iSize = (int32_t)f_size(&self->file->fp); + + int result = GIF_init(&self->gif); + if (result != 1) { + mp_arg_error_invalid(MP_QSTR_file); + } + + displayio_bitmap_t *bitmap = m_new_obj(displayio_bitmap_t); + bitmap->base.type = &displayio_bitmap_type; + common_hal_displayio_bitmap_construct(bitmap, self->gif.iCanvasWidth, self->gif.iCanvasHeight, 16); + self->bitmap = bitmap; + + GIFINFO info; + GIF_getInfo(&self->gif, &info); + self->duration = info.iDuration; + self->frame_count = info.iFrameCount; + self->min_delay = info.iMinDelay; + self->max_delay = info.iMaxDelay; + + // mp_printf(&mp_plat_print, "GIF_init returned %d %x\n", result, bitmap->data); +} + +uint16_t common_hal_gifio_ondiskgif_get_height(gifio_ondiskgif_t *self) { + return (uint16_t)self->gif.iCanvasHeight; +} + +uint16_t common_hal_gifio_ondiskgif_get_width(gifio_ondiskgif_t *self) { + return (uint16_t)self->gif.iCanvasWidth; +} + +mp_obj_t common_hal_gifio_ondiskgif_get_bitmap(gifio_ondiskgif_t *self) { + return MP_OBJ_FROM_PTR(self->bitmap); +} + +int32_t common_hal_gifio_ondiskgif_get_duration(gifio_ondiskgif_t *self) { + return self->duration; +} + +int32_t common_hal_gifio_ondiskgif_get_frame_count(gifio_ondiskgif_t *self) { + return self->frame_count; +} + +int32_t common_hal_gifio_ondiskgif_get_min_delay(gifio_ondiskgif_t *self) { + return self->min_delay; +} + +int32_t common_hal_gifio_ondiskgif_get_max_delay(gifio_ondiskgif_t *self) { + return self->max_delay; +} + +uint32_t common_hal_gifio_ondiskgif_next_frame(gifio_ondiskgif_t *self, bool setDirty) { + int nextDelay = 0; + int result = GIF_playFrame(&self->gif, &nextDelay, self->bitmap); + + if ((result >= 0) && (setDirty)) { + displayio_area_t dirty_area = { + .x1 = 0, + .y1 = 0, + .x2 = self->bitmap->width, + .y2 = self->bitmap->height, + }; + + displayio_bitmap_set_dirty_area(self->bitmap, &dirty_area); + } + + return nextDelay; +} diff --git a/shared-module/gifio/OnDiskGif.h b/shared-module/gifio/OnDiskGif.h new file mode 100644 index 0000000000..c40781ef1f --- /dev/null +++ b/shared-module/gifio/OnDiskGif.h @@ -0,0 +1,51 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Mark Komus + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_ONDISKGIF_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_ONDISKGIF_H + +#include +#include + +#include "py/obj.h" + +#include "lib/AnimatedGIF/AnimatedGIF_circuitpy.h" +#include "shared-module/displayio/Bitmap.h" + +#include "extmod/vfs_fat.h" + +typedef struct { + mp_obj_base_t base; + GIFIMAGE gif; + pyb_file_obj_t *file; + displayio_bitmap_t *bitmap; + int32_t duration; + int32_t frame_count; + int32_t min_delay; + int32_t max_delay; +} gifio_ondiskgif_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_ONDISKGIF_H diff --git a/shared-module/is31fl3741/FrameBuffer.c b/shared-module/is31fl3741/FrameBuffer.c index 400f6f843d..07bd3324f9 100644 --- a/shared-module/is31fl3741/FrameBuffer.c +++ b/shared-module/is31fl3741/FrameBuffer.c @@ -141,8 +141,7 @@ void common_hal_is31fl3741_FrameBuffer_refresh(is31fl3741_FrameBuffer_obj_t *sel if (!self->paused) { common_hal_is31fl3741_begin_transaction(self->is31fl3741); - uint8_t dirty_row_flags = 0xFF; // only supports 8 rows gotta fix - + uint8_t dirty_row_flags = 0xFF; if (self->scale) { // Based on the Arduino IS31FL3741 driver code // dirtyrows flag current not implemented for scaled displays @@ -173,7 +172,7 @@ void common_hal_is31fl3741_FrameBuffer_refresh(is31fl3741_FrameBuffer_obj_t *sel } else { color = (rsum << 16) + (gsum << 8) + bsum; } - common_hal_is31fl3741_draw_pixel(self->is31fl3741, x, y, color, self->mapping); + common_hal_is31fl3741_draw_pixel(self->is31fl3741, x, y, color, self->mapping, self->scale_height); } } } else { @@ -194,9 +193,11 @@ void common_hal_is31fl3741_FrameBuffer_refresh(is31fl3741_FrameBuffer_obj_t *sel color = *buffer; } - common_hal_is31fl3741_draw_pixel(self->is31fl3741, x, y, color, self->mapping); + common_hal_is31fl3741_draw_pixel(self->is31fl3741, x, y, color, self->mapping, self->scale_height); buffer++; } + } else { + buffer += self->width; // row did not have to be redrawn, skip it in the buffer } } } diff --git a/shared-module/is31fl3741/IS31FL3741.c b/shared-module/is31fl3741/IS31FL3741.c index bb92b5b32c..08598743b7 100644 --- a/shared-module/is31fl3741/IS31FL3741.c +++ b/shared-module/is31fl3741/IS31FL3741.c @@ -148,16 +148,17 @@ void common_hal_is31fl3741_set_led(is31fl3741_IS31FL3741_obj_t *self, uint16_t l common_hal_busio_i2c_write(self->i2c, self->device_address, cmd, 2); } -void common_hal_is31fl3741_draw_pixel(is31fl3741_IS31FL3741_obj_t *self, int16_t x, int16_t y, uint32_t color, uint16_t *mapping) { +void common_hal_is31fl3741_draw_pixel(is31fl3741_IS31FL3741_obj_t *self, int16_t x, int16_t y, uint32_t color, uint16_t *mapping, uint8_t display_height) { uint8_t r = color >> 16 & 0xFF; uint8_t g = color >> 8 & 0xFF; uint8_t b = color & 0xFF; - int16_t x1 = (x * 5 + y) * 3; + int16_t x1 = (x * display_height + y) * 3; uint16_t ridx = mapping[x1 + 2]; if (ridx != 65535) { uint16_t gidx = mapping[x1 + 1]; uint16_t bidx = mapping[x1 + 0]; + common_hal_is31fl3741_set_led(self, ridx, r, 0); common_hal_is31fl3741_set_led(self, gidx, g, 0); common_hal_is31fl3741_set_led(self, bidx, b, 0); diff --git a/shared-module/os/__init__.c b/shared-module/os/__init__.c index 35933ebaf6..4a4c02e636 100644 --- a/shared-module/os/__init__.c +++ b/shared-module/os/__init__.c @@ -36,10 +36,6 @@ #include "py/runtime.h" #include "shared-bindings/os/__init__.h" -#if CIRCUITPY_DOTENV -#include "shared-bindings/dotenv/__init__.h" -#endif - // This provides all VFS related OS functions so that ports can share the code // as needed. It does not provide uname. @@ -111,16 +107,6 @@ mp_obj_t common_hal_os_getcwd(void) { return mp_vfs_getcwd(); } -mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_) { - #if CIRCUITPY_DOTENV - mp_obj_t env_obj = common_hal_dotenv_get_key("/.env", key); - if (env_obj != mp_const_none) { - return env_obj; - } - #endif - return default_; -} - mp_obj_t common_hal_os_listdir(const char *path) { mp_obj_t path_out; mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); @@ -226,3 +212,10 @@ mp_obj_t common_hal_os_statvfs(const char *path) { } return mp_vfs_proxy_call(vfs, MP_QSTR_statvfs, 1, &path_out); } + +void common_hal_os_utime(const char *path, mp_obj_t times) { + mp_obj_t args[2]; + mp_vfs_mount_t *vfs = lookup_path(path, &args[0]); + args[1] = times; + mp_vfs_proxy_call(vfs, MP_QSTR_utime, 2, args); +} diff --git a/shared-module/os/__init__.h b/shared-module/os/__init__.h new file mode 100644 index 0000000000..1b18a1f4b9 --- /dev/null +++ b/shared-module/os/__init__.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +typedef enum { + GETENV_OK = 0, + GETENV_ERR_OPEN, + GETENV_ERR_UNICODE, + GETENV_ERR_LENGTH, + GETENV_ERR_NOT_FOUND, + GETENV_ERR_UNEXPECTED = 0xff00, // logical or'd with the byte value +} os_getenv_err_t; + +// Allocation free version that returns the full length of the value. +// If it fits, the return value is 0-terminated. The passed in buffer +// may be modified even if an error is returned. Allocation free. +// An error that is not 'open' or 'not found' is printed on the repl. +os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t value_len); + +// Returns GETENV_OK and sets value to the read value. Returns +// GETENV_ERR_... if the value was not numeric. allocation-free. +// If any error code is returned, value is guaranteed not modified +// An error that is not 'open' or 'not found' is printed on the repl. +os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value); diff --git a/shared-module/os/getenv.c b/shared-module/os/getenv.c new file mode 100644 index 0000000000..870973c5d2 --- /dev/null +++ b/shared-module/os/getenv.c @@ -0,0 +1,431 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// These functions are separate from __init__.c so that os.getenv() can be +// tested in the unix "coverage" build, without bringing in "our" os module + +#include +#include +#include + +#include "shared-bindings/os/__init__.h" +#include "shared-module/os/__init__.h" + +#include "py/gc.h" +#include "py/misc.h" +#include "py/mpstate.h" +#include "py/mpprint.h" +#include "py/objstr.h" +#include "py/parsenum.h" +#include "py/runtime.h" +#include "supervisor/filesystem.h" +#include "supervisor/memory.h" + +#define GETENV_PATH "/settings.toml" + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +typedef FIL file_arg; +STATIC bool open_file(const char *name, file_arg *active_file) { + #if defined(UNIX) + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t file_obj = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), mp_obj_new_str(name, strlen(name)), MP_ROM_QSTR(MP_QSTR_rb)); + mp_arg_validate_type(file_obj, &mp_type_vfs_fat_fileio, MP_QSTR_file); + pyb_file_obj_t *file = MP_OBJ_TO_PTR(file_obj); + *active_file = file->fp; + nlr_pop(); + return true; + } else { + return false; + } + #else + FATFS *fs = filesystem_circuitpy(); + FRESULT result = f_open(fs, active_file, name, FA_READ); + return result == FR_OK; + #endif +} +STATIC void close_file(file_arg *active_file) { + // nothing +} +STATIC bool is_eof(file_arg *active_file) { + return f_eof(active_file); +} + +// Return 0 if there is no next character (EOF). +STATIC uint8_t get_next_byte(FIL *active_file) { + uint8_t character = 0; + UINT quantity_read; + // If there's an error or quantity_read is 0, character will remain 0. + f_read(active_file, &character, 1, &quantity_read); + return character; +} +STATIC void seek_eof(file_arg *active_file) { + f_lseek(active_file, f_size(active_file)); +} + +// For a fixed buffer, record the required size rather than throwing +STATIC void vstr_add_byte_nonstd(vstr_t *vstr, byte b) { + if (!vstr->fixed_buf || vstr->alloc > vstr->len) { + vstr_add_byte(vstr, b); + } else { + vstr->len++; + } +} + +// For a fixed buffer, record the required size rather than throwing +STATIC void vstr_add_char_nonstd(vstr_t *vstr, unichar c) { + size_t ulen = + (c < 0x80) ? 1 : + (c < 0x800) ? 2 : + (c < 0x10000) ? 3 : 4; + if (!vstr->fixed_buf || vstr->alloc > vstr->len + ulen) { + vstr_add_char(vstr, c); + } else { + vstr->len += ulen; + } +} + +STATIC void next_line(file_arg *active_file) { + uint8_t character; + do { + character = get_next_byte(active_file); + } while (character != 0 && character != '\n'); +} + +// Discard whitespace, except for newlines, returning the next character after the whitespace. +// Return 0 if there is no next character (EOF). +STATIC uint8_t consume_whitespace(file_arg *active_file) { + uint8_t character; + do { + character = get_next_byte(active_file); + } while (character != '\n' && character != 0 && unichar_isspace(character)); + return character; +} + +// Starting at the start of a new line, determines if the key matches the given +// key. +// +// If result is true, the key matches and file pointer is pointing just after the "=". +// If the result is false, the key does NOT match and the file pointer is +// pointing at the start of the next line, if any +STATIC bool key_matches(file_arg *active_file, const char *key) { + uint8_t character; + character = consume_whitespace(active_file); + if (character == '[' || character == 0) { + seek_eof(active_file); + return false; + } + while (*key) { + if (character != *key++) { + // A character didn't match the key, so it's not a match + // If the non-matching char was not the end of the line, + // then consume the rest of the line + if (character != '\n') { + next_line(active_file); + } + return false; + } + character = get_next_byte(active_file); + } + // the next character could be whitespace; consume if necessary + if (unichar_isspace(character)) { + character = consume_whitespace(active_file); + } + // If we're not looking at the "=" then the key didn't match + if (character != '=') { + // A character didn't match the key, so it's not a match + // If the non-matching char was not the end of the line, + // then consume the rest of the line + if (character != '\n') { + next_line(active_file); + } + return false; + } + return true; +} + +STATIC os_getenv_err_t read_unicode_escape(file_arg *active_file, int sz, vstr_t *buf) { + char hex_buf[sz + 1]; + for (int i = 0; i < sz; i++) { + hex_buf[i] = get_next_byte(active_file); + } + hex_buf[sz] = 0; + char *end; + unsigned long c = strtoul(hex_buf, &end, 16); + if (end != &hex_buf[sz]) { + return GETENV_ERR_UNEXPECTED | *end; + } + if (c >= 0x110000) { + return GETENV_ERR_UNICODE; + } + vstr_add_char_nonstd(buf, c); + return GETENV_OK; +} + +// Read a quoted string +STATIC os_getenv_err_t read_string_value(file_arg *active_file, vstr_t *buf) { + while (true) { + int character = get_next_byte(active_file); + switch (character) { + case 0: + case '\n': + return GETENV_ERR_UNEXPECTED | character; + + case '"': + character = consume_whitespace(active_file); + switch (character) { + case '#': + next_line(active_file); + MP_FALLTHROUGH; + case 0: + case '\n': + return GETENV_OK; + default: + return GETENV_ERR_UNEXPECTED | character; + } + + case '\\': + character = get_next_byte(active_file); + switch (character) { + case 0: + case '\n': + return GETENV_ERR_UNEXPECTED | character; + case 'b': + character = '\b'; + break; + case 'r': + character = '\r'; + break; + case 'n': + character = '\n'; + break; + case 't': + character = '\t'; + break; + case 'v': + character = '\v'; + break; + case 'f': + character = '\f'; + break; + case 'U': + case 'u': { + int sz = (character == 'u') ? 4 : 8; + os_getenv_err_t res; + res = read_unicode_escape(active_file, sz, buf); + if (res != GETENV_OK) { + return res; + } + continue; + } + // default falls through, other escaped characters + // represent themselves + } + MP_FALLTHROUGH; + default: + vstr_add_byte_nonstd(buf, character); + } + } +} + +// Read a numeric value (non-quoted value) as a string +STATIC os_getenv_err_t read_bare_value(file_arg *active_file, vstr_t *buf, int first_character) { + int character = first_character; + while (true) { + switch (character) { + case 0: + case '\n': + return GETENV_OK; + case '#': + next_line(active_file); + return GETENV_OK; + default: + vstr_add_byte_nonstd(buf, character); + } + character = get_next_byte(active_file); + } +} + +STATIC mp_int_t read_value(file_arg *active_file, vstr_t *buf, bool *quoted) { + uint8_t character; + character = consume_whitespace(active_file); + *quoted = (character == '"'); + + if (*quoted) { + return read_string_value(active_file, buf); + } else { + return read_bare_value(active_file, buf, character); + } +} + +STATIC os_getenv_err_t os_getenv_vstr(const char *path, const char *key, vstr_t *buf, bool *quoted) { + file_arg active_file; + if (!open_file(path, &active_file)) { + return GETENV_ERR_OPEN; + } + + os_getenv_err_t result = GETENV_ERR_NOT_FOUND; + while (!is_eof(&active_file)) { + if (key_matches(&active_file, key)) { + result = read_value(&active_file, buf, quoted); + break; + } + } + close_file(&active_file); + return result; +} + +STATIC os_getenv_err_t os_getenv_buf_terminated(const char *key, char *value, size_t value_len, bool *quoted) { + vstr_t buf; + vstr_init_fixed_buf(&buf, value_len, value); + os_getenv_err_t result = os_getenv_vstr(GETENV_PATH, key, &buf, quoted); + + if (result == GETENV_OK) { + vstr_add_byte_nonstd(&buf, 0); + memcpy(value, buf.buf, MIN(buf.len, value_len)); + if (buf.len > value_len) { // this length includes trailing NUL + result = GETENV_ERR_LENGTH; + } + } + return result; +} + +STATIC void print_dont_raise(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) { + va_list argptr; + va_start(argptr,fmt); + mp_vcprintf(&mp_plat_print, fmt, argptr); + mp_printf(&mp_plat_print, "\n"); + va_end(argptr); +} + +STATIC void handle_getenv_error(os_getenv_err_t error, void (*handle)(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...)) { + if (error == GETENV_OK) { + return; + } + if (error & GETENV_ERR_UNEXPECTED) { + byte character = (error & 0xff); + char buf[8]; + vstr_t vstr; + vstr_init_fixed_buf(&vstr, sizeof(buf), buf); + mp_print_t print = { .data = &vstr, .print_strn = (mp_print_strn_t)vstr_add_strn }; + + if (character) { + mp_str_print_quoted(&print, &character, 1, true); + } else { + mp_str_print_quoted(&print, (byte *)"EOF", 3, true); + } + handle(&mp_type_ValueError, translate("Invalid byte %.*s"), vstr.len, vstr.buf); + } else { + switch (error) { + case GETENV_ERR_OPEN: + handle(&mp_type_ValueError, translate("%S"), translate("File not found")); + break; + case GETENV_ERR_UNICODE: + handle(&mp_type_ValueError, translate("%S"), translate("Invalid unicode escape")); + break; + case GETENV_ERR_NOT_FOUND: + handle(&mp_type_ValueError, translate("%S"), translate("Key not found")); + break; + default: + handle(&mp_type_RuntimeError, translate("%S"), translate("Internal error")); + break; + } + } +} + +STATIC void common_hal_os_getenv_showerr(const char *key, os_getenv_err_t result) { + if (result != GETENV_OK && result != GETENV_ERR_OPEN && result != GETENV_ERR_NOT_FOUND) { + mp_cprintf(&mp_plat_print, translate("An error occurred while retrieving '%s':\n"), key); + handle_getenv_error(result, print_dont_raise); + } +} + +STATIC +os_getenv_err_t common_hal_os_getenv_str_inner(const char *key, char *value, size_t value_len) { + bool quoted; + os_getenv_err_t result = os_getenv_buf_terminated(key, value, value_len, "ed); + if (result == GETENV_OK && !quoted) { + result = GETENV_ERR_UNEXPECTED | value[0]; + } + return result; +} + +os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t value_len) { + os_getenv_err_t result = common_hal_os_getenv_str_inner(key, value, value_len); + common_hal_os_getenv_showerr(key, result); + return result; +} + +mp_obj_t common_hal_os_getenv_path(const char *path, const char *key, mp_obj_t default_) { + vstr_t buf; + bool quoted; + + vstr_init(&buf, 64); + os_getenv_err_t result = os_getenv_vstr(path, key, &buf, "ed); + if (result == GETENV_ERR_NOT_FOUND || result == GETENV_ERR_OPEN) { + return default_; + } + handle_getenv_error(result, mp_raise_msg_varg); + + if (quoted) { + return mp_obj_new_str_from_vstr(&mp_type_str, &buf); + } else { + return mp_parse_num_integer(buf.buf, buf.len, 0, NULL); + } +} + +mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_) { + return common_hal_os_getenv_path(GETENV_PATH, key, default_); +} + +STATIC os_getenv_err_t common_hal_os_getenv_int_inner(const char *key, mp_int_t *value) { + char buf[16]; + bool quoted; + os_getenv_err_t result = os_getenv_buf_terminated(key, buf, sizeof(buf), "ed); + if (result != GETENV_OK) { + return result; + } + if (quoted) { + return GETENV_ERR_UNEXPECTED | '"'; + } + char *end; + long num = strtol(buf, &end, 0); + while (unichar_isspace(*end)) { + end++; + } + if (end == buf || *end) { // If the whole buffer was not consumed it's an error + return GETENV_ERR_UNEXPECTED | *end; + } + *value = (mp_int_t)num; + return GETENV_OK; +} + +os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value) { + os_getenv_err_t result = common_hal_os_getenv_int_inner(key, value); + common_hal_os_getenv_showerr(key, result); + return result; +} diff --git a/shared-module/qrio/QRDecoder.c b/shared-module/qrio/QRDecoder.c index 26a609f215..f7b25362e4 100644 --- a/shared-module/qrio/QRDecoder.c +++ b/shared-module/qrio/QRDecoder.c @@ -104,6 +104,20 @@ mp_obj_t shared_module_qrio_qrdecoder_decode(qrdecoder_qrdecoder_obj_t *self, co uint8_t *src = bufinfo->buf; switch (policy) { + case QRIO_RGB565: { + uint16_t *src16 = bufinfo->buf; + for (int i = 0; i < width * height; i++) { + framebuffer[i] = (src16[i] >> 3) & 0xfc; + } + break; + } + case QRIO_RGB565_SWAPPED: { + uint16_t *src16 = bufinfo->buf; + for (int i = 0; i < width * height; i++) { + framebuffer[i] = (__builtin_bswap16(src16[i]) >> 3) & 0xfc; + } + break; + } case QRIO_EVERY_BYTE: memcpy(framebuffer, src, width * height); break; @@ -116,6 +130,7 @@ mp_obj_t shared_module_qrio_qrdecoder_decode(qrdecoder_qrdecoder_obj_t *self, co for (int i = 0; i < width * height; i++) { framebuffer[i] = src[2 * i]; } + break; } quirc_end(self->quirc); diff --git a/shared-module/sharpdisplay/SharpMemoryFramebuffer.c b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c index 285abb1dbe..3bb7f00e1b 100644 --- a/shared-module/sharpdisplay/SharpMemoryFramebuffer.c +++ b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c @@ -36,6 +36,7 @@ #include "supervisor/memory.h" #define SHARPMEM_BIT_WRITECMD_LSB (0x80) +#define JDI_BIT_WRITECMD_LSB (0x90) #define SHARPMEM_BIT_VCOM_LSB (0x40) STATIC uint8_t bitrev(uint8_t n) { @@ -54,7 +55,11 @@ int common_hal_sharpdisplay_framebuffer_get_height(sharpdisplay_framebuffer_obj_ } STATIC int common_hal_sharpdisplay_framebuffer_get_row_stride(sharpdisplay_framebuffer_obj_t *self) { - return (self->width + 7) / 8 + 2; + if (self->jdi_display) { + return (self->width + 1) / 2 + 2; + } else { + return (self->width + 7) / 8 + 2; + } } STATIC int common_hal_sharpdisplay_framebuffer_get_first_pixel_offset(sharpdisplay_framebuffer_obj_t *self) { @@ -99,10 +104,18 @@ void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_ob memset(alloc->ptr, 0, self->bufinfo.len); uint8_t *data = self->bufinfo.buf; - *data++ = SHARPMEM_BIT_WRITECMD_LSB; + if (self->jdi_display) { + *data++ = JDI_BIT_WRITECMD_LSB; + } else { + *data++ = SHARPMEM_BIT_WRITECMD_LSB; + } for (int y = 0; y < height; y++) { - *data = bitrev(y + 1); + if (self->jdi_display) { + *data = y + 1; + } else { + *data = bitrev(y + 1); + } data += row_stride; } self->full_refresh = true; @@ -128,7 +141,14 @@ void common_hal_sharpdisplay_framebuffer_deinit(sharpdisplay_framebuffer_obj_t * memset(self, 0, sizeof(*self)); } -void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *chip_select, int baudrate, int width, int height) { +void common_hal_sharpdisplay_framebuffer_construct( + sharpdisplay_framebuffer_obj_t *self, + busio_spi_obj_t *spi, + const mcu_pin_obj_t *chip_select, + int baudrate, + int width, + int height, + bool jdi_display) { common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); common_hal_never_reset_pin(chip_select); @@ -139,6 +159,7 @@ void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_ self->width = width; self->height = height; self->baudrate = baudrate; + self->jdi_display = jdi_display; common_hal_sharpdisplay_framebuffer_get_bufinfo(self, NULL); } @@ -169,7 +190,8 @@ STATIC void common_hal_sharpdisplay_framebuffer_swapbuffers(sharpdisplay_framebu } // output a trailing zero - common_hal_busio_spi_write(self->bus, data, 1); + uint8_t zero[2] = {0, 0}; + common_hal_busio_spi_write(self->bus, zero, self->jdi_display ? 2 : 1); // set chip select low common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); @@ -191,7 +213,13 @@ STATIC void sharpdisplay_framebuffer_get_bufinfo(mp_obj_t self_in, mp_buffer_inf } STATIC int sharpdisplay_framebuffer_get_color_depth(mp_obj_t self_in) { - return 1; + sharpdisplay_framebuffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + return self->jdi_display ? 4 : 1; +} + +STATIC bool sharpdisplay_framebuffer_get_grayscale(mp_obj_t self_in) { + sharpdisplay_framebuffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + return !self->jdi_display; } STATIC int sharpdisplay_framebuffer_get_height(mp_obj_t self_in) { @@ -234,6 +262,7 @@ const framebuffer_p_t sharpdisplay_framebuffer_proto = { .deinit = sharpdisplay_framebuffer_deinit, .get_bufinfo = sharpdisplay_framebuffer_get_bufinfo, .get_color_depth = sharpdisplay_framebuffer_get_color_depth, + .get_grayscale = sharpdisplay_framebuffer_get_grayscale, .get_height = sharpdisplay_framebuffer_get_height, .get_width = sharpdisplay_framebuffer_get_width, .swapbuffers = sharpdisplay_framebuffer_swapbuffers, diff --git a/shared-module/sharpdisplay/SharpMemoryFramebuffer.h b/shared-module/sharpdisplay/SharpMemoryFramebuffer.h index abc951baf5..75abb2ff10 100644 --- a/shared-module/sharpdisplay/SharpMemoryFramebuffer.h +++ b/shared-module/sharpdisplay/SharpMemoryFramebuffer.h @@ -41,19 +41,10 @@ typedef struct { uint16_t width, height; uint32_t baudrate; - bool full_refresh : 1; + bool full_refresh; + bool jdi_display; } sharpdisplay_framebuffer_obj_t; -void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *chip_select, int baudrate, int width, int height); -void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask); -void common_hal_sharpdisplay_framebuffer_deinit(sharpdisplay_framebuffer_obj_t *self); -void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_obj_t *self, mp_buffer_info_t *bufinfo); -int common_hal_sharpdisplay_framebuffer_get_height(sharpdisplay_framebuffer_obj_t *self); -int common_hal_sharpdisplay_framebuffer_get_width(sharpdisplay_framebuffer_obj_t *self); -void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask); -void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *self); -void common_hal_sharpdisplay_framebuffer_reconstruct(sharpdisplay_framebuffer_obj_t *self); - extern const framebuffer_p_t sharpdisplay_framebuffer_proto; void common_hal_sharpdisplay_framebuffer_collect_ptrs(sharpdisplay_framebuffer_obj_t *); diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c index 8806b7c8c6..7b6eec7e1b 100644 --- a/shared-module/storage/__init__.c +++ b/shared-module/storage/__init__.c @@ -267,11 +267,14 @@ void common_hal_storage_remount(const char *mount_path, bool readonly, bool disa filesystem_set_internal_concurrent_write_protection(!disable_concurrent_write_protection); } -void common_hal_storage_erase_filesystem(void) { +void common_hal_storage_erase_filesystem(bool extended) { #if CIRCUITPY_USB usb_disconnect(); #endif mp_hal_delay_ms(1000); + #if CIRCUITPY_STORAGE_EXTEND + supervisor_flash_set_extended(extended); + #endif (void)filesystem_init(false, true); // Force a re-format. Ignore failure. common_hal_mcu_reset(); // We won't actually get here, since we're resetting. diff --git a/shared-module/supervisor/StatusBar.c b/shared-module/supervisor/StatusBar.c new file mode 100644 index 0000000000..9b6fe9b849 --- /dev/null +++ b/shared-module/supervisor/StatusBar.c @@ -0,0 +1,90 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "py/obj.h" +#include "shared-bindings/supervisor/StatusBar.h" +#include "shared-bindings/supervisor/__init__.h" +#include "supervisor/shared/display.h" +#include "supervisor/shared/status_bar.h" + +#if CIRCUITPY_TERMINALIO +#include "shared-module/terminalio/Terminal.h" +#endif + +bool shared_module_supervisor_status_bar_get_console(supervisor_status_bar_obj_t *self) { + return self->console; +} + +void shared_module_supervisor_status_bar_set_console(supervisor_status_bar_obj_t *self, bool enabled) { + if (self->console == enabled) { + // Do nothing if not changing the state. + return; + } + + if (self->updated) { + // Clear before changing state. If disabling, will remain cleared. + supervisor_status_bar_clear(); + } + + self->console = enabled; + + // Update may be ignored. + supervisor_status_bar_update(); +} + +bool shared_module_supervisor_status_bar_get_display(supervisor_status_bar_obj_t *self) { + return self->display; +} + +#if CIRCUITPY_TERMINALIO +void shared_module_supervisor_status_bar_set_display(supervisor_status_bar_obj_t *self, bool enabled) { + if (self->display == enabled) { + // Do nothing if not changing the state. + return; + } + + if (self->updated) { + // Clear before changing state. If disabling, will remain cleared. + terminalio_terminal_clear_status_bar(&supervisor_terminal); + } + + self->display = enabled; + + // Update may be ignored. + supervisor_status_bar_update(); +} +#endif + +void shared_module_supervisor_status_bar_init(supervisor_status_bar_obj_t *self) { + self->console = true; + self->display = true; + self->updated = false; +} + +void shared_module_supervisor_status_bar_updated(supervisor_status_bar_obj_t *self) { + self->updated = true; +} diff --git a/shared-module/supervisor/StatusBar.h b/shared-module/supervisor/StatusBar.h new file mode 100644 index 0000000000..a1254addc4 --- /dev/null +++ b/shared-module/supervisor/StatusBar.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_SUPERVISOR_STATUS_BAR_H +#define MICROPY_INCLUDED_SHARED_MODULE_SUPERVISOR_STATUS_BAR_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + bool console; + bool display; + bool updated; +} supervisor_status_bar_obj_t; + +extern void shared_module_supervisor_status_bar_init(supervisor_status_bar_obj_t *self); +extern void shared_module_supervisor_status_bar_updated(supervisor_status_bar_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_SUPERVISOR_STATUS_BAR_H diff --git a/shared-module/supervisor/__init__.c b/shared-module/supervisor/__init__.c new file mode 100644 index 0000000000..05e23e26e7 --- /dev/null +++ b/shared-module/supervisor/__init__.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "py/obj.h" +#include "shared-bindings/supervisor/StatusBar.h" +#include "shared-bindings/supervisor/__init__.h" + +// The singleton supervisor.StatusBar object, bound to supervisor.status_bar +supervisor_status_bar_obj_t shared_module_supervisor_status_bar_obj = { + .base = { + .type = &supervisor_status_bar_type, + }, +}; diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c index d45495d14a..a19768a622 100644 --- a/shared-module/terminalio/Terminal.c +++ b/shared-module/terminalio/Terminal.c @@ -30,20 +30,31 @@ #include "shared-bindings/displayio/TileGrid.h" #include "shared-bindings/terminalio/Terminal.h" +#if CIRCUITPY_STATUS_BAR +#include "shared-bindings/supervisor/__init__.h" +#include "shared-bindings/supervisor/StatusBar.h" +#endif + +void terminalio_terminal_clear_status_bar(terminalio_terminal_obj_t *self) { + if (self->status_bar) { + common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0); + } +} + void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font, - displayio_tilegrid_t *title_bar) { + displayio_tilegrid_t *status_bar) { self->cursor_x = 0; self->cursor_y = 0; self->font = font; self->scroll_area = scroll_area; - self->title_bar = title_bar; - self->title_x = 0; - self->title_y = 0; + self->status_bar = status_bar; + self->status_x = 0; + self->status_y = 0; self->first_row = 0; common_hal_displayio_tilegrid_set_all_tiles(self->scroll_area, 0); - if (self->title_bar) { - common_hal_displayio_tilegrid_set_all_tiles(self->title_bar, 0); + if (self->status_bar) { + common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0); } common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, 1); @@ -54,6 +65,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con if (self->scroll_area == NULL) { return len; } + const byte *i = data; uint16_t start_y = self->cursor_y; while (i < data + len) { @@ -62,21 +74,24 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con if (self->in_osc_command) { if (c == 0x1b && i[0] == '\\') { self->in_osc_command = false; - self->title_x = 0; - self->title_y = 0; + self->status_x = 0; + self->status_y = 0; i += 1; - } else if (self->osc_command == 0 && self->title_bar != NULL && self->title_y < self->title_bar->height_in_tiles) { + } else if ( + self->osc_command == 0 && + self->status_bar != NULL && + self->status_y < self->status_bar->height_in_tiles) { uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c); if (tile_index != 0xff) { // Clear the tile grid before we start putting new info. - if (self->title_x == 0 && self->title_y == 0) { - common_hal_displayio_tilegrid_set_all_tiles(self->title_bar, 0); + if (self->status_x == 0 && self->status_y == 0) { + common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0); } - common_hal_displayio_tilegrid_set_tile(self->title_bar, self->title_x, self->title_y, tile_index); - self->title_x++; - if (self->title_x >= self->title_bar->width_in_tiles) { - self->title_y++; - self->title_x %= self->title_bar->width_in_tiles; + common_hal_displayio_tilegrid_set_tile(self->status_bar, self->status_x, self->status_y, tile_index); + self->status_x++; + if (self->status_x >= self->status_bar->width_in_tiles) { + self->status_y++; + self->status_x %= self->status_bar->width_in_tiles; } } } @@ -98,7 +113,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con self->cursor_x--; } } else if (c == 0x1b) { - // Handle commands of the form \x1b.####D where . is ignored. + // Handle commands of the form [ESC]. where . is not yet known. uint16_t n = 0; uint8_t j = 1; for (; j < 6; j++) { diff --git a/shared-module/terminalio/Terminal.h b/shared-module/terminalio/Terminal.h index 2e628f5df6..7f0545c6be 100644 --- a/shared-module/terminalio/Terminal.h +++ b/shared-module/terminalio/Terminal.h @@ -40,12 +40,14 @@ typedef struct { uint16_t cursor_x; uint16_t cursor_y; displayio_tilegrid_t *scroll_area; - displayio_tilegrid_t *title_bar; - uint16_t title_x; - uint16_t title_y; + displayio_tilegrid_t *status_bar; + uint16_t status_x; + uint16_t status_y; uint16_t first_row; uint16_t osc_command; bool in_osc_command; } terminalio_terminal_obj_t; +extern void terminalio_terminal_clear_status_bar(terminalio_terminal_obj_t *self); + #endif /* SHARED_MODULE_TERMINALIO_TERMINAL_H */ diff --git a/shared-module/touchio/TouchIn.c b/shared-module/touchio/TouchIn.c index 840c14571d..35dd56a6e4 100644 --- a/shared-module/touchio/TouchIn.c +++ b/shared-module/touchio/TouchIn.c @@ -78,6 +78,7 @@ void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu uint16_t raw_reading = get_raw_reading(self); if (raw_reading == TIMEOUT_TICKS) { + common_hal_touchio_touchin_deinit(self); mp_raise_ValueError(translate("No pulldown on pin; 1Mohm recommended")); } self->threshold = raw_reading * 1.05 + 100; diff --git a/shared-module/usb_cdc/Serial.c b/shared-module/usb_cdc/Serial.c index 7f1bc75a53..23bcc8722d 100644 --- a/shared-module/usb_cdc/Serial.c +++ b/shared-module/usb_cdc/Serial.c @@ -38,7 +38,10 @@ size_t common_hal_usb_cdc_serial_read(usb_cdc_serial_obj_t *self, uint8_t *data, // Read up to len bytes immediately. // The number of bytes read will not be larger than what is already in the TinyUSB FIFO. - uint32_t total_num_read = tud_cdc_n_read(self->idx, data, len); + uint32_t total_num_read = 0; + if (tud_cdc_n_connected(self->idx)) { + total_num_read = tud_cdc_n_read(self->idx, data, len); + } if (wait_forever || wait_for_timeout) { // Continue filling the buffer past what we already read. @@ -65,7 +68,9 @@ size_t common_hal_usb_cdc_serial_read(usb_cdc_serial_obj_t *self, uint8_t *data, data += num_read; // Try to read another batch of bytes. - num_read = tud_cdc_n_read(self->idx, data, len); + if (tud_cdc_n_connected(self->idx)) { + num_read = tud_cdc_n_read(self->idx, data, len); + } total_num_read += num_read; } } diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c index f92c93baa3..680bb83893 100644 --- a/shared-module/usb_hid/Device.c +++ b/shared-module/usb_hid/Device.c @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#include #include #include "py/gc.h" @@ -241,6 +242,10 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t * mp_obj_t common_hal_usb_hid_device_get_last_received_report(usb_hid_device_obj_t *self, uint8_t report_id) { // report_id has already been validated for this device. size_t id_idx = get_report_id_idx(self, report_id); + if (!self->out_report_buffers_updated[id_idx]) { + return mp_const_none; + } + self->out_report_buffers_updated[id_idx] = false; return mp_obj_new_bytes(self->out_report_buffers[id_idx], self->out_report_lengths[id_idx]); } @@ -258,6 +263,7 @@ void usb_hid_device_create_report_buffers(usb_hid_device_obj_t *self) { ? gc_alloc(self->out_report_lengths[i], false, true /*long-lived*/) : NULL; } + memset(self->out_report_buffers_updated, 0, sizeof(self->out_report_buffers_updated)); } @@ -304,6 +310,7 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep hid_device->out_report_buffers[id_idx] && hid_device->out_report_lengths[id_idx] >= bufsize) { memcpy(hid_device->out_report_buffers[id_idx], buffer, bufsize); + hid_device->out_report_buffers_updated[id_idx] = true; } } } diff --git a/shared-module/usb_hid/Device.h b/shared-module/usb_hid/Device.h index f265712be4..06729f3c7d 100644 --- a/shared-module/usb_hid/Device.h +++ b/shared-module/usb_hid/Device.h @@ -38,6 +38,7 @@ typedef struct { const uint8_t *report_descriptor; uint8_t *in_report_buffers[CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR]; uint8_t *out_report_buffers[CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR]; + uint8_t out_report_buffers_updated[CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR]; uint16_t report_descriptor_length; uint8_t report_ids[CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR]; uint8_t in_report_lengths[CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR]; diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c index 99be84542f..11b87a78f1 100644 --- a/shared-module/usb_hid/__init__.c +++ b/shared-module/usb_hid/__init__.c @@ -220,9 +220,7 @@ bool common_hal_usb_hid_enable(const mp_obj_t devices, uint8_t boot_device) { } const mp_int_t num_devices = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(devices)); - if (num_devices > MAX_HID_DEVICES) { - mp_raise_ValueError_varg(translate("No more than %d HID devices allowed"), MAX_HID_DEVICES); - } + mp_arg_validate_length_max(num_devices, MAX_HID_DEVICES, MP_QSTR_devices); num_hid_devices = num_devices; diff --git a/shared-module/vectorio/Polygon.c b/shared-module/vectorio/Polygon.c index 24eb1c501d..5d1e0d3e58 100644 --- a/shared-module/vectorio/Polygon.c +++ b/shared-module/vectorio/Polygon.c @@ -14,7 +14,8 @@ // Converts a list of points tuples to a flat list of ints for speedier internal use. -// Also validates the points. +// Also validates the points. If this fails due to invalid types or values, the +// number of points is 0 and the points_list is NULL. static void _clobber_points_list(vectorio_polygon_t *self, mp_obj_t points_tuple_list) { size_t len = 0; mp_obj_t *items; @@ -25,15 +26,12 @@ static void _clobber_points_list(vectorio_polygon_t *self, mp_obj_t points_tuple mp_raise_TypeError(translate("Polygon needs at least 3 points")); } - if (self->len < 2 * len) { - if (self->points_list != NULL) { - VECTORIO_POLYGON_DEBUG("free(%d), ", sizeof(self->points_list)); - gc_free(self->points_list); - } - self->points_list = gc_alloc(2 * len * sizeof(uint16_t), false, false); - VECTORIO_POLYGON_DEBUG("alloc(%p, %d)", self->points_list, 2 * len * sizeof(uint16_t)); - } - self->len = 2 * len; + int16_t *points_list = gc_realloc(self->points_list, 2 * len * sizeof(uint16_t), true); + VECTORIO_POLYGON_DEBUG("realloc(%p, %d) -> %p", self->points_list, 2 * len * sizeof(uint16_t), points_list); + + // In case the validation calls below fail, set these values temporarily + self->points_list = NULL; + self->len = 0; for (uint16_t i = 0; i < len; ++i) { size_t tuple_len = 0; @@ -42,20 +40,16 @@ static void _clobber_points_list(vectorio_polygon_t *self, mp_obj_t points_tuple mp_arg_validate_length(tuple_len, 2, MP_QSTR_point); - mp_int_t x; - mp_int_t y; - if (!mp_obj_get_int_maybe(tuple_items[ 0 ], &x) - || !mp_obj_get_int_maybe(tuple_items[ 1 ], &y) - || x < SHRT_MIN || x > SHRT_MAX || y < SHRT_MIN || y > SHRT_MAX - ) { - gc_free(self->points_list); - self->points_list = NULL; - mp_raise_ValueError_varg(translate("unsupported %q type"), MP_QSTR_point); - self->len = 0; - } - self->points_list[2 * i ] = (int16_t)x; - self->points_list[2 * i + 1] = (int16_t)y; + mp_int_t x = mp_arg_validate_type_int(tuple_items[0], MP_QSTR_x); + mp_arg_validate_int_range(x, SHRT_MIN, SHRT_MAX, MP_QSTR_x); + mp_int_t y = mp_arg_validate_type_int(tuple_items[1], MP_QSTR_y); + mp_arg_validate_int_range(y, SHRT_MIN, SHRT_MAX, MP_QSTR_y); + points_list[2 * i ] = (int16_t)x; + points_list[2 * i + 1] = (int16_t)y; } + + self->points_list = points_list; + self->len = 2 * len; } diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index f72cd5cc97..35131faa4f 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -277,12 +277,8 @@ void common_hal_vectorio_vector_shape_set_location(vectorio_vector_shape_t *self mp_obj_tuple_get(xy, &tuple_len, &tuple_items); mp_arg_validate_length(tuple_len, 2, MP_QSTR_location); - mp_int_t x; - mp_int_t y; - if (!mp_obj_get_int_maybe(tuple_items[ 0 ], &x) - || !mp_obj_get_int_maybe(tuple_items[ 1 ], &y)) { - mp_raise_ValueError_varg(translate("unsupported %q type"), MP_QSTR_point); - } + mp_int_t x = mp_arg_validate_type_int(tuple_items[0], MP_QSTR_x); + mp_int_t y = mp_arg_validate_type_int(tuple_items[0], MP_QSTR_y); bool dirty = false; if (self->x != x) { check_bounds_and_set_x(self, x); @@ -297,6 +293,16 @@ void common_hal_vectorio_vector_shape_set_location(vectorio_vector_shape_t *self } } +mp_int_t common_hal_vectorio_vector_shape_get_hidden(vectorio_vector_shape_t *self) { + VECTORIO_SHAPE_DEBUG("%p get_hidden\n", self); + return self->hidden; +} + +void common_hal_vectorio_vector_shape_set_hidden(vectorio_vector_shape_t *self, bool hidden) { + VECTORIO_SHAPE_DEBUG("%p set_hidden %d\n", self, x); + self->hidden = hidden; + common_hal_vectorio_vector_shape_set_dirty(self); +} mp_obj_t common_hal_vectorio_vector_shape_get_pixel_shader(vectorio_vector_shape_t *self) { VECTORIO_SHAPE_DEBUG("%p get_pixel_shader\n", self); @@ -319,6 +325,11 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ uint64_t start = common_hal_time_monotonic_ns(); uint64_t pixel_time = 0; #endif + + if (self->hidden) { + return false; + } + VECTORIO_SHAPE_DEBUG("%p fill_area: fill: {(%5d,%5d), (%5d,%5d)}", self, area->x1, area->y1, area->x2, area->y2 @@ -395,7 +406,7 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ if (self->pixel_shader == mp_const_none) { output_pixel.pixel = input_pixel.pixel; } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { - output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel); + displayio_palette_get_color(self->pixel_shader, colorspace, &input_pixel, &output_pixel); } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel); } diff --git a/shared-module/vectorio/VectorShape.h b/shared-module/vectorio/VectorShape.h index fdbae964a8..6ce09f9308 100644 --- a/shared-module/vectorio/VectorShape.h +++ b/shared-module/vectorio/VectorShape.h @@ -37,6 +37,7 @@ typedef struct { displayio_area_t ephemeral_dirty_area; displayio_area_t current_area; bool current_area_dirty; + bool hidden; } vectorio_vector_shape_t; displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_t *self, displayio_area_t *tail); diff --git a/shared/libc/string0.c b/shared/libc/string0.c index 86e7cc5960..92b063c552 100644 --- a/shared/libc/string0.c +++ b/shared/libc/string0.c @@ -28,6 +28,8 @@ #include #include +#include "py/mpconfig.h" + #ifndef likely #define likely(x) __builtin_expect((x), 1) #endif @@ -35,6 +37,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" void *memcpy(void *dst, const void *src, size_t n) { +#if CIRCUITPY_FULL_BUILD if (likely(!(((uintptr_t)dst) & 3) && !(((uintptr_t)src) & 3))) { // pointers aligned uint32_t *d = dst; @@ -56,7 +59,9 @@ void *memcpy(void *dst, const void *src, size_t n) { // copy byte *((uint8_t*)d) = *((const uint8_t*)s); } - } else { + } else +#endif + { // unaligned access, copy bytes uint8_t *d = dst; const uint8_t *s = src; @@ -93,6 +98,7 @@ void *memmove(void *dest, const void *src, size_t n) { } void *memset(void *s, int c, size_t n) { +#if CIRCUITPY_FULL_BUILD if (c == 0 && ((uintptr_t)s & 3) == 0) { // aligned store of 0 uint32_t *s32 = s; @@ -106,7 +112,9 @@ void *memset(void *s, int c, size_t n) { if (n & 1) { *((uint8_t*)s32) = 0; } - } else { + } else +#endif + { uint8_t *s2 = s; for (; n > 0; n--) { *s2++ = c; diff --git a/shared/netutils/dhcpserver.c b/shared/netutils/dhcpserver.c index 9db42b3fd9..d396a2ba56 100644 --- a/shared/netutils/dhcpserver.c +++ b/shared/netutils/dhcpserver.c @@ -33,7 +33,7 @@ #include "py/mperrno.h" #include "py/mphal.h" -#if MICROPY_PY_LWIP +#if LWIP_UDP #include "shared/netutils/dhcpserver.h" #include "lwip/udp.h" @@ -265,9 +265,9 @@ static void dhcp_server_process(void *arg, struct udp_pcb *upcb, struct pbuf *p, d->lease[yi].expiry = (mp_hal_ticks_ms() + DEFAULT_LEASE_TIME_S * 1000) >> 16; dhcp_msg.yiaddr[3] = DHCPS_BASE_IP + yi; opt_write_u8(&opt, DHCP_OPT_MSG_TYPE, DHCPACK); - printf("DHCPS: client connected: MAC=%02x:%02x:%02x:%02x:%02x:%02x IP=%u.%u.%u.%u\n", + LWIP_DEBUGF(DHCP_DEBUG, ("DHCPS: client connected: MAC=%02x:%02x:%02x:%02x:%02x:%02x IP=%u.%u.%u.%u\n", dhcp_msg.chaddr[0], dhcp_msg.chaddr[1], dhcp_msg.chaddr[2], dhcp_msg.chaddr[3], dhcp_msg.chaddr[4], dhcp_msg.chaddr[5], - dhcp_msg.yiaddr[0], dhcp_msg.yiaddr[1], dhcp_msg.yiaddr[2], dhcp_msg.yiaddr[3]); + dhcp_msg.yiaddr[0], dhcp_msg.yiaddr[1], dhcp_msg.yiaddr[2], dhcp_msg.yiaddr[3])); break; } diff --git a/shared/netutils/netutils.h b/shared/netutils/netutils.h index b23a78e5b8..3bb9212800 100644 --- a/shared/netutils/netutils.h +++ b/shared/netutils/netutils.h @@ -33,6 +33,8 @@ #define NETUTILS_TRACE_PAYLOAD (0x0002) #define NETUTILS_TRACE_NEWLINE (0x0004) +#include "py/runtime.h" + typedef enum _netutils_endian_t { NETUTILS_LITTLE, NETUTILS_BIG, diff --git a/shared/readline/readline.c b/shared/readline/readline.c index 23183342a7..d8602a9e28 100644 --- a/shared/readline/readline.c +++ b/shared/readline/readline.c @@ -177,6 +177,17 @@ int readline_process_char(int c) { vstr_cut_tail_bytes(rl.line, rl.line->len - rl.cursor_pos); // set redraw parameters redraw_from_cursor = true; + #endif + } else if (c == CHAR_CTRL_L) { + // CTRL-L is clear screen / redraw. This specific sequence is used + // (instead of a slightly more minimal sequence) for compatibility + // with the built-in Terminal class + mp_hal_stdout_tx_str("\x1b[;H\x1b[2J"); + mp_hal_stdout_tx_str(rl.prompt); + mp_hal_stdout_tx_strn(rl.line->buf + rl.orig_line_len, rl.cursor_pos - rl.orig_line_len); + // set redraw parameters + redraw_from_cursor = true; + #if MICROPY_REPL_EMACS_KEYS } else if (c == CHAR_CTRL_N) { // CTRL-N is go to next line in history goto down_arrow_key; diff --git a/shared/readline/readline.h b/shared/readline/readline.h index 4658ee19e8..9af19b181e 100644 --- a/shared/readline/readline.h +++ b/shared/readline/readline.h @@ -35,6 +35,7 @@ #define CHAR_CTRL_E (5) #define CHAR_CTRL_F (6) #define CHAR_CTRL_K (11) +#define CHAR_CTRL_L (12) #define CHAR_CTRL_N (14) #define CHAR_CTRL_P (16) #define CHAR_CTRL_U (21) diff --git a/shared/runtime/pyexec.c b/shared/runtime/pyexec.c index b1f94db5e5..87219d18f5 100644 --- a/shared/runtime/pyexec.c +++ b/shared/runtime/pyexec.c @@ -168,17 +168,21 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input } // check for SystemExit - if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type((mp_obj_t)nlr.ret_val)), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) { + + // nlr.ret_val is an exception object. + mp_obj_t exception_obj = (mp_obj_t)nlr.ret_val; + + if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(exception_obj)), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) { // at the moment, the value of SystemExit is unused ret = pyexec_system_exit; #if CIRCUITPY_ALARM - } else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type((mp_obj_t)nlr.ret_val)), &mp_type_DeepSleepRequest)) { + } else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(exception_obj)), MP_OBJ_FROM_PTR(&mp_type_DeepSleepRequest))) { ret = PYEXEC_DEEP_SLEEP; #endif - } else if ((mp_obj_t)nlr.ret_val == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { + } else if (exception_obj == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { ret = PYEXEC_RELOAD; } else { - mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val)); + mp_obj_print_exception(&mp_plat_print, exception_obj); ret = PYEXEC_EXCEPTION; } @@ -199,7 +203,9 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input size_t n, *values; mp_obj_exception_get_traceback(return_value, &n, &values); if (values != NULL) { - result->exception_line = values[n - 2]; + result->exception_line = values[1]; + result->exception_filename[sizeof(result->exception_filename) - 1] = '\0'; + strncpy(result->exception_filename, qstr_str(values[0]), sizeof(result->exception_filename) - 1); } } } diff --git a/shared/runtime/pyexec.h b/shared/runtime/pyexec.h index d31a7fe816..411426eaaa 100644 --- a/shared/runtime/pyexec.h +++ b/shared/runtime/pyexec.h @@ -37,6 +37,9 @@ typedef struct { int return_code; mp_obj_t exception; int exception_line; + // Only store the first 32 characters of the filename. It is very unlikely that they can all be + // seen. + char exception_filename[33]; } pyexec_result_t; extern pyexec_mode_kind_t pyexec_mode_kind; diff --git a/supervisor/fatfs_port.h b/supervisor/fatfs.h similarity index 89% rename from supervisor/fatfs_port.h rename to supervisor/fatfs.h index e76ced524d..59226aae1c 100644 --- a/supervisor/fatfs_port.h +++ b/supervisor/fatfs.h @@ -24,11 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SUPERVISOR_FATFS_PORT_H -#define MICROPY_INCLUDED_SUPERVISOR_FATFS_PORT_H +#ifndef MICROPY_INCLUDED_SUPERVISOR_FATFS_H +#define MICROPY_INCLUDED_SUPERVISOR_FATFS_H #include "lib/oofatfs/ff.h" void override_fattime(DWORD time); -#endif // MICROPY_INCLUDED_SUPERVISOR_FATFS_PORT_H +#endif // MICROPY_INCLUDED_SUPERVISOR_FATFS_H diff --git a/supervisor/filesystem.h b/supervisor/filesystem.h index 6f4faf0b82..3954291513 100644 --- a/supervisor/filesystem.h +++ b/supervisor/filesystem.h @@ -45,4 +45,6 @@ void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concu bool filesystem_is_writable_by_python(fs_user_mount_t *vfs); bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs); +FATFS *filesystem_circuitpy(void); + #endif // MICROPY_INCLUDED_SUPERVISOR_FILESYSTEM_H diff --git a/supervisor/flash.h b/supervisor/flash.h index 21d76c9984..5154cb8598 100644 --- a/supervisor/flash.h +++ b/supervisor/flash.h @@ -50,4 +50,8 @@ void supervisor_flash_init_vfs(struct _fs_user_mount_t *vfs); void supervisor_flash_flush(void); void supervisor_flash_release_cache(void); +void supervisor_flash_set_extended(bool extended); +bool supervisor_flash_get_extended(void); +void supervisor_flash_update_extended(void); + #endif // MICROPY_INCLUDED_SUPERVISOR_FLASH_H diff --git a/supervisor/messages/default.h b/supervisor/messages/default.h deleted file mode 100644 index 8cdd671b31..0000000000 --- a/supervisor/messages/default.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MICROPY_SUPERVISOR_MESSAGES_DEFAULT_H -#define MICROPY_SUPERVISOR_MESSAGES_DEFAULT_H - -#ifndef MSG_OUTPUT_SUFFIX -#define MSG_OUTPUT_SUFFIX " output:\r\n" -#endif - -#ifndef MSG_NEWLINE -#define MSG_NEWLINE "\r\n" -#endif - -#ifndef MSG_AUTORELOAD_ON -#define MSG_AUTORELOAD_ON "Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\r\n" -#endif - -#ifndef MSG_AUTORELOAD_OFF -#define MSG_AUTORELOAD_OFF "Auto-reload is off.\r\n" -#endif - -#ifndef MSG_SAFE_MODE_ON -#define MSG_SAFE_MODE_ON "Running in safe mode! Auto-reload is off.\r\n" -#endif - -#ifndef MSG_SAFE_MODE_NO_MAIN -#define MSG_SAFE_MODE_NO_MAIN "Running in safe mode! Not running saved code.\r\n" -#endif - -#ifndef MSG_SAFE_MODE_USER_REQUESTED -#define MSG_SAFE_MODE_USER_REQUESTED "You requested starting safe mode by " -#endif - -#ifndef MSG_SAFE_MODE_USER_EXIT -#define MSG_SAFE_MODE_USER_EXIT "To exit, please reset the board without " -#endif - -#ifndef MSG_BAD_SAFE_MODE -#define MSG_BAD_SAFE_MODE "You are running in safe mode which means something really bad happened." -#endif - -#ifndef MSG_SAFE_MODE_CRASH -#define MSG_SAFE_MODE_CRASH "Looks like our core CircuitPython code crashed hard. Whoops!" -#endif - -#ifndef MSG_SAFE_MODE_FILE_ISSUE -#define MSG_SAFE_MODE_FILE_ISSUE "Please file an issue here with the contents of your CIRCUITPY drive:" -#endif - -#ifndef MSG_SAFE_MODE_ISSUE_LINK -#define MSG_SAFE_MODE_ISSUE_LINK "https://github.com/adafruit/circuitpython/issues" -#endif - -#ifndef MSG_SAFE_MODE_BROWN_OUT_LINE_1 -#define MSG_SAFE_MODE_BROWN_OUT_LINE_1 "The microcontroller's power dipped. Please make sure your power supply provides" -#endif - -#ifndef MSG_SAFE_MODE_BROWN_OUT_LINE_2 -#define MSG_SAFE_MODE_BROWN_OUT_LINE_2 "enough power for the whole circuit and press reset (after ejecting CIRCUITPY)." -#endif - -#ifndef MSG_WAIT_BEFORE_REPL -#define MSG_WAIT_BEFORE_REPL "Press any key to enter the REPL. Use CTRL-D to reload." -#endif - -// Be careful, some tools depend on this. -#ifndef MSG_SOFT_REBOOT -#define MSG_SOFT_REBOOT "soft reboot" -#endif - -#ifndef MSG_DOUBLE_FILE_EXTENSION -#define MSG_DOUBLE_FILE_EXTENSION "WARNING: Your code filename has two extensions\r\n" -#endif - -#endif // MICROPY_SUPERVISOR_MESSAGES_DEFAULT_H diff --git a/supervisor/port.h b/supervisor/port.h index 0a8cdfd342..70bdcb0170 100644 --- a/supervisor/port.h +++ b/supervisor/port.h @@ -90,7 +90,11 @@ void port_interrupt_after_ticks(uint32_t ticks); // may not be a system level sleep. void port_idle_until_interrupt(void); -// Execute port specific actions during background tasks. +// Execute port specific actions during background tick. Only if ticks are enabled. +void port_background_tick(void); + +// Execute port specific actions during background tasks. This is before the +// background callback system. void port_background_task(void); // Take port specific actions at the beginning and end of background tasks. @@ -99,8 +103,29 @@ void port_background_task(void); void port_start_background_task(void); void port_finish_background_task(void); -// Some ports need special handling to wake the main task from an interrupt -// context or other task. The port must implement the necessary code in this -// function. A default weak implementation is provided that does nothing. +// Some ports need special handling to wake the main task from another task. The +// port must implement the necessary code in this function. A default weak +// implementation is provided that does nothing. void port_wake_main_task(void); + +// Some ports need special handling to wake the main task from an interrupt +// context. The port must implement the necessary code in this function. A +// default weak implementation is provided that does nothing. +void port_wake_main_task_from_isr(void); + +// Some ports may use real RTOS tasks besides the background task framework of +// CircuitPython. Calling this will yield to other tasks and then return to the +// CircuitPython task when others are done. +void port_yield(void); + +// Some ports need special handling just after completing boot.py execution. +// This function is called once while boot.py's VM is still valid, and +// then a second time after the VM is finalized. +// A default weak implementation is provided that does nothing. +void port_post_boot_py(bool heap_valid); + +// Some ports want to add information to boot_out.txt. +// A default weak implementation is provided that does nothing. +void port_boot_info(void); + #endif // MICROPY_INCLUDED_SUPERVISOR_PORT_H diff --git a/supervisor/serial.h b/supervisor/serial.h index 997a2bc38f..2e30998f3b 100644 --- a/supervisor/serial.h +++ b/supervisor/serial.h @@ -49,6 +49,10 @@ char serial_read(void); bool serial_bytes_available(void); bool serial_connected(void); +// Used for temporarily suppressing output to the console or display. +bool serial_console_write_disable(bool disabled); +bool serial_display_write_disable(bool disabled); + // These have no-op versions that are weak and the port can override. They work // in tandem with the cross-port mechanics like USB and BLE. void port_serial_early_init(void); diff --git a/supervisor/shared/background_callback.c b/supervisor/shared/background_callback.c index 88ffc15911..db6d62f8e7 100644 --- a/supervisor/shared/background_callback.c +++ b/supervisor/shared/background_callback.c @@ -74,6 +74,7 @@ bool PLACE_IN_ITCM(background_callback_pending)(void) { static bool in_background_callback; void PLACE_IN_ITCM(background_callback_run_all)() { + port_background_task(); if (!background_callback_pending()) { return; } diff --git a/supervisor/shared/bluetooth/bluetooth.c b/supervisor/shared/bluetooth/bluetooth.c index 426aad9891..bb44ab0f00 100644 --- a/supervisor/shared/bluetooth/bluetooth.c +++ b/supervisor/shared/bluetooth/bluetooth.c @@ -39,8 +39,10 @@ #include "common-hal/_bleio/__init__.h" +#include "supervisor/serial.h" #include "supervisor/shared/status_leds.h" #include "supervisor/shared/tick.h" +#include "supervisor/shared/translate/translate.h" #include "py/mpstate.h" @@ -54,6 +56,10 @@ #include "bluetooth/ble_drv.h" #endif +#if CIRCUITPY_STATUS_BAR +#include "supervisor/shared/status_bar.h" +#endif + // This standard advertisement advertises the CircuitPython editing service and a CIRCUITPY short name. const uint8_t public_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags 0x02, 0x0a, 0xec, // 3-5 TX power level -20 @@ -75,18 +81,13 @@ const uint8_t public_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags const uint8_t private_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags 0x02, 0x0a, 0x00 // 3-5 TX power level 0 }; -// This scan response advertises the full CIRCPYXXXX device name. -uint8_t circuitpython_scan_response_data[] = { - 0x0a, 0x09, 0x43, 0x49, 0x52, 0x50, 0x59, 0x00, 0x00, 0x00, 0x00, - #if CIRCUITPY_SERIAL_BLE - 0x11, 0x06, 0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x01, 0x00, 0xaf, 0xad - #endif -}; - +// This scan response advertises the full device name (if it fits.) +uint8_t circuitpython_scan_response_data[31]; #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE STATIC bool boot_in_discovery_mode = false; STATIC bool advertising = false; +STATIC bool _private_advertising = false; STATIC bool ble_started = false; #define WORKFLOW_UNSET 0 @@ -96,6 +97,42 @@ STATIC bool ble_started = false; STATIC uint8_t workflow_state = WORKFLOW_UNSET; STATIC bool was_connected = false; +#if CIRCUITPY_STATUS_BAR +// To detect when the title bar changes. +STATIC bool _last_connected = false; +STATIC bool _last_advertising = false; +#endif + +#if CIRCUITPY_STATUS_BAR +// Title bar status +bool supervisor_bluetooth_status_dirty(void) { + return _last_advertising != advertising || + _last_connected != was_connected; +} +#endif + +#if CIRCUITPY_STATUS_BAR +void supervisor_bluetooth_status(void) { + serial_write("BLE:"); + if (advertising) { + if (_private_advertising) { + serial_write_compressed(translate("Reconnecting")); + } else { + const char *name = (char *)circuitpython_scan_response_data + 2; + int len = MIN(strlen(name), sizeof(circuitpython_scan_response_data) - 2); + serial_write_substring(name, len); + } + } else if (was_connected) { + serial_write_compressed(translate("Ok")); + } else { + serial_write_compressed(translate("Off")); + } + + _last_connected = was_connected; + _last_advertising = advertising; +} +#endif + STATIC void supervisor_bluetooth_start_advertising(void) { if (workflow_state != WORKFLOW_ENABLED) { return; @@ -118,18 +155,31 @@ STATIC void supervisor_bluetooth_start_advertising(void) { size_t adv_len = sizeof(private_advertising_data); const uint8_t *scan_response = NULL; size_t scan_response_len = 0; + _private_advertising = true; // Advertise with less power when doing so publicly to reduce who can hear us. This will make it // harder for someone with bad intentions to pair from a distance. - if (!bonded) { + if (!bonded || boot_in_discovery_mode) { tx_power = -20; adv = public_advertising_data; adv_len = sizeof(public_advertising_data); scan_response = circuitpython_scan_response_data; scan_response_len = sizeof(circuitpython_scan_response_data); + uint16_t max_name_len = sizeof(circuitpython_scan_response_data) - 2; + uint16_t name_len = bleio_adapter_get_name((char *)circuitpython_scan_response_data + 2, + max_name_len); + if (name_len > max_name_len) { + circuitpython_scan_response_data[0] = max_name_len + 1; + circuitpython_scan_response_data[1] = 0x8; + } else { + circuitpython_scan_response_data[0] = name_len + 1; + circuitpython_scan_response_data[1] = 0x9; + } + scan_response_len = circuitpython_scan_response_data[0] + 1; + _private_advertising = false; } uint32_t status = _common_hal_bleio_adapter_start_advertising(&common_hal_bleio_adapter_obj, true, - bonded, // Advertise anonymously if we are bonded + _private_advertising, // Advertise anonymously if we are privately advertising timeout, interval, adv, @@ -232,10 +282,19 @@ void supervisor_bluetooth_background(void) { supervisor_bluetooth_file_transfer_disconnected(); #endif } + + #if CIRCUITPY_STATUS_BAR + if (was_connected != is_connected) { + supervisor_status_bar_request_update(false); + } + #endif + was_connected = is_connected; if (!is_connected) { supervisor_bluetooth_start_advertising(); return; + } else { + advertising = false; } #if CIRCUITPY_BLE_FILE_SERVICE @@ -247,7 +306,7 @@ void supervisor_bluetooth_background(void) { void supervisor_start_bluetooth(void) { #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE - if (workflow_state != WORKFLOW_ENABLED) { + if (workflow_state != WORKFLOW_ENABLED || ble_started) { return; } @@ -267,6 +326,10 @@ void supervisor_start_bluetooth(void) { // Kick off advertisements supervisor_bluetooth_background(); + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_request_update(false); + #endif + #endif } @@ -277,6 +340,8 @@ void supervisor_stop_bluetooth(void) { return; } + ble_started = false; + #if CIRCUITPY_SERIAL_BLE supervisor_stop_bluetooth_serial(); #endif @@ -289,7 +354,6 @@ void supervisor_bluetooth_enable_workflow(void) { if (workflow_state == WORKFLOW_DISABLED) { return; } - workflow_state = WORKFLOW_ENABLED; #endif } @@ -299,3 +363,12 @@ void supervisor_bluetooth_disable_workflow(void) { workflow_state = WORKFLOW_DISABLED; #endif } + +bool supervisor_bluetooth_workflow_is_enabled(void) { + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + if (workflow_state == 1) { + return true; + } + #endif + return false; +} diff --git a/supervisor/shared/bluetooth/bluetooth.h b/supervisor/shared/bluetooth/bluetooth.h index 9de82719a5..0028c8da33 100644 --- a/supervisor/shared/bluetooth/bluetooth.h +++ b/supervisor/shared/bluetooth/bluetooth.h @@ -37,5 +37,10 @@ void supervisor_stop_bluetooth(void); // Enable only works if it hasn't been set yet. void supervisor_bluetooth_enable_workflow(void); void supervisor_bluetooth_disable_workflow(void); +bool supervisor_bluetooth_workflow_is_enabled(void); + +// Title bar status +bool supervisor_bluetooth_status_dirty(void); +void supervisor_bluetooth_status(void); #endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_BLUETOOTH_H diff --git a/supervisor/shared/bluetooth/file_transfer.c b/supervisor/shared/bluetooth/file_transfer.c index a6a2f8062a..ae24c29899 100644 --- a/supervisor/shared/bluetooth/file_transfer.c +++ b/supervisor/shared/bluetooth/file_transfer.c @@ -42,15 +42,16 @@ #include "common-hal/_bleio/__init__.h" -#include "supervisor/fatfs_port.h" +#include "supervisor/fatfs.h" +#include "supervisor/filesystem.h" #include "supervisor/shared/reload.h" #include "supervisor/shared/bluetooth/file_transfer.h" #include "supervisor/shared/bluetooth/file_transfer_protocol.h" +#include "supervisor/shared/workflow.h" #include "supervisor/shared/tick.h" #include "supervisor/usb.h" #include "py/mpstate.h" -#include "py/stackctrl.h" STATIC bleio_service_obj_t supervisor_ble_service; STATIC bleio_uuid_obj_t supervisor_ble_service_uuid; @@ -172,7 +173,7 @@ STATIC uint8_t _process_read(const uint8_t *raw_buf, size_t command_len) { char *path = (char *)((uint8_t *)command) + header_size; path[command->path_length] = '\0'; - FATFS *fs = &((fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj)->fatfs; + FATFS *fs = filesystem_circuitpy(); FRESULT result = f_open(fs, &active_file, path, FA_READ); if (result != FR_OK) { response.status = STATUS_ERROR; @@ -289,7 +290,7 @@ STATIC uint8_t _process_write(const uint8_t *raw_buf, size_t command_len) { return ANY_COMMAND; } - FATFS *fs = &((fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj)->fatfs; + FATFS *fs = filesystem_circuitpy(); DWORD fattime; _truncated_time = truncate_time(command->modification_time, &fattime); override_fattime(fattime); @@ -386,39 +387,6 @@ STATIC uint8_t _process_write_data(const uint8_t *raw_buf, size_t command_len) { return WRITE_DATA; } -STATIC FRESULT _delete_directory_contents(FATFS *fs, const TCHAR *path) { - FF_DIR dir; - FRESULT res = f_opendir(fs, &dir, path); - FILINFO file_info; - // Check the stack since we're putting paths on it. - if (mp_stack_usage() >= MP_STATE_THREAD(stack_limit)) { - return FR_INT_ERR; - } - while (res == FR_OK) { - res = f_readdir(&dir, &file_info); - if (res != FR_OK || file_info.fname[0] == '\0') { - break; - } - size_t pathlen = strlen(path); - size_t fnlen = strlen(file_info.fname); - TCHAR full_path[pathlen + 1 + fnlen]; - memcpy(full_path, path, pathlen); - full_path[pathlen] = '/'; - size_t full_pathlen = pathlen + 1 + fnlen; - memcpy(full_path + pathlen + 1, file_info.fname, fnlen); - full_path[full_pathlen] = '\0'; - if ((file_info.fattrib & AM_DIR) != 0) { - res = _delete_directory_contents(fs, full_path); - } - if (res != FR_OK) { - break; - } - res = f_unlink(fs, full_path); - } - f_closedir(&dir); - return res; -} - STATIC uint8_t _process_delete(const uint8_t *raw_buf, size_t command_len) { const struct delete_command *command = (struct delete_command *)raw_buf; size_t header_size = sizeof(struct delete_command); @@ -438,14 +406,14 @@ STATIC uint8_t _process_delete(const uint8_t *raw_buf, size_t command_len) { if (command_len < header_size + command->path_length) { return THIS_COMMAND; } - FATFS *fs = &((fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj)->fatfs; + FATFS *fs = filesystem_circuitpy(); char *path = (char *)((uint8_t *)command) + header_size; path[command->path_length] = '\0'; FILINFO file; FRESULT result = f_stat(fs, path, &file); if (result == FR_OK) { if ((file.fattrib & AM_DIR) != 0) { - result = _delete_directory_contents(fs, path); + result = supervisor_workflow_delete_directory_contents(fs, path); } if (result == FR_OK) { result = f_unlink(fs, path); @@ -495,14 +463,14 @@ STATIC uint8_t _process_mkdir(const uint8_t *raw_buf, size_t command_len) { if (command_len < header_size + command->path_length) { return THIS_COMMAND; } - FATFS *fs = &((fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj)->fatfs; + FATFS *fs = filesystem_circuitpy(); char *path = (char *)command->path; _terminate_path(path, command->path_length); DWORD fattime; response.truncated_time = truncate_time(command->modification_time, &fattime); override_fattime(fattime); - FRESULT result = f_mkdir(fs, path); + FRESULT result = supervisor_workflow_mkdir_parents(fs, path); override_fattime(0); #if CIRCUITPY_USB_MSC usb_msc_unlock(); @@ -552,7 +520,7 @@ STATIC uint8_t _process_listdir(uint8_t *raw_buf, size_t command_len) { return THIS_COMMAND; } - FATFS *fs = &((fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj)->fatfs; + FATFS *fs = filesystem_circuitpy(); char *path = (char *)&command->path; _terminate_path(path, command->path_length); // mp_printf(&mp_plat_print, "list %s\n", path); @@ -640,7 +608,7 @@ STATIC uint8_t _process_move(const uint8_t *raw_buf, size_t command_len) { if (command_len < header_size + total_path_length) { return THIS_COMMAND; } - FATFS *fs = &((fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj)->fatfs; + FATFS *fs = filesystem_circuitpy(); char *old_path = (char *)command->paths; old_path[command->old_path_length] = '\0'; diff --git a/supervisor/shared/bluetooth/serial.c b/supervisor/shared/bluetooth/serial.c index 2edf3c784f..a5f4d776b3 100644 --- a/supervisor/shared/bluetooth/serial.c +++ b/supervisor/shared/bluetooth/serial.c @@ -146,7 +146,8 @@ void supervisor_start_bluetooth_serial(void) { &supervisor_ble_circuitpython_rx_characteristic, 0.1f, (uint8_t *)_incoming, sizeof(_incoming) * sizeof(uint32_t), - &rx_static_handler_entry); + &rx_static_handler_entry, + true /* watch for interrupt character */); _enabled = true; } diff --git a/supervisor/shared/board.c b/supervisor/shared/board.c index 427c179242..2317540c1a 100644 --- a/supervisor/shared/board.c +++ b/supervisor/shared/board.c @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#include "supervisor/board.h" #include "supervisor/shared/board.h" #if CIRCUITPY_DIGITALIO && CIRCUITPY_NEOPIXEL_WRITE @@ -46,3 +47,20 @@ void board_reset_user_neopixels(const mcu_pin_obj_t *pin, size_t count) { } #endif + +// Do-nothing so not all boards need to provide this function. +MP_WEAK bool board_requests_safe_mode(void) { + return false; +} + +// Do-nothing so not all boards need to provide this function. +MP_WEAK void board_init(void) { +} + +// Do-nothing so not all boards need to provide this function. +MP_WEAK void board_deinit(void) { +} + +// Do-nothing so not all boards need to provide this function. +MP_WEAK void reset_board(void) { +} diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 849b9c3fe2..26585c54d5 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -45,6 +45,10 @@ #include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" #endif +#if CIRCUITPY_STATUS_BAR +#include "supervisor/shared/status_bar.h" +#endif + #if CIRCUITPY_REPL_LOGO extern uint32_t blinka_bitmap_data[]; extern displayio_bitmap_t blinka_bitmap; @@ -62,19 +66,16 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { #if CIRCUITPY_TERMINALIO displayio_tilegrid_t *scroll_area = &supervisor_terminal_scroll_area_text_grid; - displayio_tilegrid_t *title_bar = &supervisor_terminal_title_bar_text_grid; + displayio_tilegrid_t *status_bar = &supervisor_terminal_status_bar_text_grid; bool reset_tiles = false; uint16_t width_in_tiles = width_px / scroll_area->tile_width; - // determine scale based on h - if (width_in_tiles < 80) { + // determine scale based on width + if (width_in_tiles <= 80) { scale = 1; } - width_in_tiles = width_px / (scroll_area->tile_width * scale); - if (width_in_tiles < 1) { - width_in_tiles = 1; - } - uint16_t height_in_tiles = height_px / (scroll_area->tile_height * scale); + width_in_tiles = MAX(1, width_px / (scroll_area->tile_width * scale)); + uint16_t height_in_tiles = MAX(2, height_px / (scroll_area->tile_height * scale)); uint16_t total_tiles = width_in_tiles * height_in_tiles; @@ -103,39 +104,42 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { uint8_t *tiles = (uint8_t *)tilegrid_tiles->ptr; #if CIRCUITPY_REPL_LOGO - title_bar->x = blinka_bitmap.width; - // Align the title bar to the bottom of the logo. - title_bar->y = blinka_bitmap.height - title_bar->tile_height; + status_bar->x = supervisor_blinka_sprite.pixel_width + 1; + // Align the status bar to the bottom of the logo. + status_bar->y = supervisor_blinka_sprite.pixel_height - status_bar->tile_height; #else - title_bar->x = 0; - title_bar->y = 0; + status_bar->x = 0; + status_bar->y = 0; #endif - title_bar->top_left_y = 0; - title_bar->width_in_tiles = width_in_tiles; - title_bar->height_in_tiles = 1; - assert(width_in_tiles > 0); - title_bar->pixel_width = width_in_tiles * title_bar->tile_width; - title_bar->pixel_height = title_bar->tile_height; - title_bar->tiles = tiles; - title_bar->full_change = true; + status_bar->top_left_y = 0; + status_bar->width_in_tiles = width_in_tiles; + status_bar->height_in_tiles = 1; + status_bar->pixel_width = width_in_tiles * status_bar->tile_width; + status_bar->pixel_height = status_bar->tile_height; + status_bar->tiles = tiles; + status_bar->full_change = true; scroll_area->x = 0; - #if CIRCUITPY_REPL_LOGO - scroll_area->y = blinka_bitmap.height; - #else - scroll_area->y = scroll_area->tile_height; - #endif scroll_area->top_left_y = 0; scroll_area->width_in_tiles = width_in_tiles; scroll_area->height_in_tiles = height_in_tiles - 1; - assert(width_in_tiles > 0); - assert(height_in_tiles > 1); scroll_area->pixel_width = width_in_tiles * scroll_area->tile_width; scroll_area->pixel_height = (height_in_tiles - 1) * scroll_area->tile_height; + #if CIRCUITPY_REPL_LOGO + scroll_area->y = blinka_bitmap.height; + #else + scroll_area->y = status_bar->tile_height; + #endif + int16_t extra_height = (scroll_area->pixel_height + scroll_area->y) - (height_px / scale); + // Subtract extra height so that the bottom line fully shows. The top line will be under the + // title bar and Blinka logo. + scroll_area->y -= extra_height; scroll_area->tiles = tiles + width_in_tiles; scroll_area->full_change = true; - common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, title_bar); + common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, status_bar); + + // Do not update status bar until after boot.py has run, in case it is disabled. } #endif @@ -148,23 +152,31 @@ void supervisor_stop_terminal(void) { free_memory(tilegrid_tiles); tilegrid_tiles = NULL; supervisor_terminal_scroll_area_text_grid.tiles = NULL; - supervisor_terminal_title_bar_text_grid.tiles = NULL; + supervisor_terminal_status_bar_text_grid.tiles = NULL; supervisor_terminal.scroll_area = NULL; - supervisor_terminal.title_bar = NULL; + supervisor_terminal.status_bar = NULL; } #endif } +bool supervisor_terminal_started(void) { + #if CIRCUITPY_TERMINALIO + return tilegrid_tiles != NULL; + #else + return false; + #endif +} + void supervisor_display_move_memory(void) { #if CIRCUITPY_TERMINALIO displayio_tilegrid_t *scroll_area = &supervisor_terminal_scroll_area_text_grid; - displayio_tilegrid_t *title_bar = &supervisor_terminal_title_bar_text_grid; + displayio_tilegrid_t *status_bar = &supervisor_terminal_status_bar_text_grid; if (tilegrid_tiles != NULL) { - title_bar->tiles = (uint8_t *)tilegrid_tiles->ptr; + status_bar->tiles = (uint8_t *)tilegrid_tiles->ptr; scroll_area->tiles = (uint8_t *)tilegrid_tiles->ptr + scroll_area->width_in_tiles; } else { scroll_area->tiles = NULL; - title_bar->tiles = NULL; + status_bar->tiles = NULL; } #endif @@ -186,126 +198,9 @@ void supervisor_display_move_memory(void) { #endif } -#if CIRCUITPY_REPL_LOGO -uint32_t blinka_bitmap_data[32] = { - 0x00000011, 0x11000000, - 0x00000111, 0x53100000, - 0x00000111, 0x56110000, - 0x00000111, 0x11140000, - 0x00000111, 0x20002000, - 0x00000011, 0x13000000, - 0x00000001, 0x11200000, - 0x00000000, 0x11330000, - 0x00000000, 0x01122000, - 0x00001111, 0x44133000, - 0x00032323, 0x24112200, - 0x00111114, 0x44113300, - 0x00323232, 0x34112200, - 0x11111144, 0x44443300, - 0x11111111, 0x11144401, - 0x23232323, 0x21111110 -}; - -displayio_bitmap_t blinka_bitmap = { - .base = {.type = &displayio_bitmap_type }, - .width = 16, - .height = 16, - .data = blinka_bitmap_data, - .stride = 2, - .bits_per_value = 4, - .x_shift = 3, - .x_mask = 0x7, - .bitmask = 0xf, - .read_only = true -}; - -_displayio_color_t blinka_colors[7] = { - { - .rgb888 = 0x000000, - .rgb565 = 0x0000, - .luma = 0x00, - .chroma = 0, - .transparent = true - }, - { - .rgb888 = 0x8428bc, - .rgb565 = 0x8978, - .luma = 0xff, // We cheat the luma here. It is actually 0x60 - .hue = 184, - .chroma = 148 - }, - { - .rgb888 = 0xff89bc, - .rgb565 = 0xFCB8, - .luma = 0xb5, - .hue = 222, - .chroma = 118 - }, - { - .rgb888 = 0x7beffe, - .rgb565 = 0x869F, - .luma = 0xe0, - .hue = 124, - .chroma = 131 - }, - { - .rgb888 = 0x51395f, - .rgb565 = 0x5A0D, - .luma = 0x47, - .hue = 185, - .chroma = 38 - }, - { - .rgb888 = 0xffffff, - .rgb565 = 0xffff, - .luma = 0xff, - .chroma = 0 - }, - { - .rgb888 = 0x0736a0, - .rgb565 = 0x01f5, - .luma = 0x44, - .hue = 147, - .chroma = 153 - }, -}; - -displayio_palette_t blinka_palette = { - .base = {.type = &displayio_palette_type }, - .colors = blinka_colors, - .color_count = 7, - .needs_refresh = false -}; - -displayio_tilegrid_t blinka_sprite = { - .base = {.type = &displayio_tilegrid_type }, - .bitmap = &blinka_bitmap, - .pixel_shader = &blinka_palette, - .x = 0, - .y = 0, - .pixel_width = 16, - .pixel_height = 16, - .bitmap_width_in_tiles = 1, - .width_in_tiles = 1, - .height_in_tiles = 1, - .tile_width = 16, - .tile_height = 16, - .top_left_x = 16, - .top_left_y = 16, - .tiles = 0, - .partial_change = false, - .full_change = false, - .hidden = false, - .hidden_by_parent = false, - .moved = false, - .inline_tiles = true, - .in_group = true -}; -#endif - #if CIRCUITPY_TERMINALIO #if CIRCUITPY_REPL_LOGO -mp_obj_t members[] = { &blinka_sprite, &supervisor_terminal_title_bar_text_grid, &supervisor_terminal_scroll_area_text_grid, }; +mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_blinka_sprite, &supervisor_terminal_status_bar_text_grid, }; mp_obj_list_t splash_children = { .base = {.type = &mp_type_list }, .alloc = 3, @@ -313,7 +208,7 @@ mp_obj_list_t splash_children = { .items = members, }; #else -mp_obj_t members[] = { &supervisor_terminal_title_bar_text_grid, &supervisor_terminal_scroll_area_text_grid, }; +mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_terminal_status_bar_text_grid,}; mp_obj_list_t splash_children = { .base = {.type = &mp_type_list }, .alloc = 2, @@ -323,7 +218,7 @@ mp_obj_list_t splash_children = { #endif #else #if CIRCUITPY_REPL_LOGO -mp_obj_t members[] = { &blinka_sprite }; +mp_obj_t members[] = { &supervisor_blinka_sprite }; mp_obj_list_t splash_children = { .base = {.type = &mp_type_list }, .alloc = 1, diff --git a/supervisor/shared/display.h b/supervisor/shared/display.h index d965fdc764..0eb9bc507f 100644 --- a/supervisor/shared/display.h +++ b/supervisor/shared/display.h @@ -29,10 +29,11 @@ #include +#include "shared-bindings/displayio/TileGrid.h" + #if CIRCUITPY_TERMINALIO #include "shared-bindings/displayio/Bitmap.h" -#include "shared-bindings/displayio/TileGrid.h" #include "shared-bindings/fontio/BuiltinFont.h" #include "shared-bindings/terminalio/Terminal.h" @@ -44,13 +45,16 @@ extern const fontio_builtinfont_t supervisor_terminal_font; // These will change so they must live in RAM. extern displayio_bitmap_t supervisor_terminal_font_bitmap; extern displayio_tilegrid_t supervisor_terminal_scroll_area_text_grid; -extern displayio_tilegrid_t supervisor_terminal_title_bar_text_grid; +extern displayio_tilegrid_t supervisor_terminal_status_bar_text_grid; extern terminalio_terminal_obj_t supervisor_terminal; - #endif +// Always shown. +extern displayio_tilegrid_t supervisor_blinka_sprite; + void supervisor_start_terminal(uint16_t width_px, uint16_t height_px); void supervisor_stop_terminal(void); +bool supervisor_terminal_started(void); void supervisor_display_move_memory(void); diff --git a/supervisor/shared/external_flash/external_flash.c b/supervisor/shared/external_flash/external_flash.c index 7da45fdc99..141ad7e5f8 100644 --- a/supervisor/shared/external_flash/external_flash.c +++ b/supervisor/shared/external_flash/external_flash.c @@ -58,6 +58,9 @@ static supervisor_allocation *supervisor_cache = NULL; // Wait until both the write enable and write in progress bits have cleared. static bool wait_for_flash_ready(void) { + if (flash_device == NULL) { + return false; + } bool ok = true; // Both the write enable and write in progress bits should be low. if (flash_device->no_ready_bit) { @@ -192,6 +195,9 @@ static bool copy_block(uint32_t src_address, uint32_t dest_address) { return true; } +#define READ_JEDEC_ID_RETRY_COUNT (100) + +// If this fails, flash_device will remain NULL. void supervisor_flash_init(void) { if (flash_device != NULL) { return; @@ -220,7 +226,11 @@ void supervisor_flash_init(void) { #else // The response will be 0xff if the flash needs more time to start up. uint8_t jedec_id_response[3] = {0xff, 0xff, 0xff}; - while (jedec_id_response[0] == 0xff) { + // Response can also be 0x00 if reading before ready. When compiled with `-O2`, typically + // takes three tries to read on Grand Central M4. + + size_t count = READ_JEDEC_ID_RETRY_COUNT; + while ((count-- > 0) && (jedec_id_response[0] == 0xff || jedec_id_response[2] == 0x00)) { spi_flash_read_command(CMD_READ_JEDEC_ID, jedec_id_response, 3); } for (uint8_t i = 0; i < EXTERNAL_FLASH_DEVICE_COUNT; i++) { @@ -234,6 +244,7 @@ void supervisor_flash_init(void) { } #endif if (flash_device == NULL) { + // Flash did not respond. Give up. return; } @@ -293,6 +304,9 @@ uint32_t supervisor_flash_get_block_size(void) { // The total number of available blocks. uint32_t supervisor_flash_get_block_count(void) { + if (flash_device == NULL) { + return 0; + } // We subtract one erase sector size because we may use it as a staging area // for writes. return (flash_device->total_size - SPI_FLASH_ERASE_SIZE) / FILESYSTEM_BLOCK_SIZE; diff --git a/supervisor/shared/external_flash/spi_flash.c b/supervisor/shared/external_flash/spi_flash.c index b47508e051..abff343713 100644 --- a/supervisor/shared/external_flash/spi_flash.c +++ b/supervisor/shared/external_flash/spi_flash.c @@ -151,6 +151,7 @@ void spi_flash_init(void) { supervisor_flash_spi_bus.base.type = &busio_spi_type; common_hal_busio_spi_construct(&supervisor_flash_spi_bus, SPI_FLASH_SCK_PIN, SPI_FLASH_MOSI_PIN, SPI_FLASH_MISO_PIN, false); common_hal_busio_spi_never_reset(&supervisor_flash_spi_bus); + common_hal_busio_spi_configure(&supervisor_flash_spi_bus, SPI_FLASH_MAX_BAUDRATE, 0, 0, 8); return; } diff --git a/ports/nrf/fatfs_port.c b/supervisor/shared/fatfs.c similarity index 74% rename from ports/nrf/fatfs_port.c rename to supervisor/shared/fatfs.c index 38c2d923b8..f1452bf567 100644 --- a/ports/nrf/fatfs_port.c +++ b/supervisor/shared/fatfs.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,12 +24,15 @@ * THE SOFTWARE. */ +#include "supervisor/fatfs.h" + #include "py/runtime.h" #include "lib/oofatfs/ff.h" -#include "shared/timeutils/timeutils.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "shared-bindings/os/__init__.h" #include "shared-bindings/rtc/RTC.h" #include "shared-bindings/time/__init__.h" -#include "supervisor/fatfs_port.h" +#include "shared/timeutils/timeutils.h" DWORD _time_override = 0; DWORD get_fattime(void) { @@ -49,3 +52,17 @@ DWORD get_fattime(void) { void override_fattime(DWORD time) { _time_override = time; } + +DWORD make_volid(void) { + DWORD result; + if (!common_hal_os_urandom((uint8_t *)&result, sizeof(result))) { + #if CIRCUITPY_MICROCONTROLLER && COMMON_HAL_MCU_PROCESSOR_UID_LENGTH >= 4 + uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; + common_hal_mcu_processor_get_uid(raw_id); + memcpy(&result, raw_id, sizeof(result)); + #else + result = (DWORD)common_hal_time_monotonic_ns(); + #endif + } + return result; +} diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index 820dbe9783..1eab59c384 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -92,6 +92,9 @@ bool filesystem_init(bool create_allowed, bool force_create) { vfs_fat->blockdev.flags = 0; supervisor_flash_init_vfs(vfs_fat); + mp_vfs_mount_t *vfs = &_mp_vfs; + vfs->len = 0; + // try to mount the flash FRESULT res = f_mount(&vfs_fat->fatfs); if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) { @@ -126,6 +129,9 @@ bool filesystem_init(bool create_allowed, bool force_create) { make_empty_file(&vfs_fat->fatfs, "/.metadata_never_index"); make_empty_file(&vfs_fat->fatfs, "/.Trashes"); make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log"); + #if CIRCUITPY_OS_GETENV + make_empty_file(&vfs_fat->fatfs, "/settings.toml"); + #endif // make a sample code.py file make_sample_code_file(&vfs_fat->fatfs); @@ -140,17 +146,22 @@ bool filesystem_init(bool create_allowed, bool force_create) { } else if (res != FR_OK) { return false; } - mp_vfs_mount_t *vfs = &_mp_vfs; + vfs->str = "/"; vfs->len = 1; vfs->obj = MP_OBJ_FROM_PTR(vfs_fat); vfs->next = NULL; + MP_STATE_VM(vfs_mount_table) = vfs; // The current directory is used as the boot up directory. // It is set to the internal flash filesystem by default. MP_STATE_PORT(vfs_cur) = vfs; + #if CIRCUITPY_STORAGE_EXTEND + supervisor_flash_update_extended(); + #endif + return true; } @@ -199,5 +210,12 @@ void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concu } bool filesystem_present(void) { - return true; + return _mp_vfs.len > 0; +} + +FATFS *filesystem_circuitpy(void) { + if (!filesystem_present()) { + return NULL; + } + return &_internal_vfs.fatfs; } diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c index ff0382fc17..a5f3296a28 100644 --- a/supervisor/shared/memory.c +++ b/supervisor/shared/memory.c @@ -56,6 +56,11 @@ enum { #if CIRCUITPY_USB_VENDOR + 1 // usb_vendor_add_descriptor #endif + + + CIRCUITPY_PORT_NUM_SUPERVISOR_ALLOCATIONS + #if CIRCUITPY_AUDIOBUSIO_PDMIN + + 1 + #endif , CIRCUITPY_SUPERVISOR_MOVABLE_ALLOC_COUNT = diff --git a/supervisor/shared/micropython.c b/supervisor/shared/micropython.c index ebc0aef2d1..5ee0061544 100644 --- a/supervisor/shared/micropython.c +++ b/supervisor/shared/micropython.c @@ -62,8 +62,15 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) { #ifdef CIRCUITPY_BOOT_OUTPUT_FILE if (boot_output != NULL) { // Ensure boot_out.txt is capped at 1 filesystem block and ends with a newline - if (len + boot_output->len > 508) { - vstr_add_str(boot_output, "...\n"); + #define TRUNCATED translate("[truncated due to length]") + size_t truncated_message_len = decompress_length(TRUNCATED); + size_t maxlen = 512 - truncated_message_len; // includes trailing '\0' so we do not need to account for trailing newline '\n' in vstr_add_byte + if (len + boot_output->len > maxlen) { + size_t remaining_len = maxlen - boot_output->len; + vstr_add_strn(boot_output, str, remaining_len); + char buf[truncated_message_len]; + vstr_add_str(boot_output, decompress(TRUNCATED, buf)); + vstr_add_byte(boot_output, '\n'); boot_output = NULL; } else { vstr_add_strn(boot_output, str, len); diff --git a/supervisor/shared/port.c b/supervisor/shared/port.c new file mode 100644 index 0000000000..4070cf254e --- /dev/null +++ b/supervisor/shared/port.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/port.h" + +MP_WEAK void port_wake_main_task(void) { +} + +MP_WEAK void port_wake_main_task_from_isr(void) { +} + +MP_WEAK void port_yield(void) { +} + +MP_WEAK void port_boot_info(void) { +} diff --git a/supervisor/shared/reload.c b/supervisor/shared/reload.c index e1ae2e6764..4e351704f8 100644 --- a/supervisor/shared/reload.c +++ b/supervisor/shared/reload.c @@ -28,6 +28,7 @@ #include "py/mphal.h" #include "py/mpstate.h" +#include "supervisor/port.h" #include "supervisor/shared/reload.h" #include "supervisor/shared/tick.h" @@ -52,6 +53,7 @@ void reload_initiate(supervisor_run_reason_t run_reason) { MP_STATE_VM(sched_state) = MP_SCHED_PENDING; } #endif + port_wake_main_task(); } void autoreload_reset() { diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index aefae1e48b..5112b17ebf 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -43,20 +43,28 @@ #define SAFE_MODE_DATA_GUARD 0xad0000af #define SAFE_MODE_DATA_GUARD_MASK 0xff0000ff -static safe_mode_t current_safe_mode; +static safe_mode_t _safe_mode; + +safe_mode_t get_safe_mode(void) { + return _safe_mode; +} + +void set_safe_mode(safe_mode_t safe_mode) { + _safe_mode = safe_mode; +} safe_mode_t wait_for_safe_mode_reset(void) { uint32_t reset_state = port_get_saved_word(); - safe_mode_t safe_mode = NO_SAFE_MODE; + safe_mode_t safe_mode = SAFE_MODE_NONE; if ((reset_state & SAFE_MODE_DATA_GUARD_MASK) == SAFE_MODE_DATA_GUARD) { safe_mode = (reset_state & ~SAFE_MODE_DATA_GUARD_MASK) >> 8; } - if (safe_mode != NO_SAFE_MODE) { + if (safe_mode != SAFE_MODE_NONE) { port_set_saved_word(SAFE_MODE_DATA_GUARD); - current_safe_mode = safe_mode; + _safe_mode = safe_mode; return safe_mode; } else { - current_safe_mode = 0; + _safe_mode = SAFE_MODE_NONE; } const mcu_reset_reason_t reset_reason = common_hal_mcu_processor_get_reset_reason(); @@ -64,12 +72,12 @@ safe_mode_t wait_for_safe_mode_reset(void) { reset_reason != RESET_REASON_RESET_PIN && reset_reason != RESET_REASON_UNKNOWN && reset_reason != RESET_REASON_SOFTWARE) { - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } - #ifdef CIRCUITPY_SKIP_SAFE_MODE_WAIT - return NO_SAFE_MODE; + #if CIRCUITPY_SKIP_SAFE_MODE_WAIT + return SAFE_MODE_NONE; #endif - port_set_saved_word(SAFE_MODE_DATA_GUARD | (MANUAL_SAFE_MODE << 8)); + port_set_saved_word(SAFE_MODE_DATA_GUARD | (SAFE_MODE_USER << 8)); // Wait for a while to allow for reset. #if CIRCUITPY_STATUS_LED @@ -106,11 +114,11 @@ safe_mode_t wait_for_safe_mode_reset(void) { status_led_deinit(); #endif if (boot_in_safe_mode) { - return USER_SAFE_MODE; + return SAFE_MODE_USER; } // Restore the original state of the saved word if no reset occured during our wait period. port_set_saved_word(reset_state); - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } void safe_mode_on_next_reset(safe_mode_t reason) { @@ -119,7 +127,7 @@ void safe_mode_on_next_reset(safe_mode_t reason) { // Don't inline this so it's easy to break on it from GDB. void __attribute__((noinline,)) reset_into_safe_mode(safe_mode_t reason) { - if (current_safe_mode > BROWNOUT && reason > BROWNOUT) { + if (_safe_mode > SAFE_MODE_BROWNOUT && reason > SAFE_MODE_BROWNOUT) { while (true) { // This very bad because it means running in safe mode didn't save us. Only ignore brownout // because it may be due to a switch bouncing. @@ -133,106 +141,95 @@ void __attribute__((noinline,)) reset_into_safe_mode(safe_mode_t reason) { void print_safe_mode_message(safe_mode_t reason) { - if (reason == NO_SAFE_MODE) { + if (reason == SAFE_MODE_NONE) { return; } - serial_write("\r\n"); - serial_write_compressed(translate("You are in safe mode because:\n")); + serial_write_compressed(translate("\nYou are in safe mode because:\n")); const compressed_string_t *message = NULL; // First check for safe mode reasons that do not necessarily reflect bugs. switch (reason) { - case USER_SAFE_MODE: - #ifdef BOARD_USER_SAFE_MODE_ACTION + case SAFE_MODE_BROWNOUT: + message = translate("The power dipped. Make sure you are providing enough power."); + break; + case SAFE_MODE_USER: + #if defined(BOARD_USER_SAFE_MODE_ACTION) message = BOARD_USER_SAFE_MODE_ACTION; #elif defined(CIRCUITPY_BOOT_BUTTON) - message = translate("pressing boot button at start up.\n"); + message = translate("You pressed the BOOT button at start up"); + #else + message = translate("You pressed the reset button during boot."); #endif - if (message != NULL) { - // Output a user safe mode string if it's set. - serial_write_compressed(translate("You requested starting safe mode by ")); - serial_write_compressed(message); - serial_write_compressed(translate("To exit, please reset the board without ")); - // The final piece is printed below. - } break; - case MANUAL_SAFE_MODE: - message = translate("You pressed the reset button during boot. Press again to exit safe mode."); + case SAFE_MODE_NO_CIRCUITPY: + message = translate("CIRCUITPY drive could not be found or created."); break; - case PROGRAMMATIC_SAFE_MODE: - message = translate("The `microcontroller` module was used to boot into safe mode. Press reset to exit safe mode."); + case SAFE_MODE_PROGRAMMATIC: + message = translate("The `microcontroller` module was used to boot into safe mode."); break; - case BROWNOUT: - message = translate("The microcontroller's power dipped. Make sure your power supply provides\nenough power for the whole circuit and press reset (after ejecting CIRCUITPY)."); + #if CIRCUITPY_SAFEMODE_PY + case SAFE_MODE_SAFEMODE_PY_ERROR: + message = translate("Error in safemode.py."); break; - case USB_TOO_MANY_ENDPOINTS: + #endif + case SAFE_MODE_STACK_OVERFLOW: + message = translate("Heap was corrupted because the stack was too small. Increase stack size."); + break; + case SAFE_MODE_USB_TOO_MANY_ENDPOINTS: message = translate("USB devices need more endpoints than are available."); break; - case USB_TOO_MANY_INTERFACE_NAMES: + case SAFE_MODE_USB_TOO_MANY_INTERFACE_NAMES: message = translate("USB devices specify too many interface names."); break; - case USB_BOOT_DEVICE_NOT_INTERFACE_ZERO: - message = translate("Boot device must be first device (interface #0)."); + case SAFE_MODE_USB_BOOT_DEVICE_NOT_INTERFACE_ZERO: + message = translate("Boot device must be first (interface #0)."); break; - case WATCHDOG_RESET: + case SAFE_MODE_WATCHDOG: message = translate("Internal watchdog timer expired."); break; - case NO_CIRCUITPY: - message = translate("CIRCUITPY drive could not be found or created."); - break; default: break; } if (message) { + // Non-crash safe mode. serial_write_compressed(message); - serial_write("\r\n"); - return; + } else { + // Something worse happened. + serial_write_compressed(translate("CircuitPython core code crashed hard. Whoops!\n")); + switch (reason) { + case SAFE_MODE_GC_ALLOC_OUTSIDE_VM: + message = translate("Heap allocation when VM not running."); + break; + case SAFE_MODE_FLASH_WRITE_FAIL: + message = translate("Failed to write internal flash."); + break; + case SAFE_MODE_HARD_FAULT: + message = translate("Fault detected by hardware."); + break; + case SAFE_MODE_INTERRUPT_ERROR: + message = translate("Interrupt error."); + break; + case SAFE_MODE_NLR_JUMP_FAIL: + message = translate("NLR jump failed. Likely memory corruption."); + break; + case SAFE_MODE_NO_HEAP: + message = translate("Unable to allocate the heap."); + break; + case SAFE_MODE_SDK_FATAL_ERROR: + message = translate("Third-party firmware fatal error."); + break; + default: + message = translate("Unknown reason."); + break; + } + serial_write_compressed(message); + serial_write_compressed(translate("\nPlease file an issue with your program at https://github.com/adafruit/circuitpython/issues.")); } - // Something worse happened. - - serial_write_compressed(translate("CircuitPython core code crashed hard. Whoops!\n")); - - switch (reason) { - case HARD_CRASH: - message = translate("Crash into the HardFault_Handler."); - break; - case MICROPY_NLR_JUMP_FAIL: - message = translate("NLR jump failed. Likely memory corruption."); - break; - case MICROPY_FATAL_ERROR: - message = translate("Fatal error."); - break; - case NO_HEAP: - message = translate("CircuitPython was unable to allocate the heap."); - break; - case HEAP_OVERWRITTEN: - message = translate("The CircuitPython heap was corrupted because the stack was too small.\nIncrease the stack size if you know how. If not:"); - break; - case GC_ALLOC_OUTSIDE_VM: - message = translate("Attempted heap allocation when VM not running."); - break; - #ifdef SOFTDEVICE_PRESENT - // defined in ports/nrf/bluetooth/bluetooth_common.mk - // will print "Unknown reason" if somehow encountered on other ports - case NORDIC_SOFT_DEVICE_ASSERT: - message = translate("Nordic system firmware failure assertion."); - break; - #endif - case FLASH_WRITE_FAIL: - message = translate("Failed to write internal flash."); - break; - case MEM_MANAGE: - message = translate("Invalid memory access."); - break; - default: - message = translate("Unknown reason."); - break; - } - serial_write_compressed(message); - serial_write_compressed(translate("\nPlease file an issue with the contents of your CIRCUITPY drive at \nhttps://github.com/adafruit/circuitpython/issues\n")); + // Always tell user how to get out of safe mode. + serial_write_compressed(translate("\nPress reset to exit safe mode.\n")); } diff --git a/supervisor/shared/safe_mode.h b/supervisor/shared/safe_mode.h index 0c8d018bfe..005488552e 100644 --- a/supervisor/shared/safe_mode.h +++ b/supervisor/shared/safe_mode.h @@ -30,27 +30,32 @@ #include "py/mpconfig.h" typedef enum { - NO_SAFE_MODE = 0, - BROWNOUT, - HARD_CRASH, - USER_SAFE_MODE, - HEAP_OVERWRITTEN, - MANUAL_SAFE_MODE, - MICROPY_NLR_JUMP_FAIL, - MICROPY_FATAL_ERROR, - GC_ALLOC_OUTSIDE_VM, - PROGRAMMATIC_SAFE_MODE, - NORDIC_SOFT_DEVICE_ASSERT, - FLASH_WRITE_FAIL, - MEM_MANAGE, - WATCHDOG_RESET, - USB_TOO_MANY_ENDPOINTS, - USB_TOO_MANY_INTERFACE_NAMES, - USB_BOOT_DEVICE_NOT_INTERFACE_ZERO, - NO_HEAP, - NO_CIRCUITPY, + SAFE_MODE_NONE = 0, + // BROWNOUT should be lowest after SAFE_MODE_NONE. + SAFE_MODE_BROWNOUT, + // alphabetical from here down + SAFE_MODE_FLASH_WRITE_FAIL, + SAFE_MODE_GC_ALLOC_OUTSIDE_VM, + SAFE_MODE_HARD_FAULT, + SAFE_MODE_INTERRUPT_ERROR, + SAFE_MODE_MANUAL, + SAFE_MODE_NLR_JUMP_FAIL, + SAFE_MODE_NO_CIRCUITPY, + SAFE_MODE_NO_HEAP, + SAFE_MODE_PROGRAMMATIC, + SAFE_MODE_SAFEMODE_PY_ERROR, + SAFE_MODE_SDK_FATAL_ERROR, + SAFE_MODE_STACK_OVERFLOW, + SAFE_MODE_USB_BOOT_DEVICE_NOT_INTERFACE_ZERO, + SAFE_MODE_USB_TOO_MANY_ENDPOINTS, + SAFE_MODE_USB_TOO_MANY_INTERFACE_NAMES, + SAFE_MODE_USER, + SAFE_MODE_WATCHDOG, } safe_mode_t; +safe_mode_t get_safe_mode(void); +void set_safe_mode(safe_mode_t safe_mode); + safe_mode_t wait_for_safe_mode_reset(void); void safe_mode_on_next_reset(safe_mode_t reason); diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index 710046e62e..e683e8eb7c 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -28,6 +28,7 @@ #include #include "py/mpconfig.h" +#include "py/mphal.h" #include "supervisor/shared/cpu.h" #include "supervisor/shared/display.h" @@ -62,10 +63,23 @@ byte console_uart_rx_buf[64]; #endif #endif +#if CIRCUITPY_USB || CIRCUITPY_CONSOLE_UART +// Flag to note whether this is the first write after connection. +// Delay slightly on the first write to allow time for the host to set up things, +// including turning off echo mode. +static bool _first_write_done = false; +#endif + #if CIRCUITPY_USB_VENDOR bool tud_vendor_connected(void); #endif +// Set to true to temporarily discard writes to the console only. +static bool _serial_console_write_disabled; + +// Set to true to temporarily discard writes to the display terminal only. +static bool _serial_display_write_disabled; + #if CIRCUITPY_CONSOLE_UART STATIC void console_uart_print_strn(void *env, const char *str, size_t len) { (void)env; @@ -138,6 +152,10 @@ void serial_early_init(void) { } void serial_init(void) { + #if CIRCUITPY_USB || CIRCUITPY_CONSOLE_UART + _first_write_done = false; + #endif + port_serial_init(); } @@ -174,6 +192,12 @@ bool serial_connected(void) { } #endif + #if CIRCUITPY_TERMINALIO + if (supervisor_terminal_started()) { + return true; + } + #endif + if (port_serial_connected()) { return true; @@ -207,10 +231,17 @@ char serial_read(void) { #if CIRCUITPY_WEB_WORKFLOW if (websocket_available()) { - return websocket_read_char(); + char c = websocket_read_char(); + if (c != -1) { + return c; + } } #endif + if (port_serial_bytes_available() > 0) { + return port_serial_read(); + } + #if CIRCUITPY_USB_CDC if (!usb_cdc_console_enabled()) { return -1; @@ -220,9 +251,6 @@ char serial_read(void) { return (char)tud_cdc_read_char(); #endif - if (port_serial_bytes_available() > 0) { - return port_serial_read(); - } return -1; } @@ -272,11 +300,18 @@ void serial_write_substring(const char *text, uint32_t length) { if (length == 0) { return; } + #if CIRCUITPY_TERMINALIO int errcode; - common_hal_terminalio_terminal_write(&supervisor_terminal, (const uint8_t *)text, length, &errcode); + if (!_serial_display_write_disabled) { + common_hal_terminalio_terminal_write(&supervisor_terminal, (const uint8_t *)text, length, &errcode); + } #endif + if (_serial_console_write_disabled) { + return; + } + #if CIRCUITPY_USB_VENDOR if (tud_vendor_connected()) { tud_vendor_write(text, length); @@ -284,8 +319,11 @@ void serial_write_substring(const char *text, uint32_t length) { #endif #if CIRCUITPY_CONSOLE_UART + if (!_first_write_done) { + mp_hal_delay_ms(50); + _first_write_done = true; + } int uart_errcode; - common_hal_busio_uart_write(&console_uart, (const uint8_t *)text, length, &uart_errcode); #endif @@ -304,14 +342,21 @@ void serial_write_substring(const char *text, uint32_t length) { #endif #if CIRCUITPY_USB + // Delay the very first write + if (tud_cdc_connected() && !_first_write_done) { + mp_hal_delay_ms(50); + _first_write_done = true; + } uint32_t count = 0; - while (count < length && tud_cdc_connected()) { - count += tud_cdc_write(text + count, length - count); - // If we're in an interrupt, then don't wait for more room. Queue up what we can. - if (cpu_interrupt_active()) { - break; + if (tud_cdc_connected()) { + while (count < length) { + count += tud_cdc_write(text + count, length - count); + // If we're in an interrupt, then don't wait for more room. Queue up what we can. + if (cpu_interrupt_active()) { + break; + } + usb_background(); } - usb_background(); } #endif @@ -321,3 +366,15 @@ void serial_write_substring(const char *text, uint32_t length) { void serial_write(const char *text) { serial_write_substring(text, strlen(text)); } + +bool serial_console_write_disable(bool disabled) { + bool now = _serial_console_write_disabled; + _serial_console_write_disabled = disabled; + return now; +} + +bool serial_display_write_disable(bool disabled) { + bool now = _serial_display_write_disabled; + _serial_display_write_disabled = disabled; + return now; +} diff --git a/supervisor/shared/stack.c b/supervisor/shared/stack.c index d2188e016d..be97cee234 100644 --- a/supervisor/shared/stack.c +++ b/supervisor/shared/stack.c @@ -74,7 +74,7 @@ inline bool stack_ok(void) { inline void assert_heap_ok(void) { if (!stack_ok()) { - reset_into_safe_mode(HEAP_OVERWRITTEN); + reset_into_safe_mode(SAFE_MODE_STACK_OVERFLOW); } } @@ -107,6 +107,10 @@ void set_next_stack_size(uint32_t size) { next_stack_size = size; } +uint32_t get_next_stack_size(void) { + return next_stack_size; +} + uint32_t get_current_stack_size(void) { return current_stack_size; } diff --git a/supervisor/shared/stack.h b/supervisor/shared/stack.h index 98cc5a1685..4acda57354 100644 --- a/supervisor/shared/stack.h +++ b/supervisor/shared/stack.h @@ -38,6 +38,7 @@ uint32_t *stack_get_bottom(void); size_t stack_get_length(void); // Next/current requested stack size. void set_next_stack_size(uint32_t size); +uint32_t get_next_stack_size(void); uint32_t get_current_stack_size(void); bool stack_ok(void); diff --git a/supervisor/shared/status_bar.c b/supervisor/shared/status_bar.c new file mode 100644 index 0000000000..4f5fa06464 --- /dev/null +++ b/supervisor/shared/status_bar.c @@ -0,0 +1,168 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "genhdr/mpversion.h" +#include "py/mpconfig.h" +#include "shared-bindings/supervisor/__init__.h" +#include "shared-bindings/supervisor/StatusBar.h" +#include "supervisor/background_callback.h" +#include "supervisor/serial.h" +#include "supervisor/shared/status_bar.h" + +#if CIRCUITPY_TERMINALIO +#include "shared-module/terminalio/Terminal.h" +#endif + +#if CIRCUITPY_WEB_WORKFLOW +#include "supervisor/shared/web_workflow/web_workflow.h" +#endif + +#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE +#include "supervisor/shared/bluetooth/bluetooth.h" +#endif + +static background_callback_t status_bar_background_cb; + +static bool _forced_dirty = false; +static bool _suspended = false; + +// Clear if possible, but give up if we can't do it now. +void supervisor_status_bar_clear(void) { + if (!_suspended) { + serial_write("\x1b" "]0;" "\x1b" "\\"); + } +} + +void supervisor_status_bar_update(void) { + if (_suspended) { + supervisor_status_bar_request_update(true); + return; + } + _forced_dirty = false; + + shared_module_supervisor_status_bar_updated(&shared_module_supervisor_status_bar_obj); + + // Disable status bar console writes if supervisor.status_bar.console is False. + // Also disable if there is no serial connection now. This avoids sending part + // of the status bar update if the serial connection comes up during the update. + bool disable_console_writes = + !shared_module_supervisor_status_bar_get_console(&shared_module_supervisor_status_bar_obj) || + !serial_connected(); + + // Disable status bar display writes if supervisor.status_bar.display is False. + bool disable_display_writes = + !shared_module_supervisor_status_bar_get_display(&shared_module_supervisor_status_bar_obj); + + // Suppress writes to console and/or display if status bar is not enabled for either or both. + bool prev_console_disable; + bool prev_display_disable; + + if (disable_console_writes) { + prev_console_disable = serial_console_write_disable(true); + } + if (disable_display_writes) { + prev_display_disable = serial_display_write_disable(true); + } + + // Neighboring "..." "..." are concatenated by the compiler. Without this separation, the hex code + // doesn't get terminated after two following characters and the value is invalid. + // This is the OSC command to set the title and the icon text. It can be up to 255 characters + // but some may be cut off. + serial_write("\x1b" "]0;"); + serial_write("🐍"); + + #if CIRCUITPY_WEB_WORKFLOW + supervisor_web_workflow_status(); + serial_write(" | "); + #endif + + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + supervisor_bluetooth_status(); + serial_write(" | "); + #endif + + supervisor_execution_status(); + serial_write(" | "); + serial_write(MICROPY_GIT_TAG); + // Send string terminator + serial_write("\x1b" "\\"); + + // Restore writes to console and/or display. + if (disable_console_writes) { + serial_console_write_disable(prev_console_disable); + } + if (disable_display_writes) { + serial_display_write_disable(prev_display_disable); + } + +} + +static void status_bar_background(void *data) { + if (_suspended) { + return; + } + bool dirty = _forced_dirty; + + #if CIRCUITPY_WEB_WORKFLOW + dirty = dirty || supervisor_web_workflow_status_dirty(); + #endif + + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + dirty = dirty || supervisor_bluetooth_status_dirty(); + #endif + + if (dirty) { + supervisor_status_bar_update(); + } +} + +void supervisor_status_bar_start(void) { + supervisor_status_bar_request_update(true); +} + +void supervisor_status_bar_request_update(bool force_dirty) { + if (force_dirty) { + _forced_dirty = true; + } + background_callback_add_core(&status_bar_background_cb); +} + +void supervisor_status_bar_suspend(void) { + _suspended = true; +} + +void supervisor_status_bar_resume(void) { + _suspended = false; + supervisor_status_bar_request_update(false); +} + +void supervisor_status_bar_init(void) { + status_bar_background_cb.fun = status_bar_background; + status_bar_background_cb.data = NULL; + + shared_module_supervisor_status_bar_init(&shared_module_supervisor_status_bar_obj); +} diff --git a/supervisor/shared/status_bar.h b/supervisor/shared/status_bar.h new file mode 100644 index 0000000000..062012b545 --- /dev/null +++ b/supervisor/shared/status_bar.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include + +void supervisor_status_bar_init(void); + +void supervisor_status_bar_start(void); +void supervisor_status_bar_suspend(void); +void supervisor_status_bar_resume(void); + +void supervisor_status_bar_clear(void); + +// Update the title bar immediately. Useful from main.c where we know state has changed and the code +// will only be run once. +void supervisor_status_bar_update(void); + +// Use this if requesting from the background, as code is executing or if the status may not have +// changed. +void supervisor_status_bar_request_update(bool force_dirty); + +// Provided by main.c +void supervisor_execution_status(void); diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c index 07ff9634e9..7e6c7983b1 100644 --- a/supervisor/shared/status_leds.c +++ b/supervisor/shared/status_leds.c @@ -179,27 +179,15 @@ void status_led_init() { #elif CIRCUITPY_PWM_RGB_LED if (common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_R)) { - pwmout_result_t red_result = common_hal_pwmio_pwmout_construct(&rgb_status_r, CIRCUITPY_RGB_STATUS_R, 0, 50000, false); - - if (PWMOUT_OK == red_result) { - common_hal_pwmio_pwmout_never_reset(&rgb_status_r); - } + common_hal_pwmio_pwmout_construct(&rgb_status_r, CIRCUITPY_RGB_STATUS_R, 0, 50000, false); } if (common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_G)) { - pwmout_result_t green_result = common_hal_pwmio_pwmout_construct(&rgb_status_g, CIRCUITPY_RGB_STATUS_G, 0, 50000, false); - - if (PWMOUT_OK == green_result) { - common_hal_pwmio_pwmout_never_reset(&rgb_status_g); - } + common_hal_pwmio_pwmout_construct(&rgb_status_g, CIRCUITPY_RGB_STATUS_G, 0, 50000, false); } if (common_hal_mcu_pin_is_free(CIRCUITPY_RGB_STATUS_B)) { - pwmout_result_t blue_result = common_hal_pwmio_pwmout_construct(&rgb_status_b, CIRCUITPY_RGB_STATUS_B, 0, 50000, false); - - if (PWMOUT_OK == blue_result) { - common_hal_pwmio_pwmout_never_reset(&rgb_status_b); - } + common_hal_pwmio_pwmout_construct(&rgb_status_b, CIRCUITPY_RGB_STATUS_B, 0, 50000, false); } #elif defined(MICROPY_HW_LED_STATUS) @@ -330,6 +318,14 @@ void set_status_brightness(uint8_t level) { #endif } +uint8_t get_status_brightness(void) { + #if CIRCUITPY_STATUS_LED + return rgb_status_brightness; + #else + return 0; + #endif +} + void init_rxtx_leds(void) { #if CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_RX) common_hal_digitalio_digitalinout_construct(&rx_led, MICROPY_HW_LED_RX); diff --git a/supervisor/shared/status_leds.h b/supervisor/shared/status_leds.h index 99aa0277d6..d065b96d4a 100644 --- a/supervisor/shared/status_leds.h +++ b/supervisor/shared/status_leds.h @@ -53,6 +53,7 @@ void new_status_color(uint32_t rgb); uint32_t color_brightness(uint32_t color, uint8_t brightness); void set_status_brightness(uint8_t level); +uint8_t get_status_brightness(void); void init_rxtx_leds(void); void deinit_rxtx_leds(void); diff --git a/supervisor/shared/translate/translate.c b/supervisor/shared/translate/translate.c index ae6c7524e5..b07aa584ca 100644 --- a/supervisor/shared/translate/translate.c +++ b/supervisor/shared/translate/translate.c @@ -57,6 +57,9 @@ STATIC void get_word(int n, const mchar_t **pos, const mchar_t **end) { } STATIC int put_utf8(char *buf, int u) { + if (u >= translation_offstart) { + u += translation_offset; + } if (u <= 0x7f) { *buf = u; return 1; diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index a1885448de..fa85cddb83 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -35,6 +35,10 @@ #include "shared/runtime/interrupt_char.h" #include "shared/readline/readline.h" +#if CIRCUITPY_STATUS_BAR +#include "supervisor/shared/status_bar.h" +#endif + #if CIRCUITPY_STORAGE #include "shared-module/storage/__init__.h" #endif @@ -118,9 +122,13 @@ void usb_set_defaults(void) { #endif }; +#if CIRCUITPY_USB_IDENTIFICATION +supervisor_allocation *usb_identification_allocation; +#endif + // Some dynamic USB data must be saved after boot.py. How much is needed? size_t usb_boot_py_data_size(void) { - size_t size = 0; + size_t size = sizeof(usb_identification_t); #if CIRCUITPY_USB_HID size += usb_hid_report_descriptor_length(); @@ -131,6 +139,28 @@ size_t usb_boot_py_data_size(void) { // Fill in the data to save. void usb_get_boot_py_data(uint8_t *temp_storage, size_t temp_storage_size) { + #if CIRCUITPY_USB_IDENTIFICATION + if (usb_identification_allocation) { + memcpy(temp_storage, usb_identification_allocation->ptr, sizeof(usb_identification_t)); + free_memory(usb_identification_allocation); + } + #else + if (false) { + } + #endif + else { + usb_identification_t defaults; + // This compiles to less code than using a struct initializer. + defaults.vid = USB_VID; + defaults.pid = USB_PID; + strcpy(defaults.manufacturer_name, USB_MANUFACTURER); + strcpy(defaults.product_name, USB_PRODUCT); + memcpy(temp_storage, &defaults, sizeof(defaults)); + } + + temp_storage += sizeof(usb_identification_t); + temp_storage_size -= sizeof(usb_identification_t); + #if CIRCUITPY_USB_HID usb_hid_build_report_descriptor(temp_storage, temp_storage_size); #endif @@ -138,12 +168,18 @@ void usb_get_boot_py_data(uint8_t *temp_storage, size_t temp_storage_size) { // After VM is gone, save data into non-heap storage (storage_allocations). void usb_return_boot_py_data(uint8_t *temp_storage, size_t temp_storage_size) { + usb_identification_t identification; + memcpy(&identification, temp_storage, sizeof(usb_identification_t)); + + temp_storage += sizeof(usb_identification_t); + temp_storage_size -= sizeof(usb_identification_t); + #if CIRCUITPY_USB_HID usb_hid_save_report_descriptor(temp_storage, temp_storage_size); #endif // Now we can also build the rest of the descriptors and place them in storage_allocations. - usb_build_descriptors(); + usb_build_descriptors(&identification); } // Call this when ready to run code.py or a REPL, and a VM has been started. @@ -242,6 +278,11 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { if (coding.bit_rate == 1200) { reset_to_bootloader(); } + } else { + #if CIRCUITPY_STATUS_BAR + // We are connected, let's request a title bar update. + supervisor_status_bar_request_update(true); + #endif } } @@ -300,7 +341,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ #endif // CIRCUITPY_USB_VENDOR -#if MICROPY_KBD_EXCEPTION +#if MICROPY_KBD_EXCEPTION && CIRCUITPY_USB_CDC /** * Callback invoked when received an "wanted" char. @@ -318,4 +359,10 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { } } +void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { + if (usb_cdc_console_enabled() && mp_interrupt_char != -1 && itf == 0 && duration_ms > 0) { + mp_sched_keyboard_interrupt(); + } +} + #endif diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c index 9fe1eadd4e..e7cffee351 100644 --- a/supervisor/shared/usb/usb_desc.c +++ b/supervisor/shared/usb/usb_desc.c @@ -68,9 +68,6 @@ static supervisor_allocation *device_descriptor_allocation; static supervisor_allocation *configuration_descriptor_allocation; static supervisor_allocation *string_descriptors_allocation; -static const char manufacturer_name[] = USB_MANUFACTURER; -static const char product_name[] = USB_PRODUCT; - // Serial number string is UID length * 2 (2 nibbles per byte) + 1 byte for null termination. static char serial_number_hex_string[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2 + 1]; @@ -113,23 +110,23 @@ static const uint8_t configuration_descriptor_template[] = { 0x32, // 8 bMaxPower 100mA }; -static void usb_build_device_descriptor(uint16_t vid, uint16_t pid) { +static void usb_build_device_descriptor(const usb_identification_t *identification) { device_descriptor_allocation = allocate_memory(align32_size(sizeof(device_descriptor_template)), /*high_address*/ false, /*movable*/ false); uint8_t *device_descriptor = (uint8_t *)device_descriptor_allocation->ptr; memcpy(device_descriptor, device_descriptor_template, sizeof(device_descriptor_template)); - device_descriptor[DEVICE_VID_LO_INDEX] = vid & 0xFF; - device_descriptor[DEVICE_VID_HI_INDEX] = vid >> 8; - device_descriptor[DEVICE_PID_LO_INDEX] = pid & 0xFF; - device_descriptor[DEVICE_PID_HI_INDEX] = pid >> 8; + device_descriptor[DEVICE_VID_LO_INDEX] = identification->vid & 0xFF; + device_descriptor[DEVICE_VID_HI_INDEX] = identification->vid >> 8; + device_descriptor[DEVICE_PID_LO_INDEX] = identification->pid & 0xFF; + device_descriptor[DEVICE_PID_HI_INDEX] = identification->pid >> 8; - usb_add_interface_string(current_interface_string, manufacturer_name); + usb_add_interface_string(current_interface_string, identification->manufacturer_name); device_descriptor[DEVICE_MANUFACTURER_STRING_INDEX] = current_interface_string; current_interface_string++; - usb_add_interface_string(current_interface_string, product_name); + usb_add_interface_string(current_interface_string, identification->product_name); device_descriptor[DEVICE_PRODUCT_STRING_INDEX] = current_interface_string; current_interface_string++; @@ -231,7 +228,7 @@ static void usb_build_configuration_descriptor(void) { if (usb_hid_boot_device() > 0 && descriptor_counts.current_interface > 0) { // Hosts using boot devices generally to expect them to be at interface zero, // and will not work properly otherwise. - reset_into_safe_mode(USB_BOOT_DEVICE_NOT_INTERFACE_ZERO); + reset_into_safe_mode(SAFE_MODE_USB_BOOT_DEVICE_NOT_INTERFACE_ZERO); } descriptor_buf_remaining += usb_hid_add_descriptor( descriptor_buf_remaining, &descriptor_counts, ¤t_interface_string, @@ -261,14 +258,14 @@ static void usb_build_configuration_descriptor(void) { if (descriptor_counts.current_endpoint > USB_NUM_ENDPOINT_PAIRS || descriptor_counts.num_in_endpoints > USB_NUM_IN_ENDPOINTS || descriptor_counts.num_out_endpoints > USB_NUM_OUT_ENDPOINTS) { - reset_into_safe_mode(USB_TOO_MANY_ENDPOINTS); + reset_into_safe_mode(SAFE_MODE_USB_TOO_MANY_ENDPOINTS); } } // str must not be on the heap. void usb_add_interface_string(uint8_t interface_string_index, const char str[]) { if (interface_string_index > MAX_INTERFACE_STRINGS) { - reset_into_safe_mode(USB_TOO_MANY_INTERFACE_NAMES); + reset_into_safe_mode(SAFE_MODE_USB_TOO_MANY_INTERFACE_NAMES); } collected_interface_strings[interface_string_index].char_str = str; @@ -319,7 +316,7 @@ static void usb_build_interface_string_table(void) { // After boot.py runs, the USB devices to be used have been chosen, and the descriptors can be set up. // This is called after the VM is finished, because it uses storage_allocations. -void usb_build_descriptors(void) { +void usb_build_descriptors(const usb_identification_t *identification) { uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; common_hal_mcu_processor_get_uid(raw_id); @@ -336,7 +333,7 @@ void usb_build_descriptors(void) { current_interface_string = 1; collected_interface_strings_length = 0; - usb_build_device_descriptor(USB_VID, USB_PID); + usb_build_device_descriptor(identification); usb_build_configuration_descriptor(); usb_build_interface_string_table(); } diff --git a/supervisor/shared/web_workflow/static/code.html b/supervisor/shared/web_workflow/static/code.html new file mode 100644 index 0000000000..afb707538a --- /dev/null +++ b/supervisor/shared/web_workflow/static/code.html @@ -0,0 +1,14 @@ + + + + + + + Online Code Editor + + + + +

Uh oh! It looks like you may be offline. You can go to the file browser if you'd like to work with files without connecting to the internet.

+ + diff --git a/supervisor/shared/web_workflow/static/directory.html b/supervisor/shared/web_workflow/static/directory.html index d0ca1a3b32..cf9ff507f9 100644 --- a/supervisor/shared/web_workflow/static/directory.html +++ b/supervisor/shared/web_workflow/static/directory.html @@ -4,17 +4,21 @@ + +

 

- - + + - +
TypeSizePathModified
TypeSizePathModified

- + + +
- +🗀  + +📁  diff --git a/supervisor/shared/web_workflow/static/directory.js b/supervisor/shared/web_workflow/static/directory.js index b2b76648c2..a89d5e5602 100644 --- a/supervisor/shared/web_workflow/static/directory.js +++ b/supervisor/shared/web_workflow/static/directory.js @@ -1,10 +1,26 @@ let new_directory_name = document.getElementById("name"); let files = document.getElementById("files"); +let dirs = document.getElementById("dirs"); var url_base = window.location; var current_path; var editable = undefined; +function compareValues(a, b) { + if (a.directory == b.directory && a.name.toLowerCase() === b.name.toLowerCase()) { + return 0; + } else if (a.directory != b.directory) { + return a.directory < b.directory ? 1 : -1; + } else { + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; + } +} + +function set_upload_enabled(enabled) { + files.disabled = !enabled; + dirs.disabled = !enabled; +} + async function refresh_list() { current_path = window.location.hash.substr(1); if (current_path == "") { @@ -36,33 +52,38 @@ async function refresh_list() { ); editable = status.headers.get("Access-Control-Allow-Methods").includes("DELETE"); new_directory_name.disabled = !editable; - files.disabled = !editable; + set_upload_enabled(editable); if (!editable) { let usbwarning = document.querySelector("#usbwarning"); usbwarning.style.display = "block"; } } - if (window.location.path != "/fs/") { + if (current_path != "/") { var clone = template.content.cloneNode(true); var td = clone.querySelectorAll("td"); - td[0].textContent = "🗀"; + td[0].textContent = "📁"; var path = clone.querySelector("a"); let parent = new URL("..", "file://" + current_path); path.href = "#" + parent.pathname; path.textContent = ".."; // Remove the delete button td[4].replaceChildren(); + td[5].replaceChildren(); + td[6].replaceChildren(); new_children.push(clone); } + data.sort(compareValues); + for (const f of data) { // Clone the new row and insert it into the table var clone = template.content.cloneNode(true); var td = clone.querySelectorAll("td"); - var icon = "⬇"; + var icon = "⬇️"; var file_path = current_path + f.name; let api_url = new URL("/fs" + file_path, url_base); + let edit_url = "/edit/#" + file_path; if (f.directory) { file_path = "#" + file_path + "/"; api_url += "/"; @@ -70,28 +91,48 @@ async function refresh_list() { file_path = api_url; } + var text_file = false; if (f.directory) { - icon = "🗀"; + icon = "📁"; } else if(f.name.endsWith(".txt") || + f.name.endsWith(".toml") || f.name.endsWith(".py") || f.name.endsWith(".js") || f.name.endsWith(".json")) { - icon = "🖹"; + icon = "📄"; + text_file = true; } else if (f.name.endsWith(".html")) { icon = "🌐"; + text_file = true; } td[0].textContent = icon; td[1].textContent = f.file_size; - var path = clone.querySelector("a"); + var path = clone.querySelector("a.path"); path.href = file_path; path.textContent = f.name; - td[3].textContent = (new Date(f.modified_ns / 1000000)).toLocaleString(); + let modtime = clone.querySelector("td.modtime"); + modtime.textContent = (new Date(f.modified_ns / 1000000)).toLocaleString(); var delete_button = clone.querySelector("button.delete"); delete_button.value = api_url; delete_button.disabled = !editable; delete_button.onclick = del; + var rename_button = clone.querySelector("button.rename"); + rename_button.value = api_url; + rename_button.disabled = !editable; + rename_button.onclick = rename; + + let edit_link = clone.querySelector(".edit_link"); + if (text_file && editable && !f.directory) { + edit_url = new URL(edit_url, url_base); + edit_link.href = edit_url + } else if (f.directory) { + edit_link.style = "display: none;"; + } else { + edit_link.querySelector("button").disabled = true; + } + new_children.push(clone); } var tbody = document.querySelector("tbody"); @@ -131,8 +172,25 @@ async function mkdir(e) { } async function upload(e) { - for (const file of files.files) { - let file_path = new URL("/fs" + current_path + file.name, url_base); + set_upload_enabled(false); + let progress = document.querySelector("progress"); + let made_dirs = new Set(); + progress.max = files.files.length + dirs.files.length; + progress.value = 0; + for (const file of [...files.files, ...dirs.files]) { + let file_name = file.name; + if (file.webkitRelativePath) { + file_name = file.webkitRelativePath; + let components = file_name.split("/"); + components.pop(); + let parent_dir = components.join("/"); + if (!made_dirs.has(parent_dir)) { + new_directory_name.value = parent_dir; + await mkdir(null); + made_dirs.add(parent_dir); + } + } + let file_path = new URL("/fs" + current_path + file_name, url_base); const response = await fetch(file_path, { method: "PUT", @@ -145,10 +203,13 @@ async function upload(e) { ) if (response.ok) { refresh_list(); - files.value = ""; - upload_button.disabled = true; } + progress.value += 1; } + files.value = ""; + dirs.value = ""; + progress.value = 0; + set_upload_enabled(true); } async function del(e) { @@ -171,19 +232,33 @@ async function del(e) { } } +async function rename(e) { + let fn = new URL(e.target.value); + var new_fn = prompt("Rename to ", fn.pathname.substr(3)); + if (new_fn === null) { + return; + } + let new_uri = new URL("/fs" + new_fn, fn); + const response = await fetch(e.target.value, + { + method: "MOVE", + headers: { + 'X-Destination': new_uri.pathname, + }, + } + ) + if (response.ok) { + refresh_list(); + } +} + find_devices(); let mkdir_button = document.getElementById("mkdir"); mkdir_button.onclick = mkdir; -let upload_button = document.getElementById("upload"); -upload_button.onclick = upload; - -upload_button.disabled = files.files.length == 0; - -files.onchange = () => { - upload_button.disabled = files.files.length == 0; -} +files.onchange = upload; +dirs.onchange = upload; mkdir_button.disabled = new_directory_name.value.length == 0; diff --git a/supervisor/shared/web_workflow/static/edit.html b/supervisor/shared/web_workflow/static/edit.html new file mode 100644 index 0000000000..85408ed2b5 --- /dev/null +++ b/supervisor/shared/web_workflow/static/edit.html @@ -0,0 +1,16 @@ + + + + + Offline Code Edit + + + + + +

Loading

+ + + + + diff --git a/supervisor/shared/web_workflow/static/edit.js b/supervisor/shared/web_workflow/static/edit.js new file mode 100644 index 0000000000..60dd8b1073 --- /dev/null +++ b/supervisor/shared/web_workflow/static/edit.js @@ -0,0 +1,47 @@ +let $editor = document.querySelector("#code_textarea"); +let filename = location.hash.substring(1); +let $output_text = document.querySelector("#output_text"); + +fetch(`/fs/${filename}`) + .then(function (response) { + $output_text.innerText = `Loading Status: ${response.status}`; + return response.status === 200 ? response.text() : ""; + }) + .then(function (data) { + $editor.value = data; + }); + +function save() { + $output_text.innerText = "Saving..." + const requestOptions = { + method: 'PUT', + body: $editor.value + }; + fetch(`/fs/${filename}`, requestOptions) + .then(function (response) { + $output_text.innerText = `Saving Status: ${response.status}`; + return response.text(); + }) + .then(function (data) { + console.log("after fetch: " + data); + }); +} + +document.querySelector("#save_btn").onclick = function () { + console.log("Click Save!"); + save(); +} + +let isCtrl = false; +document.onkeyup=function(e){ + if(e.keyCode === 17) isCtrl=false; +} + +document.onkeydown=function(e){ + if(e.keyCode === 17) isCtrl=true; + if(e.keyCode === 83 && isCtrl === true) { + //ctrl-s pressed + save(); + return false; + } +} diff --git a/supervisor/shared/web_workflow/static/serial.html b/supervisor/shared/web_workflow/static/serial.html index 0c13248904..9193953443 100644 --- a/supervisor/shared/web_workflow/static/serial.html +++ b/supervisor/shared/web_workflow/static/serial.html @@ -5,6 +5,8 @@ + +
diff --git a/supervisor/shared/web_workflow/static/serial.js b/supervisor/shared/web_workflow/static/serial.js index 86ec077e92..5c644795a0 100644 --- a/supervisor/shared/web_workflow/static/serial.js +++ b/supervisor/shared/web_workflow/static/serial.js @@ -63,10 +63,12 @@ input.addEventListener("beforeinput", function(e) { input.value = ""; input.focus(); e.preventDefault(); - } else if (e.inputType == "insertText") { + } else if (e.inputType == "insertText" || e.inputType == "insertFromPaste") { ws.send(e.data); } else if (e.inputType == "deleteContentBackward") { ws.send("\b"); + } else { + console.log(e); } }); diff --git a/supervisor/shared/web_workflow/static/style.css b/supervisor/shared/web_workflow/static/style.css new file mode 100644 index 0000000000..ab9dde7fb8 --- /dev/null +++ b/supervisor/shared/web_workflow/static/style.css @@ -0,0 +1,23 @@ +body { + max-width: 960px; + margin: 20px auto; + font-size: 18px; + font-family: "Proxima Nova", Verdana, sans-serif; + line-height: 20.7px; +} + + +/* for edit.html */ +#code_textarea { + width: 90%; + height: 600px; +} + +#output_text { + margin: 0; + font-size: 0.7em; +} + +:disabled { + filter: saturate(0%); +} diff --git a/supervisor/shared/web_workflow/static/welcome.html b/supervisor/shared/web_workflow/static/welcome.html index 139e9eba39..efbb30e312 100644 --- a/supervisor/shared/web_workflow/static/welcome.html +++ b/supervisor/shared/web_workflow/static/welcome.html @@ -5,17 +5,29 @@ + + +

 Welcome!

- Welcome to CircuitPython's Web API. Go to the file browser to work with files in the CIRCUITPY drive. Go to the serial terminal to see code output and interact with the REPL. Make sure you've set CIRCUITPY_WEB_API_PASSWORD='somepassword' in /.env. Provide the password when the browser prompts for it. Leave the username blank. -

Device Info

- Board:
- Version:
- Hostname:
- IP: -

Other Devices

- Here are other CircuitPython devices on your network: + +

Welcome to CircuitPython's Web API. Go to the file browser to work with files in the CIRCUITPY drive. Go to the full code editor for a more enriching experience which requires an active internet connection. Go to the serial terminal to see code output and interact with the REPL. Make sure you've set CIRCUITPY_WEB_API_PASSWORD='somepassword' in /settings.toml. Provide the password when the browser prompts for it. Leave the username blank.

+ +

Device Info:

+ +
+
Board:
+
+
Version:
+
+
Hostname:
+
+
IP:
+
+
+ +

Here are other CircuitPython devices on your network:

diff --git a/supervisor/shared/web_workflow/static/welcome.js b/supervisor/shared/web_workflow/static/welcome.js index 79efb7e9a8..e32d6924b5 100644 --- a/supervisor/shared/web_workflow/static/welcome.js +++ b/supervisor/shared/web_workflow/static/welcome.js @@ -1,7 +1,7 @@ var url_base = window.location; var current_path; -var mdns_works = window.location.hostname.endsWith(".local"); +var mdns_works = url_base.hostname.endsWith(".local"); async function find_devices() { var version_response = await fetch("/cp/version.json"); @@ -44,7 +44,7 @@ async function find_devices() { li.appendChild(a); var port = ""; if (device.port != 80) { - port = ":" + version_info.port; + port = ":" + device.port; } var server; if (mdns_works) { diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index 81730c92d0..97530b970b 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -24,28 +24,38 @@ * THE SOFTWARE. */ +#include #include #include "extmod/vfs.h" #include "extmod/vfs_fat.h" #include "genhdr/mpversion.h" +#include "py/mperrno.h" #include "py/mpstate.h" #include "py/stackctrl.h" #include "shared-bindings/wifi/Radio.h" #include "shared-module/storage/__init__.h" #include "shared/timeutils/timeutils.h" -#include "supervisor/fatfs_port.h" +#include "supervisor/fatfs.h" +#include "supervisor/filesystem.h" +#include "supervisor/port.h" #include "supervisor/shared/reload.h" #include "supervisor/shared/translate/translate.h" #include "supervisor/shared/web_workflow/web_workflow.h" #include "supervisor/shared/web_workflow/websocket.h" +#include "supervisor/shared/workflow.h" #include "supervisor/usb.h" #include "shared-bindings/hashlib/__init__.h" #include "shared-bindings/hashlib/Hash.h" + +#if CIRCUITPY_MDNS #include "shared-bindings/mdns/RemoteService.h" #include "shared-bindings/mdns/Server.h" +#endif + +#include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/socketpool/__init__.h" #include "shared-bindings/socketpool/Socket.h" #include "shared-bindings/socketpool/SocketPool.h" @@ -54,15 +64,10 @@ #include "shared-bindings/wifi/__init__.h" #endif -#if CIRCUITPY_DOTENV -#include "shared-module/dotenv/__init__.h" +#if CIRCUITPY_OS_GETENV +#include "shared-module/os/__init__.h" #endif -// TODO: Remove ESP specific stuff. For now, it is useful as we refine the server. -#include "esp_log.h" - -static const char *TAG = "CP webserver"; - enum request_state { STATE_METHOD, STATE_PATH, @@ -76,8 +81,9 @@ typedef struct { enum request_state state; char method[8]; char path[256]; + char destination[256]; char header_key[64]; - char header_value[64]; + char header_value[256]; // We store the origin so we can reply back with it. char origin[64]; size_t content_length; @@ -90,14 +96,26 @@ typedef struct { bool expect; bool json; bool websocket; + bool new_socket; uint32_t websocket_version; // RFC6455 for websockets says this header should be 24 base64 characters long. char websocket_key[24 + 1]; } _request; -static wifi_radio_error_t wifi_status = WIFI_RADIO_ERROR_NONE; +static wifi_radio_error_t _wifi_status = WIFI_RADIO_ERROR_NONE; +#if CIRCUITPY_STATUS_BAR +// Store various last states to compute if status bar needs an update. +static bool _last_enabled = false; +static uint32_t _last_ip = 0; +static wifi_radio_error_t _last_wifi_status = WIFI_RADIO_ERROR_NONE; +#endif + +#if CIRCUITPY_MDNS static mdns_server_obj_t mdns; +#endif + +static mp_int_t web_api_port = 80; static socketpool_socketpool_obj_t pool; static socketpool_socket_obj_t listening; @@ -107,6 +125,7 @@ static _request active_request; static char _api_password[64]; +// Store the encoded IP so we don't duplicate work. static uint32_t _encoded_ip = 0; static char _our_ip_encoded[4 * 4]; @@ -169,126 +188,200 @@ static bool _base64_in_place(char *buf, size_t in_len, size_t out_len) { return true; } - -void supervisor_web_workflow_status(void) { - serial_write_compressed(translate("Wi-Fi: ")); +STATIC void _update_encoded_ip(void) { + uint32_t ipv4_address = 0; if (common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj)) { - uint32_t ipv4_address = wifi_radio_get_ipv4_address(&common_hal_wifi_radio_obj); - if (wifi_status == WIFI_RADIO_ERROR_AUTH_EXPIRE || - wifi_status == WIFI_RADIO_ERROR_AUTH_FAIL) { - serial_write_compressed(translate("Authentication failure")); - } else if (wifi_status != WIFI_RADIO_ERROR_NONE) { - mp_printf(&mp_plat_print, "%d", wifi_status); - } else if (ipv4_address == 0) { - serial_write_compressed(translate("No IP")); - } else { - if (_encoded_ip != ipv4_address) { - uint8_t *octets = (uint8_t *)&ipv4_address; - snprintf(_our_ip_encoded, sizeof(_our_ip_encoded), "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]); - _encoded_ip = ipv4_address; - } - - mp_printf(&mp_plat_print, "%s", _our_ip_encoded); - // TODO: Use these unicode to show signal strength: ▂▄▆█ - } - } else { - serial_write_compressed(translate("off")); + ipv4_address = wifi_radio_get_ipv4_address(&common_hal_wifi_radio_obj); + } + if (_encoded_ip != ipv4_address) { + uint8_t *octets = (uint8_t *)&ipv4_address; + snprintf(_our_ip_encoded, sizeof(_our_ip_encoded), "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]); + _encoded_ip = ipv4_address; } } -void supervisor_start_web_workflow(void) { - #if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI +mdns_server_obj_t *supervisor_web_workflow_mdns(mp_obj_t network_interface) { + #if CIRCUITPY_MDNS + if (network_interface == &common_hal_wifi_radio_obj && + mdns.base.type == &mdns_server_type) { + return &mdns; + } + #endif + return NULL; +} - if (common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj) && - wifi_radio_get_ipv4_address(&common_hal_wifi_radio_obj) != 0) { - // Already started. +#if CIRCUITPY_STATUS_BAR +bool supervisor_web_workflow_status_dirty(void) { + return common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj) != _last_enabled || + _encoded_ip != _last_ip || + _last_wifi_status != _wifi_status; +} +#endif + +#if CIRCUITPY_STATUS_BAR +void supervisor_web_workflow_status(void) { + _last_enabled = common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj); + if (_last_enabled) { + uint32_t ipv4_address = wifi_radio_get_ipv4_address(&common_hal_wifi_radio_obj); + if (ipv4_address != 0) { + _update_encoded_ip(); + _last_ip = _encoded_ip; + mp_printf(&mp_plat_print, "%s", _our_ip_encoded); + if (web_api_port != 80) { + mp_printf(&mp_plat_print, ":%d", web_api_port); + } + // TODO: Use these unicode to show signal strength: ▂▄▆█ + return; + } + serial_write_compressed(translate("Wi-Fi: ")); + _last_wifi_status = _wifi_status; + if (_wifi_status == WIFI_RADIO_ERROR_AUTH_EXPIRE || + _wifi_status == WIFI_RADIO_ERROR_AUTH_FAIL) { + serial_write_compressed(translate("Authentication failure")); + } else if (_wifi_status != WIFI_RADIO_ERROR_NONE) { + mp_printf(&mp_plat_print, "%d", _wifi_status); + } else if (ipv4_address == 0) { + _last_ip = 0; + serial_write_compressed(translate("No IP")); + } else { + } + } else { + // Keep Wi-Fi print separate so its data can be matched with the one above. + serial_write_compressed(translate("Wi-Fi: ")); + serial_write_compressed(translate("off")); + } +} +#endif + +void supervisor_start_web_workflow(void) { + #if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI && CIRCUITPY_OS_GETENV + + // Skip starting the workflow if we're not starting from power on or reset. + const mcu_reset_reason_t reset_reason = common_hal_mcu_processor_get_reset_reason(); + if (reset_reason != RESET_REASON_POWER_ON && + reset_reason != RESET_REASON_RESET_PIN && + reset_reason != RESET_REASON_UNKNOWN && + reset_reason != RESET_REASON_SOFTWARE) { return; } char ssid[33]; char password[64]; - mp_int_t ssid_len = 0; - mp_int_t password_len = 0; - #if CIRCUITPY_DOTENV - ssid_len = dotenv_get_key("/.env", "CIRCUITPY_WIFI_SSID", ssid, sizeof(ssid) - 1); - password_len = dotenv_get_key("/.env", "CIRCUITPY_WIFI_PASSWORD", password, sizeof(password) - 1); - #endif - if (ssid_len <= 0 || (size_t)ssid_len >= sizeof(ssid) || - password_len <= 0 || (size_t)password_len >= sizeof(password)) { + os_getenv_err_t result = common_hal_os_getenv_str("CIRCUITPY_WIFI_SSID", ssid, sizeof(ssid)); + if (result != GETENV_OK) { return; } - common_hal_wifi_init(false); - common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, true); + + result = common_hal_os_getenv_str("CIRCUITPY_WIFI_PASSWORD", password, sizeof(password)); + if (result == GETENV_ERR_NOT_FOUND) { + // if password is unspecified, assume an open network + password[0] = '\0'; + } else if (result != GETENV_OK) { + return; + } + + if (!common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj)) { + common_hal_wifi_init(false); + common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, true); + } // TODO: Do our own scan so that we can find the channel we want before calling connect. // Otherwise, connect will do a full slow scan to pick the best AP. - // NUL terminate the strings because dotenv doesn't. - ssid[ssid_len] = '\0'; - password[password_len] = '\0'; - wifi_status = common_hal_wifi_radio_connect( - &common_hal_wifi_radio_obj, (uint8_t *)ssid, ssid_len, (uint8_t *)password, password_len, - 0, 0.1, NULL, 0); + // We can all connect again because it will return early if we're already connected to the + // network. If we are connected to a different network, then it will disconnect before + // attempting to connect to the given network. + _wifi_status = common_hal_wifi_radio_connect( + &common_hal_wifi_radio_obj, (uint8_t *)ssid, strlen(ssid), (uint8_t *)password, strlen(password), + 0, 8, NULL, 0); - if (wifi_status != WIFI_RADIO_ERROR_NONE) { + if (_wifi_status != WIFI_RADIO_ERROR_NONE) { common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, false); return; } - mdns_server_construct(&mdns, true); - common_hal_mdns_server_set_instance_name(&mdns, MICROPY_HW_BOARD_NAME); - common_hal_mdns_server_advertise_service(&mdns, "_circuitpython", "_tcp", 80); + mp_int_t new_port = web_api_port; + // (leaves new_port unchanged on any failure) + (void)common_hal_os_getenv_int("CIRCUITPY_WEB_API_PORT", &new_port); - pool.base.type = &socketpool_socketpool_type; - common_hal_socketpool_socketpool_construct(&pool, &common_hal_wifi_radio_obj); + bool first_start = pool.base.type != &socketpool_socketpool_type; + bool port_changed = new_port != web_api_port; - ESP_LOGI(TAG, "Starting web workflow"); - listening.base.type = &socketpool_socket_type; - socketpool_socket(&pool, SOCKETPOOL_AF_INET, SOCKETPOOL_SOCK_STREAM, &listening); - common_hal_socketpool_socket_settimeout(&listening, 0); - // Bind to any ip. - // TODO: Make this port .env configurable. - common_hal_socketpool_socket_bind(&listening, "", 0, 80); - common_hal_socketpool_socket_listen(&listening, 1); + if (first_start) { + port_changed = false; + pool.base.type = &socketpool_socketpool_type; + common_hal_socketpool_socketpool_construct(&pool, &common_hal_wifi_radio_obj); - mp_int_t api_password_len = dotenv_get_key("/.env", "CIRCUITPY_WEB_API_PASSWORD", _api_password + 1, sizeof(_api_password) - 2); - if (api_password_len > 0) { - _api_password[0] = ':'; - _api_password[api_password_len + 1] = '\0'; - _base64_in_place(_api_password, api_password_len + 1, sizeof(_api_password)); + socketpool_socket_reset(&listening); + socketpool_socket_reset(&active); + + websocket_init(); + } + #if CIRCUITPY_MDNS + // Try to start MDNS if the user deinited it. + if (mdns.base.type != &mdns_server_type || + common_hal_mdns_server_deinited(&mdns)) { + mdns_server_construct(&mdns, true); + mdns.base.type = &mdns_server_type; + if (!common_hal_mdns_server_deinited(&mdns)) { + common_hal_mdns_server_set_instance_name(&mdns, MICROPY_HW_BOARD_NAME); + } + } + #endif + if (port_changed) { + common_hal_socketpool_socket_close(&listening); + } + if (first_start || port_changed) { + web_api_port = new_port; + #if CIRCUITPY_MDNS + if (!common_hal_mdns_server_deinited(&mdns)) { + common_hal_mdns_server_advertise_service(&mdns, "_circuitpython", "_tcp", web_api_port); + } + #endif + socketpool_socket(&pool, SOCKETPOOL_AF_INET, SOCKETPOOL_SOCK_STREAM, &listening); + common_hal_socketpool_socket_settimeout(&listening, 0); + // Bind to any ip. + common_hal_socketpool_socket_bind(&listening, "", 0, web_api_port); + common_hal_socketpool_socket_listen(&listening, 1); } - active.base.type = &socketpool_socket_type; - active.num = -1; - active.connected = false; - websocket_init(); - - // TODO: - // GET /cp/serial.txt - // - Most recent 1k of serial output. - // GET /edit/ - // - Super basic editor + const size_t api_password_len = sizeof(_api_password) - 1; + result = common_hal_os_getenv_str("CIRCUITPY_WEB_API_PASSWORD", _api_password + 1, api_password_len); + if (result == GETENV_OK) { + _api_password[0] = ':'; + _base64_in_place(_api_password, strlen(_api_password), sizeof(_api_password) - 1); + } #endif } -static void _send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) { - int sent = -EAGAIN; - while (sent == -EAGAIN && common_hal_socketpool_socket_get_connected(socket)) { - sent = socketpool_socket_send(socket, buf, len); - } - if (sent < len) { - ESP_LOGE(TAG, "short send %d %d", sent, len); +void web_workflow_send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) { + int total_sent = 0; + int sent = -MP_EAGAIN; + while ((sent == -MP_EAGAIN || (sent > 0 && total_sent < len)) && + common_hal_socketpool_socket_get_connected(socket)) { + sent = socketpool_socket_send(socket, buf + total_sent, len - total_sent); + if (sent > 0) { + total_sent += sent; + if (total_sent < len) { + // Yield so that network code can run. + port_yield(); + } + } } } +STATIC void _print_raw(void *env, const char *str, size_t len) { + web_workflow_send_raw((socketpool_socket_obj_t *)env, (const uint8_t *)str, (size_t)len); +} + static void _send_str(socketpool_socket_obj_t *socket, const char *str) { - _send_raw(socket, (const uint8_t *)str, strlen(str)); + web_workflow_send_raw(socket, (const uint8_t *)str, strlen(str)); } // The last argument must be NULL! Otherwise, it won't stop. -static void _send_strs(socketpool_socket_obj_t *socket, ...) { +static __attribute__((sentinel)) void _send_strs(socketpool_socket_obj_t *socket, ...) { va_list ap; va_start(ap, socket); @@ -301,12 +394,17 @@ static void _send_strs(socketpool_socket_obj_t *socket, ...) { } static void _send_chunk(socketpool_socket_obj_t *socket, const char *chunk) { - char encoded_len[sizeof(size_t) * 2 + 1]; - int len = snprintf(encoded_len, sizeof(encoded_len), "%X", strlen(chunk)); - _send_raw(socket, (const uint8_t *)encoded_len, len); - _send_raw(socket, (const uint8_t *)"\r\n", 2); - _send_raw(socket, (const uint8_t *)chunk, strlen(chunk)); - _send_raw(socket, (const uint8_t *)"\r\n", 2); + mp_print_t _socket_print = {socket, _print_raw}; + mp_printf(&_socket_print, "%X\r\n", strlen(chunk)); + web_workflow_send_raw(socket, (const uint8_t *)chunk, strlen(chunk)); + web_workflow_send_raw(socket, (const uint8_t *)"\r\n", 2); +} + +STATIC void _print_chunk(void *env, const char *str, size_t len) { + mp_print_t _socket_print = {env, _print_raw}; + mp_printf(&_socket_print, "%X\r\n", len); + web_workflow_send_raw((socketpool_socket_obj_t *)env, (const uint8_t *)str, len); + web_workflow_send_raw((socketpool_socket_obj_t *)env, (const uint8_t *)"\r\n", 2); } // A bit of a misnomer because it sends all arguments as one chunk. @@ -326,9 +424,9 @@ static void _send_chunks(socketpool_socket_obj_t *socket, ...) { } va_end(strs_to_count); - char encoded_len[sizeof(size_t) * 2 + 1]; - snprintf(encoded_len, sizeof(encoded_len), "%X", chunk_len); - _send_strs(socket, encoded_len, "\r\n", NULL); + + mp_print_t _socket_print = {socket, _print_raw}; + mp_printf(&_socket_print, "%X\r\n", chunk_len); str = va_arg(strs_to_send, const char *); while (str != NULL) { @@ -350,38 +448,46 @@ static bool _endswith(const char *str, const char *suffix) { return strcmp(str + (strlen(str) - strlen(suffix)), suffix) == 0; } -const char *ok_hosts[] = {"code.circuitpython.org"}; +const char *ok_hosts[] = { + "127.0.0.1", + "localhost", +}; static bool _origin_ok(const char *origin) { const char *http = "http://"; - const char *local = ".local"; - if (memcmp(origin, http, strlen(http)) != 0) { + // note: redirected requests send an Origin of "null" and will be caught by this + if (strncmp(origin, http, strlen(http)) != 0) { return false; } // These are prefix checks up to : so that any port works. - const char *hostname = common_hal_mdns_server_get_hostname(&mdns); - const char *end = origin + strlen(http) + strlen(hostname) + strlen(local); - if (memcmp(origin + strlen(http), hostname, strlen(hostname)) == 0 && - memcmp(origin + strlen(http) + strlen(hostname), local, strlen(local)) == 0 && - (end[0] == '\0' || end[0] == ':')) { - return true; + // TODO: Support DHCP hostname in addition to MDNS. + const char *end; + #if CIRCUITPY_MDNS + if (!common_hal_mdns_server_deinited(&mdns)) { + const char *local = ".local"; + const char *hostname = common_hal_mdns_server_get_hostname(&mdns); + end = origin + strlen(http) + strlen(hostname) + strlen(local); + if (strncmp(origin + strlen(http), hostname, strlen(hostname)) == 0 && + strncmp(origin + strlen(http) + strlen(hostname), local, strlen(local)) == 0 && + (end[0] == '\0' || end[0] == ':')) { + return true; + } } + #endif + _update_encoded_ip(); end = origin + strlen(http) + strlen(_our_ip_encoded); - if (memcmp(origin + strlen(http), _our_ip_encoded, strlen(_our_ip_encoded)) == 0 && + if (strncmp(origin + strlen(http), _our_ip_encoded, strlen(_our_ip_encoded)) == 0 && (end[0] == '\0' || end[0] == ':')) { return true; } - const char *localhost = "127.0.0.1:"; - if (memcmp(origin + strlen(http), localhost, strlen(localhost)) == 0) { - return true; - } - for (size_t i = 0; i < MP_ARRAY_SIZE(ok_hosts); i++) { - // This checks exactly. - if (strcmp(origin + strlen(http), ok_hosts[i]) == 0) { + // Allows any port + end = origin + strlen(http) + strlen(ok_hosts[i]); + if (strncmp(origin + strlen(http), ok_hosts[i], strlen(ok_hosts[i])) == 0 + && (end[0] == '\0' || end[0] == ':')) { return true; } } @@ -436,10 +542,10 @@ static void _reply_access_control(socketpool_socket_obj_t *socket, _request *req "HTTP/1.1 204 No Content\r\n", "Content-Length: 0\r\n", "Access-Control-Expose-Headers: Access-Control-Allow-Methods\r\n", - "Access-Control-Allow-Headers: X-Timestamp, Content-Type\r\n", + "Access-Control-Allow-Headers: X-Timestamp, X-Destination, Content-Type, Authorization\r\n", "Access-Control-Allow-Methods:GET, OPTIONS", NULL); if (!_usb_active()) { - _send_str(socket, ", PUT, DELETE"); + _send_str(socket, ", PUT, DELETE, MOVE"); #if CIRCUITPY_USB_MSC usb_msc_unlock(); #endif @@ -481,6 +587,15 @@ static void _reply_conflict(socketpool_socket_obj_t *socket, _request *request) _send_str(socket, "\r\nUSB storage active."); } + +static void _reply_precondition_failed(socketpool_socket_obj_t *socket, _request *request) { + _send_strs(socket, + "HTTP/1.1 412 Precondition Failed\r\n", + "Content-Length: 0\r\n", NULL); + _cors_header(socket, request); + _send_str(socket, "\r\n"); +} + static void _reply_payload_too_large(socketpool_socket_obj_t *socket, _request *request) { _send_strs(socket, "HTTP/1.1 413 Payload Too Large\r\n", @@ -514,12 +629,13 @@ static void _reply_server_error(socketpool_socket_obj_t *socket, _request *reque _send_str(socket, "\r\n"); } +#if CIRCUITPY_MDNS static void _reply_redirect(socketpool_socket_obj_t *socket, _request *request, const char *path) { int nodelay = 1; - lwip_setsockopt(socket->num, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); + common_hal_socketpool_socket_setsockopt(socket, SOCKETPOOL_IPPROTO_TCP, SOCKETPOOL_TCP_NODELAY, &nodelay, sizeof(nodelay)); const char *hostname = common_hal_mdns_server_get_hostname(&mdns); _send_strs(socket, - "HTTP/1.1 301 Moved Permanently\r\n", + "HTTP/1.1 307 Temporary Redirect\r\n", "Connection: close\r\n", "Content-Length: 0\r\n", "Location: ", NULL); @@ -529,15 +645,22 @@ static void _reply_redirect(socketpool_socket_obj_t *socket, _request *request, _send_str(socket, "http"); } - _send_strs(socket, "://", hostname, ".local", path, "\r\n", NULL); + _send_strs(socket, "://", hostname, ".local", NULL); + if (web_api_port != 80) { + mp_print_t _socket_print = {socket, _print_raw}; + mp_printf(&_socket_print, ":%d", web_api_port); + } + _send_strs(socket, path, "\r\n", NULL); _cors_header(socket, request); _send_str(socket, "\r\n"); } +#endif static void _reply_directory_json(socketpool_socket_obj_t *socket, _request *request, FF_DIR *dir, const char *request_path, const char *path) { socketpool_socket_send(socket, (const uint8_t *)OK_JSON, strlen(OK_JSON)); _cors_header(socket, request); _send_str(socket, "\r\n"); + mp_print_t _socket_print = {socket, _print_chunk}; _send_chunk(socket, "["); bool first = true; @@ -558,24 +681,24 @@ static void _reply_directory_json(socketpool_socket_obj_t *socket, _request *req } // We use nanoseconds past Jan 1, 1970 for consistency with BLE API and // LittleFS. - _send_chunk(socket, ", \"modified_ns\": "); + _send_chunk(socket, ", "); - uint64_t truncated_time = timeutils_mktime(1980 + (file_info.fdate >> 9), + uint32_t truncated_time = timeutils_mktime(1980 + (file_info.fdate >> 9), (file_info.fdate >> 5) & 0xf, file_info.fdate & 0x1f, file_info.ftime >> 11, - (file_info.ftime >> 5) & 0x1f, - (file_info.ftime & 0x1f) * 2) * 1000000000ULL; + (file_info.ftime >> 5) & 0x3f, + (file_info.ftime & 0x1f) * 2); - char encoded_number[32]; - snprintf(encoded_number, sizeof(encoded_number), "%lld", truncated_time); - _send_chunks(socket, encoded_number, ", \"file_size\": ", NULL); + // Manually append zeros to make the time nanoseconds. Support for printing 64 bit numbers + // varies across chipsets. + mp_printf(&_socket_print, "\"modified_ns\": %lu000000000, ", truncated_time); size_t file_size = 0; if ((file_info.fattrib & AM_DIR) == 0) { file_size = file_info.fsize; } - snprintf(encoded_number, sizeof(encoded_number), "%d", file_size); - _send_chunks(socket, encoded_number, "}", NULL); + mp_printf(&_socket_print, "\"file_size\": %d }", file_size); + first = false; res = f_readdir(dir, &file_info); } @@ -585,23 +708,21 @@ static void _reply_directory_json(socketpool_socket_obj_t *socket, _request *req static void _reply_with_file(socketpool_socket_obj_t *socket, _request *request, const char *filename, FIL *active_file) { uint32_t total_length = f_size(active_file); - char encoded_len[10]; - snprintf(encoded_len, sizeof(encoded_len), "%d", total_length); - _send_strs(socket, - "HTTP/1.1 200 OK\r\n", - "Content-Length: ", encoded_len, "\r\n", NULL); + _send_str(socket, "HTTP/1.1 200 OK\r\n"); + mp_print_t _socket_print = {socket, _print_raw}; + mp_printf(&_socket_print, "Content-Length: %d\r\n", total_length); // TODO: Make this a table to save space. - if (_endswith(filename, ".txt") || _endswith(filename, ".py")) { - _send_str(socket, "Content-Type: text/plain\r\n"); + if (_endswith(filename, ".txt") || _endswith(filename, ".py") || _endswith(filename, ".toml")) { + _send_strs(socket, "Content-Type:", "text/plain", ";charset=UTF-8\r\n", NULL); } else if (_endswith(filename, ".js")) { - _send_str(socket, "Content-Type: text/javascript\r\n"); + _send_strs(socket, "Content-Type:", "text/javascript", ";charset=UTF-8\r\n", NULL); } else if (_endswith(filename, ".html")) { - _send_str(socket, "Content-Type: text/html\r\n"); + _send_strs(socket, "Content-Type:", "text/html", ";charset=UTF-8\r\n", NULL); } else if (_endswith(filename, ".json")) { - _send_str(socket, "Content-Type: application/json\r\n"); + _send_strs(socket, "Content-Type:", "application/json", ";charset=UTF-8\r\n", NULL); } else { - _send_str(socket, "Content-Type: application/octet-stream\r\n"); + _send_strs(socket, "Content-Type:", "application/octet-stream\r\n", NULL); } _cors_header(socket, request); _send_str(socket, "\r\n"); @@ -616,10 +737,9 @@ static void _reply_with_file(socketpool_socket_obj_t *socket, _request *request, while (send_offset < quantity_read) { int sent = socketpool_socket_send(socket, data_buffer + send_offset, quantity_read - send_offset); if (sent < 0) { - if (sent == -EAGAIN) { + if (sent == -MP_EAGAIN) { sent = 0; } else { - ESP_LOGE(TAG, "file send error %d", sent); break; } } @@ -632,35 +752,38 @@ static void _reply_with_file(socketpool_socket_obj_t *socket, _request *request, } static void _reply_with_devices_json(socketpool_socket_obj_t *socket, _request *request) { + size_t total_results = 0; + #if CIRCUITPY_MDNS mdns_remoteservice_obj_t found_devices[32]; - size_t total_results = mdns_server_find(&mdns, "_circuitpython", "_tcp", 1, found_devices, MP_ARRAY_SIZE(found_devices)); + if (!common_hal_mdns_server_deinited(&mdns)) { + total_results = mdns_server_find(&mdns, "_circuitpython", "_tcp", 1, found_devices, MP_ARRAY_SIZE(found_devices)); + } size_t count = MIN(total_results, MP_ARRAY_SIZE(found_devices)); + #endif socketpool_socket_send(socket, (const uint8_t *)OK_JSON, strlen(OK_JSON)); _cors_header(socket, request); _send_str(socket, "\r\n"); - char total_encoded[4]; - snprintf(total_encoded, sizeof(total_encoded), "%d", total_results); - _send_chunks(socket, "{\"total\": ", total_encoded, ", \"devices\": [", NULL); + mp_print_t _socket_print = {socket, _print_chunk}; + + mp_printf(&_socket_print, "{\"total\": %d, \"devices\": [", total_results); + #if CIRCUITPY_MDNS for (size_t i = 0; i < count; i++) { if (i > 0) { _send_chunk(socket, ","); } const char *hostname = common_hal_mdns_remoteservice_get_hostname(&found_devices[i]); const char *instance_name = common_hal_mdns_remoteservice_get_instance_name(&found_devices[i]); - char port_encoded[4]; int port = common_hal_mdns_remoteservice_get_port(&found_devices[i]); - snprintf(port_encoded, sizeof(port_encoded), "%d", port); - char ip_encoded[4 * 4]; uint32_t ipv4_address = mdns_remoteservice_get_ipv4_address(&found_devices[i]); uint8_t *octets = (uint8_t *)&ipv4_address; - snprintf(ip_encoded, sizeof(ip_encoded), "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]); - _send_chunks(socket, - "{\"hostname\": \"", hostname, "\", ", - "\"instance_name\": \"", instance_name, "\", ", - "\"port\": ", port_encoded, ", ", - "\"ip\": \"", ip_encoded, "\"}", NULL); + mp_printf(&_socket_print, + "{\"hostname\": \"%s\", " + "\"instance_name\": \"%s\", " + "\"port\": %d, " + "\"ip\": \"%d.%d.%d.%d\"}", hostname, instance_name, port, octets[0], octets[1], octets[2], octets[3]); common_hal_mdns_remoteservice_deinit(&found_devices[i]); } + #endif _send_chunk(socket, "]}"); // Empty chunk signals the end of the response. _send_chunk(socket, ""); @@ -670,62 +793,41 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request * _send_str(socket, OK_JSON); _cors_header(socket, request); _send_str(socket, "\r\n"); - char encoded_creator_id[11]; // 2 ** 32 is 10 decimal digits plus one for \0 - snprintf(encoded_creator_id, sizeof(encoded_creator_id), "%u", CIRCUITPY_CREATOR_ID); - char encoded_creation_id[11]; // 2 ** 32 is 10 decimal digits plus one for \0 - snprintf(encoded_creation_id, sizeof(encoded_creation_id), "%u", CIRCUITPY_CREATION_ID); - const char *hostname = common_hal_mdns_server_get_hostname(&mdns); - _send_chunks(socket, - "{\"web_api_version\": 1, ", - "\"version\": \"", MICROPY_GIT_TAG, "\", ", - "\"build_date\": \"", MICROPY_BUILD_DATE, "\", ", - "\"board_name\": \"", MICROPY_HW_BOARD_NAME, "\", ", - "\"mcu_name\": \"", MICROPY_HW_MCU_NAME, "\", ", - "\"board_id\": \"", CIRCUITPY_BOARD_ID, "\", ", - "\"creator_id\": ", encoded_creator_id, ", ", - "\"creation_id\": ", encoded_creation_id, ", ", - "\"hostname\": \"", hostname, "\", ", - "\"port\": 80, ", - "\"ip\": \"", _our_ip_encoded, - "\"}", NULL); + mp_print_t _socket_print = {socket, _print_chunk}; + + const char *hostname = ""; + #if CIRCUITPY_MDNS + if (!common_hal_mdns_server_deinited(&mdns)) { + hostname = common_hal_mdns_server_get_hostname(&mdns); + } + #endif + _update_encoded_ip(); + // Note: this leverages the fact that C concats consecutive string literals together. + mp_printf(&_socket_print, + "{\"web_api_version\": 1, " + "\"version\": \"" MICROPY_GIT_TAG "\", " + "\"build_date\": \"" MICROPY_BUILD_DATE "\", " + "\"board_name\": \"" MICROPY_HW_BOARD_NAME "\", " + "\"mcu_name\": \"" MICROPY_HW_MCU_NAME "\", " + "\"board_id\": \"" CIRCUITPY_BOARD_ID "\", " + "\"creator_id\": %u, " + "\"creation_id\": %u, " + "\"hostname\": \"%s\", " + "\"port\": %d, ", CIRCUITPY_CREATOR_ID, CIRCUITPY_CREATION_ID, hostname, web_api_port, _our_ip_encoded); + #if CIRCUITPY_MICROCONTROLLER && COMMON_HAL_MCU_PROCESSOR_UID_LENGTH > 0 + uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; + common_hal_mcu_processor_get_uid(raw_id); + mp_printf(&_socket_print, "\"UID\": \""); + for (uint8_t i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) { + mp_printf(&_socket_print, "%02X", raw_id[i]); + } + mp_printf(&_socket_print, "\", "); + #endif + mp_printf(&_socket_print, "\"ip\": \"%s\"}", _our_ip_encoded); // Empty chunk signals the end of the response. _send_chunk(socket, ""); } -// Copied from ble file_transfer.c. We should share it. -STATIC FRESULT _delete_directory_contents(FATFS *fs, const TCHAR *path) { - FF_DIR dir; - FRESULT res = f_opendir(fs, &dir, path); - FILINFO file_info; - // Check the stack since we're putting paths on it. - if (mp_stack_usage() >= MP_STATE_THREAD(stack_limit)) { - return FR_INT_ERR; - } - while (res == FR_OK) { - res = f_readdir(&dir, &file_info); - if (res != FR_OK || file_info.fname[0] == '\0') { - break; - } - size_t pathlen = strlen(path); - size_t fnlen = strlen(file_info.fname); - TCHAR full_path[pathlen + 1 + fnlen]; - memcpy(full_path, path, pathlen); - full_path[pathlen] = '/'; - size_t full_pathlen = pathlen + 1 + fnlen; - memcpy(full_path + pathlen + 1, file_info.fname, fnlen); - full_path[full_pathlen] = '\0'; - if ((file_info.fattrib & AM_DIR) != 0) { - res = _delete_directory_contents(fs, full_path); - } - if (res != FR_OK) { - break; - } - res = f_unlink(fs, full_path); - } - f_closedir(&dir); - return res; -} - // FATFS has a two second timestamp resolution but the BLE API allows for nanosecond resolution. // This function truncates the time the time to a resolution storable by FATFS and fills in the // FATFS encoded version into fattime. @@ -784,7 +886,6 @@ static void _write_file_and_reply(socketpool_socket_obj_t *socket, _request *req return; } if (result != FR_OK) { - ESP_LOGE(TAG, "file write error %d %s", result, path); override_fattime(0); #if CIRCUITPY_USB_MSC usb_msc_unlock(); @@ -824,20 +925,19 @@ static void _write_file_and_reply(socketpool_socket_obj_t *socket, _request *req size_t read_len = MIN(sizeof(bytes), request->content_length - total_read); int len = socketpool_socket_recv_into(socket, bytes, read_len); if (len < 0) { - if (len == -EAGAIN) { + if (len == -MP_EAGAIN) { continue; - } else { - ESP_LOGE(TAG, "other error %d", len); } error = true; break; } + total_read += len; UINT actual; f_write(&active_file, bytes, len, &actual); - if (actual != (UINT)len) { - ESP_LOGE(TAG, "didn't write whole file"); + if (actual < (UINT)len) { + error = true; + break; } - total_read += len; } f_close(&active_file); @@ -846,7 +946,10 @@ static void _write_file_and_reply(socketpool_socket_obj_t *socket, _request *req #endif override_fattime(0); - if (new_file) { + if (error) { + _discard_incoming(socket, request->content_length - total_read); + _reply_server_error(socket, request); + } else if (new_file) { _reply_created(socket, request); } else { _reply_no_content(socket, request); @@ -855,10 +958,14 @@ static void _write_file_and_reply(socketpool_socket_obj_t *socket, _request *req #define STATIC_FILE(filename) extern uint32_t filename##_length; extern uint8_t filename[]; extern const char *filename##_content_type; +STATIC_FILE(code_html); STATIC_FILE(directory_html); STATIC_FILE(directory_js); STATIC_FILE(welcome_html); STATIC_FILE(welcome_js); +STATIC_FILE(edit_html); +STATIC_FILE(edit_js); +STATIC_FILE(style_css); STATIC_FILE(serial_html); STATIC_FILE(serial_js); STATIC_FILE(blinka_16x16_ico); @@ -866,7 +973,7 @@ STATIC_FILE(blinka_16x16_ico); static void _reply_static(socketpool_socket_obj_t *socket, _request *request, const uint8_t *response, size_t response_len, const char *content_type) { uint32_t total_length = response_len; char encoded_len[10]; - snprintf(encoded_len, sizeof(encoded_len), "%d", total_length); + snprintf(encoded_len, sizeof(encoded_len), "%" PRIu32, total_length); _send_strs(socket, "HTTP/1.1 200 OK\r\n", @@ -874,7 +981,7 @@ static void _reply_static(socketpool_socket_obj_t *socket, _request *request, co "Content-Length: ", encoded_len, "\r\n", "Content-Type: ", content_type, "\r\n", "\r\n", NULL); - _send_raw(socket, response, response_len); + web_workflow_send_raw(socket, response, response_len); } #define _REPLY_STATIC(socket, request, filename) _reply_static(socket, request, filename, filename##_length, filename##_content_type) @@ -902,23 +1009,70 @@ static void _reply_websocket_upgrade(socketpool_socket_obj_t *socket, _request * // socket is now closed and "disconnected". } +static uint8_t _hex2nibble(char h) { + if ('0' <= h && h <= '9') { + return h - '0'; + } else if ('A' <= h && h <= 'F') { + return h - 'A' + 0xa; + } + // Shouldn't usually use lower case. + return h - 'a' + 0xa; +} + +// Decode percent encoding in place. Only do this once on a string! +static void _decode_percents(char *str) { + size_t o = 0; + size_t i = 0; + size_t startlen = strlen(str); + while (i < startlen) { + if (str[i] == '%') { + str[o] = _hex2nibble(str[i + 1]) << 4 | _hex2nibble(str[i + 2]); + i += 3; + } else { + if (i != o) { + str[o] = str[i]; + } + i += 1; + } + o += 1; + } + if (o < i) { + str[o] = '\0'; + } +} + static bool _reply(socketpool_socket_obj_t *socket, _request *request) { if (request->redirect) { - _reply_redirect(socket, request, request->path); + #if CIRCUITPY_MDNS + if (!common_hal_mdns_server_deinited(&mdns)) { + _reply_redirect(socket, request, request->path); + } else { + _reply_missing(socket, request); + } + #else + _reply_missing(socket, request); + #endif } else if (strlen(request->origin) > 0 && !_origin_ok(request->origin)) { - ESP_LOGE(TAG, "bad origin %s", request->origin); _reply_forbidden(socket, request); - } else if (memcmp(request->path, "/fs/", 4) == 0) { - if (!request->authenticated) { + } else if (strncmp(request->path, "/fs/", 4) == 0) { + if (strcasecmp(request->method, "OPTIONS") == 0) { + // OPTIONS is sent for CORS preflight, unauthenticated + _reply_access_control(socket, request); + } else if (!request->authenticated) { if (_api_password[0] != '\0') { _reply_unauthorized(socket, request); } else { _reply_forbidden(socket, request); } } else { + // Decode any percent encoded bytes so that we're left with UTF-8. + // We only do this on /fs/ paths and after redirect so that any + // path echoing we do stays encoded. + _decode_percents(request->path); + char *path = request->path + 3; size_t pathlen = strlen(path); - FATFS *fs = &((fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj)->fatfs; + FATFS *fs = filesystem_circuitpy(); // Trailing / is a directory. bool directory = false; if (path[pathlen - 1] == '/') { @@ -930,9 +1084,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { } // Delete is almost identical for files and directories so share the // implementation. - if (strcmp(request->method, "OPTIONS") == 0) { - _reply_access_control(socket, request); - } else if (strcmp(request->method, "DELETE") == 0) { + if (strcasecmp(request->method, "DELETE") == 0) { if (_usb_active()) { _reply_conflict(socket, request); return false; @@ -942,7 +1094,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { FRESULT result = f_stat(fs, path, &file); if (result == FR_OK) { if ((file.fattrib & AM_DIR) != 0) { - result = _delete_directory_contents(fs, path); + result = supervisor_workflow_delete_directory_contents(fs, path); } if (result == FR_OK) { result = f_unlink(fs, path); @@ -955,14 +1107,40 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { if (result == FR_NO_PATH || result == FR_NO_FILE) { _reply_missing(socket, request); } else if (result != FR_OK) { - ESP_LOGE(TAG, "rm error %d %s", result, path); _reply_server_error(socket, request); } else { _reply_no_content(socket, request); return true; } + } else if (strcasecmp(request->method, "MOVE") == 0) { + if (_usb_active()) { + _reply_conflict(socket, request); + return false; + } + + _decode_percents(request->destination); + char *destination = request->destination + 3; + size_t destinationlen = strlen(destination); + if (destination[destinationlen - 1] == '/' && destinationlen > 1) { + destination[destinationlen - 1] = '\0'; + } + + FRESULT result = f_rename(fs, path, destination); + #if CIRCUITPY_USB_MSC + usb_msc_unlock(); + #endif + if (result == FR_EXIST) { // File exists and won't be overwritten. + _reply_precondition_failed(socket, request); + } else if (result == FR_NO_PATH || result == FR_NO_FILE) { // Missing higher directories or target file. + _reply_missing(socket, request); + } else if (result != FR_OK) { + _reply_server_error(socket, request); + } else { + _reply_created(socket, request); + return true; + } } else if (directory) { - if (strcmp(request->method, "GET") == 0) { + if (strcasecmp(request->method, "GET") == 0) { FF_DIR dir; FRESULT res = f_opendir(fs, &dir, path); // Put the / back for replies. @@ -982,7 +1160,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { } f_closedir(&dir); - } else if (strcmp(request->method, "PUT") == 0) { + } else if (strcasecmp(request->method, "PUT") == 0) { if (_usb_active()) { _reply_conflict(socket, request); return false; @@ -993,7 +1171,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { truncate_time(request->timestamp_ms * 1000000, &fattime); override_fattime(fattime); } - FRESULT result = f_mkdir(fs, path); + FRESULT result = supervisor_workflow_mkdir_parents(fs, path); override_fattime(0); #if CIRCUITPY_USB_MSC usb_msc_unlock(); @@ -1003,7 +1181,6 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { } else if (result == FR_NO_PATH) { _reply_missing(socket, request); } else if (result != FR_OK) { - ESP_LOGE(TAG, "mkdir error %d %s", result, path); _reply_server_error(socket, request); } else { _reply_created(socket, request); @@ -1011,7 +1188,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { } } } else { // Dealing with a file. - if (strcmp(request->method, "GET") == 0) { + if (strcasecmp(request->method, "GET") == 0) { FIL active_file; FRESULT result = f_open(fs, &active_file, path, FA_READ); @@ -1022,15 +1199,30 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { } f_close(&active_file); - } else if (strcmp(request->method, "PUT") == 0) { + } else if (strcasecmp(request->method, "PUT") == 0) { _write_file_and_reply(socket, request, fs, path); return true; } } } - } else if (memcmp(request->path, "/cp/", 4) == 0) { + } else if (strcmp(request->path, "/edit/") == 0) { + if (!request->authenticated) { + if (_api_password[0] != '\0') { + _reply_unauthorized(socket, request); + } else { + _reply_forbidden(socket, request); + } + } else { + _REPLY_STATIC(socket, request, edit_html); + } + } else if (strcmp(request->path, "/code/") == 0) { + _REPLY_STATIC(socket, request, code_html); + } else if (strncmp(request->path, "/cp/", 4) == 0) { const char *path = request->path + 3; - if (strcmp(request->method, "GET") != 0) { + if (strcasecmp(request->method, "OPTIONS") == 0) { + // handle preflight requests to /cp/ + _reply_access_control(socket, request); + } else if (strcasecmp(request->method, "GET") != 0) { _reply_method_not_allowed(socket, request); } else if (strcmp(path, "/devices.json") == 0) { _reply_with_devices_json(socket, request); @@ -1051,7 +1243,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { } else { _reply_missing(socket, request); } - } else if (strcmp(request->method, "GET") != 0) { + } else if (strcasecmp(request->method, "GET") != 0) { _reply_method_not_allowed(socket, request); } else { if (strcmp(request->path, "/") == 0) { @@ -1064,6 +1256,10 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { _REPLY_STATIC(socket, request, welcome_js); } else if (strcmp(request->path, "/serial.js") == 0) { _REPLY_STATIC(socket, request, serial_js); + } else if (strcmp(request->path, "/edit.js") == 0) { + _REPLY_STATIC(socket, request, edit_js); + } else if (strcmp(request->path, "/style.css") == 0) { + _REPLY_STATIC(socket, request, style_css); } else if (strcmp(request->path, "/favicon.ico") == 0) { // TODO: Autogenerate this based on the blinka bitmap and change the // palette based on MAC address. @@ -1084,6 +1280,7 @@ static void _reset_request(_request *request) { request->redirect = false; request->done = false; request->in_progress = false; + request->new_socket = false; request->authenticated = false; request->expect = false; request->json = false; @@ -1104,6 +1301,7 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) if (!request->in_progress) { autoreload_suspend(AUTORELOAD_SUSPEND_WEB); request->in_progress = true; + request->new_socket = false; } switch (request->state) { case STATE_METHOD: { @@ -1123,7 +1321,6 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) if (c == ' ') { request->path[request->offset] = '\0'; request->offset = 0; - ESP_LOGI(TAG, "Request %s %s", request->method, request->path); request->state = STATE_VERSION; } else if (request->offset > sizeof(request->path) - 1) { // Skip methods that are too long. @@ -1168,31 +1365,37 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) request->header_value[request->offset - 1] = '\0'; request->offset = 0; request->state = STATE_HEADER_KEY; - if (strcmp(request->header_key, "Authorization") == 0) { + if (strcasecmp(request->header_key, "Authorization") == 0) { const char *prefix = "Basic "; - request->authenticated = memcmp(request->header_value, prefix, strlen(prefix)) == 0 && + request->authenticated = strncmp(request->header_value, prefix, strlen(prefix)) == 0 && strcmp(_api_password, request->header_value + strlen(prefix)) == 0; - } else if (strcmp(request->header_key, "Host") == 0) { - request->redirect = strcmp(request->header_value, "circuitpython.local") == 0; - } else if (strcmp(request->header_key, "Content-Length") == 0) { + } else if (strcasecmp(request->header_key, "Host") == 0) { + // Do a prefix check so that port is ignored. Length must be the same or the + // header ends in :. + const char *cp_local = "circuitpython.local"; + request->redirect = strncmp(request->header_value, cp_local, strlen(cp_local)) == 0 && + (strlen(request->header_value) == strlen(cp_local) || + request->header_value[strlen(cp_local)] == ':'); + } else if (strcasecmp(request->header_key, "Content-Length") == 0) { request->content_length = strtoul(request->header_value, NULL, 10); - } else if (strcmp(request->header_key, "Expect") == 0) { + } else if (strcasecmp(request->header_key, "Expect") == 0) { request->expect = strcmp(request->header_value, "100-continue") == 0; - } else if (strcmp(request->header_key, "Accept") == 0) { - request->json = strcmp(request->header_value, "application/json") == 0; - } else if (strcmp(request->header_key, "Origin") == 0) { + } else if (strcasecmp(request->header_key, "Accept") == 0) { + request->json = strcasecmp(request->header_value, "application/json") == 0; + } else if (strcasecmp(request->header_key, "Origin") == 0) { strcpy(request->origin, request->header_value); - } else if (strcmp(request->header_key, "X-Timestamp") == 0) { + } else if (strcasecmp(request->header_key, "X-Timestamp") == 0) { request->timestamp_ms = strtoull(request->header_value, NULL, 10); - } else if (strcmp(request->header_key, "Upgrade") == 0) { + } else if (strcasecmp(request->header_key, "Upgrade") == 0) { request->websocket = strcmp(request->header_value, "websocket") == 0; - } else if (strcmp(request->header_key, "Sec-WebSocket-Version") == 0) { + } else if (strcasecmp(request->header_key, "Sec-WebSocket-Version") == 0) { request->websocket_version = strtoul(request->header_value, NULL, 10); - } else if (strcmp(request->header_key, "Sec-WebSocket-Key") == 0 && + } else if (strcasecmp(request->header_key, "Sec-WebSocket-Key") == 0 && strlen(request->header_value) == 24) { strcpy(request->websocket_key, request->header_value); + } else if (strcasecmp(request->header_key, "X-Destination") == 0) { + strcpy(request->destination, request->header_value); } - ESP_LOGI(TAG, "Header %s %s", request->header_key, request->header_value); } else if (request->offset > sizeof(request->header_value) - 1) { // Skip methods that are too long. } else { @@ -1209,8 +1412,9 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) } if (error) { const char *error_response = "HTTP/1.1 501 Not Implemented\r\n\r\n"; + int nodelay = 1; - lwip_setsockopt(socket->num, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); + common_hal_socketpool_socket_setsockopt(socket, SOCKETPOOL_IPPROTO_TCP, SOCKETPOOL_TCP_NODELAY, &nodelay, sizeof(nodelay)); socketpool_socket_send(socket, (const uint8_t *)error_response, strlen(error_response)); } if (!request->done) { @@ -1226,39 +1430,43 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) void supervisor_web_workflow_background(void) { - // Otherwise, see if we have another socket to accept. - if ((!common_hal_socketpool_socket_get_connected(&active) || !active_request.in_progress) && - !common_hal_socketpool_socket_get_closed(&listening) && - listening.num > 0) { - uint32_t ip; - uint32_t port; - int newsoc = socketpool_socket_accept(&listening, (uint8_t *)&ip, &port); - if (newsoc == -EBADF) { - common_hal_socketpool_socket_close(&listening); - return; + // Track if we have more to do. For example, we should start processing a + // request immediately after we accept the socket. + bool more_to_do = true; + while (more_to_do) { + more_to_do = false; + // If we have a request in progress, continue working on it. Do this first + // so that we can accept another socket after finishing this request. + if (common_hal_socketpool_socket_get_connected(&active)) { + _process_request(&active, &active_request); + } else { + // Close the active socket if it is no longer connected. + common_hal_socketpool_socket_close(&active); } - if (newsoc > 0) { - // Close the active socket because we have another we accepted. - if (!common_hal_socketpool_socket_get_closed(&active)) { - common_hal_socketpool_socket_close(&active); + + // Otherwise, see if we have another socket to accept. + if ((!common_hal_socketpool_socket_get_connected(&active) || + (!active_request.in_progress && !active_request.new_socket)) && + !common_hal_socketpool_socket_get_closed(&listening)) { + uint32_t ip; + uint32_t port; + int newsoc = socketpool_socket_accept(&listening, (uint8_t *)&ip, &port, &active); + if (newsoc == -EBADF) { + common_hal_socketpool_socket_close(&listening); + return; } - // TODO: Don't do this because it uses the private struct layout. - // Create the socket - active.num = newsoc; - active.pool = &pool; - active.connected = true; + if (newsoc > 0) { + common_hal_socketpool_socket_settimeout(&active, 0); - common_hal_socketpool_socket_settimeout(&active, 0); - - _reset_request(&active_request); - - lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK); + _reset_request(&active_request); + // Mark new sockets, otherwise we may accept another before the first + // could start its request. + active_request.new_socket = true; + more_to_do = true; + } } - } - // If we have a request in progress, continue working on it. - if (common_hal_socketpool_socket_get_connected(&active)) { - _process_request(&active, &active_request); + websocket_background(); } } diff --git a/supervisor/shared/web_workflow/web_workflow.h b/supervisor/shared/web_workflow/web_workflow.h index f233c06e48..a76490aba2 100644 --- a/supervisor/shared/web_workflow/web_workflow.h +++ b/supervisor/shared/web_workflow/web_workflow.h @@ -28,9 +28,19 @@ #include +#include "shared-bindings/mdns/Server.h" +#include "shared-bindings/socketpool/Socket.h" + // This background function should be called repeatedly. It cannot be done based // on events. void supervisor_web_workflow_background(void); +bool supervisor_web_workflow_status_dirty(void); void supervisor_web_workflow_status(void); void supervisor_start_web_workflow(void); void supervisor_stop_web_workflow(void); + +// Share the MDNS object with user code. +mdns_server_obj_t *supervisor_web_workflow_mdns(mp_obj_t network_interface); + +// To share with websocket. +void web_workflow_send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len); diff --git a/supervisor/shared/web_workflow/websocket.c b/supervisor/shared/web_workflow/websocket.c index 313e18a86d..e55e09b3e7 100644 --- a/supervisor/shared/web_workflow/websocket.c +++ b/supervisor/shared/web_workflow/websocket.c @@ -26,8 +26,15 @@ #include "supervisor/shared/web_workflow/websocket.h" -// TODO: Remove ESP specific stuff. For now, it is useful as we refine the server. -#include "esp_log.h" +#include "py/ringbuf.h" +#include "py/runtime.h" +#include "shared/runtime/interrupt_char.h" +#include "shared-bindings/socketpool/SocketPool.h" +#include "supervisor/shared/web_workflow/web_workflow.h" + +#if CIRCUITPY_STATUS_BAR +#include "supervisor/shared/status_bar.h" +#endif typedef struct { socketpool_socket_obj_t socket; @@ -41,51 +48,50 @@ typedef struct { size_t payload_remaining; } _websocket; +// Buffer the incoming serial data in the background so that we can look for the +// interrupt character. +STATIC ringbuf_t _incoming_ringbuf; +STATIC uint8_t _buf[16]; +// make sure background is not called recursively +STATIC bool in_web_background = false; + static _websocket cp_serial; -static const char *TAG = "CP websocket"; - void websocket_init(void) { - cp_serial.socket.num = -1; - cp_serial.socket.connected = false; + socketpool_socket_reset(&cp_serial.socket); + cp_serial.closed = true; + + ringbuf_init(&_incoming_ringbuf, _buf, sizeof(_buf) - 1); } void websocket_handoff(socketpool_socket_obj_t *socket) { - cp_serial.socket = *socket; + if (!cp_serial.closed) { + common_hal_socketpool_socket_close(&cp_serial.socket); + } + socketpool_socket_move(socket, &cp_serial.socket); cp_serial.closed = false; cp_serial.opcode = 0; cp_serial.frame_index = 0; cp_serial.frame_len = 2; - // Mark the original socket object as closed without telling the lower level. - socket->connected = false; - socket->num = -1; + + #if CIRCUITPY_STATUS_BAR + // Send the title bar for the new client. + supervisor_status_bar_request_update(true); + #endif } bool websocket_connected(void) { - return !cp_serial.closed && common_hal_socketpool_socket_get_connected(&cp_serial.socket); + return _incoming_ringbuf.size > 0 && !cp_serial.closed && common_hal_socketpool_socket_get_connected(&cp_serial.socket); } static bool _read_byte(uint8_t *c) { int len = socketpool_socket_recv_into(&cp_serial.socket, c, 1); if (len != 1) { - if (len != -EAGAIN) { - ESP_LOGE(TAG, "recv error %d", len); - } return false; } return true; } -static void _send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) { - int sent = -EAGAIN; - while (sent == -EAGAIN) { - sent = socketpool_socket_send(socket, buf, len); - } - if (sent < len) { - ESP_LOGE(TAG, "short send on %d err %d len %d", socket->num, sent, len); - } -} - static void _read_next_frame_header(void) { uint8_t h; if (cp_serial.frame_index == 0 && _read_byte(&h)) { @@ -94,7 +100,7 @@ static void _read_next_frame_header(void) { } if (cp_serial.frame_index == 1 && _read_byte(&h)) { cp_serial.frame_index++; - uint8_t len = h & 0xf; + uint8_t len = h & 0x7f; cp_serial.masked = (h >> 7) == 1; if (len <= 125) { cp_serial.payload_remaining = len; @@ -136,22 +142,19 @@ static void _read_next_frame_header(void) { // Set the TCP socket to send immediately so that we send the payload back before // closing the connection. int nodelay = 1; - lwip_setsockopt(cp_serial.socket.num, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); + common_hal_socketpool_socket_setsockopt(&cp_serial.socket, SOCKETPOOL_IPPROTO_TCP, SOCKETPOOL_TCP_NODELAY, &nodelay, sizeof(nodelay)); } uint8_t frame_header[2]; frame_header[0] = 1 << 7 | opcode; - if (cp_serial.payload_remaining > 125) { - ESP_LOGE(TAG, "CLOSE or PING has long payload"); - } frame_header[1] = cp_serial.payload_remaining; - _send_raw(&cp_serial.socket, (const uint8_t *)frame_header, 2); + web_workflow_send_raw(&cp_serial.socket, (const uint8_t *)frame_header, 2); } if (cp_serial.payload_remaining > 0 && _read_byte(&h)) { // Send the payload back to the client. cp_serial.frame_index++; cp_serial.payload_remaining--; - _send_raw(&cp_serial.socket, &h, 1); + web_workflow_send_raw(&cp_serial.socket, &h, 1); } if (cp_serial.payload_remaining == 0) { @@ -188,14 +191,16 @@ bool websocket_available(void) { if (!websocket_connected()) { return false; } - _read_next_frame_header(); - return cp_serial.payload_remaining > 0 && cp_serial.frame_index >= cp_serial.frame_len; + websocket_background(); + return ringbuf_num_filled(&_incoming_ringbuf) > 0; } char websocket_read_char(void) { - uint8_t c; - _read_next_payload_byte(&c); - return c; + websocket_background(); + if (ringbuf_num_filled(&_incoming_ringbuf) > 0) { + return ringbuf_get(&_incoming_ringbuf); + } + return -1; } static void _websocket_send(_websocket *ws, const char *text, size_t len) { @@ -214,21 +219,45 @@ static void _websocket_send(_websocket *ws, const char *text, size_t len) { payload_len = 127; } frame_header[1] = payload_len; - _send_raw(&ws->socket, (const uint8_t *)frame_header, 2); + web_workflow_send_raw(&ws->socket, (const uint8_t *)frame_header, 2); + uint8_t extended_len[4]; if (payload_len == 126) { - _send_raw(&ws->socket, (const uint8_t *)&len, 2); + extended_len[0] = (len >> 8) & 0xff; + extended_len[1] = len & 0xff; + web_workflow_send_raw(&ws->socket, extended_len, 2); } else if (payload_len == 127) { uint32_t zero = 0; // 64 bits where top four bytes are zero. - _send_raw(&ws->socket, (const uint8_t *)&zero, 4); - _send_raw(&ws->socket, (const uint8_t *)&len, 4); + web_workflow_send_raw(&ws->socket, (const uint8_t *)&zero, 4); + extended_len[0] = (len >> 24) & 0xff; + extended_len[1] = (len >> 16) & 0xff; + extended_len[2] = (len >> 8) & 0xff; + extended_len[3] = len & 0xff; + web_workflow_send_raw(&ws->socket, extended_len, 4); } - _send_raw(&ws->socket, (const uint8_t *)text, len); - char copy[len]; - memcpy(copy, text, len); - copy[len] = '\0'; + web_workflow_send_raw(&ws->socket, (const uint8_t *)text, len); } void websocket_write(const char *text, size_t len) { _websocket_send(&cp_serial, text, len); } + +void websocket_background(void) { + if (!websocket_connected()) { + return; + } + if (in_web_background) { + return; + } + in_web_background = true; + uint8_t c; + while (ringbuf_num_empty(&_incoming_ringbuf) > 0 && + _read_next_payload_byte(&c)) { + if (c == mp_interrupt_char) { + mp_sched_keyboard_interrupt(); + continue; + } + ringbuf_put(&_incoming_ringbuf, c); + } + in_web_background = false; +} diff --git a/supervisor/shared/web_workflow/websocket.h b/supervisor/shared/web_workflow/websocket.h index c5c5114586..c3db2bf05c 100644 --- a/supervisor/shared/web_workflow/websocket.h +++ b/supervisor/shared/web_workflow/websocket.h @@ -35,4 +35,5 @@ void websocket_handoff(socketpool_socket_obj_t *socket); bool websocket_connected(void); bool websocket_available(void); char websocket_read_char(void); +void websocket_background(void); void websocket_write(const char *text, size_t len); diff --git a/supervisor/shared/workflow.c b/supervisor/shared/workflow.c index 23532181c6..f3bc99cb5e 100644 --- a/supervisor/shared/workflow.c +++ b/supervisor/shared/workflow.c @@ -26,6 +26,8 @@ #include #include "py/mpconfig.h" +#include "py/mpstate.h" +#include "py/stackctrl.h" #include "supervisor/background_callback.h" #include "supervisor/workflow.h" #include "supervisor/serial.h" @@ -46,27 +48,9 @@ #endif static background_callback_t workflow_background_cb; -#if CIRCUITPY_STATUS_BAR -static void supervisor_workflow_update_status_bar(void) { - // Neighboring "" "" are concatenated by the compiler. Without this separation, the hex code - // doesn't get terminated after two following characters and the value is invalid. - // This is the OSC command to set the title and the icon text. It can be up to 255 characters - // but some may be cut off. - serial_write("\x1b" "]0;"); - serial_write("🐍 "); - #if CIRCUITPY_WEB_WORKFLOW - supervisor_web_workflow_status(); - #endif - // Send string terminator - serial_write("\x1b" "\\"); -} -#endif +static bool workflow_started = false; static void workflow_background(void *data) { - #if CIRCUITPY_STATUS_BAR - supervisor_workflow_update_status_bar(); - #endif - #if CIRCUITPY_WEB_WORKFLOW supervisor_web_workflow_background(); #endif @@ -88,6 +72,9 @@ void supervisor_workflow_reset(void) { } void supervisor_workflow_request_background(void) { + if (!workflow_started) { + return; + } background_callback_add_core(&workflow_background_cb); } @@ -134,4 +121,63 @@ void supervisor_workflow_start(void) { #if CIRCUITPY_WEB_WORKFLOW supervisor_start_web_workflow(); #endif + + workflow_started = true; +} + +FRESULT supervisor_workflow_mkdir_parents(FATFS *fs, char *path) { + FRESULT result = FR_OK; + // Make parent directories. + for (size_t j = 1; j < strlen(path); j++) { + if (path[j] == '/') { + path[j] = '\0'; + result = f_mkdir(fs, path); + path[j] = '/'; + if (result != FR_OK && result != FR_EXIST) { + return result; + } + } + } + // Make the target directory. + return f_mkdir(fs, path); +} + +FRESULT supervisor_workflow_delete_directory_contents(FATFS *fs, const TCHAR *path) { + FF_DIR dir; + FILINFO file_info; + // Check the stack since we're putting paths on it. + if (mp_stack_usage() >= MP_STATE_THREAD(stack_limit)) { + return FR_INT_ERR; + } + FRESULT res = FR_OK; + while (res == FR_OK) { + res = f_opendir(fs, &dir, path); + if (res != FR_OK) { + break; + } + res = f_readdir(&dir, &file_info); + // We close and reopen the directory every time since we're deleting + // entries and it may invalidate the directory handle. + f_closedir(&dir); + if (res != FR_OK || file_info.fname[0] == '\0') { + break; + } + size_t pathlen = strlen(path); + size_t fnlen = strlen(file_info.fname); + TCHAR full_path[pathlen + 1 + fnlen]; + memcpy(full_path, path, pathlen); + full_path[pathlen] = '/'; + size_t full_pathlen = pathlen + 1 + fnlen; + memcpy(full_path + pathlen + 1, file_info.fname, fnlen); + full_path[full_pathlen] = '\0'; + if ((file_info.fattrib & AM_DIR) != 0) { + res = supervisor_workflow_delete_directory_contents(fs, full_path); + } + if (res != FR_OK) { + break; + } + res = f_unlink(fs, full_path); + } + f_closedir(&dir); + return res; } diff --git a/supervisor/shared/workflow.h b/supervisor/shared/workflow.h index b3c817fb8b..df483e0ebc 100644 --- a/supervisor/shared/workflow.h +++ b/supervisor/shared/workflow.h @@ -26,4 +26,10 @@ #pragma once +#include "lib/oofatfs/ff.h" + extern bool supervisor_workflow_connecting(void); + +// File system helpers for workflow code. +FRESULT supervisor_workflow_mkdir_parents(FATFS *fs, char *path); +FRESULT supervisor_workflow_delete_directory_contents(FATFS *fs, const TCHAR *path); diff --git a/supervisor/stub/misc.c b/supervisor/stub/misc.c new file mode 100644 index 0000000000..a17188beff --- /dev/null +++ b/supervisor/stub/misc.c @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * SPDX-FileCopyrightText: Copyright (c) 2022 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "stdbool.h" + +#include "supervisor/port.h" +#include "py/mpconfig.h" + + +MP_WEAK void port_post_boot_py(bool heap_valid) { +} diff --git a/supervisor/stub/safe_mode.c b/supervisor/stub/safe_mode.c index b62cc05d78..ea5187da28 100644 --- a/supervisor/stub/safe_mode.c +++ b/supervisor/stub/safe_mode.c @@ -29,7 +29,7 @@ #include safe_mode_t wait_for_safe_mode_reset(void) { - return NO_SAFE_MODE; + return SAFE_MODE_NONE; } void reset_into_safe_mode(safe_mode_t reason) { diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 5b8cb513a7..801025f41a 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -4,19 +4,22 @@ SRC_SUPERVISOR = \ supervisor/shared/background_callback.c \ supervisor/shared/board.c \ supervisor/shared/cpu.c \ + supervisor/shared/fatfs.c \ supervisor/shared/flash.c \ supervisor/shared/lock.c \ supervisor/shared/memory.c \ supervisor/shared/micropython.c \ + supervisor/shared/port.c \ supervisor/shared/reload.c \ supervisor/shared/safe_mode.c \ - supervisor/shared/serial.c \ + supervisor/shared/serial.c \ supervisor/shared/stack.c \ supervisor/shared/status_leds.c \ supervisor/shared/tick.c \ supervisor/shared/traceback.c \ supervisor/shared/translate/translate.c \ - supervisor/shared/workflow.c + supervisor/shared/workflow.c \ + supervisor/stub/misc.c \ NO_USB ?= $(wildcard supervisor/usb.c) @@ -95,6 +98,12 @@ ifneq ($(wildcard supervisor/serial.c),) SRC_SUPERVISOR += supervisor/serial.c endif +ifeq ($(CIRCUITPY_STATUS_BAR),1) + SRC_SUPERVISOR += \ + supervisor/shared/status_bar.c \ + +endif + ifeq ($(CIRCUITPY_USB),1) SRC_SUPERVISOR += \ lib/tinyusb/src/class/cdc/cdc_device.c \ @@ -182,9 +191,8 @@ ifeq ($(CIRCUITPY_DISPLAYIO), 1) SRC_SUPERVISOR += \ supervisor/shared/display.c - ifeq ($(CIRCUITPY_TERMINALIO), 1) - SUPERVISOR_O += $(BUILD)/autogen_display_resources-$(TRANSLATION).o - endif + # Include the display resources because it includes the Blinka logo as well. + SUPERVISOR_O += $(BUILD)/autogen_display_resources-$(TRANSLATION).o endif # Preserve double quotes in these values by single-quoting them. diff --git a/supervisor/usb.h b/supervisor/usb.h index 420f42391b..3c8da6f3b7 100644 --- a/supervisor/usb.h +++ b/supervisor/usb.h @@ -31,6 +31,8 @@ #include #include +#include "supervisor/memory.h" + // Ports must call this as frequently as they can in order to keep the USB // connection alive and responsive. Normally this is called from background // tasks after the USB IRQ handler is executed, but in specific circumstances @@ -58,10 +60,19 @@ typedef struct { size_t num_out_endpoints; } descriptor_counts_t; +typedef struct { + uint16_t vid; + uint16_t pid; + char manufacturer_name[128]; + char product_name[128]; +} usb_identification_t; + +extern supervisor_allocation *usb_identification_allocation; + // Shared implementation. bool usb_enabled(void); void usb_add_interface_string(uint8_t interface_string_index, const char str[]); -void usb_build_descriptors(void); +void usb_build_descriptors(const usb_identification_t *identification); void usb_disconnect(void); void usb_init(void); void usb_set_defaults(void); diff --git a/tests/basics/exception_chain.py b/tests/basics/exception_chain.py index c3a7d6b113..b84ff19dd6 100644 --- a/tests/basics/exception_chain.py +++ b/tests/basics/exception_chain.py @@ -1,6 +1,54 @@ -# Exception chaining is not supported, but check that basic -# exception works as expected. try: - raise Exception from None -except Exception: - print("Caught Exception") + Exception().__cause__ +except AttributeError: + print("SKIP") + raise SystemExit + +def print_exc_info(e): + print("exception", type(e), e.args) + print("context", type(e.__context__), e.__suppress_context__) + print("cause", type(e.__cause__)) + +try: + try: + 1/0 + except Exception as inner: + raise RuntimeError() from inner +except Exception as e: + print_exc_info(e) +print() + +try: + try: + 1/0 + except Exception as inner: + raise RuntimeError() from OSError() +except Exception as e: + print_exc_info(e) +print() + + +try: + try: + 1/0 + except Exception as inner: + raise RuntimeError() +except Exception as e: + print_exc_info(e) +print() + +try: + try: + 1/0 + except Exception as inner: + raise RuntimeError() from None +except Exception as e: + print_exc_info(e) + +try: + try: + raise RuntimeError() + except Exception as inner: + 1/0 +except Exception as e: + print_exc_info(e) diff --git a/tests/basics/exception_chain.py.exp b/tests/basics/exception_chain.py.exp deleted file mode 100644 index 13635b3cde..0000000000 --- a/tests/basics/exception_chain.py.exp +++ /dev/null @@ -1,2 +0,0 @@ -Warning: exception chaining not supported -Caught Exception diff --git a/tests/basics/gen_yield_from_close.py b/tests/basics/gen_yield_from_close.py index e3e0116ff7..08e0d41beb 100644 --- a/tests/basics/gen_yield_from_close.py +++ b/tests/basics/gen_yield_from_close.py @@ -37,8 +37,12 @@ def gen4(): yield -1 try: print((yield from gen3())) - except GeneratorExit: + except GeneratorExit as e: print("delegating caught GeneratorExit") + try: + e.__traceback__ = None + except AttributeError: + pass # generated in micropython, not in python3 raise yield 10 yield 11 @@ -121,3 +125,20 @@ def gen9(): g = gen9() print(next(g)) g.close() + +# Test that, when chaining to a GeneratorExit exception generated internally, +# no exception or crash occurs +def gen10(): + try: + yield 1/0 + except Exception as e: + yield 1 + yield 2 + yield 3 +g = gen10() +print(next(g)) +g.close() +try: + print(next(g)) +except StopIteration: + print("StopIteration") diff --git a/tests/circuitpython/getenv.py b/tests/circuitpython/getenv.py new file mode 100644 index 0000000000..68dd328cfb --- /dev/null +++ b/tests/circuitpython/getenv.py @@ -0,0 +1,89 @@ +import uos + +uos.umount("/") + + +class RAMBlockDevice: + ERASE_BLOCK_SIZE = 512 + + def __init__(self, blocks): + self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE) + + def readblocks(self, block, buf, off=0): + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + buf[i] = self.data[addr + i] + + def writeblocks(self, block, buf, off=None): + if off is None: + # erase, then write + off = 0 + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + self.data[addr + i] = buf[i] + + def ioctl(self, op, arg): + if op == 4: # block count + return len(self.data) // self.ERASE_BLOCK_SIZE + if op == 5: # block size + return self.ERASE_BLOCK_SIZE + if op == 6: # erase block + return 0 + + +bdev = RAMBlockDevice(64) +uos.VfsFat.mkfs(bdev) +uos.mount(uos.VfsFat(bdev), "/") + +content_good = b""" +# comment +key0 = "hello world" +key1 = 7 +key2= "\\n" +key3 ="\\u00c1x" +key4 = "\\U000000c1x" +key5 = "\\f\\"\\\\" +key6 = "\\t\\r\\b" +key7 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +key8 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + key9 = "hello comment" # comment + key10 = 0x7f # comment +key11 = 0 +[section] +subvalue = "hi" +""" + +content_bad = [ + b'key = "\n', + b'key = """\n', + b"key =\n", + b'key="', +] + + +def run_test(key, content): + with open("/settings.toml", "wb") as f: + f.write(content) + + try: + v = uos.getenv(key) + print(key, repr(v)) + except Exception as e: + print(key, str(e)) + + +for i in range(13): + run_test(f"key{i}", content_good) + +content_good = content_good.replace(b"\n", b"\r\n") +for i in range(13): + run_test(f"key{i}", content_good) + +run_test(f"K", b"K = 7\r\n") +print(uos.getenv_int("K")) + +# Test value without trailing newline +run_test(f"noeol", b"noeol=3") + +for content in content_bad: + run_test("key", content) diff --git a/tests/circuitpython/getenv.py.exp b/tests/circuitpython/getenv.py.exp new file mode 100644 index 0000000000..ba1b1b3f90 --- /dev/null +++ b/tests/circuitpython/getenv.py.exp @@ -0,0 +1,33 @@ +key0 'hello world' +key1 7 +key2 '\n' +key3 'Áx' +key4 'Áx' +key5 '\x0c"\\' +key6 '\t\r\x08' +key7 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +key8 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +key9 'hello comment' +key10 127 +key11 0 +key12 None +key0 'hello world' +key1 7 +key2 '\n' +key3 'Áx' +key4 'Áx' +key5 '\x0c"\\' +key6 '\t\r\x08' +key7 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +key8 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +key9 'hello comment' +key10 127 +key11 0 +key12 None +K 7 +7 +noeol 3 +key Invalid byte '\n' +key Invalid byte '"' +key invalid syntax for integer with base 10: '' +key Invalid byte 'EOF' diff --git a/tests/circuitpython/traceback_test.py b/tests/circuitpython/traceback_test.py index 6ae73db6ae..17c54c857a 100644 --- a/tests/circuitpython/traceback_test.py +++ b/tests/circuitpython/traceback_test.py @@ -15,13 +15,13 @@ except Exception as exc: print("\nNo Trace:") traceback.print_exception(None, exc, None) print("\nDefault Trace:") - traceback.print_exception(None, exc, exc.__traceback__) + traceback.print_exception(exc) print("\nLimit=1 Trace:") traceback.print_exception(None, exc, exc.__traceback__, limit=1) print("\nLimit=0 Trace:") traceback.print_exception(None, exc, exc.__traceback__, limit=0) print("\nLimit=-1 Trace:") - traceback.print_exception(None, exc, exc.__traceback__, limit=-1) + print("".join(traceback.format_exception(None, exc, exc.__traceback__, limit=-1)), end="") class NonNativeException(Exception): diff --git a/tests/circuitpython/traceback_test_chained.py b/tests/circuitpython/traceback_test_chained.py new file mode 100644 index 0000000000..dac99e00b4 --- /dev/null +++ b/tests/circuitpython/traceback_test_chained.py @@ -0,0 +1,74 @@ +try: + Exception().__cause__ +except AttributeError: + print("SKIP") + raise SystemExit + +try: + import traceback +except: + print("SKIP") + raise SystemExit + + +def print_exc_info(e, chain=True): + print("-" * 72) + traceback.print_exception(None, e, e.__traceback__, chain=chain) + print("-" * 72) + print() + + +try: + try: + 1 / 0 + except Exception as inner: + raise RuntimeError() from inner +except Exception as e: + print_exc_info(e, chain=False) + print_exc_info(e) +print() + +try: + try: + 1 / 0 + except Exception as inner: + raise RuntimeError() from OSError() +except Exception as e: + print_exc_info(e) +print() + + +try: + try: + 1 / 0 + except Exception as inner: + raise RuntimeError() +except Exception as e: + print_exc_info(e) +print() + +try: + try: + 1 / 0 + except Exception as inner: + raise RuntimeError() from None +except Exception as e: + print_exc_info(e) + +try: + try: + raise RuntimeError() + except Exception as inner: + 1 / 0 +except Exception as e: + print_exc_info(e) + +try: + try: + 1 / 0 + except Exception as inner: + raise inner +except Exception as e: + print_exc_info(e, chain=False) + print_exc_info(e) +print() diff --git a/tests/circuitpython/traceback_test_chained.py.exp b/tests/circuitpython/traceback_test_chained.py.exp new file mode 100644 index 0000000000..a979adc24c --- /dev/null +++ b/tests/circuitpython/traceback_test_chained.py.exp @@ -0,0 +1,76 @@ +------------------------------------------------------------------------ +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 25, in +RuntimeError: +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 23, in +ZeroDivisionError: division by zero + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 25, in +RuntimeError: +------------------------------------------------------------------------ + + +------------------------------------------------------------------------ +OSError: + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 35, in +RuntimeError: +------------------------------------------------------------------------ + + +------------------------------------------------------------------------ +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 43, in +ZeroDivisionError: division by zero + +During handling of the above exception, another exception occurred: + +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 45, in +RuntimeError: +------------------------------------------------------------------------ + + +------------------------------------------------------------------------ +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 54, in +RuntimeError: +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 60, in +RuntimeError: + +During handling of the above exception, another exception occurred: + +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 62, in +ZeroDivisionError: division by zero +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 70, in + File "circuitpython/traceback_test_chained.py", line 68, in +ZeroDivisionError: division by zero +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +Traceback (most recent call last): + File "circuitpython/traceback_test_chained.py", line 70, in + File "circuitpython/traceback_test_chained.py", line 68, in +ZeroDivisionError: division by zero +------------------------------------------------------------------------ + + diff --git a/tests/extmod/framebuf_subclass.py b/tests/extmod/framebuf_subclass.py index a9e3c5efc7..4cd9ea4eb5 100644 --- a/tests/extmod/framebuf_subclass.py +++ b/tests/extmod/framebuf_subclass.py @@ -34,6 +34,7 @@ fb.pixel(2, 2, 0x0708) fb2.blit(fb, 0, 0) print(bytes(fb2)) + # Test that blitting something that isn't a subclass fails with TypeError. class NotAFrameBuf: pass diff --git a/tests/extmod/qrio.py b/tests/extmod/qrio.py index 5e9ed4c12a..53c83706f8 100644 --- a/tests/extmod/qrio.py +++ b/tests/extmod/qrio.py @@ -5,7 +5,7 @@ except: raise SystemExit loc = __file__.rsplit("/", 1)[0] -with open(f"{loc}/data/qr.pgm") as f: +with open(f"{loc}/data/qr.pgm", "rb") as f: content = f.read()[-320 * 240 :] decoder = qrio.QRDecoder(320, 240) diff --git a/tests/extmod/uasyncio_exception.py b/tests/extmod/uasyncio_exception.py index aae55d6320..4e4f978dc2 100644 --- a/tests/extmod/uasyncio_exception.py +++ b/tests/extmod/uasyncio_exception.py @@ -9,6 +9,7 @@ except ImportError: print("SKIP") raise SystemExit + # main task raising an exception async def main(): print("main start") @@ -21,6 +22,7 @@ try: except ValueError as er: print("ValueError", er.args[0]) + # sub-task raising an exception async def task(): print("task start") @@ -40,6 +42,7 @@ try: except ValueError as er: print("ValueError", er.args[0]) + # main task raising an exception with sub-task not yet scheduled # TODO not currently working, task is never scheduled async def task(): diff --git a/tests/extmod/uasyncio_task_exception.py b/tests/extmod/uasyncio_task_exception.py new file mode 100644 index 0000000000..6bf99dc93c --- /dev/null +++ b/tests/extmod/uasyncio_task_exception.py @@ -0,0 +1,42 @@ +# In MicroPython, a non-awaited task with a pending exception will raise to +# the loop's exception handler the second time it is scheduled. This is +# because without reference counting we have no way to know when the task is +# truly "non awaited" -- i.e. we only know that it wasn't awaited in the time +# it took to be re-scheduled. + +# If the task _is_ subsequently awaited, then the await should succeed without +# raising. + +try: + import uasyncio as asyncio +except ImportError: + try: + import asyncio + except ImportError: + print("SKIP") + raise SystemExit + + +def custom_handler(loop, context): + print("exception handler", type(context["exception"]).__name__) + + +async def main(): + loop = asyncio.get_event_loop() + loop.set_exception_handler(custom_handler) + + async def task(): + print("raise") + raise OSError + + print("create") + t = asyncio.create_task(task()) + print("sleep 1") + await asyncio.sleep(0) + print("sleep 2") + await asyncio.sleep(0) + print("await") + await t # should not raise. + + +asyncio.run(main()) diff --git a/tests/extmod/uasyncio_task_exception.py.exp b/tests/extmod/uasyncio_task_exception.py.exp new file mode 100644 index 0000000000..44dae61e1c --- /dev/null +++ b/tests/extmod/uasyncio_task_exception.py.exp @@ -0,0 +1,6 @@ +create +sleep 1 +raise +sleep 2 +exception handler OSError +await diff --git a/tests/extmod/vfs_fat_case.py b/tests/extmod/vfs_fat_case.py new file mode 100644 index 0000000000..40d67da9b8 --- /dev/null +++ b/tests/extmod/vfs_fat_case.py @@ -0,0 +1,81 @@ +try: + import uerrno + import uos +except ImportError: + print("missing u") + print("SKIP") + raise SystemExit + +try: + uos.VfsFat +except AttributeError: + print("missing VfsFat") + print("SKIP") + raise SystemExit + + +class RAMFS: + SEC_SIZE = 512 + + def __init__(self, blocks): + self.data = bytearray(blocks * self.SEC_SIZE) + + def readblocks(self, n, buf): + # print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf))) + for i in range(len(buf)): + buf[i] = self.data[n * self.SEC_SIZE + i] + return 0 + + def writeblocks(self, n, buf): + # print("writeblocks(%s, %x)" % (n, id(buf))) + for i in range(len(buf)): + self.data[n * self.SEC_SIZE + i] = buf[i] + return 0 + + def ioctl(self, op, arg): + # print("ioctl(%d, %r)" % (op, arg)) + if op == 4: # MP_BLOCKDEV_IOCTL_BLOCK_COUNT + return len(self.data) // self.SEC_SIZE + if op == 5: # MP_BLOCKDEV_IOCTL_BLOCK_SIZE + return self.SEC_SIZE + + +try: + bdev = RAMFS(50) +except MemoryError: + print("SKIP") + raise SystemExit + +uos.VfsFat.mkfs(bdev) +vfs = uos.VfsFat(bdev) +uos.mount(vfs, "/ramdisk") +uos.chdir("/ramdisk") + +vfs.label = "labelæ" +# This label would normally be LABELÆ but our limited upper casing does "LABELæ" +print(vfs.label) + +# Check ASCII case-insensitivity +vfs.mkdir("fooaz") +print(uos.listdir("")) +vfs.rmdir("fOOAZ") + +# Check ASCII case-insensitivity for long names (8+ characters) +vfs.mkdir("123456789fooaz") +print(uos.listdir("")) +vfs.rmdir("123456789fOOAZ") + +# Characters outside of a-z are case sensitive. +vfs.mkdir("extended_æ") +print(uos.listdir("")) +# Normally this would work ok. With our limited uppercasing, it won't. +try: + vfs.rmdir("extended_Æ") +except OSError as e: + print(e.errno == uerrno.ENOENT) + +vfs.rmdir("extended_æ") + +# Emoji test for fun. +vfs.mkdir("emoji_😀") +vfs.rmdir("emoji_😀") diff --git a/tests/extmod/vfs_fat_case.py.exp b/tests/extmod/vfs_fat_case.py.exp new file mode 100644 index 0000000000..64b5e7b27a --- /dev/null +++ b/tests/extmod/vfs_fat_case.py.exp @@ -0,0 +1,5 @@ +LABELæ +['fooaz'] +['123456789fooaz'] +['extended_æ'] +True diff --git a/tests/extmod/vfs_fat_fileio1.py b/tests/extmod/vfs_fat_fileio1.py index 10e92d6940..935f01d24f 100644 --- a/tests/extmod/vfs_fat_fileio1.py +++ b/tests/extmod/vfs_fat_fileio1.py @@ -13,7 +13,6 @@ except AttributeError: class RAMFS: - SEC_SIZE = 512 def __init__(self, blocks): diff --git a/tests/extmod/vfs_fat_fileio2.py b/tests/extmod/vfs_fat_fileio2.py index 297d75a481..6094b5a6f1 100644 --- a/tests/extmod/vfs_fat_fileio2.py +++ b/tests/extmod/vfs_fat_fileio2.py @@ -13,7 +13,6 @@ except AttributeError: class RAMFS: - SEC_SIZE = 512 def __init__(self, blocks): @@ -70,6 +69,11 @@ try: except OSError as e: print(e.errno == uerrno.ENOENT) +try: + vfs.rename("foo_dir", "foo_dir/inside_itself") +except OSError as e: + print(e.errno == uerrno.EINVAL) + # file in dir with open("foo_dir/file-in-dir.txt", "w+t") as f: f.write("data in file") diff --git a/tests/extmod/vfs_fat_fileio2.py.exp b/tests/extmod/vfs_fat_fileio2.py.exp index 2684053641..ed6e315328 100644 --- a/tests/extmod/vfs_fat_fileio2.py.exp +++ b/tests/extmod/vfs_fat_fileio2.py.exp @@ -1,6 +1,7 @@ True True True +True b'data in file' True [('sub_file.txt', 32768, 0, 11), ('file.txt', 32768, 0, 12)] diff --git a/tests/extmod/vfs_fat_more.py b/tests/extmod/vfs_fat_more.py index 1b7b04ee63..f5de729402 100644 --- a/tests/extmod/vfs_fat_more.py +++ b/tests/extmod/vfs_fat_more.py @@ -12,7 +12,6 @@ except AttributeError: class RAMFS: - SEC_SIZE = 512 def __init__(self, blocks): diff --git a/tests/extmod/vfs_fat_oldproto.py b/tests/extmod/vfs_fat_oldproto.py index e447ff4eb3..1998319dbe 100644 --- a/tests/extmod/vfs_fat_oldproto.py +++ b/tests/extmod/vfs_fat_oldproto.py @@ -13,7 +13,6 @@ except AttributeError: class RAMFS_OLD: - SEC_SIZE = 512 def __init__(self, blocks): diff --git a/tests/extmod/vfs_fat_ramdisk.py b/tests/extmod/vfs_fat_ramdisk.py index 4b79391102..a22d480dfd 100644 --- a/tests/extmod/vfs_fat_ramdisk.py +++ b/tests/extmod/vfs_fat_ramdisk.py @@ -13,7 +13,6 @@ except AttributeError: class RAMFS: - SEC_SIZE = 512 def __init__(self, blocks): diff --git a/tests/extmod/vfs_fat_ramdisklarge.py b/tests/extmod/vfs_fat_ramdisklarge.py index 69d4a8cbbd..649a53db14 100644 --- a/tests/extmod/vfs_fat_ramdisklarge.py +++ b/tests/extmod/vfs_fat_ramdisklarge.py @@ -14,7 +14,6 @@ except AttributeError: class RAMBDevSparse: - SEC_SIZE = 512 def __init__(self, blocks): diff --git a/tests/float/float_format_ftoe.py b/tests/float/float_format_ftoe.py new file mode 100644 index 0000000000..bc4e5a4a53 --- /dev/null +++ b/tests/float/float_format_ftoe.py @@ -0,0 +1,4 @@ +# check a case where rounding was suppressed inappropriately when "f" was +# promoted to "e" for large numbers. +v = 8.888e32 +print("%.2f" % v) # '%.2f' format with e32 becomes '%.2e', expect 8.89e+32. diff --git a/tests/float/float_format_ftoe.py.exp b/tests/float/float_format_ftoe.py.exp new file mode 100644 index 0000000000..f8b1deb3ec --- /dev/null +++ b/tests/float/float_format_ftoe.py.exp @@ -0,0 +1 @@ +8.89e+32 diff --git a/tests/float/float_format_ints.py b/tests/float/float_format_ints.py new file mode 100644 index 0000000000..0bf4baf12d --- /dev/null +++ b/tests/float/float_format_ints.py @@ -0,0 +1,31 @@ +# Test that integers format to exact values. + +for b in [13, 123, 457, 23456]: + for r in range(1, 10): + e_fmt = "{:." + str(r) + "e}" + f_fmt = "{:." + str(r) + "f}" + g_fmt = "{:." + str(r) + "g}" + for e in range(0, 5): + f = b * (10**e) + title = str(b) + " x 10^" + str(e) + print(title, "with format", e_fmt, "gives", e_fmt.format(f)) + print(title, "with format", f_fmt, "gives", f_fmt.format(f)) + print(title, "with format", g_fmt, "gives", g_fmt.format(f)) + +# Check that powers of 10 (that fit in float32) format correctly. +for i in range(31): + # It works to 12 digits on all platforms *except* qemu-arm, where + # 10^11 comes out as 10000000820 or something. + print("{:.7g}".format(float("1e" + str(i)))) + +# 16777215 is 2^24 - 1, the largest integer that can be completely held +# in a float32. +print("{:f}".format(16777215)) +# 4294967040 = 16777215 * 128 is the largest integer that is exactly +# represented by a float32 and that will also fit within a (signed) int32. +# The upper bound of our integer-handling code is actually double this, +# but that constant might cause trouble on systems using 32 bit ints. +print("{:f}".format(2147483520)) +# Very large positive integers can be a test for precision and resolution. +# This is a weird way to represent 1e38 (largest power of 10 for float32). +print("{:.6e}".format(float("9" * 30 + "e8"))) diff --git a/tests/float/float_format_ints_doubleprec.py b/tests/float/float_format_ints_doubleprec.py new file mode 100644 index 0000000000..57899d6d65 --- /dev/null +++ b/tests/float/float_format_ints_doubleprec.py @@ -0,0 +1,15 @@ +# Test formatting of very large ints. +# Relies on double-precision floats. + +import array +import sys + +# Challenging way to express 1e200 and 1e100. +print("{:.12e}".format(float("9" * 400 + "e-200"))) +print("{:.12e}".format(float("9" * 400 + "e-300"))) + +# These correspond to the binary representation of 1e200 in float64s: +v1 = 0x54B249AD2594C37D # 1e100 +v2 = 0x6974E718D7D7625A # 1e200 +print("{:.12e}".format(array.array("d", v1.to_bytes(8, sys.byteorder))[0])) +print("{:.12e}".format(array.array("d", v2.to_bytes(8, sys.byteorder))[0])) diff --git a/tests/import/module_getattr.py b/tests/import/module_getattr.py index df7a621815..9ca0d18455 100644 --- a/tests/import/module_getattr.py +++ b/tests/import/module_getattr.py @@ -8,6 +8,7 @@ try: except AttributeError: pass + # define __getattr__ def __getattr__(attr): if attr == "does_not_exist": diff --git a/tests/inlineasm/asmsum.py b/tests/inlineasm/asmsum.py index 6535a495d4..208709a25f 100644 --- a/tests/inlineasm/asmsum.py +++ b/tests/inlineasm/asmsum.py @@ -1,6 +1,5 @@ @micropython.asm_thumb def asm_sum_words(r0, r1): - # r0 = len # r1 = ptr # r2 = sum @@ -25,7 +24,6 @@ def asm_sum_words(r0, r1): @micropython.asm_thumb def asm_sum_bytes(r0, r1): - # r0 = len # r1 = ptr # r2 = sum diff --git a/tests/micropython/const2.py b/tests/micropython/const2.py index ed4720122e..d8b68c25f3 100644 --- a/tests/micropython/const2.py +++ b/tests/micropython/const2.py @@ -11,6 +11,7 @@ import micropython as X print(globals()["X"]) + # function name that matches a constant def X(): print("function X", X) @@ -18,6 +19,7 @@ def X(): globals()["X"]() + # arguments that match a constant def f(X, *Y, **Z): pass @@ -25,6 +27,7 @@ def f(X, *Y, **Z): f(1) + # class name that matches a constant class X: def f(self): @@ -33,6 +36,7 @@ class X: globals()["X"]().f() + # constant within a class class A: C1 = const(4) diff --git a/tests/micropython/heapalloc_yield_from.py b/tests/micropython/heapalloc_yield_from.py index 58788b1dbc..9507171890 100644 --- a/tests/micropython/heapalloc_yield_from.py +++ b/tests/micropython/heapalloc_yield_from.py @@ -2,6 +2,7 @@ import micropython + # Yielding from a function generator def sub_gen(a): for i in range(a): @@ -18,6 +19,7 @@ print(next(g)) print(next(g)) micropython.heap_unlock() + # Yielding from a user iterator class G: def __init__(self): diff --git a/tests/micropython/import_mpy_invalid.py.exp b/tests/micropython/import_mpy_invalid.py.exp index ebf72c293c..432287028e 100644 --- a/tests/micropython/import_mpy_invalid.py.exp +++ b/tests/micropython/import_mpy_invalid.py.exp @@ -1,4 +1,4 @@ mod0 RuntimeError Corrupt .mpy file mod1 RuntimeError Corrupt .mpy file -mod2 MpyError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. -mod3 MpyError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. +mod2 ValueError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. +mod3 ValueError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. diff --git a/tests/micropython/native_closure.py b/tests/micropython/native_closure.py index 07014e90da..8182cfea70 100644 --- a/tests/micropython/native_closure.py +++ b/tests/micropython/native_closure.py @@ -1,5 +1,6 @@ # test native emitter can handle closures correctly + # basic closure @micropython.native def f(): @@ -15,6 +16,7 @@ def f(): print(f()()) + # closing over an argument @micropython.native def f(x): @@ -28,6 +30,7 @@ def f(x): print(f(2)()) + # closing over an argument and a normal local @micropython.native def f(x): diff --git a/tests/micropython/native_gen.py b/tests/micropython/native_gen.py index fb42f9e25e..7ea45b1497 100644 --- a/tests/micropython/native_gen.py +++ b/tests/micropython/native_gen.py @@ -1,5 +1,6 @@ # test for native generators + # simple generator with yield and return @micropython.native def gen1(x): @@ -16,6 +17,7 @@ try: except StopIteration as e: print(e.args[0]) + # using yield from @micropython.native def gen2(x): diff --git a/tests/micropython/native_misc.py b/tests/micropython/native_misc.py index f5ef807fe1..f40fcb2407 100644 --- a/tests/micropython/native_misc.py +++ b/tests/micropython/native_misc.py @@ -1,5 +1,6 @@ # tests for natively compiled functions + # basic test @micropython.native def native_test(x): @@ -14,6 +15,7 @@ import gc gc.collect() native_test(3) + # native with 2 args @micropython.native def f(a, b): @@ -22,6 +24,7 @@ def f(a, b): f(1, 2) + # native with 3 args @micropython.native def f(a, b, c): @@ -30,6 +33,7 @@ def f(a, b, c): f(1, 2, 3) + # check not operator @micropython.native def f(a): diff --git a/tests/micropython/native_try.py b/tests/micropython/native_try.py index 492b59085c..6a2152b28c 100644 --- a/tests/micropython/native_try.py +++ b/tests/micropython/native_try.py @@ -1,5 +1,6 @@ # test native try handling + # basic try-finally @micropython.native def f(): @@ -14,6 +15,7 @@ try: except NameError: print("NameError") + # nested try-except with try-finally @micropython.native def f(): @@ -28,6 +30,7 @@ def f(): f() + # check that locals written to in try blocks keep their values @micropython.native def f(): diff --git a/tests/micropython/native_try_deep.py b/tests/micropython/native_try_deep.py index 3d31248df0..26b9243e03 100644 --- a/tests/micropython/native_try_deep.py +++ b/tests/micropython/native_try_deep.py @@ -1,5 +1,6 @@ # test native try handling + # deeply nested try (9 deep) @micropython.native def f(): diff --git a/tests/micropython/native_with.py b/tests/micropython/native_with.py index 4e20b23856..9c0b98af90 100644 --- a/tests/micropython/native_with.py +++ b/tests/micropython/native_with.py @@ -21,6 +21,7 @@ def f(): f() + # nested with and try-except @micropython.native def f(): diff --git a/tests/micropython/viper_args.py b/tests/micropython/viper_args.py index 8e3225331a..27c73fa795 100644 --- a/tests/micropython/viper_args.py +++ b/tests/micropython/viper_args.py @@ -56,6 +56,7 @@ def f6(x1: int, x2: int, x3: int, x4: int, x5: int, x6: int): f6(1, 2, 3, 4, 5, 6) + # test compiling *x, **x, * args (currently unsupported at runtime) @micropython.viper def f(*x, **y): diff --git a/tests/micropython/viper_cond.py b/tests/micropython/viper_cond.py index d5ebf837bd..752261ff50 100644 --- a/tests/micropython/viper_cond.py +++ b/tests/micropython/viper_cond.py @@ -10,6 +10,7 @@ def f(): f() + # using True as a conditional @micropython.viper def f(): @@ -20,6 +21,7 @@ def f(): f() + # using an int as a conditional @micropython.viper def g(): @@ -30,6 +32,7 @@ def g(): g() + # using an int as a conditional that has the lower 16-bits clear @micropython.viper def h(): diff --git a/tests/micropython/viper_misc.py b/tests/micropython/viper_misc.py index 41389c751d..f9267f65ca 100644 --- a/tests/micropython/viper_misc.py +++ b/tests/micropython/viper_misc.py @@ -1,5 +1,6 @@ import micropython + # viper function taking and returning ints @micropython.viper def viper_int(x: int, y: int) -> int: @@ -8,6 +9,7 @@ def viper_int(x: int, y: int) -> int: print(viper_int(1, 2)) + # viper function taking and returning objects @micropython.viper def viper_object(x: object, y: object) -> object: @@ -16,6 +18,7 @@ def viper_object(x: object, y: object) -> object: print(viper_object(1, 2)) + # return None as non-object (should return 0) @micropython.viper def viper_ret_none() -> int: @@ -24,6 +27,7 @@ def viper_ret_none() -> int: print(viper_ret_none()) + # return Ellipsis as object @micropython.viper def viper_ret_ellipsis() -> object: @@ -32,6 +36,7 @@ def viper_ret_ellipsis() -> object: print(viper_ret_ellipsis()) + # 3 args @micropython.viper def viper_3args(a: int, b: int, c: int) -> int: @@ -40,6 +45,7 @@ def viper_3args(a: int, b: int, c: int) -> int: print(viper_3args(1, 2, 3)) + # 4 args @micropython.viper def viper_4args(a: int, b: int, c: int, d: int) -> int: @@ -49,6 +55,7 @@ def viper_4args(a: int, b: int, c: int, d: int) -> int: # viper call with 4 args not yet supported # print(viper_4args(1, 2, 3, 4)) + # a local (should have automatic type int) @micropython.viper def viper_local(x: int) -> int: @@ -58,6 +65,7 @@ def viper_local(x: int) -> int: print(viper_local(3)) + # without type annotation, types should default to object @micropython.viper def viper_no_annotation(x, y): @@ -66,6 +74,7 @@ def viper_no_annotation(x, y): print(viper_no_annotation(4, 5)) + # a for loop @micropython.viper def viper_for(a: int, b: int) -> int: @@ -77,6 +86,7 @@ def viper_for(a: int, b: int) -> int: print(viper_for(10, 10000)) + # accessing a global @micropython.viper def viper_access_global(): @@ -87,6 +97,7 @@ def viper_access_global(): print(viper_access_global(), gl) + # calling print with object and int types @micropython.viper def viper_print(x, y: int): @@ -95,6 +106,7 @@ def viper_print(x, y: int): viper_print(1, 2) + # convert constants to objects in tuple @micropython.viper def viper_tuple_consts(x): @@ -103,6 +115,7 @@ def viper_tuple_consts(x): print(viper_tuple_consts(0)) + # making a tuple from an object and an int @micropython.viper def viper_tuple(x, y: int): @@ -111,6 +124,7 @@ def viper_tuple(x, y: int): print(viper_tuple(1, 2)) + # making a list from an object and an int @micropython.viper def viper_list(x, y: int): @@ -119,6 +133,7 @@ def viper_list(x, y: int): print(viper_list(1, 2)) + # making a set from an object and an int @micropython.viper def viper_set(x, y: int): @@ -127,6 +142,7 @@ def viper_set(x, y: int): print(sorted(list(viper_set(1, 2)))) + # raising an exception @micropython.viper def viper_raise(x: int): @@ -138,6 +154,7 @@ try: except OSError as e: print(repr(e)) + # calling GC after defining the function @micropython.viper def viper_gc() -> int: diff --git a/tests/micropython/viper_misc2.py b/tests/micropython/viper_misc2.py index 8f0be487d6..cc77134bd4 100644 --- a/tests/micropython/viper_misc2.py +++ b/tests/micropython/viper_misc2.py @@ -1,5 +1,6 @@ # Miscellaneous viper tests + # Test correct use of registers in load and store @micropython.viper def expand(dest: ptr8, source: ptr8, length: int): diff --git a/tests/micropython/viper_misc_intbig.py b/tests/micropython/viper_misc_intbig.py index 055c08d8e5..91673f2c10 100644 --- a/tests/micropython/viper_misc_intbig.py +++ b/tests/micropython/viper_misc_intbig.py @@ -1,5 +1,6 @@ import micropython + # unsigned ints @micropython.viper def viper_uint() -> uint: diff --git a/tests/micropython/viper_try.py b/tests/micropython/viper_try.py index 61335af221..f5822a6682 100644 --- a/tests/micropython/viper_try.py +++ b/tests/micropython/viper_try.py @@ -1,5 +1,6 @@ # test try handling within a viper function + # basic try-finally @micropython.viper def f(): @@ -14,6 +15,7 @@ try: except NameError: print("NameError") + # nested try-except with try-finally @micropython.viper def f(): @@ -28,6 +30,7 @@ def f(): f() + # check that locals written to in try blocks keep their values @micropython.viper def f(): diff --git a/tests/micropython/viper_types.py b/tests/micropython/viper_types.py index 3af148171e..3e0a4f6640 100644 --- a/tests/micropython/viper_types.py +++ b/tests/micropython/viper_types.py @@ -2,6 +2,7 @@ import micropython + # converting incoming arg to bool @micropython.viper def f1(x: bool): @@ -13,6 +14,7 @@ f1(1) f1([]) f1([1]) + # taking and returning a bool @micropython.viper def f2(x: bool) -> bool: @@ -22,6 +24,7 @@ def f2(x: bool) -> bool: print(f2([])) print(f2([1])) + # converting to bool within function @micropython.viper def f3(x) -> bool: diff --git a/tests/micropython/viper_with.py b/tests/micropython/viper_with.py index d640c8ae0f..40fbf6fb31 100644 --- a/tests/micropython/viper_with.py +++ b/tests/micropython/viper_with.py @@ -21,6 +21,7 @@ def f(): f() + # nested with and try-except @micropython.viper def f(): diff --git a/tests/misc/non_compliant.py b/tests/misc/non_compliant.py index cff1894106..1c3706ec33 100644 --- a/tests/misc/non_compliant.py +++ b/tests/misc/non_compliant.py @@ -111,6 +111,7 @@ try: except NotImplementedError: print("NotImplementedError") + # can't assign attributes to a function def f(): pass @@ -127,6 +128,7 @@ try: except TypeError: print("TypeError") + # test when object explicitly listed at not-last position in parent tuple # this is not compliant with CPython because of illegal MRO class A: @@ -140,6 +142,7 @@ class B(object, A): B().foo() + # can't assign property (or other special accessors) to already-subclassed class class A: pass diff --git a/tests/misc/sys_settrace_generator.py b/tests/misc/sys_settrace_generator.py index 43065df4ae..1199f1f4eb 100644 --- a/tests/misc/sys_settrace_generator.py +++ b/tests/misc/sys_settrace_generator.py @@ -48,11 +48,9 @@ def test_generator(): gen = make_gen() r = 0 try: - r += gen.send(None) while True: - r += gen.send(None) except StopIteration as e: diff --git a/tests/misc/sys_settrace_subdir/sys_settrace_generic.py b/tests/misc/sys_settrace_subdir/sys_settrace_generic.py index a60ca955d7..fcf034af25 100644 --- a/tests/misc/sys_settrace_subdir/sys_settrace_generic.py +++ b/tests/misc/sys_settrace_subdir/sys_settrace_generic.py @@ -1,5 +1,6 @@ print("Now comes the language constructions tests.") + # function def test_func(): def test_sub_func(): diff --git a/tests/perf_bench/bm_nqueens.py b/tests/perf_bench/bm_nqueens.py index 773dd3f7ed..160f1178aa 100644 --- a/tests/perf_bench/bm_nqueens.py +++ b/tests/perf_bench/bm_nqueens.py @@ -5,6 +5,7 @@ # author: collinwinter@google.com (Collin Winter) # n_queens function: Copyright 2009 Raymond Hettinger + # Pure-Python implementation of itertools.permutations(). def permutations(iterable, r=None): """permutations(range(3), 2) --> (0,1) (0,2) (1,0) (1,2) (2,0) (2,1)""" diff --git a/tests/perf_bench/misc_aes.py b/tests/perf_bench/misc_aes.py index 0743737cb7..8a9c58bb38 100644 --- a/tests/perf_bench/misc_aes.py +++ b/tests/perf_bench/misc_aes.py @@ -33,6 +33,7 @@ aes_s_box_table = bytes(( )) # fmt: on + # multiplication of polynomials modulo x^8 + x^4 + x^3 + x + 1 = 0x11b def aes_gf8_mul_2(x): if x & 0x80: @@ -64,6 +65,7 @@ def aes_r_con(a): ################################################################## # basic AES algorithm; see FIPS-197 + # all inputs must be size 16 def aes_add_round_key(state, w): for i in range(16): diff --git a/tests/run-internalbench.py b/tests/run-internalbench.py index 606fc3b772..24f6d5a771 100755 --- a/tests/run-internalbench.py +++ b/tests/run-internalbench.py @@ -26,7 +26,6 @@ def run_tests(pyb, test_dict): for base_test, tests in sorted(test_dict.items()): print(base_test + ":") for test_file in tests: - # run MicroPython if pyb is None: # run on PC diff --git a/tests/run-tests.py b/tests/run-tests.py index a6d08aabb3..7a7b3adbcb 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -183,7 +183,17 @@ def run_micropython(pyb, args, test_file, is_special=False): # run the actual test try: - output_mupy = subprocess.check_output(cmdlist, stderr=subprocess.STDOUT) + result = subprocess.run( + cmdlist, + stderr=subprocess.STDOUT, + stdout=subprocess.PIPE, + check=True, + timeout=10, + ) + output_mupy = result.stdout + except subprocess.TimeoutExpired as er: + had_crash = True + output_mupy = (er.output or b"") + b"TIMEOUT" except subprocess.CalledProcessError as er: had_crash = True output_mupy = er.output + b"CRASH" @@ -426,6 +436,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): if upy_float_precision < 64: skip_tests.add("float/float_divmod.py") # tested by float/float_divmod_relaxed.py instead skip_tests.add("float/float2int_doubleprec_intbig.py") + skip_tests.add("float/float_format_ints_doubleprec.py") skip_tests.add("float/float_parse_doubleprec.py") if not has_complex: @@ -511,8 +522,12 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): skip_tests.add("basics/scope_implicit.py") # requires checking for unbound local skip_tests.add("basics/try_finally_return2.py") # requires raise_varargs skip_tests.add("basics/unboundlocal.py") # requires checking for unbound local - skip_tests.add( - "circuitpython/traceback_test.py" + skip_tests.update( + ( + "basics/chained_exception.py", + "circuitpython/traceback_test.py", + "circuitpython/traceback_test_chained.py", + ) ) # because native doesn't have proper traceback info skip_tests.add("extmod/uasyncio_event.py") # unknown issue skip_tests.add("extmod/uasyncio_lock.py") # requires async with @@ -868,9 +883,15 @@ the last matching regex is used: tests = args.files if not args.keep_path: - # clear search path to make sure tests use only builtin modules and those in extmod - os.environ["MICROPYPATH"] = os.pathsep + ".frozen" + os.pathsep + base_path("../extmod") - + # clear search path to make sure tests use only builtin modules and those that can be frozen + os.environ["MICROPYPATH"] = os.pathsep.join( + [ + "", + ".frozen", + base_path("../frozen/Adafruit_CircuitPython_asyncio"), + base_path("../frozen/Adafruit_CircuitPython_Ticks"), + ] + ) try: os.makedirs(args.result_dir, exist_ok=True) res = run_tests(pyb, tests, args, args.result_dir, args.jobs) diff --git a/tests/stress/qstr_limit.py b/tests/stress/qstr_limit.py index d8ce0cf7cd..08b10a039f 100644 --- a/tests/stress/qstr_limit.py +++ b/tests/stress/qstr_limit.py @@ -17,6 +17,7 @@ for l in range(254, 259): continue print(var in g) + # calling a function with kwarg def f(**k): print(k) @@ -36,6 +37,7 @@ for l in range(254, 259): except RuntimeError: print("RuntimeError", l) + # hasattr, setattr, getattr class A: pass diff --git a/tests/stress/recursive_gen.py b/tests/stress/recursive_gen.py index 8c21397658..e051abb84d 100644 --- a/tests/stress/recursive_gen.py +++ b/tests/stress/recursive_gen.py @@ -1,5 +1,6 @@ # test deeply recursive generators + # simple "yield from" recursion def gen(): yield from gen() @@ -10,6 +11,7 @@ try: except RuntimeError: print("RuntimeError") + # recursion via an iterator over a generator def gen2(): for x in gen2(): diff --git a/tests/thread/mutate_bytearray.py b/tests/thread/mutate_bytearray.py index 9b52e0c016..7bacabec3a 100644 --- a/tests/thread/mutate_bytearray.py +++ b/tests/thread/mutate_bytearray.py @@ -9,6 +9,7 @@ import _thread # the shared bytearray ba = bytearray() + # main thread function def th(n, lo, hi): for repeat in range(n): diff --git a/tests/thread/mutate_dict.py b/tests/thread/mutate_dict.py index 0840dcafba..fb87190e77 100644 --- a/tests/thread/mutate_dict.py +++ b/tests/thread/mutate_dict.py @@ -9,6 +9,7 @@ import _thread # the shared dict di = {"a": "A", "b": "B", "c": "C", "d": "D"} + # main thread function def th(n, lo, hi): for repeat in range(n): diff --git a/tests/thread/mutate_instance.py b/tests/thread/mutate_instance.py index 8ba91cbde3..cc0ad9885d 100644 --- a/tests/thread/mutate_instance.py +++ b/tests/thread/mutate_instance.py @@ -6,6 +6,7 @@ import _thread + # the shared user class and instance class User: def __init__(self): @@ -16,6 +17,7 @@ class User: user = User() + # main thread function def th(n, lo, hi): for repeat in range(n): diff --git a/tests/thread/mutate_list.py b/tests/thread/mutate_list.py index 8ce15c0852..4df86b3008 100644 --- a/tests/thread/mutate_list.py +++ b/tests/thread/mutate_list.py @@ -9,6 +9,7 @@ import _thread # the shared list li = list() + # main thread function def th(n, lo, hi): for repeat in range(n): diff --git a/tests/thread/mutate_set.py b/tests/thread/mutate_set.py index 61169b8aa9..587a3a259a 100644 --- a/tests/thread/mutate_set.py +++ b/tests/thread/mutate_set.py @@ -9,6 +9,7 @@ import _thread # the shared set se = set([-1, -2, -3, -4]) + # main thread function def th(n, lo, hi): for repeat in range(n): diff --git a/tests/thread/stress_aes.py b/tests/thread/stress_aes.py index 673337563d..199fe3c88c 100644 --- a/tests/thread/stress_aes.py +++ b/tests/thread/stress_aes.py @@ -40,6 +40,7 @@ aes_s_box_table = bytes(( )) # fmt: on + # multiplication of polynomials modulo x^8 + x^4 + x^3 + x + 1 = 0x11b def aes_gf8_mul_2(x): if x & 0x80: @@ -82,6 +83,7 @@ def aes_r_con(a): # using OCB, where the sequence is xored against the plaintext. # Care must be taken to (almost) always choose a different IV. + # all inputs must be size 16 def aes_add_round_key(state, w): for i in range(16): diff --git a/tests/thread/thread_qstr1.py b/tests/thread/thread_qstr1.py index 2099f94bdb..9e7d7f0326 100644 --- a/tests/thread/thread_qstr1.py +++ b/tests/thread/thread_qstr1.py @@ -10,6 +10,7 @@ except ImportError: import time import _thread + # function to check the interned string def check(s, val): assert type(s) == str diff --git a/tests/unicode/unicode_id.py b/tests/unicode/unicode_id.py index 3a58e3f72b..32817287e9 100644 --- a/tests/unicode/unicode_id.py +++ b/tests/unicode/unicode_id.py @@ -10,6 +10,7 @@ bβ = 3 βb = 4 print(α, αβγ, bβ, βb) + # function, argument, local identifiers def α(β, γ): δ = β + γ @@ -18,6 +19,7 @@ def α(β, γ): α(1, 2) + # class, method identifiers class φ: def __init__(self): diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 582d90e1bc..65f67f0727 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -33,17 +33,17 @@ builtins micropython _asyncio _thread _uasyncio aesio array binascii bitmaptools btree cexample cmath collections cppexample displayio errno -ffi framebuf gc gifio -hashlib json math qrio -rainbowio re sys termios -traceback ubinascii uctypes uerrno -uheapq uio ujson ulab -ulab.numpy ulab.numpy.fft ulab.numpy.linalg -ulab.scipy ulab.scipy.linalg -ulab.scipy.optimize ulab.scipy.signal -ulab.scipy.special ulab.utils uos -urandom ure uselect ustruct -utime utimeq uzlib zlib +ffi framebuf gc hashlib +json math qrio rainbowio +re sys termios traceback +ubinascii uctypes uerrno uheapq +uio ujson ulab ulab.numpy +ulab.numpy.fft ulab.numpy.linalg ulab.scipy +ulab.scipy.linalg ulab.scipy.optimize +ulab.scipy.signal ulab.scipy.special +ulab.utils uos urandom ure +uselect ustruct utime utimeq +uzlib zlib ime utime utimeq diff --git a/tools/black_bindings.py b/tools/black_bindings.py new file mode 100755 index 0000000000..1c6fa3cfe8 --- /dev/null +++ b/tools/black_bindings.py @@ -0,0 +1,129 @@ +#!/usr/bin/python3 +import os +import re +import subprocess +import sys +from concurrent.futures import ThreadPoolExecutor +from dataclasses import dataclass +from enum import Enum, auto + +MARK_C_IN_PY = "##| " +MARK_PY_IN_C = "//| " + + +class Mode(Enum): + C = auto() + PY = auto() + + +@dataclass(frozen=True) +class LineWithMode: + data: str + mode: Mode + + +class OutputWriter: + def __init__(self): + self.content = [] + + def write(self, line): + self.content.append(line.rstrip()) + + def getcontent(self): + return "\n".join(self.content) + + +class PythonOutputWriter(OutputWriter): + def write(self, line): + if isinstance(line, str): + super().write(line) + elif line.mode == Mode.PY: + super().write(line.data) + else: # line mode is C + super().write(MARK_C_IN_PY + line.data) + + +class COutputWriter(OutputWriter): + def write(self, line): + if isinstance(line, str): + super().write(line) + elif line.mode == Mode.PY: + super().write(MARK_PY_IN_C + line.data) + else: # line mode is C + super().write(line.data) + + +def parse_line(line, defmode, mark, smark, markmode): + sline = line.strip() + if sline == smark or sline.startswith(mark): + return LineWithMode(sline[len(mark) :], markmode) + else: + return LineWithMode(line, defmode) + + +def parse_lines(lines, defmode, mark, markmode): + smark = mark.strip() + return [parse_line(line, defmode, mark, smark, markmode) for line in lines] + + +def swap_comment_markers(content, input_mode): + lines = content.rstrip().split("\n") + + if input_mode == Mode.C: + parsed = parse_lines(lines, Mode.C, MARK_PY_IN_C, Mode.PY) + writer = PythonOutputWriter() + else: + parsed = parse_lines(lines, Mode.PY, MARK_C_IN_PY, Mode.C) + writer = COutputWriter() + + for line in parsed: + writer.write(line) + + newcontent = writer.getcontent() + "\n" + + return newcontent + + +def process_one_file(fn): + with open(fn, "r", encoding="utf-8") as f: + c_content = f.read() + + if not "\n//| " in c_content: + return + + py_content = swap_comment_markers(c_content, Mode.C) + + try: + # Line length is 95 so that with "//| " the max is 99 + result = subprocess.run( + ["black", "--pyi", "-l95", "-q", "-"], + input=py_content, + check=True, + stdout=subprocess.PIPE, + encoding="utf-8", + ) + except subprocess.CalledProcessError as e: + print(f"{fn}:0: Failed to process file ") + raise + + new_py_content = result.stdout + new_c_content = swap_comment_markers(new_py_content, Mode.PY) + + if new_c_content != c_content: + with open(fn, "w", encoding="utf-8") as f: + f.write(new_c_content) + + +if __name__ == "__main__": + # Use a thread pool because most processing is inside black! + executor = ThreadPoolExecutor(max_workers=os.cpu_count()) + futures = [executor.submit(process_one_file, fn) for fn in sys.argv[1:]] + status = 0 + for f in futures: + try: + f.result() + except Exception as e: + print(e) + status = 1 + executor.shutdown() + raise SystemExit(status) diff --git a/tools/build_board_info.py b/tools/build_board_info.py index c58dc42a9d..5209337b95 100755 --- a/tools/build_board_info.py +++ b/tools/build_board_info.py @@ -10,6 +10,7 @@ import subprocess import sys import sh import base64 +from io import StringIO from datetime import date from sh.contrib import git @@ -19,75 +20,11 @@ import adabot.github_requests as github sys.path.append("../docs") from shared_bindings_matrix import ( SUPPORTED_PORTS, - aliases_by_board, support_matrix_by_board, + get_board_mapping, ) -BIN = ("bin",) -UF2 = ("uf2",) -BIN_UF2 = ("bin", "uf2") -HEX = ("hex",) -HEX_UF2 = ("hex", "uf2") -SPK = ("spk",) -DFU = ("dfu",) -BIN_DFU = ("bin", "dfu") -COMBINED_HEX = ("combined.hex",) -KERNEL8_IMG = ("disk.img.zip", "kernel8.img") -KERNEL_IMG = ("disk.img.zip", "kernel.img") - -# Default extensions -extension_by_port = { - "atmel-samd": UF2, - "broadcom": KERNEL8_IMG, - "cxd56": SPK, - "espressif": BIN_UF2, - "litex": DFU, - "mimxrt10xx": HEX_UF2, - "nrf": UF2, - "raspberrypi": UF2, - "stm": BIN, -} - -# Per board overrides -extension_by_board = { - # samd - "arduino_mkr1300": BIN_UF2, - "arduino_mkrzero": BIN_UF2, - "arduino_nano_33_iot": BIN_UF2, - "arduino_zero": BIN_UF2, - "feather_m0_adalogger": BIN_UF2, - "feather_m0_basic": BIN_UF2, - "feather_m0_rfm69": BIN_UF2, - "feather_m0_rfm9x": BIN_UF2, - "uchip": BIN_UF2, - # nRF52840 dev kits that may not have UF2 bootloaders, - "makerdiary_nrf52840_mdk": HEX, - "makerdiary_nrf52840_mdk_usb_dongle": HEX_UF2, - "pca10056": BIN_UF2, - "pca10059": BIN_UF2, - "electronut_labs_blip": HEX, - "microbit_v2": COMBINED_HEX, - # stm32 - "meowbit_v121": UF2, - "sparkfun_stm32_thing_plus": BIN_UF2, - "swan_r5": BIN_UF2, - # esp32 - "adafruit_feather_esp32_v2": BIN, - # esp32c3 - "adafruit_qtpy_esp32c3": BIN, - "ai_thinker_esp32-c3s": BIN, - "ai_thinker_esp32-c3s-2m": BIN, - "espressif_esp32c3_devkitm_1_n4": BIN, - "lilygo_ttgo_t-01c3": BIN, - "lolin_c3_mini": BIN, - "microdev_micro_c3": BIN, - "lilygo_ttgo_t-oi-plus": BIN, - # broadcom - "raspberrypi_zero": KERNEL_IMG, - "raspberrypi_zero_w": KERNEL_IMG, -} - -language_allow_list = set( +LANGUAGE_ALLOW_LIST = set( [ "ID", "de_DE", @@ -116,43 +53,19 @@ def get_languages(list_all=False): if f.name.endswith(".po"): languages.add(f.name[:-3]) if not list_all: - languages = languages & language_allow_list + languages = languages & LANGUAGE_ALLOW_LIST return sorted(list(languages), key=str.casefold) -def get_board_mapping(): - boards = {} - for port in SUPPORTED_PORTS: - board_path = os.path.join("../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 - extensions = extension_by_port[port] - extensions = extension_by_board.get(board_path.name, extensions) - aliases = aliases_by_board.get(board_path.name, []) - boards[board_id] = { - "port": port, - "extensions": extensions, - "download_count": 0, - "aliases": aliases, - } - for alias in aliases: - boards[alias] = { - "port": port, - "extensions": extensions, - "download_count": 0, - "alias": True, - "aliases": [], - } - return boards - - def get_version_info(): version = None - sha = git("rev-parse", "--short", "HEAD").stdout.decode("utf-8") + buffer = StringIO() + git("rev-parse", "--short", "HEAD", _out=buffer) + sha = buffer.getvalue().strip() try: - version = git("describe", "--tags", "--exact-match").stdout.decode("utf-8").strip() + buffer = StringIO() + git("describe", "--tags", "--exact-match", _out=buffer) + version = buffer.getvalue().strip() except sh.ErrorReturnCode_128: # No exact match pass @@ -282,7 +195,7 @@ def generate_download_info(): languages = get_languages() - support_matrix = support_matrix_by_board(use_branded_name=False) + support_matrix = support_matrix_by_board(use_branded_name=False, withurl=False) new_stable = "-" not in new_tag @@ -309,20 +222,19 @@ def generate_download_info(): board_files = os.listdir(board_path.path) board_id = board_path.name board_info = board_mapping[board_id] - for alias in [board_id] + board_info["aliases"]: alias_info = board_mapping[alias] if alias not in current_info: changes["new_boards"].append(alias) current_info[alias] = {"downloads": 0, "versions": []} - new_version = { "stable": new_stable, "version": new_tag, - "modules": support_matrix[alias][0], "languages": languages, - "extensions": board_info["extensions"], - "frozen_libraries": [frozen[0] for frozen in support_matrix[alias][1]], + # add modules, extensions, frozen_libraries explicitly + "modules": support_matrix[alias]["modules"], + "extensions": support_matrix[alias]["extensions"], + "frozen_libraries": support_matrix[alias]["frozen_libraries"], } current_info[alias]["downloads"] = alias_info["download_count"] current_info[alias]["versions"].append(new_version) @@ -332,9 +244,10 @@ def generate_download_info(): if changes["new_release"] and user: create_pr(changes, current_info, git_info, user) else: - print("No new release to update") if "DEBUG" in os.environ: print(create_json(current_info).decode("utf8")) + else: + print("No new release to update") if __name__ == "__main__": diff --git a/tools/build_memory_info.py b/tools/build_memory_info.py index 722c548a1c..09d2e72a64 100755 --- a/tools/build_memory_info.py +++ b/tools/build_memory_info.py @@ -7,6 +7,8 @@ import re import sys +import json + # Handle size constants with K or M suffixes (allowed in .ld but not in Python). K_PATTERN = re.compile(r"([0-9]+)[kK]") @@ -15,11 +17,10 @@ K_REPLACE = r"(\1*1024)" M_PATTERN = re.compile(r"([0-9]+)[mM]") M_REPLACE = r"(\1*1024*1024)" -print() - text = 0 data = 0 bss = 0 + # stdin is the linker output. for line in sys.stdin: # Uncomment to see linker output. @@ -29,6 +30,7 @@ for line in sys.stdin: text, data, bss = map(int, line.split()[:3]) regions = {} + # This file is the linker script. with open(sys.argv[1], "r") as f: for line in f: @@ -51,6 +53,11 @@ used_flash = data + text free_flash = firmware_region - used_flash used_ram = data + bss free_ram = ram_region - used_ram + +with open(f"{sys.argv[2]}/firmware.size.json", "w") as f: + json.dump({"used_flash": used_flash, "firmware_region": firmware_region}, f) + +print() print( "{} bytes used, {} bytes free in flash firmware space out of {} bytes ({}kB).".format( used_flash, free_flash, firmware_region, firmware_region / 1024 diff --git a/tools/build_release_files.py b/tools/build_release_files.py index 3fe714e393..341ae2d67f 100755 --- a/tools/build_release_files.py +++ b/tools/build_release_files.py @@ -11,11 +11,15 @@ import subprocess import shutil import build_board_info as build_info import time +import json + +sys.path.append("../docs") +from shared_bindings_matrix import get_settings_from_makefile for port in build_info.SUPPORTED_PORTS: result = subprocess.run("rm -rf ../ports/{port}/build*".format(port=port), shell=True) -PARALLEL = "-j 5" +PARALLEL = "-j 4" if "GITHUB_ACTION" in os.environ: PARALLEL = "-j 2" @@ -26,6 +30,11 @@ if "BOARDS" in os.environ: sha, version = build_info.get_version_info() +build_all = os.environ.get("GITHUB_EVENT_NAME") != "pull_request" + +LANGUAGE_FIRST = "en_US" +LANGUAGE_THRESHOLD = 10 * 1024 + languages = build_info.get_languages() all_languages = build_info.get_languages(list_all=True) @@ -39,6 +48,10 @@ for board in build_boards: bin_directory = "../bin/{}/".format(board) os.makedirs(bin_directory, exist_ok=True) board_info = all_boards[board] + board_settings = get_settings_from_makefile("../ports/" + board_info["port"], board) + + languages.remove(LANGUAGE_FIRST) + languages.insert(0, LANGUAGE_FIRST) for language in languages: bin_directory = "../bin/{board}/{language}".format(board=board, language=language) @@ -62,13 +75,20 @@ for board in build_boards: if clean_build: build_dir += "-{language}".format(language=language) + extensions = [ + extension.strip() + for extension in board_settings["CIRCUITPY_BUILD_EXTENSIONS"].split(",") + ] + + artifacts = [os.path.join(build_dir, "firmware." + extension) for extension in extensions] make_result = subprocess.run( - "make -C ../ports/{port} TRANSLATION={language} BOARD={board} BUILD={build} -j {cores}".format( + "make -C ../ports/{port} TRANSLATION={language} BOARD={board} BUILD={build} -j {cores} {artifacts}".format( port=board_info["port"], language=language, board=board, build=build_dir, cores=cores, + artifacts=" ".join(artifacts), ), shell=True, stdout=subprocess.PIPE, @@ -83,7 +103,7 @@ for board in build_boards: other_output = "" - for extension in board_info["extensions"]: + for extension in extensions: temp_filename = "../ports/{port}/{build}/firmware.{extension}".format( port=board_info["port"], build=build_dir, extension=extension ) @@ -119,4 +139,16 @@ for board in build_boards: # Flush so we will see something before 10 minutes has passed. print(flush=True) + if (not build_all) and (language is LANGUAGE_FIRST) and (exit_status is 0): + try: + with open( + f"../ports/{board_info['port']}/{build_dir}/firmware.size.json", "r" + ) as f: + firmware = json.load(f) + if firmware["used_flash"] + LANGUAGE_THRESHOLD < firmware["firmware_region"]: + print("Skipping languages") + break + except FileNotFoundError: + pass + sys.exit(exit_status) diff --git a/tools/ci_changes_per_commit.py b/tools/ci_changes_per_commit.py new file mode 100644 index 0000000000..e83a702b22 --- /dev/null +++ b/tools/ci_changes_per_commit.py @@ -0,0 +1,239 @@ +#! /usr/bin/env python3 + +# SPDX-FileCopyrightText: 2021 microDev +# +# SPDX-License-Identifier: MIT + +# GraphQL Query + +QUERY_COMMITS = """ +query ($owner: String!, $name: String!, $pullNumber: Int!, $commitsPerPage: Int!, $beforeCommit: String) { + repository(owner: $owner, name: $name) { + pullRequest(number: $pullNumber) { + commits(last: $commitsPerPage, before: $beforeCommit) { + totalCount + pageInfo { + startCursor + hasPreviousPage + } + nodes { + commit { + checkSuites(first: 100) { + nodes { + conclusion + workflowRun { + workflow { + name + } + } + id + } + totalCount + } + oid + } + } + } + } + } +} +""" + +QUERY_CHECK_RUNS = """ +query ($checkSuiteID: ID!, + $afterFailedRun: String, $afterIncompleteRun: String, + $includeFailedRuns: Boolean!, $includeIncompleteRuns: Boolean!) { + node(id: $checkSuiteID) { + ... on CheckSuite { + failedRuns: checkRuns( + first: 100 + after: $afterFailedRun + filterBy: {checkType: LATEST, conclusions: [ACTION_REQUIRED, TIMED_OUT, CANCELLED, FAILURE, NEUTRAL, STARTUP_FAILURE]} + ) @include(if: $includeFailedRuns) { + nodes { + name + } + pageInfo { + endCursor + hasNextPage + } + } + incompleteRuns: checkRuns( + first: 100 + after: $afterIncompleteRun + filterBy: {checkType: LATEST, statuses: [QUEUED, IN_PROGRESS, WAITING, PENDING, REQUESTED]} + ) @include(if: $includeIncompleteRuns) { + nodes { + name + } + pageInfo { + endCursor + hasNextPage + } + } + } + } +} +""" + + +import os +import re +import json +import requests + + +query_variables_commits = { + "owner": "", + "name": "", + "pullNumber": int(os.environ["PULL"]), + "commitsPerPage": 20, + "beforeCommit": None, +} + + +query_variables_check_runs = { + "checkSuiteID": "", + "afterFailedRun": None, + "afterIncompleteRun": None, + "includeFailedRuns": True, + "includeIncompleteRuns": True, +} + + +headers = {"Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}"} + + +class Query: + def __init__(self, query, variables={}, headers={}): + self.query = query + self.variables = variables + self.headers = headers + + def paginate(self, page_info, name): + has_page = page_info["hasNextPage" if name.startswith("after") else "hasPreviousPage"] + if has_page: + self.variables[name] = page_info[ + "endCursor" if name.startswith("after") else "startCursor" + ] + return has_page + + def fetch(self): + request = requests.post( + "https://api.github.com/graphql", + json={"query": self.query, "variables": self.variables}, + headers=self.headers, + ) + if request.status_code == 200: + return request.json() + else: + print(request.json()) + raise Exception("Query Failed: {}".format(request.status_code)) + + +def set_output(name, value): + if "GITHUB_OUTPUT" in os.environ: + with open(os.environ["GITHUB_OUTPUT"], "at") as f: + print(f"{name}={value}", file=f) + else: + print(f"Would set GitHub actions output {name} to '{value}'") + + +def get_commit_depth_and_check_suite(query_commits): + commit_depth = 0 + while True: + commits = query_commits.fetch()["data"]["repository"]["pullRequest"]["commits"] + if commits["totalCount"] > 0: + nodes = commits["nodes"] + nodes.reverse() + if nodes[0]["commit"]["oid"] == os.environ["EXCLUDE_COMMIT"]: + nodes.pop(0) + for commit in nodes: + commit_depth += 1 + commit = commit["commit"] + commit_sha = commit["oid"] + check_suites = commit["checkSuites"] + if check_suites["totalCount"] > 0: + for check_suite in check_suites["nodes"]: + if check_suite["workflowRun"]["workflow"]["name"] == "Build CI": + return [ + {"sha": commit_sha, "depth": commit_depth}, + check_suite["id"] + if check_suite["conclusion"] != "SUCCESS" + else None, + ] + if not query_commits.paginate(commits["pageInfo"], "beforeCommit"): + return [None, None] + + +def get_bad_check_runs(query_check_runs): + bad_runs = {} + more_pages = True + + run_types = ["failed", "incomplete"] + + regex_matrix = re.compile(r"^\S+ \/ (build|run) \(\S+\)$") + + while more_pages: + check_runs = query_check_runs.fetch()["data"]["node"] + more_pages = False + + for run_type in run_types: + run_type_camel = run_type.capitalize() + "Run" + run_type = run_type + "Runs" + + for check_run in check_runs[run_type]["nodes"]: + name = check_run["name"] + if name.startswith("ports") or regex_matrix.search(name): + matrix = name.split(" ", 1)[0] + matrix_job = name.rsplit(" (", 1)[1][:-1] + bad_runs.setdefault(matrix, []).append(matrix_job) + elif name != "scheduler": + bad_runs[name] = True + else: + return {} + + if query_check_runs.paginate( + check_runs[run_type]["pageInfo"], "after" + run_type_camel + ): + query_check_runs.variables["include" + run_type_camel] = True + more_pages = True + + return bad_runs + + +def set_commit(commit): + set_output("commit_sha", commit["sha"]) + set_output("commit_depth", commit["depth"]) + + +def main(): + query_commits = Query(QUERY_COMMITS, query_variables_commits, headers) + query_commits.variables["owner"], query_commits.variables["name"] = os.environ["REPO"].split( + "/" + ) + + commit, check_suite = get_commit_depth_and_check_suite(query_commits) + + if not check_suite: + if commit: + set_commit(commit) + else: + print("Abort: No check suite found") + quit() + + query_check_runs = Query(QUERY_CHECK_RUNS, query_variables_check_runs, headers) + query_check_runs.variables["checkSuiteID"] = check_suite + + check_runs = get_bad_check_runs(query_check_runs) + + if not check_runs: + print("Abort: No check runs found") + quit() + + set_commit(commit) + set_output("check_runs", json.dumps(check_runs)) + + +if __name__ == "__main__": + main() diff --git a/tools/ci_check_duplicate_usb_vid_pid.py b/tools/ci_check_duplicate_usb_vid_pid.py index 060bc8ea17..4d9a0b162e 100644 --- a/tools/ci_check_duplicate_usb_vid_pid.py +++ b/tools/ci_check_duplicate_usb_vid_pid.py @@ -54,11 +54,19 @@ DEFAULT_CLUSTERLIST = { "espressif_esp32s3_devkitc_1_n8", "espressif_esp32s3_devkitc_1_n8r2", "espressif_esp32s3_devkitc_1_n8r8", + "espressif_esp32s3_devkitc_1_n32r8", ], - "0x303A:0x7009": ["espressif_esp32s2_devkitc_1_n4", "espressif_esp32s2_devkitc_1_n4r2"], + "0x303A:0x7009": [ + "espressif_esp32s2_devkitc_1_n4", + "espressif_esp32s2_devkitc_1_n4r2", + "espressif_esp32s2_devkitc_1_n8r2", + ], + "0x239A:0x102E": ["weact_studio_pico", "weact_studio_pico_16mb"], } -cli_parser = argparse.ArgumentParser(description="USB VID/PID Duplicate Checker") +cli_parser = argparse.ArgumentParser( + description="USB VID/PID and Creator/Creation ID Duplicate Checker" +) def configboard_files(): @@ -71,29 +79,38 @@ def configboard_files(): return working_dir.glob("ports/**/boards/**/mpconfigboard.mk") +VID_PATTERN = re.compile(r"^USB_VID\s*=\s*(.*)", flags=re.M) +PID_PATTERN = re.compile(r"^USB_PID\s*=\s*(.*)", flags=re.M) +CREATOR_PATTERN = re.compile(r"^CIRCUITPY_CREATOR_ID\s*=\s*(.*)", flags=re.M) +CREATION_PATTERN = re.compile(r"^CIRCUITPY_CREATION_ID\s*=\s*(.*)", flags=re.M) + + def check_vid_pid(files, clusterlist): """Compiles a list of USB VID & PID values for all boards, and checks for duplicates. Exits with ``sys.exit()`` (non-zero exit code) if duplicates are found, and lists the duplicates. """ - vid_pattern = re.compile(r"^USB_VID\s*=\s*(.*)", flags=re.M) - pid_pattern = re.compile(r"^USB_PID\s*=\s*(.*)", flags=re.M) usb_pattern = re.compile(r"^CIRCUITPY_USB\s*=\s*0$|^IDF_TARGET = (esp32|esp32c3)$", flags=re.M) usb_ids = defaultdict(set) for board_config in files: src_text = board_config.read_text() - usb_vid = vid_pattern.search(src_text) - usb_pid = pid_pattern.search(src_text) + usb_vid = VID_PATTERN.search(src_text) + usb_pid = PID_PATTERN.search(src_text) + creator = CREATOR_PATTERN.search(src_text) + creation = CREATION_PATTERN.search(src_text) non_usb = usb_pattern.search(src_text) board_name = board_config.parts[-2] if usb_vid and usb_pid: id_group = f"0x{int(usb_vid.group(1), 16):04X}:0x{int(usb_pid.group(1), 16):04X}" elif non_usb: - continue + if creator is None or creation is None: + print(f"{board_name=} {creator=} {creation=}", file=sys.stderr) + continue + id_group = f"0x{int(creator.group(1), 16):08X}:0x{int(creation.group(1), 16):08X}" else: raise SystemExit(f"Could not find expected settings in {board_config}") @@ -117,18 +134,19 @@ def check_vid_pid(files, clusterlist): duplicate_message = ( f"Duplicate VID/PID usage found!\n{duplicates}\n" f"If you are open source maker, then you can request a PID from http://pid.codes\n" + f"For boards without native USB, you can request a Creator ID from https://github.com/creationid/creators/\n" f"Otherwise, companies should pay the USB-IF for a vendor ID: https://www.usb.org/getting-vendor-id" ) sys.exit(duplicate_message) else: - print("No USB PID duplicates found.") + print("No unexpected ID duplicates found.") if __name__ == "__main__": arguments = cli_parser.parse_args() - print("Running USB VID/PID Duplicate Checker...") + print("Running USB VID/PID and Creator/Creation ID Duplicate Checker...") board_files = configboard_files() check_vid_pid(board_files, DEFAULT_CLUSTERLIST) diff --git a/tools/ci_fetch_deps.py b/tools/ci_fetch_deps.py index 55985ffe15..1b292b9d73 100644 --- a/tools/ci_fetch_deps.py +++ b/tools/ci_fetch_deps.py @@ -1,19 +1,16 @@ -import pathlib -import shlex -import subprocess +import os import sys import time +import shlex +import pathlib +import subprocess -# target will be a board, "test", "docs", "mpy-cross-mac", or "windows" - -target = sys.argv[1] -ref = sys.argv[2] - -print(target, ref) +# Target will be a board, "test", "docs", "mpy-cross-mac", or "windows" +TARGET = sys.argv[1] # Submodules needed by port builds outside of their ports directory. # Should we try and detect these? -port_deps = { +PORT_DEPS = { "atmel-samd": [ "extmod/ulab/", "lib/adafruit_floppy/", @@ -25,14 +22,22 @@ port_deps = { ], "broadcom": ["extmod/ulab/", "lib/tinyusb/"], "cxd56": ["extmod/ulab/", "lib/tinyusb/"], - "espressif": ["extmod/ulab/", "lib/tinyusb/", "lib/protomatter/", "lib/quirc/"], + "espressif": [ + "extmod/ulab/", + "lib/certificates/nina-fw/", + "lib/protomatter/", + "lib/quirc/", + "lib/tinyusb/", + ], "litex": ["extmod/ulab/", "lib/tinyusb/"], "mimxrt10xx": ["extmod/ulab/", "lib/tinyusb/", "data/nvm.toml/"], "nrf": ["extmod/ulab/", "lib/mp3/", "lib/protomatter/", "lib/tinyusb/", "data/nvm.toml/"], "raspberrypi": [ "extmod/ulab/", "lib/adafruit_floppy/", + "lib/mbedtls/", "lib/mp3/", + "lib/certificates/nina-fw/", "lib/protomatter/", "lib/quirc/", "lib/tinyusb/", @@ -50,71 +55,89 @@ def run(title, command, check=True): try: subprocess.run(shlex.split(command), stderr=subprocess.STDOUT, check=check) finally: - print("Duration:", time.monotonic() - start, flush=True) print("::endgroup::", flush=True) + print("Duration:", time.monotonic() - start, flush=True) -run( - "Fetch back to the start of 2021 to get tag history", - 'git fetch --tags --recurse-submodules=no --shallow-since="2021-07-01" https://github.com/adafruit/circuitpython HEAD', -) -run( - "Fetch back to the start of 2021 to get commit history", - f'git fetch --recurse-submodules=no --shallow-since="2021-07-01" origin {ref}', -) -run("Init submodules", "git submodule init") -run("Submodule status", "git submodule status") +def set_output(name, value): + if "GITHUB_OUTPUT" in os.environ: + with open(os.environ["GITHUB_OUTPUT"], "at") as f: + print(f"{name}={value}", file=f) + else: + print(f"Would set GitHub actions output {name} to '{value}'") -submodules = [] -if target == "test": - submodules = ["extmod/", "lib/", "tools/", "extmod/ulab", "lib/berkeley-db-1.xx"] -elif target == "docs": - # used in .readthedocs.yml to generate RTD - submodules = ["extmod/ulab/", "frozen/"] -elif target == "mpy-cross-mac": - submodules = ["tools/"] # for huffman -elif target == "windows": - # This builds one board from a number of ports so fill out a bunch of submodules - submodules = ["extmod/", "lib/", "tools/", "ports/", "data/nvm.toml/"] -elif target == "website": - submodules = ["tools/adabot/", "frozen/"] -else: - p = list(pathlib.Path(".").glob(f"ports/*/boards/{target}/mpconfigboard.mk")) - if not p: - raise RuntimeError(f"Unsupported target: {target}") +def main(): + submodules = [] + submodules_tags = [] - config = p[0] - # Add the ports folder to init submodules - port_folder = config.parents[2] - port = port_folder.name - submodules.append(str(port_folder)) - submodules.append("tools/") # for huffman - submodules.extend(port_deps[port]) - with config.open() as f: - for line in f.readlines(): - prefix = "FROZEN_MPY_DIRS += $(TOP)/" - if line.startswith(prefix): - lib_folder = line.strip()[len(prefix) :] - # Drop everything after the second folder because the frozen - # folder may be inside the submodule. - if lib_folder.count("/") > 1: - lib_folder = lib_folder.split("/", maxsplit=2) - lib_folder = "/".join(lib_folder[:2]) - submodules.append(lib_folder) + print("Target:", TARGET) -print(submodules) -if submodules: - submodules = " ".join(submodules) - # This line will fail because the submodule's need different commits than the tip of the branch. We - # fix it later. - run( - "Init the submodules we'll need", - f"git submodule update --init -N --depth 1 {submodules}", - check=False, - ) + if TARGET == "scheduler": + # submodules = ["tools/"] + submodules = ["extmod/ulab", "lib/", "tools/"] + elif TARGET == "tests": + submodules = ["extmod/ulab", "lib/", "tools/"] + elif TARGET == "docs": + # used in .readthedocs.yml to generate RTD + submodules = ["extmod/ulab"] + submodules_tags = ["frozen/"] + elif TARGET == "mpy-cross" or TARGET == "mpy-cross-mac": + submodules = ["tools/"] # for huffman + elif TARGET == "windows": + # This builds one board from a number of ports so fill out a bunch of submodules + submodules = ["extmod/ulab", "lib/", "tools/", "ports/", "data/nvm.toml"] + elif TARGET == "website": + submodules = ["tools/adabot/"] + submodules_tags = ["frozen/"] + elif TARGET == "pre-commit": + submodules = ["extmod/ulab"] + else: + p = list(pathlib.Path(".").glob(f"ports/*/boards/{TARGET}/mpconfigboard.mk")) + if not p: + raise RuntimeError(f"Unsupported target: {TARGET}") - run( - "Fetch the submodule sha", - "git submodule foreach 'git fetch --tags --depth 1 origin $sha1 && git checkout -q $sha1'", - ) + config = p[0] + # Add the ports folder to init submodules + port_folder = config.parents[2] + port = port_folder.name + submodules.append(str(port_folder)) + submodules.append("tools/") # for huffman + submodules.extend(PORT_DEPS[port]) + with config.open() as f: + for line in f.readlines(): + prefix = "FROZEN_MPY_DIRS += $(TOP)/" + if line.startswith(prefix): + lib_folder = line.strip()[len(prefix) :] + # Drop everything after the second folder because the frozen + # folder may be inside the submodule. + if lib_folder.count("/") > 1: + lib_folder = lib_folder.split("/", maxsplit=2) + lib_folder = "/".join(lib_folder[:2]) + submodules_tags.append(lib_folder) + + print("Submodule tags[Y]:", submodules_tags) + print("Submodule tags[N]:", submodules) + + if submodules_tags: + run( + "Init the submodules with tags", + f"git submodule update --init {' '.join(submodules_tags)}", + ) + + if submodules: + run( + "Init the submodules without tags", + f"git submodule update --init --depth=1 {' '.join(submodules)}", + ) + + for submodule in submodules_tags: + if submodule.startswith("frozen"): + set_output("frozen_tags", True) + break + else: + set_output("frozen_tags", False) + + +if __name__ == "__main__": + main() diff --git a/tools/ci_set_matrix.py b/tools/ci_set_matrix.py old mode 100644 new mode 100755 index efb4427e7e..fe823ac030 --- a/tools/ci_set_matrix.py +++ b/tools/ci_set_matrix.py @@ -12,47 +12,101 @@ on the event that triggered run. Pull request runs will compare to the base branch while pushes will compare to the current ref. We override this for the adafruit/circuitpython repo so we build all docs/boards for pushes. +When making changes to the script it is useful to manually test it. +You can for instance run +```shell +tools/ci_set_matrix ports/raspberrypi/common-hal/socket/SSLSocket.c +``` +and (at the time this comment was written) get a series of messages indicating +that only the single board raspberry_pi_pico_w would be built. """ import re import os import sys import json -import yaml +import pathlib +import subprocess +from concurrent.futures import ThreadPoolExecutor + +tools_dir = pathlib.Path(__file__).resolve().parent +top_dir = tools_dir.parent + +sys.path.insert(0, str(tools_dir / "adabot")) +sys.path.insert(0, str(top_dir / "docs")) import build_board_info - -PORT_TO_ARCH = { - "atmel-samd": "arm", - "broadcom": "aarch", - "cxd56": "arm", - "espressif": "espressif", - "litex": "riscv", - "mimxrt10xx": "arm", - "nrf": "arm", - "raspberrypi": "arm", - "stm": "arm", -} +from shared_bindings_matrix import ( + get_settings_from_makefile, + SUPPORTED_PORTS, + all_ports_all_boards, +) IGNORE = [ "tools/ci_set_matrix.py", "tools/ci_check_duplicate_usb_vid_pid.py", ] -changed_files = {} -try: - changed_files = json.loads(os.environ["CHANGED_FILES"]) -except json.decoder.JSONDecodeError as exc: - if exc.msg != "Expecting value": - raise +# Files in these directories never influence board builds +IGNORE_DIRS = ["tests", "docs", ".devcontainer"] + +PATTERN_DOCS = ( + r"^(?:\.github|docs|extmod\/ulab)|" + r"^(?:(?:ports\/\w+\/bindings|shared-bindings)\S+\.c|tools\/extract_pyi\.py|conf\.py|requirements-doc\.txt)$|" + r"(?:-stubs|\.(?:md|MD|rst|RST))$" +) + +PATTERN_WINDOWS = [ + ".github/", + "extmod/", + "lib/", + "mpy-cross/", + "ports/unix/", + "ports/windows/", + "py/", + "requirements", + "tools/", +] + +if len(sys.argv) > 1: + print("Using files list on commandline") + changed_files = sys.argv[1:] + last_failed_jobs = {} +else: + c = os.environ["CHANGED_FILES"] + if c == "": + print("CHANGED_FILES is in environment, but value is empty") + changed_files = [] + else: + print("Using files list in CHANGED_FILES") + changed_files = json.loads(c.replace("\\", "")) + + j = os.environ["LAST_FAILED_JOBS"] + if j == "": + print("LAST_FAILED_JOBS is in environment, but value is empty") + last_failed_jobs = {} + else: + last_failed_jobs = json.loads(j) -def set_boards_to_build(build_all): +def set_output(name: str, value): + if "GITHUB_OUTPUT" in os.environ: + with open(os.environ["GITHUB_OUTPUT"], "at") as f: + print(f"{name}={value}", file=f) + else: + print(f"Would set GitHub actions output {name} to '{value}'") + + +def set_boards(build_all: bool): + if last_failed_jobs.get("mpy-cross") or last_failed_jobs.get("tests"): + build_all = True + # Get boards in json format boards_info_json = build_board_info.get_board_mapping() all_board_ids = set() port_to_boards = {} board_to_port = {} + board_settings = {} for board_id in boards_info_json: info = boards_info_json[board_id] if info.get("alias", False): @@ -64,12 +118,29 @@ def set_boards_to_build(build_all): port_to_boards[port].add(board_id) board_to_port[board_id] = port + def compute_board_settings(boards): + need = set(boards) - set(board_settings.keys()) + if not need: + return + + def get_settings(board): + return ( + board, + get_settings_from_makefile(str(top_dir / "ports" / board_to_port[board]), board), + ) + + with ThreadPoolExecutor(max_workers=os.cpu_count()) as ex: + board_settings.update(ex.map(get_settings, need)) + boards_to_build = all_board_ids if not build_all: boards_to_build = set() board_pattern = re.compile(r"^ports/[^/]+/boards/([^/]+)/") port_pattern = re.compile(r"^ports/([^/]+)/") + module_pattern = re.compile( + r"^(ports/[^/]+/(?:common-hal|bindings)|shared-bindings|shared-module)/([^/]+)/" + ) for p in changed_files: # See if it is board specific board_matches = board_pattern.search(p) @@ -80,8 +151,9 @@ def set_boards_to_build(build_all): # See if it is port specific port_matches = port_pattern.search(p) - if port_matches: - port = port_matches.group(1) + port = port_matches.group(1) if port_matches else None + module_matches = module_pattern.search(p) + if port and not module_matches: if port != "unix": boards_to_build.update(port_to_boards[port]) continue @@ -90,61 +162,141 @@ def set_boards_to_build(build_all): if p in IGNORE: continue - # Boards don't run tests so ignore those as well. - if p.startswith("tests"): + if any([p.startswith(d) for d in IGNORE_DIRS]): + continue + + # As a (nearly) last resort, for some certain files, we compute the settings from the + # makefile for each board and determine whether to build them that way. + if p.startswith("frozen") or p.startswith("supervisor") or module_matches: + if port: + board_ids = port_to_boards[port] + else: + board_ids = all_board_ids + compute_board_settings(board_ids) + for board in board_ids: + settings = board_settings[board] + + # Check frozen files to see if they are in each board. + frozen = settings.get("FROZEN_MPY_DIRS", "") + if frozen and p.startswith("frozen") and p in frozen: + boards_to_build.add(board) + continue + + # Check supervisor files. This is useful for limiting workflow changes to the + # relevant boards. + supervisor = settings["SRC_SUPERVISOR"] + if p.startswith("supervisor"): + if p in supervisor: + boards_to_build.add(board) + continue + + web_workflow = settings["CIRCUITPY_WEB_WORKFLOW"] + while web_workflow.startswith("$("): + web_workflow = settings[web_workflow[2:-1]] + if ( + p.startswith("supervisor/shared/web_workflow/static/") + and web_workflow != "0" + ): + boards_to_build.add(board) + continue + + # Check module matches + if module_matches: + module = module_matches.group(2) + "/" + if module in settings["SRC_PATTERNS"]: + boards_to_build.add(board) + continue continue # Otherwise build it all boards_to_build = all_board_ids break - # Split boards by architecture. - print("Building boards:") - arch_to_boards = {"aarch": [], "arm": [], "riscv": [], "espressif": []} - for board in boards_to_build: - print(" ", board) + # Append previously failed boards + boards_to_build.update(last_failed_jobs.get("ports") or []) + + print("Building boards:", bool(boards_to_build)) + + # Split boards by port + port_to_boards_to_build = {} + + # Append boards according to job + for board in sorted(boards_to_build): port = board_to_port.get(board) # A board can appear due to its _deletion_ (rare) # if this happens it's not in `board_to_port`. if not port: continue - arch = PORT_TO_ARCH[port] - arch_to_boards[arch].append(board) + port_to_boards_to_build.setdefault(port, []).append(board) + print(" ", board) - # Set the step outputs for each architecture - for arch in arch_to_boards: - print("::set-output name=boards-" + arch + "::" + json.dumps(sorted(arch_to_boards[arch]))) + if port_to_boards_to_build: + port_to_boards_to_build["ports"] = sorted(list(port_to_boards_to_build.keys())) + + # Set the step outputs + set_output("ports", json.dumps(port_to_boards_to_build)) -def set_docs_to_build(build_all): - doc_match = build_all - if not build_all: - doc_pattern = re.compile( - r"^(?:docs|extmod/ulab|(?:(?:ports/\w+/bindings|shared-bindings)\S+\.c|conf\.py|tools/extract_pyi\.py|requirements-doc\.txt)$)|(?:-stubs|\.(?:md|MD|rst|RST))$" - ) - for p in changed_files: - if doc_pattern.search(p): - doc_match = True +def set_docs(build_doc: bool): + if not build_doc: + if last_failed_jobs.get("docs"): + build_doc = True + else: + doc_pattern = re.compile(PATTERN_DOCS) + github_workspace = os.environ.get("GITHUB_WORKSPACE") or "" + github_workspace = github_workspace and github_workspace + "/" + for file in changed_files: + if doc_pattern.search(file) and ( + ( + subprocess.run( + f"git diff -U0 $BASE_SHA...$HEAD_SHA {github_workspace + file} | grep -o -m 1 '^[+-]\/\/|'", + capture_output=True, + shell=True, + ).stdout + ) + if file.endswith(".c") + else True + ): + build_doc = True + break + + # Set the step outputs + print("Building docs:", build_doc) + set_output("docs", build_doc) + + +def set_windows(build_windows: bool): + if not build_windows: + if last_failed_jobs.get("windows"): + build_windows = True + else: + for file in changed_files: + for pattern in PATTERN_WINDOWS: + if file.startswith(pattern): + build_windows = True + break + else: + continue break # Set the step outputs - print("Building docs:", doc_match) - print("::set-output name=build-doc::" + str(doc_match)) - - -def check_changed_files(): - if not changed_files: - print("Building all docs/boards") - return True - else: - print("Adding docs/boards to build based on changed files") - return False + print("Building windows:", build_windows) + set_output("windows", build_windows) def main(): - build_all = check_changed_files() - set_docs_to_build(build_all) - set_boards_to_build(build_all) + # Build all if no changed files + build_all = not changed_files + print( + "Building all docs/boards" + if build_all + else "Adding docs/boards to build based on changed files" + ) + + # Set jobs + set_docs(build_all) + set_windows(build_all) + set_boards(build_all) if __name__ == "__main__": diff --git a/tools/codeformat.py b/tools/codeformat.py index edefbc8ddc..f76e5f0681 100644 --- a/tools/codeformat.py +++ b/tools/codeformat.py @@ -67,8 +67,11 @@ EXCLUSIONS = [ "tests/**/repl_*.py", # needs careful attention before applying automatic formatting "tests/basics/*.py", + # don't reindent this third-party code we vendored in + "ports/raspberrypi/lwip_src", ] + # None of the standard Python path matching routines implement the matching # we want, which is most like git's "pathspec" version of globs. # In particular, we want "**/" to match all directories. @@ -214,8 +217,13 @@ def main(): if os.path.splitext(file)[1].lower() in exts: yield file + def bindings_files(): + for file in lang_files(C_EXTS): + if file.startswith("shared-bindings/") or "/bindings/" in file: + yield file + # Run tool on N files at a time (to avoid making the command line too long). - def batch(cmd, files, N=200): + def batch(cmd, files, N=200, check=False): while True: file_args = list(itertools.islice(files, N)) if not file_args: @@ -223,7 +231,10 @@ def main(): if args.dry_run: print(" ".join(cmd + file_args)) else: - subprocess.call(cmd + file_args) + if check: + subprocess.check_call(cmd + file_args) + else: + subprocess.run(cmd + file_args) # Format C files with uncrustify. if format_c: @@ -234,6 +245,10 @@ def main(): batch(command, lang_files(C_EXTS)) for file in lang_files(C_EXTS): fixup_c(file) + # Format bindings with black_bindings + if format_py: + command = ["python3", "tools/black_bindings.py"] + batch(command, bindings_files(), check=True) # Format Python files with black. if format_py: diff --git a/tools/describe b/tools/describe index 7fd624abe3..0f3b541e3c 100755 --- a/tools/describe +++ b/tools/describe @@ -1,3 +1,6 @@ #!/bin/sh -# Add any supplied arguments. -git describe --first-parent --dirty --tags --always --match "[1-9].*" "$@" +if [ -z "$CP_VERSION" ]; then + git describe --first-parent --dirty --tags --match "[1-9].*" "$@" +else + echo $CP_VERSION +fi diff --git a/tools/extract_pyi.py b/tools/extract_pyi.py index 7b87404fbc..e6bc703c02 100644 --- a/tools/extract_pyi.py +++ b/tools/extract_pyi.py @@ -215,7 +215,7 @@ def convert_folder(top_level, stub_directory): return (ok, total) error = False - for (level, msg) in find_stub_issues(tree): + for level, msg in find_stub_issues(tree): if level == "ERROR": error = True print(f"[{level}] {msg}") @@ -228,7 +228,8 @@ def convert_folder(top_level, stub_directory): imports, type_imports = extract_imports(tree) import_lines = ["from __future__ import annotations"] for type_module, used_types in type_imports.items(): - import_lines.append(f"from {type_module} import {', '.join(sorted(used_types))}") + if used_types: + import_lines.append(f"from {type_module} import {', '.join(sorted(used_types))}") import_lines.extend(f"import {m}" for m in sorted(imports)) import_body = "\n".join(import_lines) m = re.match(r'(\s*""".*?""")', stub_contents, flags=re.DOTALL) diff --git a/tools/gen_crt_bundle.py b/tools/gen_crt_bundle.py new file mode 100755 index 0000000000..da0d8837a9 --- /dev/null +++ b/tools/gen_crt_bundle.py @@ -0,0 +1,296 @@ +#!/usr/bin/env python +# +# ESP32 x509 certificate bundle generation utility +# +# Converts PEM and DER certificates to a custom bundle format which stores just the +# subject name and public key to reduce space +# +# The bundle will have the format: number of certificates; crt 1 subject name length; crt 1 public key length; +# crt 1 subject name; crt 1 public key; crt 2... +# +# Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import with_statement + +import argparse +import csv +import os +import re +import struct +import sys +import textwrap +from io import open + +try: + from cryptography import x509 + from cryptography.hazmat.backends import default_backend + from cryptography.hazmat.primitives import serialization +except ImportError: + print( + "The cryptography package is not installed." + "Please refer to the Get Started section of the ESP-IDF Programming Guide for " + "setting up the required packages." + ) + raise + +ca_bundle_bin_file = "x509_crt_bundle" + +quiet = False + + +def status(msg): + """Print status message to stderr""" + if not quiet: + critical(msg) + + +def critical(msg): + """Print critical message to stderr""" + sys.stderr.write("gen_crt_bundle.py: ") + sys.stderr.write(msg) + sys.stderr.write("\n") + + +class CertificateBundle: + def __init__(self): + self.certificates = [] + self.compressed_crts = [] + + if os.path.isfile(ca_bundle_bin_file): + os.remove(ca_bundle_bin_file) + + def add_from_path(self, crts_path): + found = False + for file_path in os.listdir(crts_path): + found |= self.add_from_file(os.path.join(crts_path, file_path)) + + if found is False: + raise InputError("No valid x509 certificates found in %s" % crts_path) + + def add_from_file(self, file_path): + try: + if file_path.endswith(".pem"): + status("Parsing certificates from %s" % file_path) + with open(file_path, "r", encoding="utf-8") as f: + crt_str = f.read() + self.add_from_pem(crt_str) + return True + + elif file_path.endswith(".der"): + status("Parsing certificates from %s" % file_path) + with open(file_path, "rb") as f: + crt_str = f.read() + self.add_from_der(crt_str) + return True + + except ValueError: + critical("Invalid certificate in %s" % file_path) + raise InputError("Invalid certificate") + + return False + + def add_from_pem(self, crt_str): + """A single PEM file may have multiple certificates""" + + crt = "" + count = 0 + start = False + + for strg in crt_str.splitlines(True): + if strg == "-----BEGIN CERTIFICATE-----\n" and start is False: + crt = "" + start = True + elif strg == "-----END CERTIFICATE-----\n" and start is True: + crt += strg + "\n" + start = False + self.certificates.append( + x509.load_pem_x509_certificate(crt.encode(), default_backend()) + ) + count += 1 + if start is True: + crt += strg + + if count == 0: + raise InputError("No certificate found") + + status("Successfully added %d certificates" % count) + + def add_from_der(self, crt_str): + self.certificates.append(x509.load_der_x509_certificate(crt_str, default_backend())) + status("Successfully added 1 certificate") + + def create_bundle(self): + # Sort certificates in order to do binary search when looking up certificates + self.certificates = sorted( + self.certificates, key=lambda cert: cert.subject.public_bytes(default_backend()) + ) + + bundle = struct.pack(">H", len(self.certificates)) + + for crt in self.certificates: + """Read the public key as DER format""" + pub_key = crt.public_key() + pub_key_der = pub_key.public_bytes( + serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo + ) + + """ Read the subject name as DER format """ + sub_name_der = crt.subject.public_bytes(default_backend()) + + name_len = len(sub_name_der) + key_len = len(pub_key_der) + len_data = struct.pack(">HH", name_len, key_len) + + bundle += len_data + bundle += sub_name_der + bundle += pub_key_der + + return bundle + + def add_with_filter(self, crts_path, filter_path): + filter_set = set() + with open(filter_path, "r", encoding="utf-8") as f: + csv_reader = csv.reader(f, delimiter=",") + + # Skip header + next(csv_reader) + for row in csv_reader: + filter_set.add(row[1]) + + status("Parsing certificates from %s" % crts_path) + crt_str = [] + with open(crts_path, "r", encoding="utf-8") as f: + crt_str = f.read() + + # Split all certs into a list of (name, certificate string) tuples + pem_crts = re.findall( + r"(^.+?)\n(=+\n[\s\S]+?END CERTIFICATE-----\n)", crt_str, re.MULTILINE + ) + + filtered_crts = "" + for name, crt in pem_crts: + if name in filter_set: + filtered_crts += crt + + self.add_from_pem(filtered_crts) + + +class InputError(RuntimeError): + def __init__(self, e): + super(InputError, self).__init__(e) + + +def main(): + global quiet + + parser = argparse.ArgumentParser(description="ESP-IDF x509 certificate bundle utility") + + parser.add_argument( + "--quiet", + "-q", + help="Don't print non-critical status messages to stderr", + action="store_true", + ) + parser.add_argument( + "--input", + "-i", + nargs="+", + required=True, + help="Paths to the custom certificate folders or files to parse, parses all .pem or .der files", + ) + parser.add_argument( + "--filter", + "-f", + help="Path to CSV-file where the second columns contains the name of the certificates \ + that should be included from cacrt_all.pem", + ) + parser.add_argument( + "--asm", + "-S", + action="store_true", + default=False, + help="Output an asm file for use with gas, rather than a binary file", + ) + parser.add_argument("--symbol", help="The symbol to define", default="x509_crt_bundle") + parser.add_argument("--output", "-o", help="The output file", default=None) + + args = parser.parse_args() + + quiet = args.quiet + + bundle = CertificateBundle() + + for path in args.input: + if os.path.isfile(path): + if os.path.basename(path) == "cacrt_all.pem" and args.filter: + bundle.add_with_filter(path, args.filter) + else: + bundle.add_from_file(path) + elif os.path.isdir(path): + bundle.add_from_path(path) + else: + raise InputError("Invalid --input=%s, is neither file nor folder" % args.input) + + status("Successfully added %d certificates in total" % len(bundle.certificates)) + + crt_bundle = bundle.create_bundle() + + if args.asm: + symbol = args.symbol + filename = args.output or (ca_bundle_bin_file + ".S") + with open(filename, "w") as f: + print( + textwrap.dedent( + f"""\ + // Generated from {" ".join(args.input)} with {len(bundle.certificates)} certificates + .data + .section .rodata.embedded + + .global {symbol} + .global _binary_{symbol}_start + .global _binary_{symbol}_end + {symbol}: + _binary_{symbol}_start: + """ + ), + file=f, + ) + for i in range(0, len(crt_bundle), 16): + chunk = crt_bundle[i : i + 16] + formatted = ", ".join(f"0x{byte:02x}" for byte in chunk) + print(f".byte {formatted}", file=f) + print( + textwrap.dedent( + f"""\ + _binary_{symbol}_end: + + {symbol}_length: + .word {len(crt_bundle)} + """ + ), + file=f, + ) + else: + filename = args.output or ca_bundle_bin_file + with open(filename, "wb") as f: + f.write(crt_bundle) + + +if __name__ == "__main__": + try: + main() + except InputError as e: + print(e) + sys.exit(2) diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py index dc9dbd69a4..7165db84cc 100644 --- a/tools/gen_display_resources.py +++ b/tools/gen_display_resources.py @@ -104,26 +104,150 @@ c_file = args.output_c_file c_file.write( """\ +#include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Palette.h" #include "supervisor/shared/display.h" """ ) + c_file.write( """\ +#if CIRCUITPY_REPL_LOGO +""" +) +if tile_y == 16: + blinka_size = 16 + c_file.write( + """\ +uint32_t blinka_bitmap_data[32] = { + 0x00000011, 0x11000000, + 0x00000111, 0x53100000, + 0x00000111, 0x56110000, + 0x00000111, 0x11140000, + 0x00000111, 0x20002000, + 0x00000011, 0x13000000, + 0x00000001, 0x11200000, + 0x00000000, 0x11330000, + 0x00000000, 0x01122000, + 0x00001111, 0x44133000, + 0x00032323, 0x24112200, + 0x00111114, 0x44113300, + 0x00323232, 0x34112200, + 0x11111144, 0x44443300, + 0x11111111, 0x11144401, + 0x23232323, 0x21111110 +}; +""" + ) +else: + blinka_size = 12 + c_file.write( + """\ +uint32_t blinka_bitmap_data[28] = { + 0x00000111, 0x00000000, + 0x00001153, 0x10000000, + 0x00001156, 0x11000000, + 0x00001111, 0x14000000, + 0x00000112, 0x00200000, + 0x00000011, 0x30000000, + 0x00000011, 0x20000000, + 0x00011144, 0x13000000, + 0x00232324, 0x12000000, + 0x01111444, 0x13000000, + 0x32323234, 0x12010000, + 0x11111144, 0x44100000 +}; +""" + ) + +c_file.write( + """\ +displayio_bitmap_t blinka_bitmap = {{ + .base = {{.type = &displayio_bitmap_type }}, + .width = {0}, + .height = {0}, + .data = blinka_bitmap_data, + .stride = 2, + .bits_per_value = 4, + .x_shift = 3, + .x_mask = 0x7, + .bitmask = 0xf, + .read_only = true +}}; + +_displayio_color_t blinka_colors[7] = {{ + {{ + .rgb888 = 0x000000, + .transparent = true + }}, + {{ // Purple + .rgb888 = 0x8428bc + }}, + {{ // Pink + .rgb888 = 0xff89bc + }}, + {{ // Light blue + .rgb888 = 0x7beffe + }}, + {{ // Dark purple + .rgb888 = 0x51395f + }}, + {{ // White + .rgb888 = 0xffffff + }}, + {{ // Dark Blue + .rgb888 = 0x0736a0 + }}, +}}; + +displayio_palette_t blinka_palette = {{ + .base = {{.type = &displayio_palette_type }}, + .colors = blinka_colors, + .color_count = 7, + .needs_refresh = false +}}; + +displayio_tilegrid_t supervisor_blinka_sprite = {{ + .base = {{.type = &displayio_tilegrid_type }}, + .bitmap = &blinka_bitmap, + .pixel_shader = &blinka_palette, + .x = 0, + .y = 0, + .pixel_width = {0}, + .pixel_height = {0}, + .bitmap_width_in_tiles = 1, + .width_in_tiles = 1, + .height_in_tiles = 1, + .tile_width = {0}, + .tile_height = {0}, + .top_left_x = {0}, + .top_left_y = {0}, + .tiles = 0, + .partial_change = false, + .full_change = false, + .hidden = false, + .hidden_by_parent = false, + .moved = false, + .inline_tiles = true, + .in_group = true +}}; +#endif +""".format( + blinka_size + ) +) + +c_file.write( + """\ +#if CIRCUITPY_TERMINALIO _displayio_color_t terminal_colors[2] = { { - .rgb888 = 0x000000, - .rgb565 = 0x0000, - .luma = 0x00, - .chroma = 0 + .rgb888 = 0x000000 }, { - .rgb888 = 0xffffff, - .rgb565 = 0xffff, - .luma = 0xff, - .chroma = 0 + .rgb888 = 0xffffff }, }; @@ -168,7 +292,7 @@ displayio_tilegrid_t supervisor_terminal_scroll_area_text_grid = {{ c_file.write( """\ -displayio_tilegrid_t supervisor_terminal_title_bar_text_grid = {{ +displayio_tilegrid_t supervisor_terminal_status_bar_text_grid = {{ .base = {{ .type = &displayio_tilegrid_type }}, .bitmap = (displayio_bitmap_t*) &supervisor_terminal_font_bitmap, .pixel_shader = &supervisor_terminal_color, @@ -258,7 +382,9 @@ terminalio_terminal_obj_t supervisor_terminal = { .cursor_x = 0, .cursor_y = 0, .scroll_area = NULL, - .title_bar = NULL + .status_bar = NULL }; + +#endif """ ) diff --git a/tools/gen_web_workflow_static.py b/tools/gen_web_workflow_static.py index b8c5baf619..172a80dac0 100644 --- a/tools/gen_web_workflow_static.py +++ b/tools/gen_web_workflow_static.py @@ -29,7 +29,9 @@ for f in args.files: if f.name.endswith(".html"): uncompressed = minify_html.minify(uncompressed.decode("utf-8")).encode("utf-8") elif f.name.endswith(".js"): - uncompressed = jsmin.jsmin(uncompressed.decode("utf-8")).encode("utf-8") + uncompressed = jsmin.jsmin(uncompressed.decode("utf-8"), quote_chars="'\"`").encode( + "utf-8" + ) compressed = gzip.compress(uncompressed) clen = len(compressed) compressed = ", ".join([hex(x) for x in compressed]) diff --git a/tools/gendoc.py b/tools/gendoc.py index bf79b3cf5f..f3df853e49 100644 --- a/tools/gendoc.py +++ b/tools/gendoc.py @@ -11,6 +11,7 @@ import argparse import re import markdown + # given a list of (name,regex) pairs, find the first one that matches the given line def re_match_first(regexs, line): for name, regex in regexs: diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 32b064d35f..02ea656c99 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -107,6 +107,7 @@ MP_BC_LOAD_GLOBAL = 0x12 MP_BC_LOAD_ATTR = 0x13 MP_BC_STORE_ATTR = 0x18 + # this function mirrors that in py/bc.c def mp_opcode_format(bytecode, ip, count_var_uint): opcode = bytecode[ip] diff --git a/tools/msgfmt.py b/tools/msgfmt.py new file mode 100644 index 0000000000..1ed594b84f --- /dev/null +++ b/tools/msgfmt.py @@ -0,0 +1,244 @@ +#! /usr/bin/env python3 +# Written by Martin v. Löwis + +"""Generate binary message catalog from textual translation description. +This program converts a textual Uniforum-style message catalog (.po file) into +a binary GNU catalog (.mo file). This is essentially the same function as the +GNU msgfmt program, however, it is a simpler implementation. Currently it +does not handle plural forms but it does handle message contexts. +Usage: msgfmt.py [OPTIONS] filename.po +Options: + -o file + --output-file=file + Specify the output file to write to. If omitted, output will go to a + file named filename.mo (based off the input file name). + -h + --help + Print this message and exit. + -V + --version + Display version information and exit. +""" + +import os +import sys +import ast +import getopt +import struct +import array +from email.parser import HeaderParser + +__version__ = "1.2" + +MESSAGES = {} + + +def usage(code, msg=""): + print(__doc__, file=sys.stderr) + if msg: + print(msg, file=sys.stderr) + sys.exit(code) + + +def add(ctxt, id, str, fuzzy): + "Add a non-fuzzy translation to the dictionary." + global MESSAGES + if not fuzzy and str: + if ctxt is None: + MESSAGES[id] = str + else: + MESSAGES[b"%b\x04%b" % (ctxt, id)] = str + + +def generate(): + "Return the generated output." + global MESSAGES + # the keys are sorted in the .mo file + keys = sorted(MESSAGES.keys()) + offsets = [] + ids = strs = b"" + for id in keys: + # For each string, we need size and file offset. Each string is NUL + # terminated; the NUL does not count into the size. + offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id]))) + ids += id + b"\0" + strs += MESSAGES[id] + b"\0" + output = "" + # The header is 7 32-bit unsigned integers. We don't use hash tables, so + # the keys start right after the index tables. + # translated string. + keystart = 7 * 4 + 16 * len(keys) + # and the values start after the keys + valuestart = keystart + len(ids) + koffsets = [] + voffsets = [] + # The string table first has the list of keys, then the list of values. + # Each entry has first the size of the string, then the file offset. + for o1, l1, o2, l2 in offsets: + koffsets += [l1, o1 + keystart] + voffsets += [l2, o2 + valuestart] + offsets = koffsets + voffsets + output = struct.pack( + "Iiiiiii", + 0x950412DE, # Magic + 0, # Version + len(keys), # # of entries + 7 * 4, # start of key index + 7 * 4 + len(keys) * 8, # start of value index + 0, + 0, + ) # size and offset of hash table + output += array.array("i", offsets).tobytes() + output += ids + output += strs + return output + + +def make(filename, outfile): + ID = 1 + STR = 2 + CTXT = 3 + + # Compute .mo name from .po name and arguments + if filename.endswith(".po"): + infile = filename + else: + infile = filename + ".po" + if outfile is None: + outfile = os.path.splitext(infile)[0] + ".mo" + + try: + with open(infile, "rb") as f: + lines = f.readlines() + except IOError as msg: + print(msg, file=sys.stderr) + sys.exit(1) + + section = msgctxt = None + fuzzy = 0 + + # Start off assuming Latin-1, so everything decodes without failure, + # until we know the exact encoding + encoding = "latin-1" + + # Parse the catalog + lno = 0 + for l in lines: + l = l.decode(encoding) + lno += 1 + # If we get a comment line after a msgstr, this is a new entry + if l[0] == "#" and section == STR: + add(msgctxt, msgid, msgstr, fuzzy) + section = msgctxt = None + fuzzy = 0 + # Record a fuzzy mark + if l[:2] == "#," and "fuzzy" in l: + fuzzy = 1 + # Skip comments + if l[0] == "#": + continue + # Now we are in a msgid or msgctxt section, output previous section + if l.startswith("msgctxt"): + if section == STR: + add(msgctxt, msgid, msgstr, fuzzy) + section = CTXT + l = l[7:] + msgctxt = b"" + elif l.startswith("msgid") and not l.startswith("msgid_plural"): + if section == STR: + add(msgctxt, msgid, msgstr, fuzzy) + if not msgid: + # See whether there is an encoding declaration + p = HeaderParser() + charset = p.parsestr(msgstr.decode(encoding)).get_content_charset() + if charset: + encoding = charset + section = ID + l = l[5:] + msgid = msgstr = b"" + is_plural = False + # This is a message with plural forms + elif l.startswith("msgid_plural"): + if section != ID: + print( + "msgid_plural not preceded by msgid on %s:%d" % (infile, lno), file=sys.stderr + ) + sys.exit(1) + l = l[12:] + msgid += b"\0" # separator of singular and plural + is_plural = True + # Now we are in a msgstr section + elif l.startswith("msgstr"): + section = STR + if l.startswith("msgstr["): + if not is_plural: + print("plural without msgid_plural on %s:%d" % (infile, lno), file=sys.stderr) + sys.exit(1) + l = l.split("]", 1)[1] + if msgstr: + msgstr += b"\0" # Separator of the various plural forms + else: + if is_plural: + print( + "indexed msgstr required for plural on %s:%d" % (infile, lno), + file=sys.stderr, + ) + sys.exit(1) + l = l[6:] + # Skip empty lines + l = l.strip() + if not l: + continue + l = ast.literal_eval(l) + if section == CTXT: + msgctxt += l.encode(encoding) + elif section == ID: + msgid += l.encode(encoding) + elif section == STR: + msgstr += l.encode(encoding) + else: + print("Syntax error on %s:%d" % (infile, lno), "before:", file=sys.stderr) + print(l, file=sys.stderr) + sys.exit(1) + # Add last entry + if section == STR: + add(msgctxt, msgid, msgstr, fuzzy) + + # Compute output + output = generate() + + try: + with open(outfile, "wb") as f: + f.write(output) + except IOError as msg: + print(msg, file=sys.stderr) + + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], "hVo:", ["help", "version", "output-file="]) + except getopt.error as msg: + usage(1, msg) + + outfile = None + # parse options + for opt, arg in opts: + if opt in ("-h", "--help"): + usage(0) + elif opt in ("-V", "--version"): + print("msgfmt.py", __version__) + sys.exit(0) + elif opt in ("-o", "--output-file"): + outfile = arg + # do it + if not args: + print("No input file given", file=sys.stderr) + print("Try `msgfmt --help' for more information.", file=sys.stderr) + return + + for filename in args: + make(filename, outfile) + + +if __name__ == "__main__": + main() diff --git a/tools/preprocess_frozen_modules.py b/tools/preprocess_frozen_modules.py index 30263d2e02..6c41c4cd43 100755 --- a/tools/preprocess_frozen_modules.py +++ b/tools/preprocess_frozen_modules.py @@ -46,7 +46,6 @@ def version_string(path=None, *, valid_semver=False): # with actual version info derived from git. def copy_and_process(in_dir, out_dir): for root, subdirs, files in os.walk(in_dir): - # Skip library examples directory and subfolders. relative_path_parts = Path(root).relative_to(in_dir).parts if relative_path_parts and relative_path_parts[0] in [ diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index 5c14bf2d5b..79b03f1383 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -100,6 +100,7 @@ exclude_tests = ( "float/float_divmod.py", # requires double precision floating point to work "float/float2int_doubleprec_intbig.py", + "float/float_format_ints_doubleprec.py", "float/float_parse_doubleprec.py", # inline asm FP tests (require Cortex-M4) "inlineasm/asmfpaddsub.py",