diff --git a/.codespell/exclude-file.txt b/.codespell/exclude-file.txt new file mode 100644 index 000000000000..9f49d9ae0cc2 --- /dev/null +++ b/.codespell/exclude-file.txt @@ -0,0 +1,7 @@ +#define MICROPY_HW_BOARD_NAME "BLOK" +USB_PRODUCT = "BLOK" + uint32_t THI = (*(uint32_t *)FUSES_HOT_TEMP_VAL_INT_ADDR & FUSES_HOT_TEMP_VAL_INT_Msk) >> FUSES_HOT_TEMP_VAL_INT_Pos; + float TH = THI + convert_dec_to_frac(THD); +print(binascii.b2a_base64(b"fo")) + # again, neither will "there" or "wither", since they have "the" +i1Qb$TE"rl diff --git a/.codespell/ignore-words.txt b/.codespell/ignore-words.txt new file mode 100644 index 000000000000..f2a8dc2be59d --- /dev/null +++ b/.codespell/ignore-words.txt @@ -0,0 +1,22 @@ +ans +ure +clen +ser +endianess +pris +synopsys +reenable +dout +inout +wel +iput +hsi +astroid +busses +cyphertext +dum +deque +deques +extint +shs +pass-thru diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 000000000000..d4ef112d7ae4 --- /dev/null +++ b/.codespellrc @@ -0,0 +1,10 @@ +# See: https://github.com/codespell-project/codespell#using-a-config-file +[codespell] +# In the event of a false positive, add the problematic word, in all lowercase, to 'ignore-words.txt' (one word per line). +# Or copy & paste the whole problematic line to 'exclude-file.txt' +ignore-words = .codespell/ignore-words.txt +exclude-file = .codespell/exclude-file.txt +check-filenames = +check-hidden = +count = +skip = .cproject,.git,./lib,./locale,ACKNOWLEDGEMENTS diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 7b6a53dbbad9..c81bf63123dd 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 000000000000..a26579b53d55 --- /dev/null +++ b/.github/actions/deps/external/action.yml @@ -0,0 +1,63 @@ +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 update + 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 000000000000..8125de2acc48 --- /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 000000000000..7ea747999ba4 --- /dev/null +++ b/.github/actions/deps/ports/broadcom/action.yml @@ -0,0 +1,22 @@ +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 update + 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 000000000000..aa1e98f8a094 --- /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 000000000000..a89a22250525 --- /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 000000000000..d977c937b3dc --- /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 000000000000..9b3732c9e095 --- /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 000000000000..bca76b204cc8 --- /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 000000000000..d9fe54fdc704 --- /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 000000000000..643dd003427d --- /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 000000000000..85e789bf8700 --- /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 000000000000..10c4498bc87c --- /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 c584f5f42722..1b504d34c708 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,174 +9,114 @@ on: pull_request: release: types: [published] - check_suite: - types: [rerequested] concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 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@v3 + - name: Set up repository + uses: actions/checkout@v3 with: submodules: false fetch-depth: 1 - - name: Set up Python 3 + - 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@v3 + - 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@v3 + 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@v3 + 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@v3 - 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 + download: false - name: Get last commit with checks id: get-last-commit-with-checks if: github.event_name == 'pull_request' 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.after }} - run: python3 -u ci_changes_per_commit.py - - name: Get changes - id: get-changes + EXCLUDE_COMMIT: ${{ github.event.pull_request.head.sha }} + - name: Set head sha (pull) if: github.event_name == 'pull_request' - uses: tj-actions/changed-files@v34 - with: - json: true - sha: ${{ steps.get-last-commit-with-checks.outputs.commit && github.event.after }} - base_sha: ${{ steps.get-last-commit-with-checks.outputs.commit }} + run: echo "HEAD_SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV + - name: Set base sha (pull) + if: github.event_name == 'pull_request' + run: git cat-file -e $SHA && echo "BASE_SHA=$SHA" >> $GITHUB_ENV || true + env: + SHA: ${{ steps.get-last-commit-with-checks.outputs.commit_sha || github.event.pull_request.base.sha }} + - name: Set head sha (push) + if: github.event_name == 'push' + run: echo "HEAD_SHA=${{ github.event.after }}" >> $GITHUB_ENV + - name: Set base sha (push) + if: github.event_name == 'push' + run: git cat-file -e $SHA && echo "BASE_SHA=$SHA" >> $GITHUB_ENV || true + env: + SHA: ${{ github.event.before }} - name: Set matrix id: set-matrix + run: python3 -u ci_set_matrix.py working-directory: tools env: - CHANGED_FILES: ${{ steps.get-changes.outputs.all_changed_and_modified_files }} - LAST_FAILED_JOBS: ${{ steps.get-last-commit-with-checks.outputs.checkruns }} - run: python3 -u ci_set_matrix.py + 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-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@v3 + - name: Set up repository + uses: actions/checkout@v3 with: submodules: false fetch-depth: 1 - - name: Set up Python 3 + - name: Set up python uses: actions/setup-python@v4 with: - python-version: "3.10" - - 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 @@ -196,47 +136,47 @@ jobs: 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@v3 + - name: Upload artifact + uses: actions/upload-artifact@v3 with: 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-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/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/mpy-cross-macos-11-${{ env.CP_VERSION }}-x64 --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@v3 + - 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 + - name: Set up python uses: actions/setup-python@v4 with: - python-version: "3.10" + 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@v3 @@ -256,15 +196,13 @@ jobs: 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: @@ -275,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@v4 - with: - python-version: "3.10" - - 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 }} - - 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 + # 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: + 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: | - 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@v3 - 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@v4 - with: - python-version: "3.10" - - 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 }} + 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: | - 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@v3 - 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.10" - - uses: actions/checkout@v3 + 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: CircuitPython version - run: | - tools/describe || git log --parents HEAD~4.. - echo >>$GITHUB_ENV CP_VERSION=$(tools/describe) - - uses: actions/cache@v3 - 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 - 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 - 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@v3 - 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 - build-aarch: - runs-on: ubuntu-20.04 - needs: test + ports: + needs: [scheduler, mpy-cross, tests] + if: needs.scheduler.outputs.ports != '{}' + uses: ./.github/workflows/build-boards.yml + secrets: inherit 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@v4 - with: - python-version: "3.10" - - 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@v3 - 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')) + 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 59% rename from .github/workflows/create_website_pr.yml rename to .github/workflows/create-website-pr.yml index 75de556c68a7..7f047d4b1ea9 100644 --- a/.github/workflows/create_website_pr.yml +++ b/.github/workflows/create-website-pr.yml @@ -10,37 +10,34 @@ on: 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@v3 + - name: Set up repository + uses: actions/checkout@v3 with: submodules: false fetch-depth: 1 - - name: Set up Python 3 + - 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 000000000000..aa8044b0d2f5 --- /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 000000000000..da1ac0a18e28 --- /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 4cfb22298f55..000000000000 --- 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 6d38f3b853e4..000000000000 --- 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@v3 - 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 a23dcd1d115b..b3e51a214847 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -5,8 +5,8 @@ name: pre-commit on: - pull_request: push: + pull_request: concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -16,24 +16,25 @@ jobs: pre-commit: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 - - name: Set up Python 3 + - 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: Install deps + 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 update 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@v3 - with: - path: ~/.cache/pre-commit - key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} - - uses: pre-commit/action@v3.0.0 + - name: Run pre-commit + uses: pre-commit/action@v3.0.0 - name: Make patch if: failure() run: git diff > ~/pre-commit.patch diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 000000000000..44146662f2f9 --- /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/.gitmodules b/.gitmodules index dfd718630c24..a33354bbff28 100644 --- a/.gitmodules +++ b/.gitmodules @@ -33,9 +33,6 @@ path = ports/atmel-samd/asf4 url = https://github.com/adafruit/asf4.git branch = circuitpython -[submodule "tools/usb_descriptor"] - path = tools/usb_descriptor - url = https://github.com/adafruit/usb_descriptor.git [submodule "lib/nrfutil"] path = lib/nrfutil url = https://github.com/adafruit/nRF52_nrfutil @@ -103,7 +100,7 @@ url = https://github.com/adafruit/Adafruit_MP3 [submodule "ports/mimxrt10xx/sdk"] path = ports/mimxrt10xx/sdk - url = https://github.com/adafruit/MIMXRT10xx_SDK + url = https://github.com/nxp-mcuxpresso/mcux-sdk.git [submodule "frozen/Adafruit_CircuitPython_Register"] path = frozen/Adafruit_CircuitPython_Register url = https://github.com/adafruit/Adafruit_CircuitPython_Register.git @@ -187,10 +184,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 @@ -313,8 +306,7 @@ branch = circuitpython [submodule "ports/raspberrypi/lib/cyw43-driver"] path = ports/raspberrypi/lib/cyw43-driver - url = https://github.com/adafruit/cyw43-driver.git - branch = circuitpython8 + 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 @@ -328,3 +320,14 @@ [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 +[submodule "ports/silabs/gecko_sdk"] + path = ports/silabs/gecko_sdk + url = https://github.com/SiliconLabs/gecko_sdk.git + branch = v4.2.1 +[submodule "ports/silabs/tools/slc_cli_linux"] + path = ports/silabs/tools/slc_cli_linux + url = https://github.com/SiliconLabs/circuitpython_slc_cli_linux diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1905b233cfc3..942a51afdc53 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,9 +8,19 @@ repos: hooks: - id: check-yaml - id: end-of-file-fixer - exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/espressif/esp-idf-config/.*|ports/espressif/boards/.*/sdkconfig)' + exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*)' - id: trailing-whitespace - exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|lib/mbedtls_errors/.*)' + exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|lib/mbedtls_errors/generate_errors.diff)' +- repo: https://github.com/codespell-project/codespell + rev: v2.2.4 + hooks: + - id: codespell + args: [-w] + exclude: | + (?x)^( + locale/| + lib/ + ) - repo: local hooks: - id: translations diff --git a/.readthedocs.yml b/.readthedocs.yml index 94ba8750b04c..8f1b89cb6751 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 docs formats: - pdf diff --git a/BUILDING.md b/BUILDING.md index 4793824cf1f8..f108675b7cd9 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -109,7 +109,7 @@ Pre-commit also requires some additional programs to be installed through your p * Standard Unix tools such as make, find, etc * The gettext package, any modern version - * uncrustify version 0.71 (0.72 is also tested) + * uncrustify version 0.71 (0.72 is also tested and OK; 0.75 is not OK) Each time you create a git commit, the pre-commit quality checks will be run. You can also run them e.g., with `pre-commit run foo.c` or `pre-commit run --all` to run on all files whether modified or not. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index be1966ce1eb0..2c17dcfe1659 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -123,7 +123,7 @@ accordingly. ## Attribution -This Code of Conduct is adapted from the [Contributor Covenant][homepage], +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, available at , and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). diff --git a/Makefile b/Makefile index 40952d261d82..d0f1fcb3d078 100644 --- a/Makefile +++ b/Makefile @@ -323,10 +323,25 @@ clean-nrf: clean-stm: $(MAKE) -C ports/stm BOARD=feather_stm32f405_express clean + +# If available, do blobless partial clones of submodules to save time and space. +# A blobless partial clone lazily fetches data as needed, but has all the metadata available (tags, etc.) +# so it does not have the idiosyncrasies of a shallow clone. +# +# If not available, do a fetch that will fail, and then fix it up with a second fetch. +# (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' + git submodule sync + ##################################################################################### + # NOTE: Ideally, use git version 2.36.0 or later, to do partial clones of submodules. + # If an older git is used, submodules will be cloned with a shallow clone of depth 1. + # You will see a git usage message first if the git version is too old to do + # clones of submodules. + ##################################################################################### + git submodule update --init --filter=blob:none || git submodule update --init -N --depth 1 || git submodule foreach 'git fetch --tags --depth 1 origin $$sha1 && git checkout -q $$sha1' || echo 'make fetch-submodules FAILED' + +.PHONY: remove-submodules +remove-submodules: + git submodule deinit -f --all + rm -rf .git/modules/* diff --git a/README.rst b/README.rst index d8a35fb98c28..1a6dc2c33e72 100644 --- a/README.rst +++ b/README.rst @@ -138,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. @@ -145,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 ~~~ diff --git a/conf.py b/conf.py index 7b3b4ca585c7..e14c6ace835a 100644 --- a/conf.py +++ b/conf.py @@ -77,6 +77,7 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', + "sphinxcontrib.jquery", 'sphinxcontrib.rsvgconverter', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', @@ -215,6 +216,7 @@ def autoapi_prepare_jinja_env(jinja_env): "ports/nrf/usb", "ports/raspberrypi/sdk", "ports/raspberrypi/lib", + "ports/silabs", "ports/stm/st_driver", "ports/stm/packages", "ports/stm/peripherals", diff --git a/data/nvm.toml b/data/nvm.toml index 2d292ad4e678..427cc9239762 160000 --- a/data/nvm.toml +++ b/data/nvm.toml @@ -1 +1 @@ -Subproject commit 2d292ad4e67890d4b85b027431ba9fef7bf561fd +Subproject commit 427cc923976229bcb981ca6f218ebe8efd636df6 diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.c b/devices/ble_hci/common-hal/_bleio/Adapter.c index f558d66d40b1..843c14342470 100644 --- a/devices/ble_hci/common-hal/_bleio/Adapter.c +++ b/devices/ble_hci/common-hal/_bleio/Adapter.c @@ -483,7 +483,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t if (self->scan_results != NULL) { if (!shared_module_bleio_scanresults_get_done(self->scan_results)) { - mp_raise_bleio_BluetoothError(translate("Scan already in progess. Stop with stop_scan.")); + mp_raise_bleio_BluetoothError(translate("Scan already in progress. Stop with stop_scan.")); } self->scan_results = NULL; } diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.h b/devices/ble_hci/common-hal/_bleio/Adapter.h index 48d4f2e6a2e8..45a37ad67c2c 100644 --- a/devices/ble_hci/common-hal/_bleio/Adapter.h +++ b/devices/ble_hci/common-hal/_bleio/Adapter.h @@ -65,7 +65,7 @@ typedef struct _bleio_adapter_obj_t { uint16_t manufacturer; uint16_t lmp_subversion; - // Used to monitor advertising timeout for legacy avertising. + // Used to monitor advertising timeout for legacy advertising. uint64_t advertising_start_ticks; uint64_t advertising_timeout_msecs; // If zero, do not check. diff --git a/devices/ble_hci/common-hal/_bleio/Connection.c b/devices/ble_hci/common-hal/_bleio/Connection.c index 95312315061c..e9e1254b4398 100644 --- a/devices/ble_hci/common-hal/_bleio/Connection.c +++ b/devices/ble_hci/common-hal/_bleio/Connection.c @@ -515,7 +515,7 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern // (gattc_char->char_props.write ? CHAR_PROP_WRITE : 0) | // (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0); -// // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. +// // Call common_hal_bleio_characteristic_construct() to initialize some fields and set up evt handler. // common_hal_bleio_characteristic_construct( // characteristic, m_char_discovery_service, gattc_char->handle_value, uuid, // props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, diff --git a/devices/ble_hci/common-hal/_bleio/att.c b/devices/ble_hci/common-hal/_bleio/att.c index f649967ca98e..9dfe9eb26cd4 100644 --- a/devices/ble_hci/common-hal/_bleio/att.c +++ b/devices/ble_hci/common-hal/_bleio/att.c @@ -96,7 +96,7 @@ STATIC uint8_t bleio_properties_to_ble_spec_properties(uint8_t bleio_properties) return ble_spec_properties; } -// FIX not currently used; reenable when used. +// FIX not currently used; re-enable when used. #if 0 STATIC uint8_t ble_spec_properties_to_bleio_properties(uint8_t ble_spec_properties) { uint8_t bleio_properties = 0; @@ -964,7 +964,7 @@ static void process_read_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t d // Keep track of the first one to make sure. size_t sizeof_first_service_uuid = 0; - // Size of a single bt_att_group_data chunk. Start with the intial size, and + // Size of a single bt_att_group_data chunk. Start with the initial size, and // add the uuid size in the loop below. size_t data_length = sizeof(struct bt_att_group_data); diff --git a/devices/ble_hci/common-hal/_bleio/hci_include/att_internal.h b/devices/ble_hci/common-hal/_bleio/hci_include/att_internal.h index af8695da9800..0f03894caac0 100644 --- a/devices/ble_hci/common-hal/_bleio/hci_include/att_internal.h +++ b/devices/ble_hci/common-hal/_bleio/hci_include/att_internal.h @@ -150,7 +150,7 @@ struct bt_att_read_mult_req { uint16_t handles[]; } __packed; -/* Read Multiple Respose */ +/* Read Multiple Response */ #define BT_ATT_OP_READ_MULT_RSP 0x0f struct bt_att_read_mult_rsp { uint8_t _dummy[0]; @@ -243,7 +243,7 @@ struct bt_att_read_mult_vl_req { uint16_t handles[]; } __packed; -/* Read Multiple Respose */ +/* Read Multiple Response */ #define BT_ATT_OP_READ_MULT_VL_RSP 0x21 struct bt_att_read_mult_vl_rsp { uint16_t len; diff --git a/docs/design_guide.rst b/docs/design_guide.rst index 4170d499fee8..40ce285177c8 100644 --- a/docs/design_guide.rst +++ b/docs/design_guide.rst @@ -267,6 +267,14 @@ After the license comment:: """ +Version description +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After the import statements:: + + __version__ = "0.0.0+auto.0" + __repo__ = "" + Class description ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -734,14 +742,7 @@ You could other examples if needed featuring different functionalities of the library. If you add additional examples, be sure to include them in the ``examples.rst``. Naming of the examples files should use the name of the library followed by a description, using underscore to separate them. -When using print statements you should use the ``" ".format()`` format, as there are particular boards -that are not capable to use f-strings. - -.. code-block:: python - - text_to_display = "World!" - print("Hello {}".format(text_to_display)) Sensor properties and units -------------------------------------------------------------------------------- diff --git a/docs/environment.rst b/docs/environment.rst index 58ada402c610..f8144407ef0d 100644 --- a/docs/environment.rst +++ b/docs/environment.rst @@ -74,6 +74,10 @@ CIRCUITPY_WEB_API_PORT ~~~~~~~~~~~~~~~~~~~~~~ TCP port number used for the web HTTP API. Defaults to 80 when omitted. +CIRCUITPY_WEB_INSTANCE_NAME +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Name the board advertises as for the WEB workflow. Defaults to human readable board name if omitted. + CIRCUITPY_WIFI_PASSWORD ~~~~~~~~~~~~~~~~~~~~~~~ Wi-Fi password used to auto connect to CIRCUITPY_WIFI_SSID. diff --git a/docs/shared_bindings_matrix.py b/docs/shared_bindings_matrix.py index 761e3e29f28d..f7efb4738555 100644 --- a/docs/shared_bindings_matrix.py +++ b/docs/shared_bindings_matrix.py @@ -31,7 +31,18 @@ from concurrent.futures import ThreadPoolExecutor -SUPPORTED_PORTS = ['atmel-samd', 'broadcom', 'cxd56', 'espressif', 'litex', 'mimxrt10xx', 'nrf', 'raspberrypi', 'stm'] +SUPPORTED_PORTS = [ + "atmel-samd", + "broadcom", + "cxd56", + "espressif", + "litex", + "mimxrt10xx", + "nrf", + "raspberrypi", + "silabs", + "stm", +] ALIASES_BY_BOARD = { "circuitplayground_express": [ @@ -44,16 +55,11 @@ } ALIASES_BRAND_NAMES = { - "circuitplayground_express_4h": - "Adafruit Circuit Playground Express 4-H", - "circuitplayground_express_digikey_pycon2019": - "Circuit Playground Express Digi-Key PyCon 2019", - "edgebadge": - "Adafruit EdgeBadge", - "pyportal_pynt": - "Adafruit PyPortal Pynt", - "gemma_m0_pycon2018": - "Adafruit Gemma M0 PyCon 2018", + "circuitplayground_express_4h": "Adafruit Circuit Playground Express 4-H", + "circuitplayground_express_digikey_pycon2019": "Circuit Playground Express Digi-Key PyCon 2019", + "edgebadge": "Adafruit EdgeBadge", + "pyportal_pynt": "Adafruit PyPortal Pynt", + "gemma_m0_pycon2018": "Adafruit Gemma M0 PyCon 2018", } ADDITIONAL_MODULES = { @@ -72,7 +78,19 @@ "usb": "CIRCUITPY_USB_HOST", } -MODULES_NOT_IN_SHARED_BINDINGS = ["_asyncio", "array", "binascii", "builtins", "collections", "errno", "json", "re", "select", "sys", "ulab"] +MODULES_NOT_IN_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. @@ -83,16 +101,23 @@ root_dir = pathlib.Path(__file__).resolve().parent.parent + def get_circuitpython_root_dir(): - """ The path to the root './circuitpython' directory. - """ + """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. - """ - shared_bindings_dir = get_circuitpython_root_dir() / "shared-bindings" - return [item.name for item in shared_bindings_dir.iterdir()] + MODULES_NOT_IN_SHARED_BINDINGS + +def get_bindings(): + """Get a list of modules in shared-bindings and ports/*/bindings based on folder names.""" + shared_bindings_modules = [ + module.name + for module in (get_circuitpython_root_dir() / "shared-bindings").iterdir() + if module.is_dir() + ] + bindings_modules = [] + for d in get_circuitpython_root_dir().glob("ports/*/bindings"): + bindings_modules.extend(module.name for module in d.iterdir() if d.is_dir()) + return shared_bindings_modules + bindings_modules + MODULES_NOT_IN_BINDINGS def get_board_mapping(): @@ -124,8 +149,7 @@ def get_board_mapping(): def read_mpconfig(): - """ Open 'circuitpy_mpconfig.mk' and return the contents. - """ + """Open 'circuitpy_mpconfig.mk' and return the contents.""" configs = [] cpy_mpcfg = get_circuitpython_root_dir() / "py" / "circuitpy_mpconfig.mk" with open(cpy_mpcfg) as mpconfig: @@ -135,14 +159,14 @@ def read_mpconfig(): def build_module_map(): - """ Establish the base of the JSON file, based on the contents from - `configs`. Base will contain module names, if they're part of - the `FULL_BUILD`, or their default value (0, 1, or a list of - modules that determine default [see audiocore, audiomixer, etc.]). + """Establish the base of the JSON file, based on the contents from + `configs`. Base will contain module names, if they're part of + the `FULL_BUILD`, or their default value (0, 1, or a list of + modules that determine default [see audiocore, audiomixer, etc.]). """ base = dict() - modules = get_shared_bindings() + modules = get_bindings() configs = read_mpconfig() full_build = False for module in modules: @@ -150,7 +174,7 @@ def build_module_map(): if module in ADDITIONAL_MODULES: search_identifier = ADDITIONAL_MODULES[module] else: - search_identifier = 'CIRCUITPY_'+module.lstrip("_").upper() + search_identifier = "CIRCUITPY_" + module.lstrip("_").upper() re_pattern = f"{re.escape(search_identifier)}\s*\??=\s*(.+)" find_config = re.findall(re_pattern, configs) if not find_config: @@ -173,21 +197,22 @@ def build_module_map(): return base + def get_settings_from_makefile(port_dir, board_name): - """ Invoke make in a mode which prints the database, then parse it for - settings. + """Invoke make in a mode which prints the database, then parse it for + settings. - This means that the effect of all Makefile directives is taken - into account, without having to re-encode the logic that sets them - in this script, something that has proved error-prone + This means that the effect of all Makefile directives is taken + into account, without having to re-encode the logic that sets them + in this script, something that has proved error-prone """ contents = subprocess.run( - ["make", "-C", port_dir, f"BOARD={board_name}", "-qp", "print-CC"], - encoding="utf-8", - errors="replace", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) + ["make", "-C", port_dir, f"BOARD={board_name}", "-qp", "print-CC"], + encoding="utf-8", + errors="replace", + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) # Make signals errors with exit status 2; 0 and 1 are "non-error" statuses if contents.returncode not in (0, 1): error_msg = ( @@ -197,22 +222,23 @@ def get_settings_from_makefile(port_dir, board_name): raise RuntimeError(error_msg) settings = {} - for line in contents.stdout.split('\n'): + for line in contents.stdout.split("\n"): # Handle both = and := definitions. - m = re.match(r'^([A-Z][A-Z0-9_]*) :?= (.*)$', line) + m = re.match(r"^([A-Z][A-Z0-9_]*) :?= (.*)$", line) if m: settings[m.group(1)] = m.group(2) return settings + def get_repository_url(directory): if directory in repository_urls: return repository_urls[directory] readme = None for readme_path in ( - os.path.join(directory, "README.rst"), - os.path.join(os.path.dirname(directory), "README.rst") - ): + os.path.join(directory, "README.rst"), + os.path.join(os.path.dirname(directory), "README.rst"), + ): if os.path.exists(readme_path): readme = readme_path break @@ -220,7 +246,10 @@ def get_repository_url(directory): if readme: with open(readme, "r") as fp: for line in fp.readlines(): - if m := re.match("\s+:target:\s+(http\S+(docs.circuitpython|readthedocs)\S+)\s*", line): + if m := re.match( + "\s+:target:\s+(http\S+(docs.circuitpython|readthedocs)\S+)\s*", + line, + ): path = m.group(1) break if m := re.search("<(http[^>]+)>", line): @@ -233,12 +262,13 @@ def get_repository_url(directory): errors="replace", stdout=subprocess.PIPE, stderr=subprocess.PIPE, - cwd=directory + cwd=directory, ) path = contents.stdout.strip() repository_urls[directory] = path return path + def frozen_modules_from_dirs(frozen_mpy_dirs, withurl): """ Go through the list of frozen directories and extract the python modules. @@ -261,34 +291,36 @@ def frozen_modules_from_dirs(frozen_mpy_dirs, withurl): else: frozen_modules.append(sub.name[:-3]) continue - if next(sub.glob("**/*.py"), None): # tests if not empty + if next(sub.glob("**/*.py"), None): # tests if not empty if withurl: frozen_modules.append((sub.name, url_repository)) else: frozen_modules.append(sub.name) return frozen_modules -def lookup_setting(settings, key, default=''): + +def lookup_setting(settings, key, default=""): while True: value = settings.get(key, default) - if not value.startswith('$'): + if not value.startswith("$"): break key = value[2:-1] return value + @functools.cache def all_ports_all_boards(ports=SUPPORTED_PORTS): for port in ports: - port_dir = get_circuitpython_root_dir() / "ports" / port for entry in (port_dir / "boards").iterdir(): if not entry.is_dir(): continue yield (port, entry) + def support_matrix_by_board(use_branded_name=True, withurl=True): - """ Compiles a list of the available core modules available for each - board. + """Compiles a list of the available core modules available for each + board. """ base = build_module_map() @@ -300,8 +332,9 @@ def support_matrix(arg): if use_branded_name: with open(entry / "mpconfigboard.h") as get_name: board_contents = get_name.read() - board_name_re = re.search(r"(?<=MICROPY_HW_BOARD_NAME)\s+(.+)", - board_contents) + board_name_re = re.search( + r"(?<=MICROPY_HW_BOARD_NAME)\s+(.+)", board_contents + ) if board_name_re: board_name = board_name_re.group(1).strip('"') else: @@ -309,56 +342,69 @@ def support_matrix(arg): board_modules = [] for module in base: - key = base[module]['key'] - if int(lookup_setting(settings, key, '0')): - board_modules.append(base[module]['name']) + key = base[module]["key"] + if int(lookup_setting(settings, key, "0")): + 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(",") + 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"], withurl) + 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, { - "modules": board_modules, - "frozen_libraries": frozen_modules, - "extensions": board_extensions, - } - )] + 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] else: - alias = alias.replace("_"," ").title() - 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) + alias = alias.replace("_", " ").title() + 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], key=lambda x: x[0])) + boards = dict( + sorted( + [board for matrix in mapped_exec for board in matrix], key=lambda x: x[0] + ) + ) return boards -if __name__ == '__main__': + +if __name__ == "__main__": print(json.dumps(support_matrix_by_board(), indent=2)) diff --git a/docs/workflows.md b/docs/workflows.md index 29229bd00e8a..453b425491b1 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -72,7 +72,8 @@ Read-only characteristic that returns the UTF-8 encoded version string. 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 unless overridden by `CIRCUITPY_WEB_API_PORT`. It also enables MDNS. +is on port 80 unless overridden by `CIRCUITPY_WEB_API_PORT`. It also enables MDNS. The name +of the board as advertised to the network can be overridden by `CIRCUITPY_WEB_INSTANCE_NAME`. Here is an example `/settings.toml`: @@ -86,6 +87,7 @@ CIRCUITPY_WIFI_PASSWORD="secretpassword" CIRCUITPY_WEB_API_PASSWORD="passw0rd" CIRCUITPY_WEB_API_PORT=80 +CIRCUITPY_WEB_INSTANCE_NAME="" ``` MDNS is used to resolve [`circuitpython.local`](http://circuitpython.local) to a device specific diff --git a/examples/natmod/features1/features1.c b/examples/natmod/features1/features1.c index f865f1887cd0..a5e82252a170 100644 --- a/examples/natmod/features1/features1.c +++ b/examples/natmod/features1/features1.c @@ -88,7 +88,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a // This must be first, it sets up the globals dict and other things MP_DYNRUNTIME_INIT_ENTRY - // Messages can be printed as usualy + // Messages can be printed as usually mp_printf(&mp_plat_print, "initialising module self=%p\n", self); // Make the functions available in the module's namespace diff --git a/extmod/ulab b/extmod/ulab index e68bb707b20e..f2dd2230c4fd 160000 --- a/extmod/ulab +++ b/extmod/ulab @@ -1 +1 @@ -Subproject commit e68bb707b20ee326d84ab75fc9fb35f2e85b87e3 +Subproject commit f2dd2230c4fdf1aa5c7a160782efdde18e8204bb diff --git a/frozen/Adafruit_CircuitPython_APDS9960 b/frozen/Adafruit_CircuitPython_APDS9960 index ba05423ed9aa..9ddd59650598 160000 --- a/frozen/Adafruit_CircuitPython_APDS9960 +++ b/frozen/Adafruit_CircuitPython_APDS9960 @@ -1 +1 @@ -Subproject commit ba05423ed9aae09ce293603b519a4ac644ef0dab +Subproject commit 9ddd59650598b7a0641d70aabcc8aab71799cb93 diff --git a/frozen/Adafruit_CircuitPython_BLE b/frozen/Adafruit_CircuitPython_BLE index 4fd499e39720..e07e1853d7e9 160000 --- a/frozen/Adafruit_CircuitPython_BLE +++ b/frozen/Adafruit_CircuitPython_BLE @@ -1 +1 @@ -Subproject commit 4fd499e39720f8ce970cceeb97c2a85c485f7335 +Subproject commit e07e1853d7e995b9797a064c098bccc5c384632e diff --git a/frozen/Adafruit_CircuitPython_DRV2605 b/frozen/Adafruit_CircuitPython_DRV2605 index 4a4619a52491..ab0ffa938dfa 160000 --- a/frozen/Adafruit_CircuitPython_DRV2605 +++ b/frozen/Adafruit_CircuitPython_DRV2605 @@ -1 +1 @@ -Subproject commit 4a4619a524918f2705c05ca4959385937afa9a7c +Subproject commit ab0ffa938dfa7eb1fd7260353a7a4e28f55e537a diff --git a/frozen/Adafruit_CircuitPython_DS3231 b/frozen/Adafruit_CircuitPython_DS3231 index 726270f5103d..e6a9a0140ed4 160000 --- a/frozen/Adafruit_CircuitPython_DS3231 +++ b/frozen/Adafruit_CircuitPython_DS3231 @@ -1 +1 @@ -Subproject commit 726270f5103d9d94810eb8b52041b7521afafc5c +Subproject commit e6a9a0140ed44ef5f15d8040fce35b5319c1f216 diff --git a/frozen/Adafruit_CircuitPython_Display_Shapes b/frozen/Adafruit_CircuitPython_Display_Shapes index 656be4d79196..cf2b173d0fc3 160000 --- a/frozen/Adafruit_CircuitPython_Display_Shapes +++ b/frozen/Adafruit_CircuitPython_Display_Shapes @@ -1 +1 @@ -Subproject commit 656be4d79196b5f25ab9ebca731d448c5b3bdc17 +Subproject commit cf2b173d0fc3ac2cd961754c6adf8f614a1c7c39 diff --git a/frozen/Adafruit_CircuitPython_Display_Text b/frozen/Adafruit_CircuitPython_Display_Text index 6cf9f3cf32e0..911201504a26 160000 --- a/frozen/Adafruit_CircuitPython_Display_Text +++ b/frozen/Adafruit_CircuitPython_Display_Text @@ -1 +1 @@ -Subproject commit 6cf9f3cf32e0c176c861de6356813ea4d08034d6 +Subproject commit 911201504a269dbfc49b04ca59bc54adabd4716a diff --git a/frozen/Adafruit_CircuitPython_DotStar b/frozen/Adafruit_CircuitPython_DotStar index d645fc2aded3..187279a95e5c 160000 --- a/frozen/Adafruit_CircuitPython_DotStar +++ b/frozen/Adafruit_CircuitPython_DotStar @@ -1 +1 @@ -Subproject commit d645fc2aded3606e5b0c17689e9f29e7e56bb612 +Subproject commit 187279a95e5cdd634d233af59352558cea4c1227 diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote index 992b601e2469..340c62ef6ce8 160000 --- a/frozen/Adafruit_CircuitPython_IRRemote +++ b/frozen/Adafruit_CircuitPython_IRRemote @@ -1 +1 @@ -Subproject commit 992b601e2469f30e95ec35c9859b4aa2cd917504 +Subproject commit 340c62ef6ce867b3924d166afc3d2a171680f799 diff --git a/frozen/Adafruit_CircuitPython_IS31FL3731 b/frozen/Adafruit_CircuitPython_IS31FL3731 index 794488d1de3d..5433ba3760ca 160000 --- a/frozen/Adafruit_CircuitPython_IS31FL3731 +++ b/frozen/Adafruit_CircuitPython_IS31FL3731 @@ -1 +1 @@ -Subproject commit 794488d1de3d17d1a08887c4a651cfac2c5a1524 +Subproject commit 5433ba3760ca605267223de883a44cb8394f40a5 diff --git a/frozen/Adafruit_CircuitPython_LC709203F b/frozen/Adafruit_CircuitPython_LC709203F index 1919916dcf57..38bd02f01440 160000 --- a/frozen/Adafruit_CircuitPython_LC709203F +++ b/frozen/Adafruit_CircuitPython_LC709203F @@ -1 +1 @@ -Subproject commit 1919916dcf57e0879832b9c274c5fb77712d7775 +Subproject commit 38bd02f014403954ab52154e3877e502d83862dc diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH index 5b4703428fc2..240fe51935f4 160000 --- a/frozen/Adafruit_CircuitPython_LIS3DH +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -1 +1 @@ -Subproject commit 5b4703428fc299ac268d08350c885122b2af1e75 +Subproject commit 240fe51935f4a9def33ef347d40b13862a60b7ac diff --git a/frozen/Adafruit_CircuitPython_LSM6DS b/frozen/Adafruit_CircuitPython_LSM6DS index c8e82b96c680..d689ca77c678 160000 --- a/frozen/Adafruit_CircuitPython_LSM6DS +++ b/frozen/Adafruit_CircuitPython_LSM6DS @@ -1 +1 @@ -Subproject commit c8e82b96c68041a11a52f3053d0d2733ae2d1a49 +Subproject commit d689ca77c67806484037e00110c669cf55846b6e diff --git a/frozen/Adafruit_CircuitPython_MIDI b/frozen/Adafruit_CircuitPython_MIDI index b6891e734183..e38bf1f9cf1e 160000 --- a/frozen/Adafruit_CircuitPython_MIDI +++ b/frozen/Adafruit_CircuitPython_MIDI @@ -1 +1 @@ -Subproject commit b6891e734183f978e7b3d0a363140e98635c0a04 +Subproject commit e38bf1f9cf1e8faeb7d15a1d10674fb2c0a81e72 diff --git a/frozen/Adafruit_CircuitPython_Motor b/frozen/Adafruit_CircuitPython_Motor index 31c819f377cf..9c3de3abce00 160000 --- a/frozen/Adafruit_CircuitPython_Motor +++ b/frozen/Adafruit_CircuitPython_Motor @@ -1 +1 @@ -Subproject commit 31c819f377cf71f61cfb84eae159f1f948980db7 +Subproject commit 9c3de3abce00b50ba936f4f8daad0a8a6bee34a6 diff --git a/frozen/Adafruit_CircuitPython_NeoPixel b/frozen/Adafruit_CircuitPython_NeoPixel index 1064fdee5a14..9516aa97e921 160000 --- a/frozen/Adafruit_CircuitPython_NeoPixel +++ b/frozen/Adafruit_CircuitPython_NeoPixel @@ -1 +1 @@ -Subproject commit 1064fdee5a1421f528af452be5e45ae95ef2b89a +Subproject commit 9516aa97e9216eac2b229fbb7dac34fa60c347c4 diff --git a/frozen/Adafruit_CircuitPython_PortalBase b/frozen/Adafruit_CircuitPython_PortalBase index 7eeea1aaf6bb..759c5c348878 160000 --- a/frozen/Adafruit_CircuitPython_PortalBase +++ b/frozen/Adafruit_CircuitPython_PortalBase @@ -1 +1 @@ -Subproject commit 7eeea1aaf6bb5fa0deb080a1dc1aa3cd103f9aad +Subproject commit 759c5c348878932adc5fcc9e4f3b3f570b43e17f diff --git a/frozen/Adafruit_CircuitPython_ProgressBar b/frozen/Adafruit_CircuitPython_ProgressBar index cad34af5267a..74a1c261103c 160000 --- a/frozen/Adafruit_CircuitPython_ProgressBar +++ b/frozen/Adafruit_CircuitPython_ProgressBar @@ -1 +1 @@ -Subproject commit cad34af5267aca3665fdaf1ea5a0eee921d13f06 +Subproject commit 74a1c261103cda43172053ff2370777255b9bf8d diff --git a/frozen/Adafruit_CircuitPython_RFM69 b/frozen/Adafruit_CircuitPython_RFM69 index 96b4a05c8a22..af1cba8a7e4e 160000 --- a/frozen/Adafruit_CircuitPython_RFM69 +++ b/frozen/Adafruit_CircuitPython_RFM69 @@ -1 +1 @@ -Subproject commit 96b4a05c8a225ad7ddc392be7fb69efebe151981 +Subproject commit af1cba8a7e4e3950fcc5367e9c55a024d9ab9f64 diff --git a/frozen/Adafruit_CircuitPython_RFM9x b/frozen/Adafruit_CircuitPython_RFM9x index df4c73a5e719..c46c59e30048 160000 --- a/frozen/Adafruit_CircuitPython_RFM9x +++ b/frozen/Adafruit_CircuitPython_RFM9x @@ -1 +1 @@ -Subproject commit df4c73a5e719f17fae0309e811ff17627cd0f268 +Subproject commit c46c59e3004817c708c78c59d247b02161c6bf06 diff --git a/frozen/Adafruit_CircuitPython_Register b/frozen/Adafruit_CircuitPython_Register index f611d5e31c97..46a49205f3f1 160000 --- a/frozen/Adafruit_CircuitPython_Register +++ b/frozen/Adafruit_CircuitPython_Register @@ -1 +1 @@ -Subproject commit f611d5e31c9735a3c3ac43185e35dcd5f659e3aa +Subproject commit 46a49205f3f14546273dd1267e66cad82f03986c diff --git a/frozen/Adafruit_CircuitPython_Requests b/frozen/Adafruit_CircuitPython_Requests index 317f4bdb799a..558fff722317 160000 --- a/frozen/Adafruit_CircuitPython_Requests +++ b/frozen/Adafruit_CircuitPython_Requests @@ -1 +1 @@ -Subproject commit 317f4bdb799afa59b164def4ea0610f57db9922e +Subproject commit 558fff7223178eae6228e5262f3a08d3a4101394 diff --git a/frozen/Adafruit_CircuitPython_SD b/frozen/Adafruit_CircuitPython_SD index bb2fc8c157ee..eb17bffa757d 160000 --- a/frozen/Adafruit_CircuitPython_SD +++ b/frozen/Adafruit_CircuitPython_SD @@ -1 +1 @@ -Subproject commit bb2fc8c157ee44869cde4cbc1ab20e6f31ac727f +Subproject commit eb17bffa757dc8c0a53fe9e61c45246c06418099 diff --git a/frozen/Adafruit_CircuitPython_SSD1680 b/frozen/Adafruit_CircuitPython_SSD1680 index 168624262c18..91b6867aca2b 160000 --- a/frozen/Adafruit_CircuitPython_SSD1680 +++ b/frozen/Adafruit_CircuitPython_SSD1680 @@ -1 +1 @@ -Subproject commit 168624262c18f5ee80ec392c0844d6a4c6548760 +Subproject commit 91b6867aca2b0511571fed14ab051d37f1f1544c diff --git a/frozen/Adafruit_CircuitPython_ST7789 b/frozen/Adafruit_CircuitPython_ST7789 index 9ff56ce53f05..e23c4871456c 160000 --- a/frozen/Adafruit_CircuitPython_ST7789 +++ b/frozen/Adafruit_CircuitPython_ST7789 @@ -1 +1 @@ -Subproject commit 9ff56ce53f05e23ff678965ba54af89b24b1199a +Subproject commit e23c4871456cdf0ef1bfb59d1c2f6e38b7b640ee diff --git a/frozen/Adafruit_CircuitPython_SimpleIO b/frozen/Adafruit_CircuitPython_SimpleIO index 0a8fcbfc9206..eac33b430b0c 160000 --- a/frozen/Adafruit_CircuitPython_SimpleIO +++ b/frozen/Adafruit_CircuitPython_SimpleIO @@ -1 +1 @@ -Subproject commit 0a8fcbfc92060eb298ea52d5e88587b37347a0be +Subproject commit eac33b430b0cbe1f6f583000f6b29f75bfe8507e diff --git a/frozen/Adafruit_CircuitPython_Ticks b/frozen/Adafruit_CircuitPython_Ticks index 7832bbb5449d..2634ca016302 160000 --- a/frozen/Adafruit_CircuitPython_Ticks +++ b/frozen/Adafruit_CircuitPython_Ticks @@ -1 +1 @@ -Subproject commit 7832bbb5449d55d8c7b731e4ff7490b801e94a9e +Subproject commit 2634ca0163020bebec300fcca6e0b5afcdc655b8 diff --git a/frozen/Adafruit_CircuitPython_UC8151D b/frozen/Adafruit_CircuitPython_UC8151D index 565fed515138..b6d9f852f50b 160000 --- a/frozen/Adafruit_CircuitPython_UC8151D +++ b/frozen/Adafruit_CircuitPython_UC8151D @@ -1 +1 @@ -Subproject commit 565fed515138f962c4bcce0ee756d32e708a151a +Subproject commit b6d9f852f50b489615f3f357f9758d0073335334 diff --git a/frozen/Adafruit_CircuitPython_asyncio b/frozen/Adafruit_CircuitPython_asyncio index fbdb77d7127e..596cc896e5c8 160000 --- a/frozen/Adafruit_CircuitPython_asyncio +++ b/frozen/Adafruit_CircuitPython_asyncio @@ -1 +1 @@ -Subproject commit fbdb77d7127e7d6a8d3574440b0f790c94a28cf8 +Subproject commit 596cc896e5c8815caa2a6f405560833193848149 diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw index 6234787515e2..d4ff0388f3e3 160000 --- a/frozen/Adafruit_CircuitPython_seesaw +++ b/frozen/Adafruit_CircuitPython_seesaw @@ -1 +1 @@ -Subproject commit 6234787515e2f0ece40b6408722ff0b42824038e +Subproject commit d4ff0388f3e3af2745864f2c3e5926f500673a40 diff --git a/lib/AnimatedGIF/AnimatedGIF.cpp b/lib/AnimatedGIF/AnimatedGIF.cpp new file mode 100644 index 000000000000..ad79b212b8a7 --- /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 000000000000..e1868bb6cd5a --- /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 000000000000..c1f359194f5c --- /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 000000000000..25b8cd59b79b --- /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 000000000000..0822b608c183 --- /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/lib/oofatfs/ff.c b/lib/oofatfs/ff.c index 9d3c67cf7d6a..dbcfa3efc314 100644 --- a/lib/oofatfs/ff.c +++ b/lib/oofatfs/ff.c @@ -278,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, \ @@ -286,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, \ @@ -2887,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 diff --git a/lib/oofatfs/ffunicode.c b/lib/oofatfs/ffunicode.c index 4153f9131c3c..a04577616a6c 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/lib/tinyusb b/lib/tinyusb index 73896a3b71c5..ec9c666107c0 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 73896a3b71c525a3ee4cefa7e35ce3b3a93786ef +Subproject commit ec9c666107c0be0f8dc7c2a15e3bdea8c44a50b4 diff --git a/locale/ID.po b/locale/ID.po index 9f1e185dff94..7163efb5dfb6 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -33,12 +33,21 @@ 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" -"Harap ajukan masalah dengan konten drive CIRCUITPY Anda di\n" -"https://github.com/adafruit/circuitpython/issues\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -91,7 +100,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -111,7 +120,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -126,7 +140,7 @@ msgstr "%q indeks di luar batas" msgid "%q init failed" msgstr "" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "" @@ -178,12 +192,21 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q harus bertipe %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" + +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "" -#: py/objexcept.c 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 @@ -203,10 +226,6 @@ 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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -223,7 +242,7 @@ msgstr "%q, %q, dan %q semuanya harus memiliki panjang yang sama" msgid "%q=%q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s kesalahan 0x%x" @@ -389,10 +408,6 @@ msgstr "0.0 ke kompleks berpangkat" msgid "3-arg pow() not supported" msgstr "pow() 3-arg tidak didukung" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "" - #: 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 @@ -439,7 +454,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" @@ -492,6 +506,7 @@ msgstr "Sudah disebarkan." msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -531,10 +546,6 @@ msgstr "Nilai array harus berupa byte tunggal." 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 "" @@ -585,20 +596,13 @@ 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 msgid "Both RX and TX required for flow control" 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/meowmeow/mpconfigboard.h -msgid "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Kedua pin harus mendukung hardware interrut" @@ -664,11 +668,6 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "Pin bus %d sudah digunakan" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Byte buffer harus 16 byte." @@ -681,7 +680,7 @@ msgstr "Blok CBC harus merupakan kelipatan 16 byte" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -803,10 +802,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" @@ -822,6 +817,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" @@ -846,10 +849,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" @@ -941,24 +940,16 @@ msgstr "" msgid "Error in regex" msgstr "Error pada regex" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Diharapkan %q" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1026,7 +1017,7 @@ 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 @@ -1085,7 +1076,7 @@ msgstr "Fungsinya membutuhkan kunci" msgid "GNSS init" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1114,6 +1105,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" @@ -1131,11 +1131,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 "" @@ -1235,10 +1230,19 @@ msgstr "Kesalahan internal #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "%q pada tidak valid" @@ -1256,12 +1260,15 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Argumen tidak valid" @@ -1279,19 +1286,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "" + #: shared-module/audiocore/WaveFile.c 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 "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "" @@ -1300,7 +1307,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "" @@ -1332,7 +1339,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "" @@ -1532,10 +1539,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "Tidak ada kunci yang ditentukan" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "Tidak ada dukungan bilangan bulat yang panjang" @@ -1575,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 "" @@ -1598,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" @@ -1701,11 +1696,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "Waktu habis" @@ -1713,7 +1708,7 @@ msgstr "Waktu habis" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "Kehabisan memori" @@ -1886,6 +1881,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1895,7 +1891,7 @@ msgstr "Baca-saja" msgid "Read-only filesystem" msgstr "sistem file (filesystem) bersifat Read-only" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1915,7 +1911,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "Mode AES yang diminta tidak didukung" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1969,8 +1965,8 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." -msgstr "Pindai sudah dalam proses. Hentikan dengan stop_scan." +msgid "Scan already in progress. Stop with stop_scan." +msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2030,10 +2026,6 @@ msgstr "" 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 "Berikan setidaknya satu pin UART" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2047,50 +2039,19 @@ msgid "Temperature read timed out" msgstr "Waktu baca suhu habis" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2109,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 "" @@ -2141,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2189,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 "" @@ -2236,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 "" @@ -2254,10 +2228,20 @@ 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" @@ -2294,6 +2278,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2329,11 +2318,6 @@ 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 @@ -2382,7 +2366,7 @@ msgstr "Panjang nilai != Panjang tetap yang dibutuhkan" msgid "Value length > max_length" msgstr "Panjang nilai > max_length" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2443,13 +2427,56 @@ msgstr "" msgid "Writes not supported on Characteristic" msgstr "Menulis tidak didukung pada Karakteristik" +#: 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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2521,6 +2548,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2741,7 +2772,7 @@ msgstr "" msgid "can't set attribute" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2949,6 +2980,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "" @@ -2990,9 +3025,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -3000,14 +3035,6 @@ msgstr "" 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 "" @@ -3045,8 +3072,8 @@ msgid "extra positional arguments given" msgstr "argumen posisi ekstra telah diberikan" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3377,7 +3404,7 @@ msgstr "key tidak valid" msgid "invalid micropython decorator" msgstr "micropython decorator tidak valid" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3634,7 +3661,7 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" @@ -3771,6 +3798,10 @@ msgstr "" 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 "" @@ -3832,11 +3863,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3861,14 +3888,10 @@ msgstr "" msgid "parameters must be registers in sequence r0 to r3" msgstr "parameter harus menjadi register dalam urutan r0 sampai r3" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4116,10 +4139,6 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4155,8 +4174,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" @@ -4287,10 +4304,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4378,6 +4391,43 @@ msgstr "zi harus berjenis float" msgid "zi must be of shape (n_section, 2)" msgstr "Zi harus berbentuk (n_section, 2)" +#~ msgid "No key was specified" +#~ msgstr "Tidak ada kunci yang ditentukan" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "Pindai sudah dalam proses. Hentikan dengan stop_scan." + +#~ 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" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 7546dfa0c6ca..f87fc029752d 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -31,8 +31,20 @@ 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 @@ -85,7 +97,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -105,7 +117,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -120,7 +137,7 @@ msgstr "" msgid "%q init failed" msgstr "" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "" @@ -172,12 +189,21 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" + +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" msgstr "" -#: py/objexcept.c 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,10 +223,6 @@ msgstr "" msgid "%q out of range" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -217,7 +239,7 @@ msgstr "" msgid "%q=%q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -383,10 +405,6 @@ msgstr "" msgid "3-arg pow() not supported" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "" - #: 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 @@ -433,7 +451,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 "" @@ -486,6 +503,7 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -525,10 +543,6 @@ msgstr "" 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 "" @@ -577,20 +591,13 @@ 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 msgid "Both RX and TX required for flow control" 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/meowmeow/mpconfigboard.h -msgid "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "" @@ -656,11 +663,6 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "" @@ -673,7 +675,7 @@ msgstr "" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -791,10 +793,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 "" @@ -809,6 +807,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 "" @@ -833,10 +839,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 "" @@ -928,24 +930,16 @@ msgstr "" msgid "Error in regex" msgstr "" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" -msgstr "" - -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1013,7 +1007,7 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c @@ -1072,7 +1066,7 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1101,6 +1095,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 "" @@ -1118,11 +1121,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 "" @@ -1220,10 +1218,19 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "" @@ -1241,12 +1248,15 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "" @@ -1264,19 +1274,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "" @@ -1285,7 +1295,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "" @@ -1317,7 +1327,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "" @@ -1517,10 +1527,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -1560,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 "" @@ -1583,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" @@ -1681,11 +1679,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1693,7 +1691,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1859,6 +1857,7 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" @@ -1868,7 +1867,7 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1888,7 +1887,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1940,7 +1939,7 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." +msgid "Scan already in progress. Stop with stop_scan." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -2001,10 +2000,6 @@ msgstr "" 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 "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2018,50 +2013,19 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2080,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 "" @@ -2112,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2160,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 "" @@ -2207,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 "" @@ -2225,10 +2202,20 @@ 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" @@ -2265,6 +2252,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2300,11 +2292,6 @@ 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 @@ -2351,7 +2338,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2412,13 +2399,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2490,6 +2520,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2710,7 +2744,7 @@ msgstr "" msgid "can't set attribute" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2918,6 +2952,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "" @@ -2959,9 +2997,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -2969,14 +3007,6 @@ msgstr "" 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 "" @@ -3014,8 +3044,8 @@ msgid "extra positional arguments given" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3346,7 +3376,7 @@ msgstr "" msgid "invalid micropython decorator" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3603,7 +3633,7 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" @@ -3739,6 +3769,10 @@ msgstr "" 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 "" @@ -3800,11 +3834,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3829,14 +3859,10 @@ msgstr "" msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4084,10 +4110,6 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4123,8 +4145,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 "" @@ -4255,10 +4275,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index b73fe1df8804..0e6b8714af1a 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -35,12 +35,21 @@ 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\"" @@ -92,7 +101,7 @@ msgstr "%d adresní pin, %d rgb pin a %d dlaždice indikuje výšku %d, ne %d" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -112,7 +121,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -127,7 +141,7 @@ msgstr "Index %q je mimo rozsah" msgid "%q init failed" msgstr "Inicializace %q selhala" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "" @@ -179,13 +193,22 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q musí být typu %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q musí být typu %q nebo None" +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +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 msgid "%q must be power of 2" @@ -204,10 +227,6 @@ 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ý" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -224,7 +243,7 @@ msgstr "%q, %q, a %q musí mít všechny shodnou délku" msgid "%q=%q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s chyba 0x%x" @@ -390,10 +409,6 @@ msgstr "" msgid "3-arg pow() not supported" msgstr "pow() nepodporuje 3 argumenty" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "64 bit typy" - #: 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 @@ -440,7 +455,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" @@ -493,6 +507,7 @@ msgstr "Již propagujeme." msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -532,10 +547,6 @@ msgstr "Hodnoty pole by měly být jednoduché bajty." 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" @@ -586,20 +597,13 @@ 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" msgstr "RX a TX jsou vyžadovány pro kontrolu toku" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Oba piny musí podporovat hardwarové přerušení" @@ -665,11 +669,6 @@ msgstr "Buffery musí mít stejnou velikost" msgid "Bus pin %d is already in use" msgstr "Sběrnicový pin %d je již používán" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Bajtový buffer musí být 16 bajtů." @@ -682,7 +681,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -801,10 +800,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é" @@ -820,6 +815,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" @@ -844,10 +847,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" @@ -939,24 +938,16 @@ msgstr "Chyba v MIDI přenosu na pozici %d" msgid "Error in regex" msgstr "Chyba v regulárním výrazu" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.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" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1024,8 +1015,8 @@ 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" @@ -1085,7 +1076,7 @@ msgstr "Funkce vyžaduje zámek" msgid "GNSS init" msgstr "Inicializace GNSS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "Základní chyba" @@ -1114,6 +1105,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 "" @@ -1131,11 +1131,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 "" @@ -1235,10 +1230,19 @@ msgstr "Vnitřní chyba #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Neplatný pin %q" @@ -1256,12 +1260,15 @@ msgstr "Chybný BLE parametr" msgid "Invalid BSSID" msgstr "Chybné BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Chybná MAC adresa" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Neplatný argument" @@ -1279,19 +1286,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "Chybný data_pin[%d]" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "" + #: shared-module/audiocore/WaveFile.c 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" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "Chybná velikost" @@ -1300,7 +1307,7 @@ msgstr "Chybná velikost" msgid "Invalid socket for TLS" msgstr "Chybný soket pro TLS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "Chybný stav" @@ -1332,7 +1339,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "MAC adresa byla chybná" @@ -1532,10 +1539,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "Nebyl zadán klíč" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -1575,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 "" @@ -1598,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" @@ -1697,11 +1692,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1709,7 +1704,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1877,6 +1872,7 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" @@ -1886,7 +1882,7 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1906,7 +1902,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1958,7 +1954,7 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." +msgid "Scan already in progress. Stop with stop_scan." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -2019,10 +2015,6 @@ msgstr "" 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 "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2036,50 +2028,19 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2098,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 "" @@ -2130,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2178,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 "" @@ -2225,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 "" @@ -2243,10 +2217,20 @@ 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" @@ -2283,6 +2267,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2318,11 +2307,6 @@ 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 @@ -2369,7 +2353,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2430,13 +2414,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2508,6 +2535,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2728,7 +2759,7 @@ msgstr "" msgid "can't set attribute" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2936,6 +2967,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "" @@ -2977,9 +3012,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -2987,14 +3022,6 @@ msgstr "" 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 "" @@ -3032,8 +3059,8 @@ msgid "extra positional arguments given" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3364,7 +3391,7 @@ msgstr "" msgid "invalid micropython decorator" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3621,7 +3648,7 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" @@ -3757,6 +3784,10 @@ msgstr "" 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 "" @@ -3818,11 +3849,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3847,14 +3874,10 @@ msgstr "" msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4102,10 +4125,6 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4141,8 +4160,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 "" @@ -4273,10 +4290,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4364,6 +4377,55 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "64 bit types" +#~ msgstr "64 bit typy" + +#~ msgid "No key was specified" +#~ msgstr "Nebyl zadán klíč" + +#~ 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" diff --git a/locale/de_DE.po b/locale/de_DE.po index 69d2e6ee366a..6b6883128846 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-11-09 19:20+0000\n" +"PO-Revision-Date: 2023-03-31 14: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.15-dev\n" +"X-Generator: Weblate 4.17-dev\n" #: main.c msgid "" @@ -34,12 +34,28 @@ 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 "" "\n" -"Bitte melde ein Problem mit dem Inhalt Ihres CIRCUITPY-Laufwerks unter\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Bitte erstellen Sie ein Problem (Issue) für Ihr Programm unter https://" +"github.com/adafruit/circuitpython/issues." + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" +"\n" +"Drücke Reset, um den Sicherheitsmodus zu beenden.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" +"\n" +"Sie befinden sich im abgesicherten Modus, weil:\n" #: py/obj.c msgid " File \"%q\"" @@ -93,7 +109,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -113,7 +129,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -128,13 +149,13 @@ msgstr "Der Index %q befindet sich außerhalb des Bereiches" msgid "%q init failed" msgstr "%q Initialisierung ist gescheitert" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.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 "" +msgstr "%q ist für diese Platine schreibgeschützt" #: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" @@ -174,20 +195,29 @@ msgstr "%q muss >= %d sein" #: shared-bindings/analogbufio/BufferedIn.c msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "" +msgstr "%q muss ein Bytearray oder ein Array vom Typ 'H' oder 'B' 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" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q muss vom Type %q sein" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "%q muss ein Array vom Typ 'H' sein" + +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +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 muss von Typ %q oder %q sein, nicht %q" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q muss vom Type %q oder None sein" +#: 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" @@ -206,13 +236,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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" -msgstr "" +msgstr "Schritt %q kann nicht Null sein" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -227,7 +253,7 @@ msgstr "%q, %q und %q müssen alle die gleiche Länge haben" msgid "%q=%q" msgstr "%q=%q" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s Fehler 0x%x" @@ -393,10 +419,6 @@ msgstr "0.0 zu einer komplexen Potenz" msgid "3-arg pow() not supported" msgstr "3-arg pow() wird nicht unterstützt" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "64 bit-Typen" - #: 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 @@ -414,7 +436,7 @@ msgstr "Die Adresse muss %d Bytes lang sein" #: ports/espressif/common-hal/memorymap/AddressRange.c msgid "Address range not allowed" -msgstr "" +msgstr "Adressbereich nicht erlaubt" #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" @@ -443,7 +465,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" @@ -496,6 +517,7 @@ msgstr "Bereits am Anbieten (advertising)." msgid "Already have all-matches listener" msgstr "All-Matchers-Listener bereits vorhanden" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -510,7 +532,7 @@ msgstr "Sucht bereits nach Wifi-Netzwerken" #: shared-module/os/getenv.c #, c-format msgid "An error occurred while retrieving '%s':\n" -msgstr "" +msgstr "Ein Fehler ist aufgetreten beim Abfragen von '%s':\n" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" @@ -535,10 +557,6 @@ msgstr "Array-Werte sollten aus Einzelbytes bestehen." 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" @@ -589,20 +607,13 @@ 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 "Boot-Device muss an erster Stelle kommen (Interface #0)." #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" msgstr "Sowohl RX als auch TX sind zu Flusssteuerung erforderlich" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "Beim Starten wurden beide Tasten gedrückt.\n" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Beide Pins müssen Hardware-Interrupts unterstützen" @@ -668,11 +679,6 @@ msgstr "Buffers müssen gleiche Größe haben" msgid "Bus pin %d is already in use" msgstr "Bus-Pin %d wird schon benutzt" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "Beim Starten wurde Taste A gedrückt.\n" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Der Puffer muss 16 Bytes lang sein." @@ -685,7 +691,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC oder Checksumme ungültig" @@ -792,9 +798,8 @@ 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 "Kann nicht durch \"Pin edge\" geweckt werden nur durch \"level\"" +msgstr "Kann nicht durch Flanke an Pin geweckt werden, sondern nur durch Pegel" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." @@ -808,10 +813,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" @@ -828,6 +829,14 @@ msgstr "" "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 "Koordinaten-Arrays haben unterschiedliche Längen" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "Typen der Koordinaten-Arrays haben unterschiedliche Längen" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Beschädigte .mpy Datei" @@ -852,10 +861,6 @@ 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" @@ -921,6 +926,8 @@ 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" @@ -947,25 +954,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 "Fehler in safemode.py." + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "Error: Bind Fehler" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.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" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" -msgstr "Erwartete ein %q oder %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" -msgstr "Erwartet ein %q" +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 @@ -1033,8 +1032,8 @@ 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 "Hardware hat Fehler festgestellt." #: py/moduerrno.c msgid "File exists" @@ -1042,7 +1041,7 @@ msgstr "Datei existiert" #: shared-module/os/getenv.c msgid "File not found" -msgstr "" +msgstr "Datei nicht gefunden" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c @@ -1096,7 +1095,7 @@ msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde" msgid "GNSS init" msgstr "GNSS-Initialisierung" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "Generischer Fehler" @@ -1125,6 +1124,16 @@ msgstr "Hardware beschäftigt, versuche alternative Pins" 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 "Allokation auf Heap während VM nicht läuft." + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" +"Heap wurde beschädigt, weil der Stack zu klein war. Bitte Stack vergrößern." + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "Lese/Schreibe-operation an geschlossener Datei" @@ -1142,11 +1151,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" @@ -1250,10 +1254,19 @@ msgstr "Interner Fehler #%d" msgid "Internal watchdog timer expired." msgstr "Der Interne WatchDog Timer ist abgelaufen." -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Interrupt Fehler." + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Ungültiger %q Pin" @@ -1271,12 +1284,15 @@ msgstr "Ungültiges BLE Parameter" msgid "Invalid BSSID" msgstr "Ungültige BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "Ungültiger Wert CIRCUITPY_PYSTACK_SIZE\n" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Ungültige MAC-Adresse" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Ungültiges Argument" @@ -1287,26 +1303,26 @@ msgstr "Ungültige Bits pro Wert" #: shared-module/os/getenv.c #, c-format msgid "Invalid byte %.*s" -msgstr "" +msgstr "Ungültiges Byte %.*s" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" msgstr "Ungültige data_pins[%d]" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "Ungültiges Format" + #: shared-module/audiocore/WaveFile.c 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" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "Ungültige Größe" @@ -1315,13 +1331,13 @@ msgstr "Ungültige Größe" msgid "Invalid socket for TLS" msgstr "Ungültiges Socket für TLS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "Ungültiger Zustand" #: shared-module/os/getenv.c msgid "Invalid unicode escape" -msgstr "" +msgstr "Ungültiges Unicode-Escape-Zeichen" #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" @@ -1329,7 +1345,7 @@ msgstr "Der Schlüssel muss 16, 24 oder 32 Byte lang sein" #: shared-module/os/getenv.c msgid "Key not found" -msgstr "" +msgstr "Schlüssel nicht gefunden" #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" @@ -1347,7 +1363,7 @@ msgstr "Ebene ist bereits in der Gruppe" msgid "Layer must be a Group or TileGrid subclass" msgstr "Ebene muss eine Gruppe oder eine TileGrid Subklasse sein" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "MAC Adresse war ungültig" @@ -1440,7 +1456,7 @@ msgstr "NVS-Fehler" #: shared-bindings/socketpool/SocketPool.c msgid "Name or service not known" -msgstr "" +msgstr "Name oder Dienst nicht bekannt" #: py/qstr.c msgid "Name too long" @@ -1548,10 +1564,6 @@ msgstr "Nicht in Programm" msgid "No in or out in program" msgstr "Kein Ein oder Aus in Programm" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "Es wurde kein Schlüssel angegeben" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "Keine langen Integer (long) unterstützt" @@ -1591,10 +1603,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" @@ -1614,10 +1622,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" @@ -1692,7 +1696,7 @@ msgstr "Nur ein %q kann im Deep-Sleep gesetzt werden." #: ports/espressif/common-hal/espulp/ULPAlarm.c msgid "Only one %q can be set." -msgstr "" +msgstr "Es kann nur ein %q festgelegt werden." #: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c @@ -1718,19 +1722,19 @@ msgstr "Nur eine Farbe kann transparent sein zu einer Zeit" msgid "Operation not permitted" msgstr "Operation nicht erlaubt" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "Vorgang oder Funktion wird nicht unterstützt" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "Zeit für Vorgang abgelaufen" #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Out of MDNS service slots" -msgstr "" +msgstr "Keine freien Slots für MDNS-Dienst mehr verfügbar" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "Kein Speicher mehr verfügbar" @@ -1834,7 +1838,7 @@ msgstr "Polygone brauchen mindestens 3 Punkte" #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" -msgstr "Der Präfix-Puffer muss sich auf dem Heap befinden" +msgstr "Präfix-Puffer muss sich auf dem Heap befinden" #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" @@ -1861,7 +1865,7 @@ msgstr "Programm-Größe ist ungültig" #: ports/espressif/common-hal/espulp/ULP.c msgid "Program too long" -msgstr "" +msgstr "Programm zu lang" #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." @@ -1882,7 +1886,7 @@ msgstr "RNG DeInit-Fehler" #: ports/stm/common-hal/os/__init__.c msgid "RNG Init Error" -msgstr "RNG Init-Fehler" +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 @@ -1902,6 +1906,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1911,7 +1916,7 @@ msgstr "Nur lesen möglich, da Schreibgeschützt" msgid "Read-only filesystem" msgstr "Schreibgeschützte Dateisystem" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "Erhaltene Antwort ist ungültig" @@ -1931,7 +1936,7 @@ msgstr "RemoteTransmissionRequests limitiert auf 8 Bytes" msgid "Requested AES mode is unsupported" msgstr "Der angeforderte AES-Modus wird nicht unterstützt" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "Angefragte Ressource nicht gefunden" @@ -1983,8 +1988,8 @@ 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 bereits in Bearbeitung. Stoppe mit stop_scan." +msgid "Scan already in progress. Stop with stop_scan." +msgstr "Scan läuft schon. Stoppen mit stop_scan." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2022,7 +2027,7 @@ msgstr "SocketPool kann nur mit wifi.radio verwendet werden" #: shared-bindings/aesio/aes.c msgid "Source and destination buffers must be the same length" -msgstr "Quell- und Zielbuffer müssen gleich lang sein" +msgstr "Quell- und Zielpuffer müssen gleich lang sein" #: shared-bindings/paralleldisplay/ParallelBus.c msgid "Specify exactly one of data0 or data_pins" @@ -2042,11 +2047,7 @@ msgstr "Stereo rechts muss sich auf PWM-Kanal B befinden" #: 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 "Gib mindestens einen UART-Pin an" +msgstr "Das Stoppen des AP wird nicht unterstützt." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -2061,58 +2062,25 @@ msgid "Temperature read timed out" msgstr "Zeitüberschreitung beim Auslesen der Temperatur" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -msgstr "Beim Starten wurde die Taste BOOT gedrückt.\n" - -#: 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ößere den Stack, wenn du weißt, wie. Wenn nicht:" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "Beim Starten wurde die Taste SW38 gedrückt.\n" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "Beim Starten wurde die Taste VOLUME gedrückt.\n" - -#: supervisor/shared/safe_mode.c -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." +"Das 'microcontroller'-Modul wurde benutzt, um in den Sichheitsmodus zu " +"booten." #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" - -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "Beim Starten wurde die zentrale Taste gedrückt.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "Beim Starten wurde die linke Taste gedrückt.\n" +"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. 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)." +"Die Spannung ist eingebrochen. Stelle sicher, dass genügend Leistung " +"verfügbar ist." #: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" @@ -2121,7 +2089,7 @@ msgstr "" #: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" -msgstr "Die Kanalanzahl des Samples stimmt nicht mit der des Mixers überein" +msgstr "Die Kanalanzahl des Samples stimmt nicht mit der des Mischers überein" #: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" @@ -2129,8 +2097,11 @@ msgstr "Die Abtastrate der Probe stimmt nicht mit der des Mischers überein" #: shared-module/audiomixer/MixerVoice.c 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" +msgstr "Der Vorzeichentyp des Samples stimmt nicht mit dem des Mixers überein" + +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "Fataler Fehler bei Drittanbieter-Firmware." #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." @@ -2150,7 +2121,7 @@ msgstr "Die Kachelhöhe muss die Bitmaphöhe genau teilen" #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" -msgstr "Kachel index außerhalb der Grenzen" +msgstr "Kachelindex außerhalb der Grenzen" #: shared-bindings/displayio/TileGrid.c msgid "Tile width must exactly divide bitmap width" @@ -2167,12 +2138,6 @@ 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 requesting safe mode." -msgstr "" -"Zum Beenden setze bitte das Board zurück, ohne den abgesicherten Modus " -"aufzurufen." - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "Zu viele Kanäle im Beispiel" @@ -2183,7 +2148,7 @@ msgstr "Zu viele Kanäle im sample." #: shared-module/displayio/__init__.c msgid "Too many display busses" -msgstr "Zu viele Display Busse" +msgstr "Zu viele Anzeigebusse" #: shared-module/displayio/__init__.c msgid "Too many displays" @@ -2217,6 +2182,10 @@ msgstr "UART wird de-initialisiert" msgid "UART init" msgstr "UART-Initialisierung" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "UART-Endgerät in Benutzung" + #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "UART wird erneut Initialisiert" @@ -2264,6 +2233,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 "Keine Allokation auf dem Heap möglich." + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "ADC-DMA-Controller konnte nicht konfiguriert werden, Fehlercode: %d" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "Lock kann nicht erzeugt werden" @@ -2282,10 +2260,20 @@ 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 "ADC-DMA-Controller konnte nicht initialisiert werden, Fehlercode: %d" + #: 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 "ADC-DMA-Controller konnte nicht gestartet werden, Fehlercode: %d" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2293,7 +2281,7 @@ msgstr "mDNS-Abfrage kann nicht gestartet werden" #: shared-bindings/memorymap/AddressRange.c msgid "Unable to write to address." -msgstr "" +msgstr "An die Adresse kann nicht geschrieben werden." #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." @@ -2322,6 +2310,11 @@ msgstr "Unbekannter BLE-Fehler bei %s:%d: %d" msgid "Unknown BLE error: %d" msgstr "Unbekannter BLE-Fehler: %d" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "Unbekannter Fehlercode %d" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2357,11 +2350,6 @@ 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 @@ -2403,7 +2391,7 @@ msgstr "Update fehlgeschlagen" #: ports/nrf/common-hal/_bleio/Characteristic.c #: ports/nrf/common-hal/_bleio/Descriptor.c msgid "Value length != required fixed length" -msgstr "Wert Länge != Erforderliche feste Länge" +msgstr "Länge des Wertes != Erforderliche feste Länge" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/espressif/common-hal/_bleio/Descriptor.c @@ -2412,7 +2400,7 @@ msgstr "Wert Länge != Erforderliche feste Länge" msgid "Value length > max_length" msgstr "Länge des Wertes > max_length" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "Version ist ungültig" @@ -2464,15 +2452,15 @@ msgstr "Wi-Fi: " #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is in access point mode." -msgstr "" +msgstr "Das Wifi ist im Accesspoint-Modus." #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is in station mode." -msgstr "" +msgstr "Das Wifi ist im Station-Modus." #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is not enabled" -msgstr "" +msgstr "WLAN ist nicht aktiviert" #: main.c msgid "Woken up by alarm.\n" @@ -2481,18 +2469,59 @@ msgstr "Aufgeweckt durch Alarm.\n" #: ports/espressif/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" -msgstr "Schreiben nicht unterstüzt für diese Charakteristik" +msgstr "Schreiben für diese Charakteristik nicht unterstützt" + +#: 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 "Beide Knöpfe wurden beim Starten gedrückt." + +#: 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 "Knopf A wurde beim Starten gedrückt." #: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" -msgstr "Du befindest dich im abgesicherten Modus, weil:\n" +msgid "You pressed the BOOT button at start up" +msgstr "Der BOOT-Knopf wurde beim Starten gedrückt." + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "Der GPIO0-Knopf wurde beim Starten gedrückt." + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "Der Rec-Knopf wurde beim Starten gedrückt." + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "Der SW38-Knopf wurde beim Starten gedrückt." + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "Der VOLUME-Knopf wurde beim Starten gedrückt." + +#: 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 "Der zentrale Knopf wurde beim Starten gedrückt." + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "Der linke Knopf wurde beim Starten gedrückt." #: supervisor/shared/safe_mode.c -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 "You pressed the reset button during boot." +msgstr "Der Reset-Knopf wurde beim Booten gedrückt." + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "[abgeschnitten wegen der Länge]" #: py/objtype.c msgid "__init__() should return None" @@ -2563,6 +2592,10 @@ msgstr "Array- und Indexlänge müssen gleich sein" msgid "array has too many dimensions" msgstr "Das Array hat zu viele Dimensionen" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "Array ist zu groß" + #: py/objarray.c shared-bindings/alarm/SleepMemory.c #: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2776,8 +2809,8 @@ msgstr "kann keinen relativen Import durchführen" #: py/objgenerator.c msgid "can't send non-None value to a just-started generator" msgstr "" -"Nicht \"None\" Werte können nicht an einen gerade gestarteten Generator " -"gesendet werden" +"Nicht-None-Wert kann nicht an einen gerade gestarteten Generator gesendet " +"werden" #: shared-module/sdcardio/SDCard.c msgid "can't set 512 block size" @@ -2787,9 +2820,9 @@ msgstr "Kann Blockgröße von 512 nicht setzen" msgid "can't set attribute" msgstr "kann Attribut nicht setzen" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" -msgstr "" +msgstr "Attribut '%q' kann nicht gesetzt werden" #: py/emitnative.c msgid "can't store '%q'" @@ -2859,7 +2892,7 @@ msgstr "Kanal wird erneut initialisiert" #: shared-bindings/_stage/Text.c msgid "chars buffer too small" -msgstr "(char) Zeichenpuffer zu klein" +msgstr "Zeichenpuffer zu klein" #: py/modbuiltins.c msgid "chr() arg not in range(0x110000)" @@ -2925,7 +2958,7 @@ msgstr "Convolve-Argumente müssen ndarrays sein" #: extmod/ulab/code/numpy/filter.c msgid "convolve arguments must not be empty" -msgstr "Convolve Argumente dürfen nicht leer sein" +msgstr "Faltungsargumente dürfen nicht leer sein" #: extmod/ulab/code/numpy/io/io.c msgid "corrupted file" @@ -2976,8 +3009,8 @@ msgstr "default ist keine Funktion" msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -"Der Zielbuffer muss ein Bytearray oder ein Array vom Typ 'B' für bit_depth = " -"8 sein" +"Zielpuffer muss ein Bytearray oder ein Array vom Typ 'B' für bit_depth = 8 " +"sein" #: shared-bindings/audiobusio/PDMIn.c msgid "destination buffer must be an array of type 'H' for bit_depth = 16" @@ -3003,6 +3036,10 @@ msgstr "Abmessungen stimmen nicht überein" msgid "div/mod not implemented for uint" msgstr "div/mod für uint nicht implementiert" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "durch Null dividieren" + #: py/runtime.c msgid "division by zero" msgstr "Division durch Null" @@ -3033,7 +3070,7 @@ msgstr "leere Sequenz" #: py/objstr.c msgid "end of format while looking for conversion specifier" -msgstr "Ende des Formats wärend der Suche nach einem conversion specifier" +msgstr "Ende des Formats bei der Suche nach einem Konvertierungsspezifizierer" #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" @@ -3044,26 +3081,18 @@ msgstr "epoch_time wird auf diesem Board nicht unterstützt" msgid "error = 0x%08lX" msgstr "Fehler = 0x%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.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." +"espcamera.Camera benötigt reservierten PSRAM um konfiguriert zu werden. " +"Siehe Dokumentation für Anweisungen." #: 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" @@ -3101,8 +3130,8 @@ msgid "extra positional arguments given" msgstr "Es wurden zusätzliche Argumente ohne Schlüsselwort angegeben" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "Die Datei muss eine im Byte-Modus geöffnete Datei sein" @@ -3278,7 +3307,7 @@ msgstr "Index ist außerhalb der Grenzen" #: shared-bindings/_pixelmap/PixelMap.c msgid "index must be tuple or int" -msgstr "" +msgstr "Index muss tuple oder int sein" #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c #: ports/espressif/common-hal/pulseio/PulseIn.c @@ -3435,7 +3464,7 @@ msgstr "ungültiger Schlüssel" msgid "invalid micropython decorator" msgstr "ungültiger micropython decorator" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "Invalide Einstellung" @@ -3470,7 +3499,7 @@ msgstr "issubclass() arg 2 muss eine Klasse oder ein Tupel von Klassen sein" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "iterations did not converge" -msgstr "Iterationen sind nicht konvergiert (converged)" +msgstr "Iterationen sind nicht konvergiert" #: py/objstr.c msgid "join expects a list of str/bytes objects consistent with self object" @@ -3538,7 +3567,7 @@ msgstr "mDNS funktioniert nur mit integriertem WiFi" #: py/parse.c msgid "malformed f-string" -msgstr "fehlformatierter f-string" +msgstr "fehlerhafter F-String" #: shared-bindings/_stage/Layer.c msgid "map buffer too small" @@ -3622,7 +3651,7 @@ msgstr "Mehrfache Vererbung nicht unterstützt" #: py/emitnative.c msgid "must raise an object" -msgstr "muss ein Objekt verursachen (raise)" +msgstr "muss ein Objekt aufwerfen (raise)" #: py/modbuiltins.c msgid "must use keyword argument for key function" @@ -3642,7 +3671,7 @@ msgstr "native Methode zu groß" #: py/emitnative.c msgid "native yield" -msgstr "native Ausbeute (yield)" +msgstr "natives yield" #: py/runtime.c #, c-format @@ -3655,15 +3684,15 @@ msgstr "negative Fakultät" #: py/objint_longlong.c py/objint_mpz.c py/runtime.c msgid "negative power with no float support" -msgstr "negative Potenz ohne Gleitkomma (float) Unterstützung" +msgstr "negative Potenz ohne Gleitkomma(float)-Unterstützung" #: py/objint_mpz.c py/runtime.c msgid "negative shift count" -msgstr "Negative shift Anzahl" +msgstr "Negative Anzahl an Verschiebungen" #: shared-bindings/_pixelmap/PixelMap.c msgid "nested index must be int" -msgstr "" +msgstr "verschachtelter Index muss int sein" #: shared-module/sdcardio/SDCard.c msgid "no SD card" @@ -3671,11 +3700,11 @@ msgstr "keine SD-Karte" #: py/vm.c msgid "no active exception to reraise" -msgstr "Keine aktive Ausnahme zu verusachen (raise)" +msgstr "Keine aktive Ausnahme zum Wiederaufwerfen (reraise)" #: py/compile.c msgid "no binding for nonlocal found" -msgstr "Kein Binding für nonlocal gefunden" +msgstr "Keine Bindung für nichtlokale Variable gefunden" #: shared-module/msgpack/__init__.c msgid "no default packer" @@ -3698,14 +3727,14 @@ msgstr "kein Reset Pin verfügbar" msgid "no response from SD card" msgstr "keine Antwort von der SD-Karte" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nrf/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" -msgstr "non-UUID gefunden in service_uuids_whitelist" +msgstr "Nicht-UUID in service_uuids_whitelist gefunden" #: py/compile.c msgid "non-default argument follows default argument" @@ -3721,7 +3750,7 @@ msgstr "Nicht-Schlüsselwort arg nach * / **" #: py/compile.c msgid "non-keyword arg after keyword arg" -msgstr "Nicht-Schlüsselwort Argument nach Schlüsselwort Argument" +msgstr "Nicht-Schlüsselwort-Argument nach Schlüsselwort-Argument" #: ports/nrf/common-hal/_bleio/Adapter.c msgid "non-zero timeout must be > 0.01" @@ -3738,11 +3767,12 @@ msgstr "keine 128-bit UUID" #: py/objstr.c msgid "not all arguments converted during string formatting" msgstr "" -"Nicht alle Argumente wurden während der Formatierung des Strings konvertiert" +"Nicht alle Argumente wurden während der Formatierung der Zeichenfolge " +"konvertiert" #: py/objstr.c msgid "not enough arguments for format string" -msgstr "Nicht genügend Argumente für den Formatierungs-String" +msgstr "Nicht genügend Argumente für die Formatzeichenfolge" #: extmod/ulab/code/numpy/carray/carray_tools.c msgid "not implemented for complex dtype" @@ -3834,11 +3864,15 @@ msgstr "nur eine bit_depth=16 wird unterstützt" #: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only mono is supported" -msgstr "" +msgstr "nur Mono wird unterstützt" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "nur ndarrays können aneinandergehängt werden" #: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only oversample=64 is supported" -msgstr "" +msgstr "nur oversample=64 wird unterstützt" #: ports/nrf/common-hal/audiobusio/PDMIn.c #: ports/stm/common-hal/audiobusio/PDMIn.c @@ -3875,7 +3909,7 @@ msgstr "Operation wird nur für boolesche 1D-Arrays implementiert" #: extmod/ulab/code/numpy/numerical.c msgid "operation is not implemented on ndarrays" -msgstr "Die Operation ist für ndarrays nicht implementiert" +msgstr "Operation ist auf ndarrays nicht implementiert" #: extmod/ulab/code/ndarray.c msgid "operation is not supported for given type" @@ -3900,11 +3934,7 @@ msgstr "Ausgabe-Array ist zu klein" msgid "out must be a float dense array" msgstr "Ausgabe muss ein floatdichtes Array sein" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "Außerhalb des Bereichs der Quelle" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "Außerhalb des Bereichs des Ziels" @@ -3927,16 +3957,12 @@ msgstr "Die Parameter müssen Register der Reihenfolge a2 bis a5 sein" #: py/emitinlinethumb.c msgid "parameters must be registers in sequence r0 to r3" -msgstr "Die Parameter müssen Register der Reihenfolge r0 bis r3 sein" +msgstr "Parameter müssen Register im Bereich von r0 bis r3 sein" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "Pixelkoordinaten außerhalb der Grenzen" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "Der Pixelwert erfordert zu viele Bits" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader muss displayio.Palette oder displayio.ColorConverter sein" @@ -3968,7 +3994,7 @@ msgstr "pow() drittes Argument darf nicht 0 sein" #: py/objint_mpz.c msgid "pow() with 3 arguments requires integers" -msgstr "pow() mit 3 Argumenten erfordert Integer" +msgstr "pow() mit 3 Argumenten erfordert ganze Zahlen" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" @@ -4000,7 +4026,7 @@ msgstr "Rückgabewert-Beschreibung muss ein Identifier sein" #: py/emitnative.c msgid "return expected '%q' but got '%q'" -msgstr "Rückgabe erwartet '%q', aber '%q' erhalten" +msgstr "Rückgabe (return) erwartet '%q', hat aber '%q' erhalten" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format @@ -4010,7 +4036,7 @@ msgstr "rgb_pins[%d] dupliziert eine andere Pinbelegung" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "rgb_pins[%d] is not on the same port as clock" -msgstr "rgb_pins [%d] befindet sich nicht am selben Port wie clock" +msgstr "rgb_pins[%d] befindet sich nicht am selben Port wie clock" #: extmod/ulab/code/numpy/numerical.c msgid "roll argument must be an ndarray" @@ -4047,7 +4073,7 @@ msgstr "kurze Lektüre" #: py/objstr.c msgid "sign not allowed in string format specifier" -msgstr "Vorzeichen nicht erlaubt in einem String formatierungs specifier" +msgstr "Vorzeichen im Zeichenfolgenformatbezeichner nicht zulässig" #: py/objstr.c msgid "sign not allowed with integer format specifier 'c'" @@ -4079,7 +4105,7 @@ msgstr "weicher reboot\n" #: extmod/ulab/code/numpy/numerical.c msgid "sort argument must be an ndarray" -msgstr "sortierungs Argument muss ein ndarray sein" +msgstr "Sortierungsargument muss ein ndarray sein" #: extmod/ulab/code/scipy/signal/signal.c msgid "sos array must be of shape (n_section, 6)" @@ -4184,10 +4210,6 @@ msgstr "Zeitstempel außerhalb des Bereichs für Plattform time_t" msgid "tobytes can be invoked for dense arrays only" msgstr "tobytes kann nur für dichte Arrays aufgerufen werden" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "zu viele Argumente mit dem angegebenen Format" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "zu viele Dimensionen" @@ -4203,7 +4225,7 @@ msgstr "zu viele Lokale für die native Methode" #: py/runtime.c #, c-format msgid "too many values to unpack (expected %d)" -msgstr "zu viele Werte zum Auspacken (erwartet %d)" +msgstr "zu viele Werte zum Auspacken (%d erwartet)" #: extmod/ulab/code/numpy/approx.c msgid "trapz is defined for 1D arrays of equal length" @@ -4223,8 +4245,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" @@ -4239,7 +4259,7 @@ msgstr "Typ ist kein akzeptierter Basis-Typ" #: py/objgenerator.c py/runtime.c msgid "type object '%q' has no attribute '%q'" -msgstr "Typ vom Objekt '%q' hat kein Attribut '%q'" +msgstr "Typ-Objekt '%q' hat kein Attribut '%q'" #: py/objtype.c msgid "type takes 1 or 3 arguments" @@ -4269,7 +4289,7 @@ msgstr "unerwartetes Schlüsselwort-Argument '%q'" #: py/lexer.c msgid "unicode name escapes" -msgstr "Unicode Name ausgebrochen (escaped)" +msgstr "Escaping von Unicode-Namen" #: py/parse.c msgid "unindent doesn't match any outer indent level" @@ -4278,7 +4298,7 @@ msgstr "unindent stimmt mit keiner äußeren Einrückungsebene überein" #: py/objstr.c #, c-format msgid "unknown conversion specifier %c" -msgstr "unbekannter Konvertierungs specifier %c" +msgstr "unbekannter Konvertierungsspezifizierer %c" #: py/objstr.c msgid "unknown format code '%c' for object of type '%q'" @@ -4295,7 +4315,7 @@ msgstr "unbekannter Typ '%q'" #: py/objstr.c #, c-format msgid "unmatched '%c' in format" -msgstr "" +msgstr "'%c' in Format konnte nicht zugeordnet werden" #: py/objtype.c py/runtime.c msgid "unreadable attribute" @@ -4357,10 +4377,6 @@ msgstr "Wert muss in %d Byte(s) passen" msgid "value out of range of target" msgstr "Wert außerhalb des Zielbereiches" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "value_count muss größer als 0 sein" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "watchdog nicht initialisiert" @@ -4448,6 +4464,172 @@ 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 "out of range of source" +#~ msgstr "Außerhalb des Bereichs der Quelle" + +#~ msgid "pixel value requires too many bits" +#~ msgstr "Der Pixelwert erfordert zu viele Bits" + +#~ msgid "value_count must be > 0" +#~ msgstr "value_count muss größer als 0 sein" + +#~ msgid "64 bit types" +#~ msgstr "64 bit-Typen" + +#~ msgid "No key was specified" +#~ msgstr "Es wurde kein Schlüssel angegeben" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "Scannen bereits in Bearbeitung. Stoppe mit stop_scan." + +#, c-format +#~ msgid "Unkown error code %d" +#~ msgstr "Unbekannter Fehlercode %d" + +#~ msgid "too many arguments provided with the given format" +#~ msgstr "zu viele Argumente mit dem angegebenen Format" + +#~ msgid "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "Ungültige CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\n" + +#~ 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" @@ -4488,9 +4670,6 @@ msgstr "zi muss die Form (n_section, 2) haben" #~ msgid "complex division by zero" #~ msgstr "Komplexe Division durch null" -#~ msgid "divide by zero" -#~ msgstr "durch Null dividieren" - #~ msgid "int() arg 2 must be >= 2 and <= 36" #~ msgstr "int() arg 2 muss >= 2 und <= 36 sein" diff --git a/locale/el.po b/locale/el.po index fe882c9f302a..c1d8350462d3 100644 --- a/locale/el.po +++ b/locale/el.po @@ -38,13 +38,21 @@ 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" -"Παρακαλώ δημιουγήστε ενα πρόβλημα με τα περιεχόμενα του CIRCUITPY δίσκου " -"στο\n" -"https://github.com/adafruit/circuitpython/issues\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -97,7 +105,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -117,7 +125,12 @@ msgstr "%q περιέχει διπλότυπα pins" 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -132,7 +145,7 @@ msgstr "%q δείκτης εκτός εμβέλειας" msgid "%q init failed" msgstr "%q εκκίνηση απέτυχε" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "" @@ -184,13 +197,22 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "%q πρέπει να είναι bytearray ή array τύπου 'h', 'H', 'b', ή 'B'" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q πρέπει να είναι τύπου %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" + +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q πρέπει να είναι τύπου %q ή 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 msgid "%q must be power of 2" @@ -209,10 +231,6 @@ msgstr "%q εκτός ορίων" msgid "%q out of range" msgstr "%q εκτός εμβέλειας" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "%q άκυρο pin" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -229,7 +247,7 @@ msgstr "%q, %q, και %q πρέπει να είναι όλα του ιδίου msgid "%q=%q" msgstr "%q=%q" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s σφάλμα 0x%x" @@ -395,11 +413,6 @@ msgstr "0.0 σε μία σύνθετη δύναμη" msgid "3-arg pow() not supported" msgstr "pow() με 3 παραμέτρους δεν υποστηρίζεται" -#: shared-module/msgpack/__init__.c -#, fuzzy -msgid "64 bit types" -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 @@ -446,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 περιφεριακά ειναι σε χρήση" @@ -499,6 +511,7 @@ msgstr "Ήδη διαφημίζουμε." msgid "Already have all-matches listener" msgstr "Ύπάρχει ήδη all-matches ακροατής" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -538,10 +551,6 @@ msgstr "Η τιμές της παράταξη πρέπει να είναι μο msgid "Attempt to allocate %d blocks" msgstr "Προσπάθεια να δεσμευτούν %d blocks" -#: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when VM not running." -msgstr "Προσπάθεια δέσμευσης heap όταν το VM δεν τρέχει." - #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" msgstr "Η μετατροπή ήχου δεν υποστηρίζεται" @@ -592,20 +601,13 @@ msgid "Bitmap size and bits per value must match" msgstr "Το μέγεθος του bitmap και τα bits ανα τιμή πρέπει να ταιριάζουν" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "Η συσκευή boot πρέπει να είναι η πρώτη συσκευή (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 "Και RX και TX απαιτούνται για έλεγχο flow" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Και τα δύο pin πρέπει να υποστηρίζουν interrupts υλικού" @@ -671,11 +673,6 @@ msgstr "Τα Buffers πρέπει να είναι του ιδίου μεγέθο msgid "Bus pin %d is already in use" msgstr "Bus pin %d είναι ήδη σε χρήση" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Byte buffer πρέπει να είναι 16 bytes." @@ -688,7 +685,7 @@ msgstr "CBC blocks πρέπει να είναι πολλαπλάσια του 16 msgid "CIRCUITPY drive could not be found or created." msgstr "Ο CIRCUITPY δίσκος δεν μπόρεσε να βρεθεί ή να δημιουργηθεί." -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC ή checksum ήταν άκυρο" @@ -814,10 +811,6 @@ msgstr "Δεν υποστηρίζονται εγγραφές στο Characterist 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 "Stretch ρολογιού πολύ μεγάλο" @@ -834,6 +827,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 αρχείο" @@ -858,10 +859,6 @@ msgstr "Δεν μπόρεσε να εκκινηθεί το interrupt, RX κατ msgid "Couldn't allocate decoder" msgstr "Δεν μπόρεσε να δεσμευτεί decoder" -#: 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" @@ -953,24 +950,16 @@ msgstr "" msgid "Error in regex" msgstr "" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" -msgstr "" - -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1038,7 +1027,7 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c @@ -1097,7 +1086,7 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1126,6 +1115,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 "" @@ -1143,11 +1141,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 "" @@ -1245,10 +1238,19 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "" @@ -1266,12 +1268,15 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "" @@ -1289,19 +1294,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "" @@ -1310,7 +1315,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "" @@ -1342,7 +1347,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "" @@ -1542,10 +1547,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -1585,10 +1586,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 "" @@ -1608,10 +1605,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" @@ -1706,11 +1699,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1718,7 +1711,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1886,6 +1879,7 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" @@ -1895,7 +1889,7 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1915,7 +1909,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1967,7 +1961,7 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." +msgid "Scan already in progress. Stop with stop_scan." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -2028,10 +2022,6 @@ msgstr "" 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 "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2045,50 +2035,19 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2107,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 "" @@ -2139,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2187,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 "" @@ -2234,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 "" @@ -2252,10 +2224,20 @@ 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" @@ -2292,6 +2274,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2327,11 +2314,6 @@ 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 @@ -2378,7 +2360,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2439,13 +2421,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2517,6 +2542,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2737,7 +2766,7 @@ msgstr "" msgid "can't set attribute" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2945,6 +2974,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "" @@ -2986,9 +3019,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -2996,14 +3029,6 @@ msgstr "" 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 "" @@ -3041,8 +3066,8 @@ msgid "extra positional arguments given" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3373,7 +3398,7 @@ msgstr "" msgid "invalid micropython decorator" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3630,7 +3655,7 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" @@ -3766,6 +3791,10 @@ msgstr "" 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 "" @@ -3827,11 +3856,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3856,14 +3881,10 @@ msgstr "" msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4111,10 +4132,6 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4150,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 "" @@ -4282,10 +4297,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4373,6 +4384,41 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#, fuzzy +#~ msgid "64 bit types" +#~ msgstr "64 bit τύποι" + +#~ 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" diff --git a/locale/en_GB.po b/locale/en_GB.po index 6bb13d257090..8b7a1da9fcb1 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2022-05-22 00:18+0000\n" -"Last-Translator: Dan Halbert \n" +"PO-Revision-Date: 2023-04-16 13:51+0000\n" +"Last-Translator: Andi Chandler \n" "Language-Team: none\n" "Language: en_GB\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.17-dev\n" #: main.c msgid "" @@ -26,7 +26,6 @@ msgstr "" "Code done running.\n" #: main.c -#, fuzzy msgid "" "\n" "Code stopped by auto-reload. Reloading soon.\n" @@ -37,12 +36,28 @@ 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 "" +"\n" +"Please file an issue with your program at https://github.com/adafruit/" +"circuitpython/issues." + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" +"\n" +"Press reset to exit safe mode.\n" + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" "\n" -"Please file an issue with the contents of your CIRCUITPY drive at \n" -"https://github.com/adafruit/circuitpython/issues\n" +"You are in safe mode because:\n" #: py/obj.c msgid " File \"%q\"" @@ -72,7 +87,7 @@ msgstr "%%c requires int or char" #: main.c #, c-format msgid "%02X" -msgstr "" +msgstr "%02X" #: shared-module/os/getenv.c #, c-format @@ -95,9 +110,9 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.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" @@ -105,7 +120,7 @@ msgstr "%q and %q contain duplicate pins" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "%q and %q must be different" -msgstr "" +msgstr "%q and %q must be different" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -115,7 +130,12 @@ 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 "%q in %q must be of type %q, not %q" + #: ports/espressif/common-hal/espulp/ULP.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -128,19 +148,19 @@ msgstr "%q index out of range" #: shared-module/bitbangio/SPI.c msgid "%q init failed" -msgstr "" +msgstr "%q init failed" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" -msgstr "" +msgstr "%q is %q" #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "%q is read-only for this board" -msgstr "" +msgstr "%q is read-only for this board" #: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" -msgstr "" +msgstr "%q length must be %d" #: py/argcheck.c msgid "%q length must be %d-%d" @@ -148,15 +168,15 @@ msgstr "%q length must be %d-%d" #: py/argcheck.c msgid "%q length must be <= %d" -msgstr "" +msgstr "%q length must be <= %d" #: py/argcheck.c msgid "%q length must be >= %d" -msgstr "" +msgstr "%q length must be >= %d" #: py/argcheck.c msgid "%q must be %d" -msgstr "" +msgstr "%q must be %d" #: py/argcheck.c msgid "%q must be %d-%d" @@ -164,11 +184,11 @@ msgstr "%q must be %d-%d" #: shared-bindings/displayio/Display.c msgid "%q must be 1 when %q is True" -msgstr "" +msgstr "%q must be 1 when %q is True" #: py/argcheck.c shared-bindings/gifio/GifWriter.c msgid "%q must be <= %d" -msgstr "" +msgstr "%q must be <= %d" #: py/argcheck.c msgid "%q must be >= %d" @@ -176,19 +196,28 @@ msgstr "%q must be >= %d" #: shared-bindings/analogbufio/BufferedIn.c msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "" +msgstr "%q must be a bytearray or array of type 'H' or 'B'" #: shared-bindings/audiocore/RawSample.c msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" -msgstr "" +msgstr "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "%q must be array of type 'H'" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "" +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "%q must be array of type 'h'" + +#: 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 must be of type %q or %q, not %q" + +#: py/argcheck.c py/obj.c py/objstrunicode.c +msgid "%q must be of type %q, not %q" +msgstr "%q must be of type %q, not %q" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" @@ -196,7 +225,7 @@ msgstr "%q must be power of 2" #: shared-bindings/wifi/Monitor.c msgid "%q out of bounds" -msgstr "" +msgstr "%q out of bounds" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c @@ -207,13 +236,9 @@ 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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" -msgstr "" +msgstr "%q step cannot be zero" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -225,9 +250,9 @@ msgstr "%q, %q, and %q must all be the same length" #: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s error 0x%x" @@ -393,10 +418,6 @@ msgstr "0.0 to a complex power" msgid "3-arg pow() not supported" msgstr "3-arg pow() not supported" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "64 bit types" - #: 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 @@ -414,7 +435,7 @@ msgstr "Address must be %d bytes long" #: ports/espressif/common-hal/memorymap/AddressRange.c msgid "Address range not allowed" -msgstr "" +msgstr "Address range not allowed" #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" @@ -443,7 +464,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" @@ -496,6 +516,7 @@ msgstr "Already advertising." msgid "Already have all-matches listener" msgstr "Already have all-matches listener" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -510,7 +531,7 @@ msgstr "Already scanning for WiFi networks" #: shared-module/os/getenv.c #, c-format msgid "An error occurred while retrieving '%s':\n" -msgstr "" +msgstr "An error occurred while retrieving '%s':\n" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" @@ -535,10 +556,6 @@ msgstr "Array values should be single bytes." 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" @@ -586,23 +603,16 @@ msgstr "Bit depth must be multiple of 8." #: shared-bindings/bitmaptools/__init__.c msgid "Bitmap size and bits per value must match" -msgstr "" +msgstr "Bitmap size and bits per value must match" #: supervisor/shared/safe_mode.c -msgid "Boot device must be first device (interface #0)." -msgstr "" +msgid "Boot device must be first (interface #0)." +msgstr "Boot device must be first (interface #0)." #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" msgstr "Both RX and TX required for flow control" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Both pins must support hardware interrupts" @@ -658,7 +668,7 @@ msgstr "Buffer too short by %d bytes" #: ports/espressif/common-hal/imagecapture/ParallelImageCapture.c msgid "Buffers must be same size" -msgstr "" +msgstr "Buffers must be same size" #: ports/atmel-samd/common-hal/paralleldisplay/ParallelBus.c #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c @@ -668,11 +678,6 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "Bus pin %d is already in use" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Byte buffer must be 16 bytes." @@ -683,9 +688,9 @@ msgstr "CBC blocks must be multiples of 16 bytes" #: supervisor/shared/safe_mode.c msgid "CIRCUITPY drive could not be found or created." -msgstr "" +msgstr "CIRCUITPY drive could not be found or created." -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC or checksum was invalid" @@ -695,7 +700,7 @@ msgstr "Call super().__init__() before accessing native object." #: ports/cxd56/common-hal/camera/Camera.c msgid "Camera init" -msgstr "" +msgstr "Camera init" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on RTC IO from deep sleep." @@ -760,7 +765,7 @@ msgstr "Cannot remount '/' when visible via USB." #: 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 "Cannot reset into bootloader because no bootloader is present" #: ports/espressif/common-hal/socketpool/Socket.c msgid "Cannot set socket options" @@ -781,7 +786,7 @@ msgstr "Cannot subclass slice" #: shared-module/bitbangio/SPI.c msgid "Cannot transfer without MOSI and MISO pins" -msgstr "" +msgstr "Cannot transfer without MOSI and MISO pins" #: shared-bindings/pwmio/PWMOut.c msgid "Cannot vary frequency on a timer that is already in use" @@ -789,7 +794,7 @@ msgstr "Cannot vary frequency on a timer that is already in use" #: ports/nrf/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" -msgstr "" +msgstr "Cannot wake on pin edge, only level" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." @@ -803,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" @@ -823,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 "Coordinate arrays have different lengths" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "Coordinate arrays types have different sizes" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Corrupt .mpy file" @@ -847,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" @@ -907,7 +912,7 @@ msgstr "Display rotation must be in 90 degree increments" #: main.c msgid "Done" -msgstr "" +msgstr "Done" #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." @@ -915,7 +920,7 @@ msgstr "Drive mode not used when direction is input." #: py/obj.c msgid "During handling of the above exception, another exception occurred:" -msgstr "" +msgstr "During handling of the above exception, another exception occurred:" #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" @@ -942,25 +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 "Error in safemode.py." + #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" msgstr "Error: Failure to bind" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.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" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" -msgstr "" - #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" -msgstr "" +msgid "Expected a kind of %q" +msgstr "Expected a kind of %q" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -990,7 +987,7 @@ msgstr "Failed to acquire mutex, err 0x%04x" #: shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" -msgstr "" +msgstr "Failed to allocate %q buffer" #: ports/espressif/common-hal/wifi/__init__.c msgid "Failed to allocate Wifi memory" @@ -1027,8 +1024,8 @@ 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 "Fault detected by hardware." #: py/moduerrno.c msgid "File exists" @@ -1036,7 +1033,7 @@ msgstr "File exists" #: shared-module/os/getenv.c msgid "File not found" -msgstr "" +msgstr "File not found" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c @@ -1046,23 +1043,23 @@ msgstr "Filters too complex" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is duplicate" -msgstr "" +msgstr "Firmware is duplicate" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is invalid" -msgstr "" +msgstr "Firmware is invalid" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is too big" -msgstr "" +msgstr "Firmware is too big" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" -msgstr "" +msgstr "For L8 colourspace, input bitmap must have 8 bits per pixel" #: shared-bindings/bitmaptools/__init__.c msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" -msgstr "" +msgstr "For RGB colourspaces, input bitmap must have 16 bits per pixel" #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" @@ -1072,6 +1069,7 @@ msgstr "Format not supported" msgid "" "Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" msgstr "" +"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" #: shared-bindings/pwmio/PWMOut.c msgid "Frequency must match existing PWMOut using this timer" @@ -1084,9 +1082,9 @@ msgstr "Function requires lock" #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" -msgstr "" +msgstr "GNSS init" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "Generic Failure" @@ -1103,7 +1101,7 @@ msgstr "Group already used" #: 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 "Half duplex SPI is not implemented" #: 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 @@ -1115,13 +1113,23 @@ 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 "Heap allocation when VM not running." + +#: supervisor/shared/safe_mode.c +msgid "" +"Heap was corrupted because the stack was too small. Increase stack size." +msgstr "" +"Heap was corrupted because the stack was too small. Increase stack size." + #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" msgstr "I/O operation on closed file" #: ports/stm/common-hal/busio/I2C.c msgid "I2C init error" -msgstr "" +msgstr "I2C init error" #: ports/raspberrypi/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c @@ -1132,11 +1140,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" @@ -1212,7 +1215,7 @@ msgstr "Insufficient encryption" #: ports/espressif/common-hal/wifi/Radio.c msgid "Interface must be started" -msgstr "" +msgstr "Interface must be started" #: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c msgid "Internal audio buffer too small" @@ -1225,7 +1228,7 @@ msgstr "Internal define error" #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c #: shared-module/os/getenv.c msgid "Internal error" -msgstr "" +msgstr "Internal error" #: shared-module/rgbmatrix/RGBMatrix.c #, c-format @@ -1234,12 +1237,21 @@ msgstr "Internal error #%d" #: supervisor/shared/safe_mode.c msgid "Internal watchdog timer expired." -msgstr "" +msgstr "Internal watchdog timer expired." + +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Interrupt error." -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Invalid %q pin" @@ -1257,12 +1269,15 @@ msgstr "Invalid BLE parameter" msgid "Invalid BSSID" msgstr "Invalid BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "Invalid CIRCUITPY_PYSTACK_SIZE\n" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" -msgstr "" +msgstr "Invalid MAC address" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Invalid argument" @@ -1273,26 +1288,26 @@ msgstr "Invalid bits per value" #: shared-module/os/getenv.c #, c-format msgid "Invalid byte %.*s" -msgstr "" +msgstr "Invalid byte %.*s" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" msgstr "Invalid data_pins[%d]" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "Invalid format" + #: shared-module/audiocore/WaveFile.c 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 "" +msgstr "Invalid multicast MAC address" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "Invalid size" @@ -1301,13 +1316,13 @@ msgstr "Invalid size" msgid "Invalid socket for TLS" msgstr "Invalid socket for TLS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "Invalid state" #: shared-module/os/getenv.c msgid "Invalid unicode escape" -msgstr "" +msgstr "Invalid unicode escape" #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" @@ -1315,11 +1330,11 @@ msgstr "Key must be 16, 24, or 32 bytes long" #: shared-module/os/getenv.c msgid "Key not found" -msgstr "" +msgstr "Key not found" #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" -msgstr "" +msgstr "LED mappings must match display size" #: py/compile.c msgid "LHS of keyword arg must be an id" @@ -1327,19 +1342,19 @@ msgstr "LHS of keyword arg must be an id" #: shared-module/displayio/Group.c msgid "Layer already in a group" -msgstr "" +msgstr "Layer already in a group" #: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass" -msgstr "" +msgstr "Layer must be a Group or TileGrid subclass" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "MAC address was invalid" #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" -msgstr "" +msgstr "Mapping must be a tuple" #: shared-module/displayio/Shape.c #, c-format @@ -1353,11 +1368,11 @@ msgstr "Microphone startup delay must be in range 0.0 to 1.0" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" -msgstr "" +msgstr "Mismatched data size" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched swap flag" -msgstr "" +msgstr "Mismatched swap flag" #: ports/mimxrt10xx/common-hal/busio/SPI.c msgid "Missing MISO or MOSI Pin" @@ -1365,7 +1380,7 @@ msgstr "Missing MISO or MOSI pin" #: ports/stm/common-hal/busio/SPI.c msgid "Missing MISO or MOSI pin" -msgstr "" +msgstr "Missing MISO or MOSI pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format @@ -1425,7 +1440,7 @@ msgstr "NVS Error" #: shared-bindings/socketpool/SocketPool.c msgid "Name or service not known" -msgstr "" +msgstr "Name or service not known" #: py/qstr.c msgid "Name too long" @@ -1433,11 +1448,11 @@ msgstr "Name too long" #: shared-bindings/displayio/TileGrid.c msgid "New bitmap must be same size as old bitmap" -msgstr "" +msgstr "New bitmap must be same size as old bitmap" #: ports/espressif/common-hal/_bleio/__init__.c msgid "Nimble out of memory" -msgstr "" +msgstr "Nimble out of memory" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nrf/common-hal/_bleio/Characteristic.c @@ -1463,11 +1478,11 @@ msgstr "No DMA pacing timer found" #: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c #, c-format msgid "No I2C device at address: 0x%x" -msgstr "" +msgstr "No I2C device at address: 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 @@ -1476,7 +1491,7 @@ msgstr "No MISO pin" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MISO pin" -msgstr "" +msgstr "No MISO pin" #: ports/espressif/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c @@ -1485,7 +1500,7 @@ msgstr "No MOSI pin" #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c msgid "No MOSI pin" -msgstr "" +msgstr "No MOSI pin" #: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c @@ -1507,7 +1522,7 @@ msgstr "No available clocks" #: ports/espressif/common-hal/imagecapture/ParallelImageCapture.c msgid "No capture in progress" -msgstr "" +msgstr "No capture in progress" #: shared-bindings/_bleio/PacketBuffer.c msgid "No connection: length cannot be determined" @@ -1533,10 +1548,6 @@ msgstr "No in in program" msgid "No in or out in program" msgstr "No in or out in program" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "No key was specified" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "No long integer support" @@ -1566,7 +1577,7 @@ msgstr "No space left on device" #: py/moduerrno.c msgid "No such device" -msgstr "" +msgstr "No such device" #: py/moduerrno.c msgid "No such file/directory" @@ -1576,10 +1587,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" @@ -1599,14 +1606,10 @@ 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" -msgstr "" +msgstr "Number of data_pins must be 8 or 16, not %d" #: shared-bindings/util.c msgid "" @@ -1620,11 +1623,11 @@ msgstr "Odd parity is not supported" #: supervisor/shared/bluetooth/bluetooth.c msgid "Off" -msgstr "" +msgstr "Off" #: supervisor/shared/bluetooth/bluetooth.c msgid "Ok" -msgstr "" +msgstr "Ok" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c @@ -1671,22 +1674,22 @@ msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." -msgstr "" +msgstr "Only one %q can be set in deep sleep." #: ports/espressif/common-hal/espulp/ULPAlarm.c msgid "Only one %q can be set." -msgstr "" +msgstr "Only one %q can be set." #: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" -msgstr "" +msgstr "Only one address is allowed" #: 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 "Only one alarm.time alarm can be set" #: ports/espressif/common-hal/alarm/time/TimeAlarm.c #: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c @@ -1699,21 +1702,21 @@ msgstr "Only one colour can be transparent at a time" #: py/moduerrno.c msgid "Operation not permitted" -msgstr "" +msgstr "Operation not permitted" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "Operation or feature not supported" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "Operation timed out" #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Out of MDNS service slots" -msgstr "" +msgstr "Out of MDNS service slots" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "Out of memory" @@ -1742,7 +1745,7 @@ msgstr "" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "PWM restart" -msgstr "" +msgstr "PWM restart" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "PWM slice already in use" @@ -1802,7 +1805,7 @@ msgstr "Pins must be sequential" #: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c msgid "Pins must be sequential GPIO pins" -msgstr "" +msgstr "Pins must be sequential GPIO pins" #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Pins must share PWM slice" @@ -1842,7 +1845,7 @@ msgstr "Program size invalid" #: ports/espressif/common-hal/espulp/ULP.c msgid "Program too long" -msgstr "" +msgstr "Program too long" #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." @@ -1855,7 +1858,7 @@ msgstr "RAISE mode is not implemented" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "RISE_AND_FALL not available on this chip" -msgstr "" +msgstr "RISE_AND_FALL not available on this chip" #: ports/stm/common-hal/os/__init__.c msgid "RNG DeInit Error" @@ -1868,7 +1871,7 @@ msgstr "RNG init Error" #: 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 @@ -1883,6 +1886,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1892,13 +1896,13 @@ msgstr "Read-only" msgid "Read-only filesystem" msgstr "Read-only filesystem" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "Received response was invalid" #: supervisor/shared/bluetooth/bluetooth.c msgid "Reconnecting" -msgstr "" +msgstr "Reconnecting" #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" @@ -1912,7 +1916,7 @@ msgstr "RemoteTransmissionRequests limited to 8 bytes" msgid "Requested AES mode is unsupported" msgstr "Requested AES mode is unsupported" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "Requested resource not found" @@ -1930,7 +1934,7 @@ msgstr "SD card CSD format not supported" #: ports/cxd56/common-hal/sdioio/SDCard.c msgid "SDCard init" -msgstr "" +msgstr "SDCard init" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format @@ -1948,7 +1952,7 @@ msgstr "SPI configuration failed" #: ports/stm/common-hal/busio/SPI.c msgid "SPI init error" -msgstr "" +msgstr "SPI init error" #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" @@ -1956,16 +1960,16 @@ msgstr "SPI peripheral in use" #: ports/stm/common-hal/busio/SPI.c msgid "SPI re-init" -msgstr "" +msgstr "SPI re-init" #: shared-bindings/is31fl3741/FrameBuffer.c msgid "Scale dimensions must divide by 3" -msgstr "" +msgstr "Scale dimensions must divide by 3" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." -msgstr "Scan already in progess. Stop with stop_scan." +msgid "Scan already in progress. Stop with stop_scan." +msgstr "Scan already in progress. Stop with stop_scan." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2007,7 +2011,7 @@ msgstr "Source and destination buffers must be the same length" #: shared-bindings/paralleldisplay/ParallelBus.c msgid "Specify exactly one of data0 or data_pins" -msgstr "" +msgstr "Specify exactly one of data0 or data_pins" #: extmod/modure.c msgid "Splitting with sub-captures" @@ -2023,11 +2027,7 @@ msgstr "Stereo right must be on PWM channel B" #: 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 "Supply at least one UART pin" +msgstr "Stopping AP is not supported." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -2042,58 +2042,20 @@ msgid "Temperature read timed out" msgstr "Temperature read timed out" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" -"The CircuitPython heap was corrupted because the stack was too small.\n" -"Increase the stack size if you know how. If not:" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -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` module was used to boot into safe mode." +msgstr "The `microcontroller` module was used to boot into safe mode." #: py/obj.c msgid "The above exception was the direct cause of the following exception:" -msgstr "" - -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" +msgstr "The above exception was the direct cause of the following exception:" #: 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)." -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 "The power dipped. Make sure you are providing enough power." +msgstr "The power dipped. Make sure you are providing enough power." #: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" @@ -2111,15 +2073,21 @@ 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 "Third-party firmware fatal error." + #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." -msgstr "" +msgstr "This microcontroller does not support continuous capture." #: shared-module/paralleldisplay/ParallelBus.c msgid "" "This microcontroller only supports data0=, not data_pins=, because it " "requires contiguous pins." msgstr "" +"This microcontroller only supports data0=, not data_pins=, because it " +"requires contiguous pins." #: shared-bindings/displayio/TileGrid.c msgid "Tile height must exactly divide bitmap height" @@ -2143,13 +2111,9 @@ 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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" -msgstr "" +msgstr "Too many channels in sample" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." @@ -2184,24 +2148,28 @@ msgstr "Tuple or struct_time argument required" #: ports/stm/common-hal/busio/UART.c msgid "UART de-init" -msgstr "" +msgstr "UART de-init" #: 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 init" + +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "UART peripheral in use" #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" -msgstr "" +msgstr "UART re-init" #: ports/stm/common-hal/busio/UART.c msgid "UART write" -msgstr "" +msgstr "UART write" #: main.c msgid "UID:" -msgstr "" +msgstr "UID:" #: shared-module/usb_hid/Device.c msgid "USB busy" @@ -2238,6 +2206,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 "Unable to allocate the heap." + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +#, c-format +msgid "Unable to configure ADC DMA controller, ErrorCode:%d" +msgstr "Unable to configure ADC DMA controller, ErrorCode:%d" + #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" msgstr "Unable to create lock" @@ -2256,18 +2233,28 @@ 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 "Unable to initialise ADC DMA controller, ErrorCode:%d" + #: 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 "Unable to start ADC DMA controller, ErrorCode:%d" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" -msgstr "" +msgstr "Unable to start mDNS query" #: shared-bindings/memorymap/AddressRange.c msgid "Unable to write to address." -msgstr "" +msgstr "Unable to write to address." #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." @@ -2289,12 +2276,17 @@ msgstr "Unhandled ESP TLS error %d %d %x %d" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown BLE error at %s:%d: %d" -msgstr "" +msgstr "Unknown BLE error at %s:%d: %d" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown BLE error: %d" -msgstr "" +msgstr "Unknown BLE error: %d" + +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "Unknown error code %d" #: shared-bindings/wifi/Radio.c #, c-format @@ -2319,7 +2311,7 @@ msgstr "Unknown security error: 0x%04x" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error at %s:%d: %d" -msgstr "" +msgstr "Unknown system firmware error at %s:%d: %d" #: ports/nrf/common-hal/_bleio/__init__.c #, c-format @@ -2329,12 +2321,7 @@ msgstr "Unknown system firmware error: %04x" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error: %d" -msgstr "" - -#: ports/raspberrypi/common-hal/wifi/__init__.c -#, c-format -msgid "Unkown error code %d" -msgstr "" +msgstr "Unknown system firmware error: %d" #: shared-bindings/adafruit_pixelbuf/PixelBuf.c #: shared-module/_pixelmap/PixelMap.c @@ -2352,7 +2339,7 @@ msgstr "" #: shared-bindings/bitmaptools/__init__.c msgid "Unsupported colorspace" -msgstr "" +msgstr "Unsupported colourspace" #: shared-module/displayio/display_core.c msgid "Unsupported display bus type" @@ -2364,7 +2351,7 @@ msgstr "Unsupported format" #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" -msgstr "" +msgstr "Unsupported hash algorithm" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Update Failed" @@ -2384,7 +2371,7 @@ msgstr "Value length != required fixed length" msgid "Value length > max_length" msgstr "Value length > max_length" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "Version was invalid" @@ -2419,22 +2406,27 @@ msgid "" "\n" "To list built-in modules type `help(\"modules\")`.\n" msgstr "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Visit circuitpython.org for more information.\n" +"\n" +"To list built-in modules type `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 "" +msgstr "Wifi is in access point mode." #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is in station mode." -msgstr "" +msgstr "Wifi is in station mode." #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is not enabled" -msgstr "" +msgstr "Wifi is not enabled" #: main.c msgid "Woken up by alarm.\n" @@ -2445,15 +2437,57 @@ msgstr "Woken up by alarm.\n" msgid "Writes not supported on Characteristic" msgstr "Writes not supported on Characteristic" +#: 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 "You pressed both buttons at start up." + +#: 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 button A at start up." + #: supervisor/shared/safe_mode.c -msgid "You are in safe mode because:\n" -msgstr "You are in safe mode because:\n" +msgid "You pressed the BOOT button at start up" +msgstr "You pressed the BOOT button at start up" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "You pressed the GPIO0 button at start up." + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "You pressed the Rec button at start up." + +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "You pressed the SW38 button at start up." + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "You pressed the VOLUME button at start up." + +#: 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 "You pressed the central button at start up." + +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "You pressed the left button at start up." #: supervisor/shared/safe_mode.c -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 "You pressed the reset button during boot." +msgstr "You pressed the reset button during boot." + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "[truncated due to length]" #: py/objtype.c msgid "__init__() should return None" @@ -2522,7 +2556,11 @@ msgstr "array and index length must be equal" #: extmod/ulab/code/numpy/io/io.c msgid "array has too many dimensions" -msgstr "" +msgstr "array has too many dimensions" + +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "array is too big" #: py/objarray.c shared-bindings/alarm/SleepMemory.c #: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c @@ -2579,7 +2617,7 @@ msgstr "binary op %q not implemented" #: shared-bindings/bitmaptools/__init__.c msgid "bitmap sizes must match" -msgstr "" +msgstr "bitmap sizes must match" #: extmod/modurandom.c msgid "bits must be 32 or less" @@ -2637,7 +2675,7 @@ msgstr "Calibration is read only" #: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c #: shared-module/vectorio/Rectangle.c msgid "can only have one parent" -msgstr "" +msgstr "can only have one parent" #: py/emitinlinethumb.c msgid "can only have up to 4 parameters to Thumb assembly" @@ -2674,7 +2712,7 @@ msgstr "Can't convert '%q' object to %q implicitly" #: extmod/ulab/code/numpy/vector.c msgid "can't convert complex to float" -msgstr "" +msgstr "can't convert complex to float" #: py/obj.c msgid "can't convert to %q" @@ -2730,7 +2768,7 @@ msgstr "can't load with '%q' index" #: py/builtinimport.c msgid "can't perform relative import" -msgstr "" +msgstr "can't perform relative import" #: py/objgenerator.c msgid "can't send non-None value to a just-started generator" @@ -2744,9 +2782,9 @@ msgstr "can't set 512 block size" msgid "can't set attribute" msgstr "can't set attribute" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" -msgstr "" +msgstr "can't set attribute '%q'" #: py/emitnative.c msgid "can't store '%q'" @@ -2782,11 +2820,11 @@ msgstr "can't cast output with casting rule" #: extmod/ulab/code/ndarray.c msgid "cannot convert complex to dtype" -msgstr "" +msgstr "cannot convert complex to dtype" #: extmod/ulab/code/ndarray.c msgid "cannot convert complex type" -msgstr "" +msgstr "cannot convert complex type" #: py/objtype.c msgid "cannot create '%q' instances" @@ -2810,7 +2848,7 @@ msgstr "casting" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "channel re-init" -msgstr "" +msgstr "channel re-init" #: shared-bindings/_stage/Text.c msgid "chars buffer too small" @@ -2882,7 +2920,7 @@ msgstr "convolve arguments must not be empty" #: extmod/ulab/code/numpy/io/io.c msgid "corrupted file" -msgstr "" +msgstr "corrupted file" #: extmod/ulab/code/numpy/poly.c msgid "could not invert Vandermonde matrix" @@ -2955,13 +2993,17 @@ msgstr "dimensions do not match" msgid "div/mod not implemented for uint" msgstr "div/mod not implemented for uint" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "divide by zero" + #: py/runtime.c msgid "division by zero" msgstr "division by zero" #: extmod/ulab/code/numpy/vector.c msgid "dtype must be float, or complex" -msgstr "" +msgstr "dtype must be float, or complex" #: py/objdeque.c msgid "empty" @@ -2969,7 +3011,7 @@ msgstr "empty" #: extmod/ulab/code/numpy/io/io.c msgid "empty file" -msgstr "" +msgstr "empty file" #: extmod/moduasyncio.c extmod/moduheapq.c extmod/modutimeq.c msgid "empty heap" @@ -2996,24 +3038,18 @@ msgstr "epoch_time not supported on this board" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" +"espcamera.Camera requires reserved PSRAM to be configured. See the " +"documentation for instructions." #: 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" @@ -3051,8 +3087,8 @@ msgid "extra positional arguments given" msgstr "extra positional arguments given" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "file must be a file opened in byte mode" @@ -3139,7 +3175,7 @@ msgstr "function is defined for ndarrays only" #: extmod/ulab/code/numpy/carray/carray.c msgid "function is implemented for ndarrays only" -msgstr "" +msgstr "function is implemented for ndarrays only" #: py/argcheck.c #, c-format @@ -3226,7 +3262,7 @@ msgstr "index is out of bounds" #: shared-bindings/_pixelmap/PixelMap.c msgid "index must be tuple or int" -msgstr "" +msgstr "index must be tuple or int" #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c #: ports/espressif/common-hal/pulseio/PulseIn.c @@ -3240,7 +3276,7 @@ msgstr "indices must be integers, slices, or Boolean lists" #: ports/espressif/common-hal/busio/I2C.c msgid "init I2C" -msgstr "" +msgstr "init I2C" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" @@ -3276,7 +3312,7 @@ msgstr "input data must be an iterable" #: extmod/ulab/code/numpy/vector.c msgid "input dtype must be float or complex" -msgstr "" +msgstr "input dtype must be float or complex" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "input matrix is asymmetric" @@ -3289,11 +3325,11 @@ msgstr "input matrix is singular" #: extmod/ulab/code/numpy/create.c msgid "input must be 1- or 2-d" -msgstr "" +msgstr "input must be 1- or 2-d" #: extmod/ulab/code/numpy/carray/carray.c msgid "input must be a 1D ndarray" -msgstr "" +msgstr "input must be a 1D ndarray" #: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c msgid "input must be a dense ndarray" @@ -3305,7 +3341,7 @@ msgstr "input must be an ndarray" #: extmod/ulab/code/numpy/carray/carray.c msgid "input must be an ndarray, or a scalar" -msgstr "" +msgstr "input must be an ndarray, or a scalar" #: extmod/ulab/code/scipy/signal/signal.c msgid "input must be one-dimensional" @@ -3383,9 +3419,9 @@ msgstr "invalid key" msgid "invalid micropython decorator" msgstr "invalid micropython decorator" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" -msgstr "" +msgstr "invalid setting" #: shared-bindings/random/__init__.c msgid "invalid step" @@ -3471,12 +3507,12 @@ 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 "" +msgstr "mDNS already initialszed" #: 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 only works with built-in WiFi" #: py/parse.c msgid "malformed f-string" @@ -3503,7 +3539,7 @@ msgstr "max_length must be 0-%d when fixed_length is %s" #: extmod/ulab/code/ndarray.c msgid "maximum number of dimensions is " -msgstr "" +msgstr "maximum number of dimensions is " #: py/runtime.c msgid "maximum recursion depth exceeded" @@ -3544,7 +3580,7 @@ msgstr "module not found" #: ports/espressif/common-hal/wifi/Monitor.c msgid "monitor init failed" -msgstr "" +msgstr "monitor init failed" #: extmod/ulab/code/numpy/poly.c msgid "more degrees of freedom than data points" @@ -3605,7 +3641,7 @@ msgstr "negative shift count" #: shared-bindings/_pixelmap/PixelMap.c msgid "nested index must be int" -msgstr "" +msgstr "nested index must be int" #: shared-module/sdcardio/SDCard.c msgid "no SD card" @@ -3640,7 +3676,7 @@ msgstr "no reset pin available" msgid "no response from SD card" msgstr "no response from SD card" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" @@ -3687,7 +3723,7 @@ msgstr "not enough arguments for format string" #: extmod/ulab/code/numpy/carray/carray_tools.c msgid "not implemented for complex dtype" -msgstr "" +msgstr "not implemented for complex dtype" #: extmod/ulab/code/numpy/create.c msgid "number of points must be at least 2" @@ -3749,7 +3785,7 @@ msgstr "odd-length string" #: supervisor/shared/web_workflow/web_workflow.c msgid "off" -msgstr "" +msgstr "off" #: extmod/ulab/code/utils/utils.c msgid "offset is too large" @@ -3774,11 +3810,15 @@ msgstr "only bit_depth=16 is supported" #: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only mono is supported" -msgstr "" +msgstr "only mono is supported" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "only ndarrays can be concatenated" #: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only oversample=64 is supported" -msgstr "" +msgstr "only oversample=64 is supported" #: ports/nrf/common-hal/audiobusio/PDMIn.c #: ports/stm/common-hal/audiobusio/PDMIn.c @@ -3837,11 +3877,7 @@ msgstr "out array is too small" msgid "out must be a float dense array" msgstr "out must be a float dense array" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "out of range of source" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "out of range of target" @@ -3866,21 +3902,17 @@ msgstr "parameters must be registers in sequence a2 to a5" msgid "parameters must be registers in sequence r0 to r3" msgstr "parameters must be registers in sequence r0 to r3" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "pixel coordinates out of bounds" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "pixel value requires too many bits" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader must be displayio.Palette or displayio.ColorConverter" #: extmod/vfs_posix_file.c msgid "poll on file not available on win32" -msgstr "" +msgstr "poll on file not available on win32" #: ports/espressif/common-hal/pulseio/PulseIn.c msgid "pop from an empty PulseIn" @@ -3917,7 +3949,7 @@ msgstr "queue overflow" #: py/parse.c msgid "raw f-strings are not supported" -msgstr "" +msgstr "raw f-strings are not supported" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "real and imaginary parts must be of equal length" @@ -4036,15 +4068,15 @@ msgstr "source palette too large" #: shared-bindings/bitmaptools/__init__.c msgid "source_bitmap must have value_count of 2 or 65536" -msgstr "" +msgstr "source_bitmap must have value_count of 2 or 65536" #: shared-bindings/bitmaptools/__init__.c msgid "source_bitmap must have value_count of 65536" -msgstr "" +msgstr "source_bitmap must have value_count of 65536" #: shared-bindings/bitmaptools/__init__.c msgid "source_bitmap must have value_count of 8" -msgstr "" +msgstr "source_bitmap must have value_count of 8" #: py/objstr.c msgid "start/end indices" @@ -4111,7 +4143,7 @@ msgstr "timeout waiting for v2 card" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "timer re-init" -msgstr "" +msgstr "timer re-init" #: shared-bindings/time/__init__.c msgid "timestamp out of range for platform time_t" @@ -4121,10 +4153,6 @@ msgstr "timestamp out of range for platform time_t" msgid "tobytes can be invoked for dense arrays only" msgstr "tobytes can be invoked for dense arrays only" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "too many arguments provided with the given format" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "too many dimensions" @@ -4160,8 +4188,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" @@ -4208,7 +4234,7 @@ msgstr "unicode name escapes" #: py/parse.c msgid "unindent doesn't match any outer indent level" -msgstr "" +msgstr "unindent doesn't match any outer indent level" #: py/objstr.c #, c-format @@ -4230,7 +4256,7 @@ msgstr "unknown type '%q'" #: py/objstr.c #, c-format msgid "unmatched '%c' in format" -msgstr "" +msgstr "unmatched '%c' in format" #: py/objtype.c py/runtime.c msgid "unreadable attribute" @@ -4252,11 +4278,11 @@ msgstr "unsupported Xtensa instruction '%s' with %d arguments" #: shared-module/gifio/GifWriter.c msgid "unsupported colorspace for GifWriter" -msgstr "" +msgstr "unsupported colourspace for GifWriter" #: shared-bindings/bitmaptools/__init__.c msgid "unsupported colorspace for dither" -msgstr "" +msgstr "unsupported colourspace for dither" #: py/objstr.c #, c-format @@ -4277,11 +4303,11 @@ msgstr "unsupported types for %q: '%q', '%q'" #: extmod/ulab/code/numpy/io/io.c msgid "usecols is too high" -msgstr "" +msgstr "usecols is too high" #: extmod/ulab/code/numpy/io/io.c msgid "usecols keyword must be specified" -msgstr "" +msgstr "usecols keyword must be specified" #: py/objint.c #, c-format @@ -4292,10 +4318,6 @@ msgstr "value must fit in %d byte(s)" msgid "value out of range of target" msgstr "value out of range of target" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "value_count must be > 0" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "WatchDog not initialised" @@ -4311,7 +4333,7 @@ msgstr "WiFi is not enabled" #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" -msgstr "" +msgstr "wifi.Monitor not available" #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" @@ -4327,11 +4349,11 @@ msgstr "wrong axis specified" #: extmod/ulab/code/numpy/io/io.c msgid "wrong dtype" -msgstr "" +msgstr "wrong dtype" #: extmod/ulab/code/numpy/transform.c msgid "wrong index type" -msgstr "" +msgstr "wrong index type" #: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c #: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c @@ -4341,11 +4363,11 @@ msgstr "wrong input type" #: extmod/ulab/code/numpy/transform.c msgid "wrong length of condition array" -msgstr "" +msgstr "wrong length of condition array" #: extmod/ulab/code/numpy/transform.c msgid "wrong length of index array" -msgstr "" +msgstr "wrong length of index array" #: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c msgid "wrong number of arguments" @@ -4383,6 +4405,107 @@ 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 "out of range of source" +#~ msgstr "out of range of source" + +#~ msgid "pixel value requires too many bits" +#~ msgstr "pixel value requires too many bits" + +#~ msgid "value_count must be > 0" +#~ msgstr "value_count must be > 0" + +#~ msgid "64 bit types" +#~ msgstr "64 bit types" + +#~ msgid "No key was specified" +#~ msgstr "No key was specified" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "Scan already in progess. Stop with stop_scan." + +#~ msgid "too many arguments provided with the given format" +#~ msgstr "too many arguments provided with the given format" + +#~ 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" @@ -4411,9 +4534,6 @@ msgstr "zi must be of shape (n_section, 2)" #~ msgid "complex division by zero" #~ msgstr "complex division by zero" -#~ msgid "divide by zero" -#~ msgstr "divide by zero" - #~ msgid "int() arg 2 must be >= 2 and <= 36" #~ msgstr "int() arg 2 must be >= 2 and <= 36" diff --git a/locale/es.po b/locale/es.po index f65f60a770f7..3ebfdc7833e7 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: 2022-12-31 17:50+0000\n" -"Last-Translator: Orlando Caro \n" +"PO-Revision-Date: 2023-04-07 00:49+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.15.1-dev\n" +"X-Generator: Weblate 4.17-dev\n" #: main.c msgid "" @@ -37,12 +37,28 @@ 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 "" "\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\"" @@ -72,7 +88,7 @@ msgstr "%%c requiere int o char" #: main.c #, c-format msgid "%02X" -msgstr "" +msgstr "%02X" #: shared-module/os/getenv.c #, c-format @@ -96,9 +112,9 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.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" @@ -116,7 +132,12 @@ msgstr "%q contiene pines duplicados" 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -125,35 +146,35 @@ msgstr "%q está siendo utilizado" #: py/objstr.c py/objstrunicode.c msgid "%q index out of range" -msgstr "%q indice fuera de rango" +msgstr "%q índice fuera de rango" #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "%q inicializado fallido" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.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 "" +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 "%q tamaño debe ser %d" +msgstr "%q longitud debe ser %d" #: py/argcheck.c msgid "%q length must be %d-%d" -msgstr "%q tamaño debe ser %d-%d" +msgstr "%q longitud debe ser %d-%d" #: py/argcheck.c msgid "%q length must be <= %d" -msgstr "%q tamaño debe ser <= %d" +msgstr "%q longitud debe ser <= %d" #: py/argcheck.c msgid "%q length must be >= %d" -msgstr "%q tamaño debe ser >= %d" +msgstr "%q longitud debe ser >= %d" #: py/argcheck.c msgid "%q must be %d" @@ -177,19 +198,28 @@ msgstr "%q debe ser >= %d" #: shared-bindings/analogbufio/BufferedIn.c msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "%q debe ser un byte-matriz o matriz de tipo 'H' o 'B'" +msgstr "%q debe ser un bytearray o array de tipo 'H' o 'B'" #: 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 py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q debe ser de typo %q" +#: 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/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "%q debe ser una matriz de tipo 'h'" + +#: 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/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q debe ser de tipo %q o None" +#: 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" @@ -208,10 +238,6 @@ msgstr "%q fuera de limites" 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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "%q paso no puede ser cero" @@ -222,13 +248,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 "%q, %q, y %q deben tener el mismo largo" +msgstr "%q, %q, y %q deben tener la misma longitud" #: py/objint.c shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "%q=%q" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s error 0x%x" @@ -328,7 +354,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" @@ -394,15 +420,11 @@ msgstr "0.0 a una potencia compleja" msgid "3-arg pow() not supported" msgstr "pow() con 3 argumentos no soportado" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "tipos de 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 "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" @@ -411,7 +433,7 @@ 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" @@ -425,7 +447,7 @@ msgstr "Todos los periféricos CAN están en uso" #: 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 @@ -441,37 +463,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 @@ -499,6 +520,7 @@ msgstr "Ya se encuentra publicando." msgid "Already have all-matches listener" msgstr "Ya se tiene un escucha de todas las coincidencias" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -538,13 +560,9 @@ msgstr "Valores del array deben ser bytes individuales." 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 "Conversión de audio no esta implementada" +msgstr "Conversión de audio no está implementada" #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" @@ -563,12 +581,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 @@ -577,7 +595,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" @@ -589,24 +608,16 @@ msgstr "Bits depth debe ser múltiplo de 8." #: shared-bindings/bitmaptools/__init__.c msgid "Bitmap size and bits per value must match" -msgstr "El tamaño del mapa de bits y los bits por valor deben cotejar" +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 "" -"El dispositivo de arranque debe de ser el primer dispositivo (interfase #0)." +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" msgstr "Ambos RX y TX requeridos para control de flujo" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "Ambos botones fueron prensados al inicio\n" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Ambos pines deben soportar interrupciones por hardware" @@ -626,44 +637,44 @@ 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." -msgstr "Búfer no es un bytearray." +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 "Búfer 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 búfer %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úfer 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 "Búferes deben ser del mismo tamaño" +msgstr "Los buffers deben ser del mismo tamaño" #: ports/atmel-samd/common-hal/paralleldisplay/ParallelBus.c #: ports/espressif/common-hal/paralleldisplay/ParallelBus.c @@ -673,11 +684,6 @@ msgstr "Búferes deben ser del mismo tamaño" msgid "Bus pin %d is already in use" msgstr "Bus pin %d ya está siendo utilizado" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "Botón A fue presionado al inicio.\n" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Búfer Byte debe de ser 16 bytes." @@ -687,11 +693,10 @@ msgid "CBC blocks must be multiples of 16 bytes" msgstr "Los bloques CBC deben ser múltiplos de 16 bytes" #: supervisor/shared/safe_mode.c -#, fuzzy msgid "CIRCUITPY drive could not be found or created." -msgstr "CIRCUITPY dispositivo de guardo no pudo ser encontrado o creado." +msgstr "El dispositivo CIRCUITPY no pudo ser encontrado o creado." -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC o suma de comprobación inválida" @@ -756,7 +761,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" @@ -771,6 +776,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" @@ -791,7 +798,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" @@ -799,7 +806,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." @@ -813,10 +820,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" @@ -833,6 +836,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" @@ -857,10 +868,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" @@ -918,7 +925,7 @@ msgstr "Rotación de display debe ser en incrementos de 90 grados" #: main.c msgid "Done" -msgstr "" +msgstr "Hecho" #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." @@ -926,7 +933,7 @@ 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 "" +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" @@ -953,25 +960,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/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.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" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" -msgstr "" - #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" -msgstr "" +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 @@ -1001,7 +1000,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" @@ -1038,8 +1037,8 @@ 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" @@ -1047,7 +1046,7 @@ msgstr "El archivo ya existe" #: shared-module/os/getenv.c msgid "File not found" -msgstr "" +msgstr "Archivo no encontrado" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c @@ -1057,23 +1056,26 @@ msgstr "Filtros muy complejos" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is duplicate" -msgstr "" +msgstr "El Firmware es duplicado" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is invalid" -msgstr "" +msgstr "El Firmware es inválido" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is too big" -msgstr "" +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" @@ -1083,6 +1085,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" @@ -1096,9 +1100,9 @@ msgstr "La función requiere lock" #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" -msgstr "" +msgstr "Inicialización GNSS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "Fallo Genérico" @@ -1115,7 +1119,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 @@ -1127,13 +1131,23 @@ 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 @@ -1144,11 +1158,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 "" @@ -1231,11 +1240,11 @@ 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" @@ -1244,7 +1253,7 @@ 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 @@ -1253,12 +1262,21 @@ msgstr "Error interno #%d" #: supervisor/shared/safe_mode.c msgid "Internal watchdog timer expired." -msgstr "" +msgstr "El temporizador interno watchdog terminó." + +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Error de interrupción." -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Pin %q inválido" @@ -1276,12 +1294,15 @@ msgstr "Parámetro BLE invalido" msgid "Invalid BSSID" msgstr "BSSID inválido" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "CIRCUITPY_PYSTACK_SIZE inválido\n" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" -msgstr "" +msgstr "Dirección MAC inválida" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Argumento inválido" @@ -1292,26 +1313,26 @@ msgstr "Inválido bits por valor" #: shared-module/os/getenv.c #, c-format msgid "Invalid byte %.*s" -msgstr "" +msgstr "byte %.*s Inválido" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" msgstr "Inválidos los data_pins[%d]" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "Formato inválido" + #: shared-module/audiocore/WaveFile.c 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" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "Tamaño incorrecto" @@ -1320,13 +1341,13 @@ msgstr "Tamaño incorrecto" msgid "Invalid socket for TLS" msgstr "socket invalido para TLS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "Estado invalido" #: shared-module/os/getenv.c msgid "Invalid unicode escape" -msgstr "" +msgstr "Unicode del caracter \"escape\" inválido" #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" @@ -1334,11 +1355,11 @@ msgstr "La llave debe tener 16, 24 o 32 bytes de longitud" #: shared-module/os/getenv.c msgid "Key not found" -msgstr "" +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" @@ -1346,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.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 @@ -1372,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" @@ -1384,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 @@ -1423,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." @@ -1448,7 +1469,7 @@ msgstr "Error NVS" #: shared-bindings/socketpool/SocketPool.c msgid "Name or service not known" -msgstr "" +msgstr "Nombre o servicio desconocido" #: py/qstr.c msgid "Name too long" @@ -1456,11 +1477,11 @@ 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 @@ -1486,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 @@ -1499,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 @@ -1508,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 @@ -1530,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" @@ -1556,10 +1577,6 @@ msgstr "No hay \"in\" en el programa" msgid "No in or out in program" msgstr "No hay \"in\" o \"out\" en el programa" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "No se especificó ninguna llave" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "No hay soporte de entero largo" @@ -1589,7 +1606,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" @@ -1599,10 +1616,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" @@ -1622,14 +1635,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 "" @@ -1644,11 +1653,11 @@ msgstr "Paridad impar no soportada" #: supervisor/shared/bluetooth/bluetooth.c msgid "Off" -msgstr "" +msgstr "Apagado" #: supervisor/shared/bluetooth/bluetooth.c msgid "Ok" -msgstr "" +msgstr "Ok" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c @@ -1696,22 +1705,22 @@ msgstr "" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." -msgstr "" +msgstr "Solamente un %q puede ser establecido en deep sleep." #: ports/espressif/common-hal/espulp/ULPAlarm.c msgid "Only one %q can be set." -msgstr "" +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 @@ -1724,21 +1733,21 @@ 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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "Operación no característica no soportada" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "Tiempo de espera agotado" #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Out of MDNS service slots" -msgstr "" +msgstr "No hay slots MDNS de servicio" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "Memoria agotada" @@ -1768,7 +1777,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" @@ -1828,7 +1837,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" @@ -1854,7 +1863,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 @@ -1871,7 +1880,7 @@ msgstr "El tamaño del programa no es correcto" #: ports/espressif/common-hal/espulp/ULP.c msgid "Program too long" -msgstr "" +msgstr "El programa es demasiado grande" #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." @@ -1884,7 +1893,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" @@ -1897,7 +1906,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 @@ -1912,6 +1921,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1921,13 +1931,13 @@ msgstr "Solo-lectura" msgid "Read-only filesystem" msgstr "Sistema de archivos de solo-Lectura" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "La respuesta recibida es invalida" #: supervisor/shared/bluetooth/bluetooth.c msgid "Reconnecting" -msgstr "" +msgstr "Reconectando" #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" @@ -1941,7 +1951,7 @@ msgstr "RemoteTransmissionRequests limitado a 8 bytes" msgid "Requested AES mode is unsupported" msgstr "El modo AES solicitado no es compatible" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "Recurso solicitado no encontrado" @@ -1960,7 +1970,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 @@ -1978,7 +1988,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" @@ -1986,16 +1996,16 @@ 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 -msgid "Scan already in progess. Stop with stop_scan." -msgstr "Escaneo en progreso. Usa stop_scan para detener." +msgid "Scan already in progress. Stop with stop_scan." +msgstr "Escaneo en progreso. Usa stop_scan para detenerlo." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2037,7 +2047,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" @@ -2053,11 +2063,7 @@ msgstr "Estéreo derecho debe estar en el canal PWM B" #: 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 "Suministre al menos un pin UART" +msgstr "Parar el AP no esta soportado." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -2072,59 +2078,22 @@ msgid "Temperature read timed out" msgstr "Lectura de temperatura expirada" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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 "" -"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:" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: 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." +"El modulo `microcontrolador` fue usado para inicializar en modo seguro." #: py/obj.c msgid "The above exception was the direct cause of the following exception:" -msgstr "" - -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" +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" @@ -2142,15 +2111,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" @@ -2176,13 +2151,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 requesting safe mode." -msgstr "" - #: 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." @@ -2217,24 +2188,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 "" +msgstr "UID:" #: shared-module/usb_hid/Device.c msgid "USB busy" @@ -2271,6 +2246,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" @@ -2289,18 +2273,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 "" +msgstr "Imposible de escribir en esa dirección." #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." @@ -2322,12 +2317,17 @@ 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" + +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "Código de error desconocido %d" #: shared-bindings/wifi/Radio.c #, c-format @@ -2352,7 +2352,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 @@ -2362,12 +2362,7 @@ msgstr "Error desconocido en el firmware sistema: %04x" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error: %d" -msgstr "" - -#: ports/raspberrypi/common-hal/wifi/__init__.c -#, c-format -msgid "Unkown error code %d" -msgstr "" +msgstr "Error del sistema de firmware desconocido: %d" #: shared-bindings/adafruit_pixelbuf/PixelBuf.c #: shared-module/_pixelmap/PixelMap.c @@ -2385,7 +2380,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" @@ -2397,7 +2392,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" @@ -2417,7 +2412,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "La versión era invalida" @@ -2455,22 +2450,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 "" +msgstr "Wifi est en modo de access point." #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is in station mode." -msgstr "" +msgstr "Wifi esta en modo station." #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is not enabled" -msgstr "" +msgstr "Wifi no esta activado" #: main.c msgid "Woken up by alarm.\n" @@ -2481,16 +2481,57 @@ msgstr "Despertado por la alarma.\n" msgid "Writes not supported on Characteristic" msgstr "Escrituras no admitidas en Characteristic" +#: 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 are in safe mode because:\n" -msgstr "Estás en modo seguro por la razón:\n" +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 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 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" @@ -2559,7 +2600,11 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c @@ -2592,7 +2637,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" @@ -2616,7 +2661,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" @@ -2674,7 +2719,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" @@ -2711,7 +2756,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" @@ -2767,7 +2812,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" @@ -2782,9 +2827,9 @@ msgstr "no se puede definir un tamaño de bloque de 512" msgid "can't set attribute" msgstr "no se puede asignar el atributo" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" -msgstr "" +msgstr "no se puede configurar el attributo '%q'" #: py/emitnative.c msgid "can't store '%q'" @@ -2814,7 +2859,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" @@ -2822,11 +2867,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" @@ -2850,7 +2895,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" @@ -2922,7 +2967,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" @@ -2996,13 +3041,17 @@ msgstr "las dimensiones no concuerdan" msgid "div/mod not implemented for uint" msgstr "div/mod no implementado para uint" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "divide por cero" + #: 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" @@ -3010,7 +3059,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" @@ -3037,24 +3086,18 @@ msgstr "epoch_time no esta soportado en esta tarjeta" msgid "error = 0x%08lX" msgstr "error = 0x%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"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" @@ -3092,14 +3135,14 @@ msgid "extra positional arguments given" msgstr "argumento posicional adicional dado" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" 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" @@ -3180,7 +3223,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 @@ -3267,7 +3310,7 @@ msgstr "el índice está fuera de límites" #: shared-bindings/_pixelmap/PixelMap.c msgid "index must be tuple or int" -msgstr "" +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 @@ -3281,7 +3324,7 @@ 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" @@ -3317,7 +3360,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" @@ -3330,11 +3373,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" @@ -3346,7 +3389,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" @@ -3384,7 +3427,7 @@ 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" @@ -3402,7 +3445,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" @@ -3424,9 +3467,9 @@ msgstr "llave inválida" msgid "invalid micropython decorator" msgstr "decorador de micropython inválido" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" -msgstr "" +msgstr "configuracion invalida" #: shared-bindings/random/__init__.c msgid "invalid step" @@ -3515,12 +3558,12 @@ 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" @@ -3547,7 +3590,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" @@ -3581,7 +3624,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" @@ -3589,7 +3632,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" @@ -3650,7 +3693,7 @@ msgstr "cuenta de corrimientos negativo" #: shared-bindings/_pixelmap/PixelMap.c msgid "nested index must be int" -msgstr "" +msgstr "indice anidado debe ser int" #: shared-module/sdcardio/SDCard.c msgid "no SD card" @@ -3685,7 +3728,7 @@ msgstr "no hay pin de reinicio disponible" msgid "no response from SD card" msgstr "no hay respuesta de la tarjeta SD" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" @@ -3735,7 +3778,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" @@ -3797,7 +3840,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" @@ -3822,11 +3865,15 @@ msgstr "solo se admite bit_depth=16" #: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only mono is supported" -msgstr "" +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 "" +msgstr "solamente oversample=64 esta soportado" #: ports/nrf/common-hal/audiobusio/PDMIn.c #: ports/stm/common-hal/audiobusio/PDMIn.c @@ -3850,11 +3897,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" @@ -3885,11 +3932,7 @@ msgstr "La matriz de salida es demasiado pequeña" msgid "out must be a float dense array" msgstr "la matriz de salida debe ser densa de números float" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "fuera de rango de fuente" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "fuera de rango del objetivo" @@ -3914,21 +3957,17 @@ msgstr "los parámetros deben ser registros en secuencia de a2 a a5" msgid "parameters must be registers in sequence r0 to r3" msgstr "los parametros deben ser registros en secuencia del r0 al r3" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "coordenadas del pixel fuera de límites" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "valor del pixel require demasiado bits" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" 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" @@ -3965,7 +4004,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" @@ -4084,15 +4123,15 @@ 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" @@ -4160,7 +4199,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" @@ -4170,10 +4209,6 @@ msgstr "timestamp fuera de rango para plataform time_t" msgid "tobytes can be invoked for dense arrays only" msgstr "tobytes solo pueden ser invocados por arrays densos" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "demasiados argumentos provistos con el formato dado" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "demasiadas dimensiones" @@ -4209,8 +4244,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" @@ -4341,10 +4374,6 @@ msgstr "el valor debe caber en %d byte(s)" msgid "value out of range of target" msgstr "valor fuera de alcance al blanco" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "value_count debe ser > 0" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "watchdog no inicializado" @@ -4432,6 +4461,167 @@ 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 "out of range of source" +#~ msgstr "fuera de rango de fuente" + +#~ msgid "pixel value requires too many bits" +#~ msgstr "valor del pixel require demasiado bits" + +#~ msgid "value_count must be > 0" +#~ msgstr "value_count debe ser > 0" + +#~ msgid "64 bit types" +#~ msgstr "tipos de 64 bit" + +#~ msgid "No key was specified" +#~ msgstr "No se especificó ninguna llave" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "Escaneo en progreso. Usa stop_scan para detener." + +#, c-format +#~ msgid "Unkown error code %d" +#~ msgstr "Codigo de error desconocido: %d" + +#~ msgid "too many arguments provided with the given format" +#~ msgstr "demasiados argumentos provistos con el formato dado" + +#~ msgid "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "CIRCUITPY_PYSTACK_SIZE inválido\n" +#~ "\n" +#~ "\n" + +#~ 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" @@ -4460,9 +4650,6 @@ msgstr "zi debe ser una forma (n_section,2)" #~ msgid "complex division by zero" #~ msgstr "división compleja por cero" -#~ msgid "divide by zero" -#~ msgstr "divide por cero" - #~ msgid "int() arg 2 must be >= 2 and <= 36" #~ msgstr "int() arg 2 debe ser >= 2 y <= 36" diff --git a/locale/fil.po b/locale/fil.po index 7a77dab021cf..2a9127c34c95 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -32,8 +32,20 @@ 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 @@ -86,7 +98,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -106,7 +118,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -121,7 +138,7 @@ msgstr "%q indeks wala sa sakop" msgid "%q init failed" msgstr "" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "" @@ -173,12 +190,21 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" + +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" msgstr "" -#: py/objexcept.c 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 @@ -198,10 +224,6 @@ msgstr "" msgid "%q out of range" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -219,7 +241,7 @@ msgstr "" msgid "%q=%q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -385,10 +407,6 @@ msgstr "0.0 para sa complex power" msgid "3-arg pow() not supported" msgstr "3-arg pow() hindi suportado" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "" - #: 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 @@ -435,7 +453,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" @@ -489,6 +506,7 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -528,10 +546,6 @@ msgstr "Array values ay dapat single bytes." 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 "" @@ -582,20 +596,13 @@ 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 msgid "Both RX and TX required for flow control" 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/meowmeow/mpconfigboard.h -msgid "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Ang parehong mga pin ay dapat na sumusuporta sa hardware interrupts" @@ -661,11 +668,6 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "Ginagamit na ang DAC" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c #, fuzzy msgid "Byte buffer must be 16 bytes." @@ -679,7 +681,7 @@ msgstr "" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -798,10 +800,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" @@ -816,6 +814,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 "" @@ -840,10 +846,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 "" @@ -938,24 +940,16 @@ msgstr "" msgid "Error in regex" msgstr "May pagkakamali sa REGEX" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.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" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1023,7 +1017,7 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c @@ -1082,7 +1076,7 @@ msgstr "Function nangangailangan ng lock" msgid "GNSS init" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1111,6 +1105,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" @@ -1128,11 +1131,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 "" @@ -1232,10 +1230,19 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Mali ang %q pin" @@ -1253,12 +1260,15 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Maling argumento" @@ -1276,19 +1286,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "" + #: shared-module/audiocore/WaveFile.c 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 "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "" @@ -1297,7 +1307,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "" @@ -1329,7 +1339,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "" @@ -1529,10 +1539,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -1572,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 "" @@ -1596,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" @@ -1696,11 +1694,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1708,7 +1706,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1875,6 +1873,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1884,7 +1883,7 @@ msgstr "Basahin-lamang" msgid "Read-only filesystem" msgstr "Basahin-lamang mode" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1904,7 +1903,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1956,7 +1955,7 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." +msgid "Scan already in progress. Stop with stop_scan." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -2017,10 +2016,6 @@ msgstr "" 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 "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2034,50 +2029,19 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2096,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 "" @@ -2128,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2176,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 "" @@ -2223,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 "" @@ -2241,10 +2218,20 @@ 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" @@ -2282,6 +2269,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2317,11 +2309,6 @@ 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 @@ -2369,7 +2356,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2430,13 +2417,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2508,6 +2538,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2731,7 +2765,7 @@ msgstr "" msgid "can't set attribute" msgstr "hindi ma i-set ang attribute" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2947,6 +2981,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "dibisyon ng zero" @@ -2988,9 +3026,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -2998,14 +3036,6 @@ msgstr "" 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" @@ -3043,8 +3073,8 @@ msgid "extra positional arguments given" msgstr "dagdag na positional argument na ibinigay" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "file ay dapat buksan sa byte mode" @@ -3376,7 +3406,7 @@ msgstr "mali ang key" msgid "invalid micropython decorator" msgstr "mali ang micropython decorator" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3637,7 +3667,7 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" @@ -3774,6 +3804,10 @@ msgstr "" 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 "" @@ -3835,11 +3869,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3864,15 +3894,11 @@ msgstr "ang mga parameter ay dapat na nagrerehistro sa sequence a2 hanggang a5" msgid "parameters must be registers in sequence r0 to r3" msgstr "ang mga parameter ay dapat na nagrerehistro sa sequence r0 hanggang r3" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c #, fuzzy msgid "pixel coordinates out of bounds" msgstr "wala sa sakop ang address" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader ay dapat displayio.Palette o displayio.ColorConverter" @@ -4120,10 +4146,6 @@ msgstr "wala sa sakop ng timestamp ang platform time_t" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "masyadong maraming mga argumento na ibinigay sa ibinigay na format" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4159,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 at rx hindi pwedeng parehas na None" @@ -4291,10 +4311,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4384,6 +4400,12 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "too many arguments provided with the given format" +#~ msgstr "masyadong maraming mga argumento na ibinigay sa ibinigay na format" + +#~ msgid "Expected a %q" +#~ msgstr "Umasa ng %q" + #, fuzzy #~ msgid "Read-only object" #~ msgstr "Basahin-lamang" diff --git a/locale/fr.po b/locale/fr.po index 910c11cf57b7..22391687cb5f 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-12-27 18:02+0000\n" -"Last-Translator: Blinka CircuitPython \n" +"PO-Revision-Date: 2023-04-18 13:22+0000\n" +"Last-Translator: Jeff Epler \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.15.1-dev\n" +"X-Generator: Weblate 4.17\n" #: main.c msgid "" @@ -37,13 +37,28 @@ 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 "" "\n" -"Veuillez signaler un problème avec le contenu de votre lecteur CIRCUITPY à " -"l'adresse\n" -"https://github.com/adafruit/circuitpython/issues\n" +"Veuillez signaler un problème avec votre programme sur https://github.com/" +"adafruit/circuitpython/issues." + +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" +"\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\"" @@ -97,7 +112,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -117,7 +132,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -132,13 +152,13 @@ msgstr "index %q hors de portée" msgid "%q init failed" msgstr "échec de l'initialisation %q" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.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 "" +msgstr "%q est en lecture seule sur cette carte" #: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" @@ -178,19 +198,28 @@ msgstr "%q doit être >= %d" #: shared-bindings/analogbufio/BufferedIn.c msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "" +msgstr "%q doit être un bytearray ou matrice de type 'H' ou 'B'" #: 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 py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q doit être du type %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q doit être du type %q ou None" +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +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 doit être de type %q ou %q, pas %q" + +#: 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" @@ -209,13 +238,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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" -msgstr "" +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" @@ -229,7 +254,7 @@ msgstr "%q, %q, et %q doivent tous être de la même longueur" msgid "%q=%q" msgstr "%q=%q" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s erreur 0x%x" @@ -395,10 +420,6 @@ msgstr "0.0 à une puissance complexe" msgid "3-arg pow() not supported" msgstr "pow() non supporté avec 3 paramètres" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "types à 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 @@ -416,7 +437,7 @@ msgstr "L'adresse doit être longue de %d octets" #: ports/espressif/common-hal/memorymap/AddressRange.c msgid "Address range not allowed" -msgstr "" +msgstr "Plage d'adresses non autorisée" #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" @@ -445,7 +466,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" @@ -498,6 +518,7 @@ msgstr "S'annonce déjà." msgid "Already have all-matches listener" msgstr "Il y a déjà un auditeur all-matches" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -512,7 +533,7 @@ 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 "" +msgstr "Erreur survenue en récupérant '%s':\n" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" @@ -537,12 +558,6 @@ msgstr "Les valeurs de la matrice doivent être des octets singuliers." 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" @@ -595,20 +610,13 @@ 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" msgstr "RX et TX requis pour le contrôle de flux" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "Les deux boutons étaient pressés au démarrage.\n" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Les deux broches doivent supporter les interruptions matérielles" @@ -674,11 +682,6 @@ msgstr "Les tampons doivent avoir la même taille" msgid "Bus pin %d is already in use" msgstr "La broche %d du bus est déjà utilisée" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "Le bouton A était pressé au démarrage.\n" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Le tampon doit être de 16 octets." @@ -691,7 +694,7 @@ msgstr "Les blocs CBC doivent être des multiples de 16 octets" msgid "CIRCUITPY drive could not be found or created." msgstr "L'appareil CIRCUITPY ne peut pas être trouvé ou créé." -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC ou somme de contrôle invalide" @@ -821,10 +824,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" @@ -841,6 +840,14 @@ 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" @@ -865,10 +872,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" @@ -935,7 +938,7 @@ msgstr "" #: py/obj.c msgid "During handling of the above exception, another exception occurred:" -msgstr "" +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" @@ -962,25 +965,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/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.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" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" -msgstr "Attendu un %q ou %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" -msgstr "" +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 @@ -1048,8 +1043,8 @@ 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" @@ -1057,7 +1052,7 @@ msgstr "Le fichier existe" #: shared-module/os/getenv.c msgid "File not found" -msgstr "" +msgstr "Fichier non trouvé" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c @@ -1113,7 +1108,7 @@ msgstr "La fonction nécessite un verrou ('lock')" msgid "GNSS init" msgstr "Initialisation GNSS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "Échec génerique" @@ -1143,6 +1138,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é" @@ -1154,17 +1158,12 @@ 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" @@ -1274,10 +1273,19 @@ msgstr "Erreur interne #%d" msgid "Internal watchdog timer expired." msgstr "Le minuteur du watchdog interne a expiré." -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Erreur d'interruption." + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Broche invalide pour '%q'" @@ -1295,12 +1303,15 @@ msgstr "Paramètre BLE invalide" msgid "Invalid BSSID" msgstr "BSSID invalide" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Adresse MAC invalide" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Paramètre invalide" @@ -1311,26 +1322,26 @@ msgstr "Bits par valeur invalides" #: shared-module/os/getenv.c #, c-format msgid "Invalid byte %.*s" -msgstr "" +msgstr "Octet invalide %.*s" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" msgstr "data_pins[%d] invalide" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "" + #: shared-module/audiocore/WaveFile.c 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" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "Taille invalide" @@ -1339,13 +1350,13 @@ msgstr "Taille invalide" msgid "Invalid socket for TLS" msgstr "Socket non valide pour TLS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "État invalide" #: shared-module/os/getenv.c msgid "Invalid unicode escape" -msgstr "" +msgstr "Séquence unicode invalide" #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" @@ -1353,7 +1364,7 @@ msgstr "La clé doit comporter 16, 24 ou 32 octets" #: shared-module/os/getenv.c msgid "Key not found" -msgstr "" +msgstr "Clé non trouvée" #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" @@ -1371,7 +1382,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "Adresse physique (MAC) invalide" @@ -1466,7 +1477,7 @@ msgstr "Erreur NVS" #: shared-bindings/socketpool/SocketPool.c msgid "Name or service not known" -msgstr "" +msgstr "Nom ou service inconnu" #: py/qstr.c msgid "Name too long" @@ -1575,10 +1586,6 @@ msgstr "Programme n'a pas de \"in\"" msgid "No in or out in program" msgstr "Programme n'a aucun \"in\" ni \"out\"" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "Aucune clé n'a été spécifiée" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "Pas de support pour chiffre entier long" @@ -1618,10 +1625,6 @@ 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 n'a plus de mémoire" @@ -1641,10 +1644,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" @@ -1719,7 +1718,7 @@ msgstr "Une seul %q autorisée en sommeil profond." #: ports/espressif/common-hal/espulp/ULPAlarm.c msgid "Only one %q can be set." -msgstr "" +msgstr "Un seul %q peut être défini." #: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c @@ -1745,19 +1744,19 @@ msgstr "Une seule couleur peut être transparente à la fois" msgid "Operation not permitted" msgstr "Cette opération n'est pas permise" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "Opération ou fonction non supportée" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "Timeout de l'opération" #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Out of MDNS service slots" -msgstr "" +msgstr "À cours de services MDNS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "Mémoire insuffisante" @@ -1891,7 +1890,7 @@ msgstr "Taille du programme invalide" #: ports/espressif/common-hal/espulp/ULP.c msgid "Program too long" -msgstr "" +msgstr "Programme trop long" #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." @@ -1932,6 +1931,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1941,7 +1941,7 @@ msgstr "Lecture seule" msgid "Read-only filesystem" msgstr "Système de fichier en lecture seule" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "Réponse reçue invalide" @@ -1961,7 +1961,7 @@ msgstr "RemoteTransmissionRequests limité à 8 octets" msgid "Requested AES mode is unsupported" msgstr "Le mode AES demandé n'est pas supporté" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "Resource demandée non trouvée" @@ -2013,8 +2013,8 @@ msgstr "La dimension d'échelle doit être un multiple de 3" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." -msgstr "Scan déjà en cours. Arrêtez avec stop_scan." +msgid "Scan already in progress. Stop with stop_scan." +msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2072,11 +2072,7 @@ msgstr "Canal stéréo droit doit être sur le canal PWM B" #: 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 "Fournissez au moins une broche UART" +msgstr "Stopper n'est pas supporté." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -2091,59 +2087,20 @@ msgid "Temperature read timed out" msgstr "Délais de lecture de température dépassée" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -msgstr "Le bouton BOOT était pressé au démarrage.\n" - -#: 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 :" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "Le bouton SW38 était pressé au démarrage.\n" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "Le bouton VOLUME était pressé au démarrage.\n" - -#: 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." +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." #: py/obj.c msgid "The above exception was the direct cause of the following exception:" -msgstr "" - -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "Le bouton central était pressé au démarrage.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "Le bouton gauche était pressé au démarrage.\n" +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" @@ -2162,6 +2119,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." @@ -2196,10 +2157,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 requesting safe mode." -msgstr "Pour le quitter, redémarrez sans demander le mode sans-échec." - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "Trop de canaux dans l'échantillon" @@ -2244,6 +2201,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" @@ -2295,6 +2256,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')" @@ -2313,10 +2283,20 @@ 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" @@ -2324,7 +2304,7 @@ msgstr "Impossible de lancer la requête mDNS" #: shared-bindings/memorymap/AddressRange.c msgid "Unable to write to address." -msgstr "" +msgstr "L'écriture a échoué." #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." @@ -2353,6 +2333,11 @@ msgstr "Erreur BLE inconnue à %s:%d : %d" msgid "Unknown BLE error: %d" msgstr "Erreur BLE inconnue : %d" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2388,11 +2373,6 @@ msgstr "Faute inconnue du logiciel système : %04x" msgid "Unknown system firmware error: %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 @@ -2442,7 +2422,7 @@ msgstr "Longueur de valeur != Longueur fixe requise" msgid "Value length > max_length" msgstr "Longueur de la valeur > max_length" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "Version est invalide" @@ -2493,15 +2473,15 @@ msgstr "Wi-Fi : " #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is in access point mode." -msgstr "" +msgstr "Wifi en mode point d'accès." #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is in station mode." -msgstr "" +msgstr "Wifi en mode station." #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is not enabled" -msgstr "" +msgstr "Le wifi n'est pas activé" #: main.c msgid "Woken up by alarm.\n" @@ -2512,16 +2492,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 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" @@ -2592,6 +2613,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2815,9 +2840,9 @@ msgstr "impossible de définir une taille de bloc de 512" msgid "can't set attribute" msgstr "attribut non modifiable" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" -msgstr "" +msgstr "attribut '%q' non modifiable" #: py/emitnative.c msgid "can't store '%q'" @@ -3033,6 +3058,10 @@ msgstr "les dimensions ne correspondent pas" msgid "div/mod not implemented for uint" msgstr "div/mod ne sont pas implémentés pour uint" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "division par zéro" + #: py/runtime.c msgid "division by zero" msgstr "division par zéro" @@ -3074,26 +3103,18 @@ msgstr "epoch_time n'est pas supporté sur ce panneau" msgid "error = 0x%08lX" msgstr "erreur = 0x%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.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." +"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" @@ -3131,8 +3152,8 @@ msgid "extra positional arguments given" msgstr "argument(s) positionnel(s) supplémentaire(s) donné(s)" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "le fichier doit être un fichier ouvert en mode 'byte'" @@ -3306,7 +3327,7 @@ msgstr "l'index est hors limites" #: shared-bindings/_pixelmap/PixelMap.c msgid "index must be tuple or int" -msgstr "" +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 @@ -3465,7 +3486,7 @@ msgstr "clé invalide" msgid "invalid micropython decorator" msgstr "décorateur micropython invalide" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "réglage invalide" @@ -3692,7 +3713,7 @@ msgstr "compte de décalage négatif" #: shared-bindings/_pixelmap/PixelMap.c msgid "nested index must be int" -msgstr "" +msgstr "sous index doit être entier" #: shared-module/sdcardio/SDCard.c msgid "no SD card" @@ -3727,7 +3748,7 @@ msgstr "pas de broche de réinitialisation disponible" msgid "no response from SD card" msgstr "pas de réponse de la carte SD" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" @@ -3864,11 +3885,15 @@ 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 "" +msgstr "seul oversample=64 supporté" #: ports/nrf/common-hal/audiobusio/PDMIn.c #: ports/stm/common-hal/audiobusio/PDMIn.c @@ -3928,11 +3953,7 @@ msgstr "matrice de sortie est trop petite" msgid "out must be a float dense array" msgstr "la matrice sortante doit être de type float" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "dépassement des bornes de source" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "dépassement des bornes de target" @@ -3957,14 +3978,10 @@ msgstr "les paramètres doivent être des registres dans la séquence a2 à a5" msgid "parameters must be registers in sequence r0 to r3" msgstr "les paramètres doivent être des registres dans la séquence r0 à r3" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "coordonnées de pixel hors limites" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "la valeur du pixel requiet trop de bits" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4214,10 +4231,6 @@ msgstr "timestamp hors bornes pour 'time_t' de la plateforme" msgid "tobytes can be invoked for dense arrays only" msgstr "tobytes ne peut être appelée que pour des matrices dense" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "trop d'arguments fournis avec ce format" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "Trop de dimensions" @@ -4253,8 +4266,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" @@ -4385,10 +4396,6 @@ msgstr "la valeur doit tenir dans %d octet(s)" msgid "value out of range of target" msgstr "valeur hors de porté de la cible" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "'value_count' doit être > 0" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "chien de garde (watchdog) non initialisé" @@ -4476,6 +4483,171 @@ 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 "out of range of source" +#~ msgstr "dépassement des bornes de source" + +#~ msgid "pixel value requires too many bits" +#~ msgstr "la valeur du pixel requiet trop de bits" + +#~ msgid "value_count must be > 0" +#~ msgstr "'value_count' doit être > 0" + +#~ msgid "64 bit types" +#~ msgstr "types à 64 bit" + +#~ msgid "No key was specified" +#~ msgstr "Aucune clé n'a été spécifiée" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "Scan déjà en cours. Arrêtez avec stop_scan." + +#, c-format +#~ msgid "Unkown error code %d" +#~ msgstr "Erreur inconnue %d" + +#~ msgid "too many arguments provided with the given format" +#~ msgstr "trop d'arguments fournis avec ce format" + +#~ msgid "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "CIRCUITPY_PYSTACK_SIZE invalide\n" +#~ "\n" +#~ "\n" + +#~ 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" @@ -4516,9 +4688,6 @@ msgstr "zi doit être de forme (n_section, 2)" #~ msgid "complex division by zero" #~ msgstr "division complexe par zéro" -#~ msgid "divide by zero" -#~ msgstr "division 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" diff --git a/locale/hi.po b/locale/hi.po index 6b43cffabcf6..1f60a526cd14 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -31,8 +31,20 @@ 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 @@ -85,7 +97,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -105,7 +117,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -120,7 +137,7 @@ msgstr "" msgid "%q init failed" msgstr "" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "" @@ -172,12 +189,21 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" + +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" msgstr "" -#: py/objexcept.c 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,10 +223,6 @@ msgstr "" msgid "%q out of range" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -217,7 +239,7 @@ msgstr "" msgid "%q=%q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -383,10 +405,6 @@ msgstr "" msgid "3-arg pow() not supported" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "" - #: 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 @@ -433,7 +451,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 "" @@ -486,6 +503,7 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -525,10 +543,6 @@ msgstr "" 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 "" @@ -577,20 +591,13 @@ 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 msgid "Both RX and TX required for flow control" 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/meowmeow/mpconfigboard.h -msgid "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "" @@ -656,11 +663,6 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "" @@ -673,7 +675,7 @@ msgstr "" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -791,10 +793,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 "" @@ -809,6 +807,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 "" @@ -833,10 +839,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 "" @@ -928,24 +930,16 @@ msgstr "" msgid "Error in regex" msgstr "" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" -msgstr "" - -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1013,7 +1007,7 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c @@ -1072,7 +1066,7 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1101,6 +1095,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 "" @@ -1118,11 +1121,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 "" @@ -1220,10 +1218,19 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "" @@ -1241,12 +1248,15 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "" @@ -1264,19 +1274,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "" @@ -1285,7 +1295,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "" @@ -1317,7 +1327,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "" @@ -1517,10 +1527,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -1560,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 "" @@ -1583,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" @@ -1681,11 +1679,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1693,7 +1691,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1859,6 +1857,7 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" @@ -1868,7 +1867,7 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1888,7 +1887,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1940,7 +1939,7 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." +msgid "Scan already in progress. Stop with stop_scan." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -2001,10 +2000,6 @@ msgstr "" 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 "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2018,50 +2013,19 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2080,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 "" @@ -2112,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2160,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 "" @@ -2207,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 "" @@ -2225,10 +2202,20 @@ 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" @@ -2265,6 +2252,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2300,11 +2292,6 @@ 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 @@ -2351,7 +2338,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2412,13 +2399,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2490,6 +2520,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2710,7 +2744,7 @@ msgstr "" msgid "can't set attribute" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2918,6 +2952,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "" @@ -2959,9 +2997,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -2969,14 +3007,6 @@ msgstr "" 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 "" @@ -3014,8 +3044,8 @@ msgid "extra positional arguments given" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3346,7 +3376,7 @@ msgstr "" msgid "invalid micropython decorator" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3603,7 +3633,7 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" @@ -3739,6 +3769,10 @@ msgstr "" 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 "" @@ -3800,11 +3834,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3829,14 +3859,10 @@ msgstr "" msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4084,10 +4110,6 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4123,8 +4145,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 "" @@ -4255,10 +4275,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 33c397da0127..57a9a3b91f9d 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -34,12 +34,21 @@ 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" -"Per favore, segnala il problema con il contenuto del tuo CIRCUITPY a\n" -"https://github.com/adafruit/circuitpython/issues\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -92,7 +101,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -112,7 +121,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -127,7 +141,7 @@ msgstr "indice %q fuori intervallo" msgid "%q init failed" msgstr "" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "" @@ -179,12 +193,21 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +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 @@ -204,10 +227,6 @@ 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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -224,7 +243,7 @@ msgstr "" msgid "%q=%q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s errore 0x%x" @@ -391,10 +410,6 @@ msgstr "0.0 elevato alla potenza di un numero complesso" msgid "3-arg pow() not supported" msgstr "pow() con tre argmomenti non supportata" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "Tipo 64 bits" - #: 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 @@ -441,7 +456,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" @@ -495,6 +509,7 @@ msgstr "" msgid "Already have all-matches listener" msgstr "Già in possesso di tutti i listener abbinati" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -534,10 +549,6 @@ msgstr "I valori dell'Array dovrebbero essere bytes singoli." 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 "" @@ -589,20 +600,13 @@ 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 msgid "Both RX and TX required for flow control" msgstr "Sia RX che TX richiedono il controllo del flow" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Entrambi i pin devono supportare gli interrupt hardware" @@ -668,11 +672,6 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "Bus pin %d è già in uso" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "I buffer byte devono essere di almeno 16 bytes." @@ -685,7 +684,7 @@ msgstr "I blocchi CBC devono essere multipli di 16 bytes" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC o controllo totale è risultato non valido" @@ -804,10 +803,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" @@ -822,6 +817,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 "" @@ -846,10 +849,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 "" @@ -943,24 +942,16 @@ msgstr "" msgid "Error in regex" msgstr "Errore nella regex" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.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" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1028,7 +1019,7 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c @@ -1087,7 +1078,7 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1116,6 +1107,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" @@ -1133,11 +1133,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 "" @@ -1237,10 +1232,19 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Pin %q non valido" @@ -1258,12 +1262,15 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Argomento non valido" @@ -1281,19 +1288,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "" @@ -1302,7 +1309,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "" @@ -1334,7 +1341,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "" @@ -1535,10 +1542,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -1578,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 "" @@ -1602,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" @@ -1703,11 +1698,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1715,7 +1710,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1885,6 +1880,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1894,7 +1890,7 @@ msgstr "Sola lettura" msgid "Read-only filesystem" msgstr "Filesystem in sola lettura" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1914,7 +1910,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1966,7 +1962,7 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." +msgid "Scan already in progress. Stop with stop_scan." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -2027,10 +2023,6 @@ msgstr "" 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 "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2044,50 +2036,19 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2106,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 "" @@ -2138,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2186,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 "" @@ -2233,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 "" @@ -2251,10 +2225,20 @@ 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" @@ -2292,6 +2276,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2327,11 +2316,6 @@ 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 @@ -2379,7 +2363,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2440,13 +2424,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2518,6 +2545,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2742,7 +2773,7 @@ msgstr "" msgid "can't set attribute" msgstr "impossibile impostare attributo" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2955,6 +2986,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "divisione per zero" @@ -2996,9 +3031,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "errore = 0x%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -3006,14 +3041,6 @@ msgstr "" 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" @@ -3051,8 +3078,8 @@ msgid "extra positional arguments given" msgstr "argomenti posizonali extra dati" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3384,7 +3411,7 @@ msgstr "chiave non valida" msgid "invalid micropython decorator" msgstr "decoratore non valido in micropython" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3646,7 +3673,7 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" @@ -3785,6 +3812,10 @@ msgstr "" 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 "" @@ -3847,11 +3878,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3877,15 +3904,11 @@ msgstr "parametri devono essere i registri in sequenza da a2 a a5" msgid "parameters must be registers in sequence r0 to r3" msgstr "parametri devono essere i registri in sequenza da a2 a a5" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c #, fuzzy msgid "pixel coordinates out of bounds" msgstr "indirizzo fuori limite" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader deve essere displayio.Palette o displayio.ColorConverter" @@ -4133,10 +4156,6 @@ msgstr "timestamp è fuori intervallo per il time_t della piattaforma" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "troppi argomenti forniti con il formato specificato" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4172,8 +4191,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" @@ -4304,10 +4321,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4397,6 +4410,27 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "64 bit types" +#~ msgstr "Tipo 64 bits" + +#~ msgid "too many arguments provided with the given format" +#~ msgstr "troppi argomenti forniti con il formato specificato" + +#~ 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" diff --git a/locale/ja.po b/locale/ja.po index afe7997d33c5..fbe0d8c9023c 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -37,12 +37,21 @@ 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" -"CIRCUITPYドライブの内容を添えて問題を以下で報告してください:\n" -"https://github.com/adafruit/circuitpython/issues\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -70,7 +79,7 @@ msgid "%%c requires int or char" msgstr "%%c にはintまたはcharが必要" #: main.c -#, c-format, fuzzy +#, fuzzy, c-format msgid "%02X" msgstr "%02X" @@ -94,7 +103,7 @@ msgstr "%dアドレスピン、%dRGBピン、%dタイルは%dの高さを指示 #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c #, fuzzy msgid "%q" msgstr "%q" @@ -115,7 +124,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -130,7 +144,7 @@ msgstr "%q インデックスは範囲外" msgid "%q init failed" msgstr "%qは初期化には失敗" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "%qは%q" @@ -182,12 +196,21 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +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 @@ -207,10 +230,6 @@ msgstr "" msgid "%q out of range" msgstr "%q が範囲外" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "%q ピンは無効" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -227,7 +246,7 @@ msgstr "" msgid "%q=%q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -393,10 +412,6 @@ msgstr "0.0を複素数でべき乗" msgid "3-arg pow() not supported" msgstr "引数3つのpow()は非対応" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "" - #: 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 @@ -443,7 +458,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周辺機器が使用中" @@ -496,6 +510,7 @@ msgstr "すでにアドバータイズ中" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -535,10 +550,6 @@ msgstr "Arrayの各値は1バイトでなければなりません" 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 "" @@ -589,20 +600,13 @@ 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 msgid "Both RX and TX required for flow control" msgstr "フロー制御のためRXとTXの両方が必要" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "両方のピンにハードウェア割り込み対応が必要" @@ -668,11 +672,6 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "Busピン%dはすでに使用中" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "バッファは16バイトでなければなりません" @@ -685,7 +684,7 @@ msgstr "CBCブロックは16バイトの整数倍でなければなりません" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -805,10 +804,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 "クロックのストレッチが長すぎ" @@ -823,6 +818,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 ファイル" @@ -847,10 +850,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チャネル初期化エラー" @@ -942,24 +941,16 @@ msgstr "" msgid "Error in regex" msgstr "正規表現にエラーがあります" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "%qが必要" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1027,7 +1018,7 @@ msgid "Failed to write internal flash." msgstr "内部フラッシュ書き込みに失敗" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c @@ -1086,7 +1077,7 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1115,6 +1106,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操作" @@ -1132,11 +1132,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 "" @@ -1236,10 +1231,19 @@ msgstr "内部エラー #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "不正な%qピン" @@ -1257,12 +1261,15 @@ msgstr "" msgid "Invalid BSSID" msgstr "不正なBSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "不正な引数" @@ -1280,19 +1287,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "" + #: shared-module/audiocore/WaveFile.c 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 "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "" @@ -1301,7 +1308,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "" @@ -1333,7 +1340,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "" @@ -1533,10 +1540,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "キーが指定されていません" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "long integerに対応していません" @@ -1576,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 "" @@ -1599,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" @@ -1699,11 +1694,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1711,7 +1706,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1816,7 +1811,8 @@ msgstr "Prefixバッファはヒープ上になければなりません" #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" -msgstr "REPLに入るため、エンターキーを押す。リーロードするため、Ctl-Dを入力する。\n" +msgstr "" +"REPLに入るため、エンターキーを押す。リーロードするため、Ctl-Dを入力する。\n" #: main.c msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" @@ -1877,6 +1873,7 @@ msgstr "このボードはRTCに対応していません" msgid "Random number generation error" msgstr "乱数生成エラー" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" @@ -1886,7 +1883,7 @@ msgstr "読み込み専用" msgid "Read-only filesystem" msgstr "読み込み専用のファイルシステム" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1906,7 +1903,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "要求のAESモードは非対応" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1958,8 +1955,8 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." -msgstr "既にスキャン進行中。stop_scanで停止してください" +msgid "Scan already in progress. Stop with stop_scan." +msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2019,10 +2016,6 @@ msgstr "" 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 "少なくとも1つのUARTピンが必要" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2036,50 +2029,19 @@ msgid "Temperature read timed out" msgstr "温度読み取りがタイムアウトしました" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2098,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 "" @@ -2130,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2178,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 "" @@ -2226,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 "" @@ -2244,10 +2219,20 @@ 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" @@ -2284,6 +2269,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2319,11 +2309,6 @@ 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 @@ -2370,7 +2355,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2431,13 +2416,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2509,6 +2537,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2729,7 +2761,7 @@ msgstr "" msgid "can't set attribute" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2941,6 +2973,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "ゼロ除算 (division by zero)" @@ -2982,9 +3018,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "error = 0x1%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -2992,14 +3028,6 @@ msgstr "" 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 "書式化指定子の後に':'が必要" @@ -3037,8 +3065,8 @@ msgid "extra positional arguments given" msgstr "余分な位置引数が与えられました" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "fileはバイトモードで開かれたファイルでなければなりません" @@ -3370,7 +3398,7 @@ msgstr "不正な鍵" msgid "invalid micropython decorator" msgstr "不正なmicropythonデコレータ" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3627,7 +3655,7 @@ msgstr "利用可能なリセットピンがありません" msgid "no response from SD card" msgstr "SDカードからの応答がありません" -#: ports/espressif/common-hal/esp32_camera/Camera.c py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "指定の属性はありません" @@ -3763,6 +3791,10 @@ msgstr "bit_depth=16のみ対応しています" 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 "" @@ -3824,11 +3856,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "ソースが範囲外" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3853,14 +3881,10 @@ msgstr "" msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4110,10 +4134,6 @@ msgstr "timestampがプラットフォームのtime_tの範囲外" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "指定された書式に対して引数が多すぎます" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4149,8 +4169,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にできません" @@ -4281,10 +4299,6 @@ msgstr "値は%dバイトに収まらなければなりません" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "value_countは0より大きくなければなりません" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4372,6 +4386,52 @@ msgstr "ziはfloat値でなければなりません" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "out of range of source" +#~ msgstr "ソースが範囲外" + +#~ msgid "value_count must be > 0" +#~ msgstr "value_countは0より大きくなければなりません" + +#~ msgid "No key was specified" +#~ msgstr "キーが指定されていません" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "既にスキャン進行中。stop_scanで停止してください" + +#~ msgid "too many arguments provided with the given format" +#~ 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 "読み込み専用のオブジェクト" diff --git a/locale/ko.po b/locale/ko.po index 39ff657affcc..339cb42c86a3 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -32,8 +32,20 @@ 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 @@ -86,7 +98,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -106,7 +118,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -121,7 +138,7 @@ msgstr "%q 인덱스 범위를 벗어났습니다" msgid "%q init failed" msgstr "" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "" @@ -173,12 +190,21 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" + +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" msgstr "" -#: py/objexcept.c 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 @@ -198,10 +224,6 @@ msgstr "" msgid "%q out of range" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -218,7 +240,7 @@ msgstr "" msgid "%q=%q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -384,10 +406,6 @@ msgstr "" msgid "3-arg pow() not supported" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "" - #: 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 @@ -434,7 +452,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주변 기기" @@ -487,6 +504,7 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -526,10 +544,6 @@ msgstr "" 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 "" @@ -580,20 +594,13 @@ 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 msgid "Both RX and TX required for flow control" 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/meowmeow/mpconfigboard.h -msgid "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "" @@ -659,11 +666,6 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "잘못된 크기의 버퍼. 16 바이트 여야합니다." @@ -676,7 +678,7 @@ msgstr "" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -794,10 +796,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 "" @@ -812,6 +810,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 "" @@ -836,10 +842,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 "" @@ -931,24 +933,16 @@ msgstr "" msgid "Error in regex" msgstr "Regex에 오류가 있습니다." -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "%q 이 예상되었습니다." - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1016,7 +1010,7 @@ msgid "Failed to write internal flash." msgstr "" #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c @@ -1075,7 +1069,7 @@ msgstr "" msgid "GNSS init" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1104,6 +1098,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 "" @@ -1121,11 +1124,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 "" @@ -1223,10 +1221,19 @@ msgstr "" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "" @@ -1244,12 +1251,15 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "" @@ -1267,19 +1277,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "" + #: shared-module/audiocore/WaveFile.c 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 "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "" @@ -1288,7 +1298,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "" @@ -1320,7 +1330,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "" @@ -1520,10 +1530,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -1563,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 "" @@ -1586,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" @@ -1684,11 +1682,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1696,7 +1694,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1862,6 +1860,7 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" @@ -1871,7 +1870,7 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1891,7 +1890,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1943,7 +1942,7 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." +msgid "Scan already in progress. Stop with stop_scan." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -2004,10 +2003,6 @@ msgstr "" 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 "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2021,50 +2016,19 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2083,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 "" @@ -2115,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2163,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 "" @@ -2211,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 "" @@ -2229,10 +2206,20 @@ 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" @@ -2269,6 +2256,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2304,11 +2296,6 @@ 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 @@ -2355,7 +2342,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2416,13 +2403,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2494,6 +2524,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2714,7 +2748,7 @@ msgstr "" msgid "can't set attribute" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2922,6 +2956,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "" @@ -2963,9 +3001,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -2973,14 +3011,6 @@ msgstr "" 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,8 +3048,8 @@ msgid "extra positional arguments given" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3350,7 +3380,7 @@ msgstr "키가 유효하지 않습니다" msgid "invalid micropython decorator" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3607,7 +3637,7 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" @@ -3743,6 +3773,10 @@ msgstr "" 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 "" @@ -3804,11 +3838,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3833,14 +3863,10 @@ msgstr "" msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4088,10 +4114,6 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4127,8 +4149,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 "" @@ -4259,10 +4279,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4350,6 +4366,9 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Expected a %q" +#~ msgstr "%q 이 예상되었습니다." + #~ msgid "Invalid pins" #~ msgstr "핀이 유효하지 않습니다" diff --git a/locale/nl.po b/locale/nl.po index 79b6333de4e3..a91063c256df 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -31,12 +31,21 @@ 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" -"Meld een probleem met de inhoud van de CIRCUITPY drive op:\n" -"https://github.com/adafruit/circuitpython/issues\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -88,7 +97,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -108,7 +117,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -123,7 +137,7 @@ msgstr "%q index buiten bereik" msgid "%q init failed" msgstr "" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "" @@ -175,12 +189,21 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +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 @@ -200,10 +223,6 @@ 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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -220,7 +239,7 @@ msgstr "" msgid "%q=%q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -386,10 +405,6 @@ msgstr "0.0 tot een complexe macht" msgid "3-arg pow() not supported" msgstr "3-arg pow() niet ondersteund" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "" - #: 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 @@ -436,7 +451,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" @@ -489,6 +503,7 @@ msgstr "Advertising is al bezig." msgid "Already have all-matches listener" msgstr "Heeft al een luisteraar voor 'all-matches'" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -528,10 +543,6 @@ msgstr "Array waardes moet enkele bytes zijn." 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 "" @@ -582,20 +593,13 @@ 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 msgid "Both RX and TX required for flow control" msgstr "RX en TX zijn beide vereist voor stroomregeling" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Beide pinnen moeten hardware interrupts ondersteunen" @@ -661,11 +665,6 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "Bus pin %d al in gebruik" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Byte buffer moet 16 bytes zijn." @@ -678,7 +677,7 @@ msgstr "CBC blocks moeten meervouden van 16 bytes zijn" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -797,10 +796,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" @@ -817,6 +812,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" @@ -841,10 +844,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" @@ -936,24 +935,16 @@ msgstr "" msgid "Error in regex" msgstr "Fout in regex" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.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" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1021,7 +1012,7 @@ 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 @@ -1081,7 +1072,7 @@ msgstr "Functie vereist lock" msgid "GNSS init" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1110,6 +1101,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" @@ -1127,11 +1127,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 "" @@ -1231,10 +1226,19 @@ msgstr "Interne fout #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Ongeldige %q pin" @@ -1252,12 +1256,15 @@ msgstr "" msgid "Invalid BSSID" msgstr "Ongeldig BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Ongeldig argument" @@ -1275,19 +1282,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "" + #: shared-module/audiocore/WaveFile.c 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 "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "" @@ -1296,7 +1303,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "" @@ -1328,7 +1335,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "" @@ -1528,10 +1535,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "Een sleutel was niet gespecificeerd" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "Geen lange integer ondersteuning" @@ -1571,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 "" @@ -1594,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" @@ -1698,11 +1693,11 @@ msgstr "Er kan maar één kleur per keer transparant zijn" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1710,7 +1705,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1883,6 +1878,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1892,7 +1888,7 @@ msgstr "Alleen-lezen" msgid "Read-only filesystem" msgstr "Alleen-lezen bestandssysteem" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1912,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1964,8 +1960,8 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." -msgstr "Scan wordt al uitvoerd. Stop met stop_scan." +msgid "Scan already in progress. Stop with stop_scan." +msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2025,10 +2021,6 @@ msgstr "" 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 "Geef op zijn minst 1 UART pin op" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "Geef monotonic_time of epoch_time" @@ -2042,50 +2034,19 @@ msgid "Temperature read timed out" msgstr "Temperatuur lees time-out" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2104,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 "" @@ -2136,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2184,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 "" @@ -2231,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" @@ -2249,10 +2223,20 @@ 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" @@ -2289,6 +2273,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2324,11 +2313,6 @@ 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 @@ -2377,7 +2361,7 @@ msgstr "Waarde lengte != vereist vaste lengte" msgid "Value length > max_length" msgstr "Waarde length > max_length" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2442,13 +2426,56 @@ msgstr "Gewekt door alarm.\n" msgid "Writes not supported on Characteristic" msgstr "Schrijven niet ondersteund op Characteristic" +#: 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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2520,6 +2547,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2741,7 +2772,7 @@ msgstr "kan geen 512 blokgrootte instellen" msgid "can't set attribute" msgstr "kan attribute niet instellen" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2951,6 +2982,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "deling door nul" @@ -2992,9 +3027,9 @@ msgstr "epoch_time niet ondersteund op dit bord" msgid "error = 0x%08lX" msgstr "fout = 0x%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -3002,14 +3037,6 @@ msgstr "" 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" @@ -3047,8 +3074,8 @@ msgid "extra positional arguments given" msgstr "extra positionele argumenten gegeven" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "bestand moet een bestand zijn geopend in byte modus" @@ -3380,7 +3407,7 @@ msgstr "ongeldige sleutel" msgid "invalid micropython decorator" msgstr "ongeldige micropython decorator" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3640,7 +3667,7 @@ msgstr "geen reset pin beschikbaar" msgid "no response from SD card" msgstr "geen antwoord van SD kaart" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" @@ -3776,6 +3803,10 @@ msgstr "alleen bit_depth=16 wordt ondersteund" 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 "" @@ -3837,11 +3868,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "buiten bereik van bron" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "buiten bereik van doel" @@ -3866,14 +3893,10 @@ msgstr "parameters moeten registers zijn in de volgorde a2 tot a5" msgid "parameters must be registers in sequence r0 to r3" msgstr "parameters moeten registers zijn in de volgorde r0 tot r3" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "pixel coördinaten buiten bereik" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "pixel waarde vereist te veel bits" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader moet displayio.Palette of displayio.ColorConverter zijn" @@ -4121,10 +4144,6 @@ msgstr "timestamp buiten bereik voor platform time_t" msgid "tobytes can be invoked for dense arrays only" msgstr "tobytes kunnen alleen ingeroepen worden voor gesloten arrays" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "te veel argumenten opgegeven bij dit formaat" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4160,8 +4179,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" @@ -4292,10 +4309,6 @@ msgstr "waarde moet in %d byte(s) passen" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "value_count moet groter dan 0 zijn" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "watchdog niet geïnitialiseerd" @@ -4383,6 +4396,64 @@ 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 "out of range of source" +#~ msgstr "buiten bereik van bron" + +#~ msgid "pixel value requires too many bits" +#~ msgstr "pixel waarde vereist te veel bits" + +#~ msgid "value_count must be > 0" +#~ msgstr "value_count moet groter dan 0 zijn" + +#~ msgid "No key was specified" +#~ msgstr "Een sleutel was niet gespecificeerd" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "Scan wordt al uitvoerd. Stop met stop_scan." + +#~ msgid "too many arguments provided with the given format" +#~ msgstr "te veel argumenten opgegeven bij dit formaat" + +#~ 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" diff --git a/locale/pl.po b/locale/pl.po index 814a5d06d478..fbd76182cc9e 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -33,12 +33,21 @@ 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" -"Zgłoś problem z zawartością dysku CIRCUITPY pod adresem\n" -"https://github.com/adafruit/circuitpython/issues\n" +"You are in safe mode because:\n" +msgstr "" #: py/obj.c msgid " File \"%q\"" @@ -90,7 +99,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "" @@ -110,7 +119,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -125,7 +139,7 @@ msgstr "%q poza zakresem" msgid "%q init failed" msgstr "" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "" @@ -177,12 +191,21 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +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 @@ -202,10 +225,6 @@ 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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "" @@ -222,7 +241,7 @@ msgstr "" msgid "%q=%q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "" @@ -388,10 +407,6 @@ msgstr "0.0 do potęgi zespolonej" msgid "3-arg pow() not supported" msgstr "3-argumentowy pow() jest niewspierany" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "" - #: 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 @@ -438,7 +453,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" @@ -491,6 +505,7 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -530,10 +545,6 @@ msgstr "Wartości powinny być bajtami." 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 "" @@ -584,20 +595,13 @@ 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 msgid "Both RX and TX required for flow control" msgstr "Do kontroli przepływu wymagane są zarówno RX, jak i TX" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Obie nóżki muszą wspierać przerwania sprzętowe" @@ -663,11 +667,6 @@ msgstr "" msgid "Bus pin %d is already in use" msgstr "Nóżka magistrali %d jest w użyciu" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Bufor musi mieć 16 bajtów." @@ -680,7 +679,7 @@ msgstr "Bloki CBC muszą być wielokrotnościami 16 bajtów" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -798,10 +797,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" @@ -818,6 +813,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" @@ -842,10 +845,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" @@ -937,24 +936,16 @@ msgstr "" msgid "Error in regex" msgstr "Błąd w regex" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "Error: Failure to bind" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Oczekiwano %q" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "Error: Failure to bind" msgstr "" #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" +msgid "Expected a kind of %q" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c @@ -1022,7 +1013,7 @@ 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 @@ -1081,7 +1072,7 @@ msgstr "Funkcja wymaga blokady" msgid "GNSS init" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1110,6 +1101,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" @@ -1127,11 +1127,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 "" @@ -1231,10 +1226,19 @@ msgstr "Błąd wewnętrzny #%d" msgid "Internal watchdog timer expired." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Zła nóżka %q" @@ -1252,12 +1256,15 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Zły argument" @@ -1275,19 +1282,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "" + #: shared-module/audiocore/WaveFile.c 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 "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "Nieprawidłowy rozmiar" @@ -1296,7 +1303,7 @@ msgstr "Nieprawidłowy rozmiar" msgid "Invalid socket for TLS" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "Nieprawidłowy stan" @@ -1328,7 +1335,7 @@ msgstr "" msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "" @@ -1528,10 +1535,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "Nie określono klucza" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -1571,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 "" @@ -1594,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" @@ -1692,11 +1687,11 @@ msgstr "W danym momencie przezroczysty może być tylko jeden kolor" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1704,7 +1699,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "Brak pamięci" @@ -1870,6 +1865,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1879,7 +1875,7 @@ msgstr "Tylko do odczytu" msgid "Read-only filesystem" msgstr "System plików tylko do odczytu" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "Otrzymana odpowiedź była nieprawidłowa" @@ -1899,7 +1895,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "Żądany tryb AES nie jest obsługiwany" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "Nie znaleziono żądanego zasobu" @@ -1951,8 +1947,8 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." -msgstr "Skanuj już w toku. Zatrzymaj za pomocą stop_scan." +msgid "Scan already in progress. Stop with stop_scan." +msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2012,10 +2008,6 @@ msgstr "" 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 "Podaj co najmniej jeden pin UART" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2029,50 +2021,19 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2091,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 "" @@ -2123,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2171,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 "" @@ -2218,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 "" @@ -2236,10 +2210,20 @@ 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" @@ -2276,6 +2260,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2311,11 +2300,6 @@ 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 @@ -2362,7 +2346,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2423,13 +2407,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2501,6 +2528,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2721,7 +2752,7 @@ msgstr "" msgid "can't set attribute" msgstr "nie można ustawić atrybutu" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2930,6 +2961,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "dzielenie przez zero" @@ -2971,9 +3006,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "błąd = 0x%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -2981,14 +3016,6 @@ msgstr "" 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" @@ -3026,8 +3053,8 @@ msgid "extra positional arguments given" msgstr "nadmiarowe argumenty pozycyjne" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "file musi być otwarte w trybie bajtowym" @@ -3358,7 +3385,7 @@ msgstr "zły klucz" msgid "invalid micropython decorator" msgstr "zły dekorator micropythona" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3615,7 +3642,7 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" @@ -3751,6 +3778,10 @@ msgstr "obsługiwane jest tylko bit_depth=16" 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 "" @@ -3812,11 +3843,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3841,14 +3868,10 @@ msgstr "parametry muszą być rejestrami w kolejności a2 do a5" msgid "parameters must be registers in sequence r0 to r3" msgstr "parametry muszą być rejestrami w kolejności r0 do r3" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "współrzędne piksela poza zakresem" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "wartość piksela wymaga zbyt wielu bitów" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4097,10 +4120,6 @@ msgstr "timestamp poza zakresem dla time_t na tej platformie" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "zbyt wiele argumentów podanych dla tego formatu" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4136,8 +4155,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" @@ -4268,10 +4285,6 @@ msgstr "wartość musi mieścić się w %d bajtach" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "value_count musi być > 0" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4359,6 +4372,49 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "pixel value requires too many bits" +#~ msgstr "wartość piksela wymaga zbyt wielu bitów" + +#~ msgid "value_count must be > 0" +#~ msgstr "value_count musi być > 0" + +#~ msgid "No key was specified" +#~ msgstr "Nie określono klucza" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "Skanuj już w toku. Zatrzymaj za pomocą stop_scan." + +#~ msgid "too many arguments provided with the given format" +#~ msgstr "zbyt wiele argumentów podanych dla tego formatu" + +#~ 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" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index e4569ad596bb..d130fcc464dd 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: 2023-01-05 02:52+0000\n" +"PO-Revision-Date: 2023-04-07 00:49+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.15.1-dev\n" +"X-Generator: Weblate 4.17-dev\n" #: main.c msgid "" @@ -35,12 +35,28 @@ 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 "" "\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\"" @@ -94,7 +110,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -114,7 +130,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -129,7 +150,7 @@ msgstr "O índice %q está fora do intervalo" msgid "%q init failed" msgstr "a inicialização do %q falhou" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "%q é %q" @@ -181,13 +202,22 @@ msgstr "%q deve ser um bytearray ou uma matriz do tipo 'H' ou 'B'" 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 py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q deve ser do tipo %q" +#: 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/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "%q deve ser uma matriz do tipo 'h'" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q deve ser do tipo %q ou nenhum" +#: 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 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" @@ -206,10 +236,6 @@ 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" - #: 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" @@ -226,7 +252,7 @@ msgstr "todos os %q, %q, e %q devem ter mesmo comprimento" msgid "%q=%q" msgstr "%q=%q" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s erro 0x%x" @@ -396,10 +422,6 @@ msgstr "0,0 para uma potência complexa" msgid "3-arg pow() not supported" msgstr "3-arg pow() não compatível" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "Tipos 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 @@ -446,7 +468,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" @@ -499,6 +520,7 @@ msgstr "Já está anunciando." msgid "Already have all-matches listener" msgstr "Já há um ouvinte com todas as correspondências" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -538,11 +560,6 @@ msgstr "Os valores das matrizes devem ser bytes simples." 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" @@ -595,22 +612,13 @@ 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" msgstr "Ambos os RX e TX são necessários para o controle do fluxo" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "Ambos os botões foram pressionados na inicialização.\n" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Ambos os pinos devem suportar interrupções de hardware" @@ -676,11 +684,6 @@ msgstr "Os buffers devem ter o mesmo tamanho" msgid "Bus pin %d is already in use" msgstr "O pino bus %d já está em uso" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "O botão A foi pressionado na inicialização.\n" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "O buffer deve ter 16 bytes." @@ -693,7 +696,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC ou checksum inválido" @@ -817,10 +820,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" @@ -836,6 +835,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" @@ -860,10 +867,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" @@ -955,25 +958,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/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Esperado um" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" -msgstr "Era esperado um %q ou %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" -msgstr "Esperava-se um(a) %q" +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 @@ -1040,8 +1035,8 @@ 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" @@ -1103,7 +1098,7 @@ msgstr "A função requer bloqueio" msgid "GNSS init" msgstr "Inicialização do GNSS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "Falha Genérica" @@ -1132,6 +1127,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" @@ -1149,11 +1155,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" @@ -1259,10 +1260,19 @@ msgstr "Erro interno #%d" msgid "Internal watchdog timer expired." msgstr "O temporizador do watchdog interno expirou." -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Erro de interrupção." + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Pino do %q inválido" @@ -1280,12 +1290,15 @@ msgstr "Parâmetro BLE inválido" msgid "Invalid BSSID" msgstr "BSSID Inválido" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "CIRCUITPY_PYSTACK_SIZE inválido\n" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Endereço MAC inválido" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Argumento inválido" @@ -1303,19 +1316,19 @@ msgstr "Byte %.*s inválido" msgid "Invalid data_pins[%d]" msgstr "data_pins[%d] inválido" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "Formato inválido" + #: shared-module/audiocore/WaveFile.c 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" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "Tamanho inválido" @@ -1324,7 +1337,7 @@ msgstr "Tamanho inválido" msgid "Invalid socket for TLS" msgstr "Soquete inválido para o TLS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "Estado inválido" @@ -1356,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "Endereço MAC inválido" @@ -1556,10 +1569,6 @@ msgstr "Sem entrada no programa" msgid "No in or out in program" msgstr "Sem entrada ou saída no programa" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "Nenhuma chave foi definida" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "Não há compatibilidade com inteiro longo" @@ -1601,10 +1610,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" @@ -1624,10 +1629,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" @@ -1727,11 +1728,11 @@ msgstr "Apenas uma cor pode ser transparente de cada vez" msgid "Operation not permitted" msgstr "A operação não é permitida" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "A operação ou o recurso não é suportado" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "A operação expirou" @@ -1739,7 +1740,7 @@ msgstr "A operação expirou" 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 +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "Sem memória" @@ -1915,6 +1916,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1924,7 +1926,7 @@ msgstr "Somente leitura" msgid "Read-only filesystem" msgstr "Sistema de arquivos somente leitura" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "A resposta recebida foi inválida" @@ -1944,7 +1946,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "O recurso solicitado não foi encontrado" @@ -1996,8 +1998,8 @@ msgstr "As dimensões da escala devem ser poder ser divididas por 3" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." -msgstr "O escaneamento já está em andamento. Interrompa com stop_scan." +msgid "Scan already in progress. Stop with stop_scan." +msgstr "Digitalização já em andamento. Pare com stop_scan." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2057,10 +2059,6 @@ msgstr "O estéreo à direita deve estar no canal PWM B" msgid "Stopping AP is not supported." msgstr "Não há suporte para a interrupção do AP." -#: 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" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "Forneça um de monotonic_time ou de epoch_time" @@ -2074,60 +2072,22 @@ msgid "Temperature read timed out" msgstr "A leitura da temperatura expirou" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -msgstr "O botão BOOT foi pressionado na inicialização.\n" - -#: 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:" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "O botão SW38 foi pressionado na inicialização.\n" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "O botão VOLUME foi pressionado na inicialização.\n" - -#: 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." +"O módulo `microcontroller` foi usado para inicializar em 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:" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "O botão central foi pressionado na inicialização.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "O botão esquerdo foi pressionado na inicialização.\n" - #: 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" @@ -2145,6 +2105,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." @@ -2181,10 +2145,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 requesting safe mode." -msgstr "Para sair, reinicie a placa sem solicitar o modo de segurança." - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "Muitos canais na amostra" @@ -2229,6 +2189,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" @@ -2277,6 +2241,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" @@ -2295,10 +2268,20 @@ 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" @@ -2335,6 +2318,11 @@ msgstr "Houve um erro BLE desconhecido em %s:%d: %d" msgid "Unknown BLE error: %d" msgstr "Houve um erro BLE desconhecido: %d" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "Código de erro desconhecido %d" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2370,11 +2358,6 @@ 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 @@ -2423,7 +2406,7 @@ msgstr "Comprimento do valor != comprimento fixo necessário" msgid "Value length > max_length" msgstr "O comprimento do valor é > max_length" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "A versão era inválida" @@ -2493,16 +2476,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" +#: 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 are in safe mode because:\n" -msgstr "Você está no modo de segurança pois:\n" +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 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 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" @@ -2573,6 +2597,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2795,7 +2823,7 @@ msgstr "não é possível definir o tamanho de 512 blocos" msgid "can't set attribute" msgstr "não é possível definir o atributo" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "não é possível definir o atributo '%q'" @@ -3010,6 +3038,10 @@ msgstr "as dimensões não coincidem" msgid "div/mod not implemented for uint" msgstr "div/mod não implementado para uint" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "divido por zero" + #: py/runtime.c msgid "division by zero" msgstr "divisão por zero" @@ -3051,26 +3083,18 @@ msgstr "O epoch_time não é compatível com esta placa" msgid "error = 0x%08lX" msgstr "erro = 0x%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.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." +"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" @@ -3108,8 +3132,8 @@ msgid "extra positional arguments given" msgstr "argumentos extra posicionais passados" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "o arquivo deve ser um arquivo aberto no modo byte" @@ -3441,7 +3465,7 @@ msgstr "chave inválida" msgid "invalid micropython decorator" msgstr "o decorador micropython é inválido" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "configuração inválida" @@ -3703,7 +3727,7 @@ msgstr "nenhum pino de redefinição está disponível" msgid "no response from SD card" msgstr "não houve resposta do cartão SD" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" @@ -3839,6 +3863,10 @@ msgstr "apenas bit_depth = 16 é compatível" 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" @@ -3903,11 +3931,7 @@ msgstr "a matriz externa é muito pequena" msgid "out must be a float dense array" msgstr "deve ser uma matriz densa flutuante" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "fora do alcance da fonte" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "fora do alcance do alvo" @@ -3934,14 +3958,10 @@ msgstr "os parâmetros devem ser registradores na sequência a2 até a5" msgid "parameters must be registers in sequence r0 to r3" msgstr "os parâmetros devem ser registradores na sequência r0 até r3" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "as coordenadas do pixel estão fora dos limites" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "o valor do pixel requer bits demais" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "o pixel_shader deve ser displayio.Palette ou displayio.ColorConverter" @@ -4189,10 +4209,6 @@ msgstr "timestamp fora do intervalo para a plataforma time_t" msgid "tobytes can be invoked for dense arrays only" msgstr "os tobytes podem ser invocados apenas nas matrizes densas" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "Muitos argumentos fornecidos com o formato dado" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "dimensões demais" @@ -4228,8 +4244,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" @@ -4360,10 +4374,6 @@ msgstr "o valor deve caber em %d byte(s)" msgid "value out of range of target" msgstr "valor fora do alcance do alvo" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "o value_count deve ser > 0" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "o watchdog não foi inicializado" @@ -4451,6 +4461,174 @@ 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 "out of range of source" +#~ msgstr "fora do alcance da fonte" + +#~ msgid "pixel value requires too many bits" +#~ msgstr "o valor do pixel requer bits demais" + +#~ msgid "value_count must be > 0" +#~ msgstr "o value_count deve ser > 0" + +#~ msgid "64 bit types" +#~ msgstr "Tipos 64 bit" + +#~ msgid "No key was specified" +#~ msgstr "Nenhuma chave foi definida" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "O escaneamento já está em andamento. Interrompa com stop_scan." + +#, c-format +#~ msgid "Unkown error code %d" +#~ msgstr "Código de erro desconhecido %d" + +#~ msgid "too many arguments provided with the given format" +#~ msgstr "Muitos argumentos fornecidos com o formato dado" + +#~ msgid "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "CIRCUITPY_PYSTACK_SIZE inválido\n" +#~ "\n" +#~ "\n" + +#~ 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" @@ -4494,9 +4672,6 @@ msgstr "zi deve estar na forma (n_section, 2)" #~ msgid "complex division by zero" #~ msgstr "divisão complexa por zero" -#~ msgid "divide by zero" -#~ msgstr "divido por zero" - #~ msgid "int() arg 2 must be >= 2 and <= 36" #~ msgstr "int() arg 2 deve ser >= 2 e <= 36" diff --git a/locale/ru.po b/locale/ru.po index 5549e7e3f991..8fe6419b1148 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -37,13 +37,21 @@ 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\"" @@ -96,7 +104,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -116,7 +124,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -131,7 +144,7 @@ msgstr "Индекс %q вне диапазона" msgid "%q init failed" msgstr "Инициализация %q не удалась" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "%q является %q" @@ -183,13 +196,22 @@ msgstr "%q должно быть bytearray или array типа 'H' или 'B'" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "%q должно быть bytearray или array типа 'h', 'H', 'b', или 'B'" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q должно быть типа %q" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q должно быть типа %q или None" +#: shared-bindings/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +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 msgid "%q must be power of 2" @@ -208,10 +230,6 @@ msgstr "%q за пределом" msgid "%q out of range" msgstr "%q вне диапазона" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -msgid "%q pin invalid" -msgstr "Пин %q не допустим" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "Шаг %q не может быть нулём" @@ -228,7 +246,7 @@ msgstr "%q, %q, и %q должны быть одной длинны" msgid "%q=%q" msgstr "%q=%q" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s ошибка 0x%x" @@ -394,10 +412,6 @@ msgstr "0.0 в комплексную степень" msgid "3-arg pow() not supported" msgstr "3-аргументный pow() не поддерживается" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "64-битные типы" - #: 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 @@ -444,7 +458,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 уже используются" @@ -497,6 +510,7 @@ msgstr "Уже объявляемся (advertising)." msgid "Already have all-matches listener" msgstr "Уже есть универсальный слушатель" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -536,10 +550,6 @@ msgstr "Значения массива должны быть однобайто 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 "Преобразование звука не реализовано" @@ -594,20 +604,13 @@ 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" msgstr "Для управления потоком требуется как RX, так и TX" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "Обе кнопки были нажаты при загрузке.\n" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Оба пина должны поддерживать аппаратные прерывания" @@ -673,11 +676,6 @@ msgstr "Буферы должны быть одинакового размера msgid "Bus pin %d is already in use" msgstr "Пин шины %d уже используется" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "Кнопка A была нажата при загрузке\n" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Буфер байтов должен быть размером 16 байтам." @@ -690,7 +688,7 @@ msgstr "Блоки CBC должны быть кратны 16 байтам" msgid "CIRCUITPY drive could not be found or created." msgstr "Не удалось найти или создать диск CIRCUITPY." -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC или контрольная сумма неправильная" @@ -818,10 +816,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 "Длинна такта слишком велика" @@ -838,6 +832,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 поврежден" @@ -862,10 +864,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 "Ошибка инициализации канала ЦАП" @@ -961,26 +959,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/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "Ожидалось(ся) %q" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" -msgstr "Ожидалось %q или %q" - #: shared-bindings/alarm/__init__.c -#, fuzzy -msgid "Expected an %q" -msgstr "Ожидалось %q" +msgid "Expected a kind of %q" +msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -1047,8 +1036,8 @@ 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" @@ -1114,7 +1103,7 @@ msgstr "Функция требует блокировки" msgid "GNSS init" msgstr "Инициализация GNSS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "Общий сбой" @@ -1143,6 +1132,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 "Операция ввода-вывода на закрытом файле" @@ -1160,11 +1158,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 байта" @@ -1270,10 +1263,19 @@ msgstr "Внутренняя ошибка #%d" msgid "Internal watchdog timer expired." msgstr "Внутренний сторожевой таймер истек." -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Недопустимый пин %q" @@ -1291,12 +1293,15 @@ msgstr "Недопустимый параметр BLE" msgid "Invalid BSSID" msgstr "Неверный BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Неверный MAC-адрес" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Недопустимый аргумент" @@ -1314,19 +1319,19 @@ msgstr "Неверный байт %.*s" msgid "Invalid data_pins[%d]" msgstr "Неверный data_pins[%d]" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "" + #: shared-module/audiocore/WaveFile.c 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" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "Неверный размер" @@ -1335,7 +1340,7 @@ msgstr "Неверный размер" msgid "Invalid socket for TLS" msgstr "Неверный сокет для TLS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "Неверное состояние" @@ -1369,7 +1374,7 @@ msgstr "Слой уже в группе (Group)" msgid "Layer must be a Group or TileGrid subclass" msgstr "Слой должен быть группой (Group) или субклассом TileGrid." -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "MAC адрес был недействительным" @@ -1570,10 +1575,6 @@ msgstr "Нет in в программе" msgid "No in or out in program" msgstr "В программе отсутствует ввод или вывод" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "Ключ не был указан" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "Нет поддержки длинных целых чисел (long integer)" @@ -1615,11 +1616,6 @@ msgstr "Файл/директория не существует" msgid "No timer available" msgstr "Нет доступного таймера" -#: supervisor/shared/safe_mode.c -#, fuzzy -msgid "Nordic system firmware failure assertion." -msgstr "Сбой системной прошивки Nordic (assertion)." - #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "" @@ -1640,11 +1636,6 @@ msgstr "Не подключено" msgid "Not playing" msgstr "Не воспроизводится (Not playing)" -#: shared-bindings/_bleio/__init__.c -#, fuzzy -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" @@ -1744,11 +1735,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1756,7 +1747,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1927,6 +1918,7 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" @@ -1936,7 +1928,7 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1956,7 +1948,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -2008,7 +2000,7 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." +msgid "Scan already in progress. Stop with stop_scan." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -2069,10 +2061,6 @@ msgstr "" 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 "" @@ -2086,50 +2074,19 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2148,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 "" @@ -2182,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2230,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 "" @@ -2277,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 "" @@ -2295,10 +2265,20 @@ 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" @@ -2335,6 +2315,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2370,11 +2355,6 @@ 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 @@ -2421,7 +2401,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2482,13 +2462,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2560,6 +2583,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2780,7 +2807,7 @@ msgstr "" msgid "can't set attribute" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2988,6 +3015,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "" @@ -3029,9 +3060,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -3039,14 +3070,6 @@ msgstr "" 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 "" @@ -3084,8 +3107,8 @@ msgid "extra positional arguments given" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3416,7 +3439,7 @@ msgstr "" msgid "invalid micropython decorator" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3673,7 +3696,7 @@ msgstr "нет доступного контакта сброса" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" @@ -3809,6 +3832,10 @@ msgstr "" 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 "" @@ -3870,11 +3897,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3899,14 +3922,10 @@ msgstr "" msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4154,10 +4173,6 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4193,8 +4208,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 "" @@ -4325,10 +4338,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4416,6 +4425,81 @@ msgstr "zi должно быть типа float" msgid "zi must be of shape (n_section, 2)" msgstr "zi должен иметь форму (n_section, 2)" +#~ msgid "64 bit types" +#~ msgstr "64-битные типы" + +#~ msgid "No key was specified" +#~ msgstr "Ключ не был указан" + +#~ 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" diff --git a/locale/sv.po b/locale/sv.po index 4f83512286f2..8cb79da28e9f 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: 2023-01-05 02:52+0000\n" +"PO-Revision-Date: 2023-04-07 00:49+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.15.1-dev\n" +"X-Generator: Weblate 4.17-dev\n" #: main.c msgid "" @@ -35,12 +35,28 @@ 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 "" "\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\"" @@ -93,7 +109,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -113,7 +129,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -128,7 +149,7 @@ msgstr "Index %q ligger utanför intervallet" msgid "%q init failed" msgstr "%q init misslyckades" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "%q är %q" @@ -182,13 +203,22 @@ msgstr "" "%q måste vara en bytearray eller en array av typen \"h\", \"H\", \"b\" eller " "\"B\"" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q måste vara av typen %q" +#: 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/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "%q måste vara en matris av typen 'h'" -#: py/objexcept.c shared-bindings/digitalio/Pull.c -msgid "%q must be of type %q or None" -msgstr "%q måste vara av typen %q eller 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 "%q måste vara av typen %q eller %q, inte %q" + +#: 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" @@ -207,10 +237,6 @@ 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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "%q steg kan inte vara noll" @@ -227,7 +253,7 @@ msgstr "%q, %q och %q måste vara lika långa" msgid "%q=%q" msgstr "%q=%q" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s fel 0x%x" @@ -393,10 +419,6 @@ msgstr "0,0 till ett komplext nummer" msgid "3-arg pow() not supported" msgstr "3-arguments pow() stöds inte" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "64-bitars typer" - #: 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 @@ -443,7 +465,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" @@ -496,6 +517,7 @@ msgstr "Annonserar redan." msgid "Already have all-matches listener" msgstr "Har redan lyssnare för all-matchningar" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -535,10 +557,6 @@ msgstr "Matrisvärden ska bestå av enstaka bytes." 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" @@ -589,20 +607,13 @@ 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" msgstr "Både RX och TX krävs för handskakning" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "Båda knapparna trycktes ned vid start.\n" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Båda pinnarna måste stödja maskinvaruavbrott" @@ -668,11 +679,6 @@ msgstr "Buffertarna måste ha samma storlek" msgid "Bus pin %d is already in use" msgstr "Busspinne %d används redan" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "Knapp A trycktes ned vid start.\n" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Byte-buffert måste vara 16 byte." @@ -685,7 +691,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC eller checksumma var ogiltig" @@ -805,10 +811,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" @@ -825,6 +827,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" @@ -849,10 +859,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" @@ -945,25 +951,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/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.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" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" -msgstr "Förväntade %q eller %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" -msgstr "Förväntade en %q" +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 @@ -1030,8 +1028,8 @@ 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" @@ -1091,7 +1089,7 @@ msgstr "Funktionen kräver lås" msgid "GNSS init" msgstr "GNSS start" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "Allmänt fel" @@ -1120,6 +1118,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" @@ -1137,11 +1144,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" @@ -1243,10 +1245,19 @@ msgstr "Internt fel #%d" msgid "Internal watchdog timer expired." msgstr "Intern watchdog-timer har löpt ut." -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Interrupt-fel." + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Ogiltig %q-pinne" @@ -1264,12 +1275,15 @@ msgstr "Ogiltig BLE-parameter" msgid "Invalid BSSID" msgstr "Ogiltig BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "Ogiltig CIRCUITPY_PYSTACK_SIZE\n" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Ogiltig MAC-adress" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Ogiltigt argument" @@ -1287,19 +1301,19 @@ msgstr "Ogiltig byte %.*s" msgid "Invalid data_pins[%d]" msgstr "Ogiltig data_pins[%d]" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "Ogiltigt format" + #: shared-module/audiocore/WaveFile.c 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" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "Ogiltig storlek" @@ -1308,7 +1322,7 @@ msgstr "Ogiltig storlek" msgid "Invalid socket for TLS" msgstr "Ogiltig socket för TLS" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "Ogiltigt tillstånd" @@ -1340,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "MAC-adressen var ogiltig" @@ -1541,10 +1555,6 @@ msgstr "Inget in i programmet" msgid "No in or out in program" msgstr "Inget in eller ut i programmet" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "Ingen nyckel angavs" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "Inget stöd för långt heltal" @@ -1584,10 +1594,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" @@ -1607,10 +1613,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" @@ -1710,11 +1712,11 @@ msgstr "Bara en färg kan vara genomskinlig i taget" msgid "Operation not permitted" msgstr "Åtgärden inte tillåten" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "Operation eller funktion stöds inte" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "Åtgärden orsakade timeout" @@ -1722,7 +1724,7 @@ msgstr "Åtgärden orsakade timeout" msgid "Out of MDNS service slots" msgstr "Slut på MDNS-serviceplatser" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "Slut på minne" @@ -1895,6 +1897,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1904,7 +1907,7 @@ msgstr "Skrivskyddad" msgid "Read-only filesystem" msgstr "Skrivskyddat filsystem" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "Mottaget svar var ogiltigt" @@ -1924,7 +1927,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "Begärd resurs hittades inte" @@ -1976,8 +1979,8 @@ msgstr "Skaldimension måste vara delbar med 3" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." -msgstr "Skanning pågår redan. Avsluta med stop_scan." +msgid "Scan already in progress. Stop with stop_scan." +msgstr "Skanning pågår redan. Stoppa med stop_scan." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2037,10 +2040,6 @@ msgstr "Höger stereokanal måste använda PWM kanal B" msgid "Stopping AP is not supported." msgstr "Stoppa AP stöds inte." -#: 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" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "Ange en av monotonic_time eller epoch_time" @@ -2054,59 +2053,20 @@ msgid "Temperature read timed out" msgstr "Temperaturavläsning tog för lång tid" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -msgstr "BOOT-knappen trycktes ner vid start.\n" - -#: 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:" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "SW38-knappen trycktes ned vid start.\n" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "VOLUME-knappen trycktes ned vid start.\n" - -#: 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." +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." #: 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:" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "Mittknappen trycktes in vid start.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "Den vänstra knappen trycktes ned vid start.\n" - #: 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" @@ -2124,6 +2084,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." @@ -2158,10 +2122,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 requesting safe mode." -msgstr "För att avsluta, återställ kortet utan att begära säkert läge." - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "För många kanaler i urvalet" @@ -2206,6 +2166,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" @@ -2253,6 +2217,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" @@ -2271,10 +2244,20 @@ 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" @@ -2311,6 +2294,11 @@ msgstr "Okänt BLE-fel vid %s:%d: %d" msgid "Unknown BLE error: %d" msgstr "Okänt BLE-fel: %d" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "Okänd felkod %d" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2346,11 +2334,6 @@ 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 @@ -2399,7 +2382,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "Versionen var ogiltig" @@ -2466,16 +2449,57 @@ msgstr "Vaknade av larm.\n" msgid "Writes not supported on Characteristic" msgstr "Skrivning stöds inte på karaktäristik" +#: 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 are in safe mode because:\n" -msgstr "Du är i felsäkert läge eftersom:\n" +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 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 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" @@ -2546,6 +2570,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2766,7 +2794,7 @@ msgstr "kan inte sätta blockstorlek 512" msgid "can't set attribute" msgstr "kan inte att ange attribut" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "kan inte sätta attribut '%q'" @@ -2979,6 +3007,10 @@ msgstr "dimensioner matchar inte" msgid "div/mod not implemented for uint" msgstr "div/mod inte implementerat för uint" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "division med noll" + #: py/runtime.c msgid "division by zero" msgstr "division med noll" @@ -3020,26 +3052,18 @@ msgstr "epoch_time stöds inte av detta kort" msgid "error = 0x%08lX" msgstr "fel = 0x%08lX" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" -"esp32_camera.Camera kräver reserverad PSRAM att konfigureras. Se " +"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" @@ -3077,8 +3101,8 @@ msgid "extra positional arguments given" msgstr "extra positions-argument angivna" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "filen måste vara en fil som öppnats i byte-läge" @@ -3409,7 +3433,7 @@ msgstr "ogiltig nyckel" msgid "invalid micropython decorator" msgstr "ogiltig mikropython-dekorator" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "ogiltig inställning" @@ -3669,7 +3693,7 @@ msgstr "ingen reset-pinne tillgänglig" msgid "no response from SD card" msgstr "inget svar från SD-kort" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" @@ -3805,6 +3829,10 @@ msgstr "bara bit_depth=16 stöds" 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" @@ -3866,11 +3894,7 @@ msgstr "matrisen för out är för liten" msgid "out must be a float dense array" msgstr "out måste vara en float dense array" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "utanför räckvidd för source" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "utanför räckvidd för target" @@ -3895,14 +3919,10 @@ msgstr "parametrarna måste registreras i följd a2-a5" msgid "parameters must be registers in sequence r0 to r3" msgstr "parametrarna måste registreras i följd r0-r3" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "pixelkoordinater utanför gränserna" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "pixelvärdet kräver för många bitar" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4151,10 +4171,6 @@ msgstr "timestamp utom räckvidd för plattformens \"time_t\"" msgid "tobytes can be invoked for dense arrays only" msgstr "tobyte kan enbart anropas för täta matriser" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "för många argument för det givna formatet" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "för många dimensioner" @@ -4190,8 +4206,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" @@ -4322,10 +4336,6 @@ msgstr "värdet måste passa i %d byte(s)" msgid "value out of range of target" msgstr "värde utanför målintervall" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "value_count måste vara > 0" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "watchdog är inte initierad" @@ -4413,6 +4423,171 @@ 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 "out of range of source" +#~ msgstr "utanför räckvidd för source" + +#~ msgid "pixel value requires too many bits" +#~ msgstr "pixelvärdet kräver för många bitar" + +#~ msgid "value_count must be > 0" +#~ msgstr "value_count måste vara > 0" + +#~ msgid "64 bit types" +#~ msgstr "64-bitars typer" + +#~ msgid "No key was specified" +#~ msgstr "Ingen nyckel angavs" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "Skanning pågår redan. Avsluta med stop_scan." + +#, c-format +#~ msgid "Unkown error code %d" +#~ msgstr "Okänd felkod %d" + +#~ msgid "too many arguments provided with the given format" +#~ msgstr "för många argument för det givna formatet" + +#~ msgid "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "Ogiltig CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\n" + +#~ 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" @@ -4456,9 +4631,6 @@ msgstr "zi måste vara i formen (n_section, 2)" #~ msgid "complex division by zero" #~ msgstr "komplex division med noll" -#~ msgid "divide by zero" -#~ msgstr "division med noll" - #~ msgid "int() arg 2 must be >= 2 and <= 36" #~ msgstr "int() arg 2 måste vara >= 2 och <= 36" diff --git a/locale/tr.po b/locale/tr.po index e25e81d67965..1f8874167b37 100644 --- a/locale/tr.po +++ b/locale/tr.po @@ -37,13 +37,21 @@ 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\"" @@ -97,7 +105,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -117,7 +125,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -132,7 +145,7 @@ msgstr "%q indeksi aralık dışında" msgid "%q init failed" msgstr "%q init başarısız oldu" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" msgstr "%q %q dir" @@ -184,13 +197,22 @@ msgstr "%q 'H' ya da 'B' tipi bir bytearray ya da array olmalıdır" 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ı" -#: py/argcheck.c py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q, %q türünde olmalıdır" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" -#: py/objexcept.c 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/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +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 msgid "%q must be power of 2" @@ -209,10 +231,6 @@ 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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" msgstr "%q sıfır olamaz" @@ -229,7 +247,7 @@ msgstr "%q, %q ve %q aynı uzunlukta olmalıdır" msgid "%q=%q" msgstr "%q=%q" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s hatası 0x%x" @@ -396,10 +414,6 @@ msgstr "0.0'dan bir karmaşık güce" msgid "3-arg pow() not supported" msgstr "3-argümanlı pow() desteklenmemektedir" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "64 bit tipler" - #: 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 @@ -446,7 +460,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" @@ -499,6 +512,7 @@ msgstr "Halihazırda duyuruluyor." msgid "Already have all-matches listener" msgstr "Tüm eşleşmelerle eşleşen dinleyiciniz var" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -538,10 +552,6 @@ msgstr "Dizi değerleri tekil bytelar olmalıdır." 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" @@ -592,20 +602,13 @@ 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" msgstr "Hem RX hem de TX akış kontrolü için gerekli" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "Başlatma sırasında her iki düğmeye de basıldı.\n" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "Her iki pin de donanım kesintilerini desteklemelidir" @@ -671,11 +674,6 @@ msgstr "Arabellek boyutları aynı olmalı" msgid "Bus pin %d is already in use" msgstr "Veriyolu pini %d kullanımda" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "Başlatma sırasında A düğmesine basıldı.\n" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Bit buffer'ı 16bit olmalı." @@ -688,7 +686,7 @@ msgstr "CBC blokları 16 baytın katları şeklinde olmalı" msgid "CIRCUITPY drive could not be found or created." msgstr "CIRCUITPY sürücüsü bulunamadı veya oluşturulamadı." -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC yada checksum geçersiz" @@ -807,10 +805,6 @@ msgstr "CharacteristicBuffer yazılmı sağlanmadı" msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "CircuitPython kor kodu patladı. Haydaaa!\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 "Saat uzatması çok uzun" @@ -825,6 +819,14 @@ msgid "" "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 "Bozuk .mpy dosyası" @@ -849,10 +851,6 @@ msgstr "Kesinti başlatılamadı, RX kullanımda" 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 "" @@ -944,25 +942,17 @@ msgstr "%d konumundaki MIDI akışında hata" 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 "Hata: Bağlanamadı" -#: ports/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c -#: shared-bindings/microcontroller/Pin.c -#: shared-bindings/neopixel_write/__init__.c -msgid "Expected a %q" -msgstr "%q bekleniyor" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" -msgstr "%q yada %q bekleniyor" - #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" -msgstr "%q bekleniyor" +msgid "Expected a kind of %q" +msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c @@ -1029,7 +1019,7 @@ msgid "Failed to write internal flash." msgstr "Dahili flaş yazılamadı." #: supervisor/shared/safe_mode.c -msgid "Fatal error." +msgid "Fault detected by hardware." msgstr "" #: py/moduerrno.c @@ -1092,7 +1082,7 @@ msgstr "Fonksiyon kilit gerektirir" msgid "GNSS init" msgstr "GNSS init" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "" @@ -1121,6 +1111,15 @@ msgstr "Donanım meşgul, alternatif pinleri deneyin" 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 "Kapalı dosyada I/O işlemi" @@ -1138,11 +1137,6 @@ msgstr "I2C çevre cihazı kullanımda" msgid "I2SOut not available" msgstr "I2SOut uygundeğil" -#: shared-bindings/aesio/aes.c -#, c-format -msgid "IV must be %d bytes long" -msgstr "IV %d bayt uzunluğunda olmalı" - #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" msgstr "Buffer öğeleri <=4 bayt uzunluğunda olmalı" @@ -1242,10 +1236,19 @@ msgstr "Dahili hata #%d" msgid "Internal watchdog timer expired." msgstr "Dahili bekçi zamanlayıcısının süresi doldu." -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "" + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c py/argcheck.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "Geçersiz %q" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Geersi %q pin" @@ -1263,12 +1266,15 @@ msgstr "Geçersiz BLE parametresi" msgid "Invalid BSSID" msgstr "Geçersiz BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Geçersiz MAC adresi" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Geçersiz argüman" @@ -1287,19 +1293,19 @@ msgstr "" msgid "Invalid data_pins[%d]" msgstr "Geçersiz veri_pini [%d]" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "" + #: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" msgstr "Geçersiz biçim yığın boyutu" -#: supervisor/shared/safe_mode.c -msgid "Invalid memory access." -msgstr "Geçersiz bellek erişimi." - #: ports/espressif/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Geçersiz multicast MAC adresi" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "Geçersiz boyut" @@ -1308,7 +1314,7 @@ msgstr "Geçersiz boyut" msgid "Invalid socket for TLS" msgstr "TLS için geçersiz soket" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "Geçersiz durum" @@ -1340,7 +1346,7 @@ msgstr "Katman zaten bir grupta" msgid "Layer must be a Group or TileGrid subclass" msgstr "Katman, bir Grup ya da TileGrid alt sınıfı olmalıdır" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "MAC adresi geçersiz" @@ -1540,10 +1546,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -1583,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 "" @@ -1606,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" @@ -1704,11 +1698,11 @@ msgstr "" msgid "Operation not permitted" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "" @@ -1716,7 +1710,7 @@ msgstr "" msgid "Out of MDNS service slots" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "" @@ -1885,6 +1879,7 @@ msgstr "" msgid "Random number generation error" msgstr "" +#: shared-bindings/_bleio/__init__.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c shared-module/displayio/Bitmap.c msgid "Read-only" @@ -1894,7 +1889,7 @@ msgstr "" msgid "Read-only filesystem" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "" @@ -1914,7 +1909,7 @@ msgstr "" msgid "Requested AES mode is unsupported" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "" @@ -1966,7 +1961,7 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." +msgid "Scan already in progress. Stop with stop_scan." msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -2027,10 +2022,6 @@ msgstr "" 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 "" - #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" msgstr "" @@ -2044,50 +2035,19 @@ msgid "Temperature read timed out" msgstr "" #: supervisor/shared/safe_mode.c -msgid "The BOOT button was pressed at start up.\n" -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:" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "" -"The `microcontroller` module was used to boot into safe mode. Press reset to " -"exit safe mode." +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "" - #: shared-bindings/rgbmatrix/RGBMatrix.c 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 @@ -2106,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 "" @@ -2138,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 requesting safe mode." -msgstr "" - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2186,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 "" @@ -2233,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 "" @@ -2251,10 +2224,20 @@ 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" @@ -2291,6 +2274,11 @@ msgstr "" msgid "Unknown BLE error: %d" msgstr "" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2326,11 +2314,6 @@ 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 @@ -2377,7 +2360,7 @@ msgstr "" msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "" @@ -2438,13 +2421,56 @@ msgstr "" msgid "Writes not supported on Characteristic" 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/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 are in safe mode because:\n" +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. Press again to exit safe mode." +msgid "You pressed the reset button during boot." +msgstr "" + +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" #: py/objtype.c @@ -2516,6 +2542,10 @@ 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2736,7 +2766,7 @@ msgstr "" msgid "can't set attribute" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -2944,6 +2974,10 @@ msgstr "" msgid "div/mod not implemented for uint" msgstr "" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "" + #: py/runtime.c msgid "division by zero" msgstr "" @@ -2985,9 +3019,9 @@ msgstr "" msgid "error = 0x%08lX" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.Camera requires reserved PSRAM to be configured. See the " "documentation for instructions." msgstr "" @@ -2995,14 +3029,6 @@ msgstr "" 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 "" @@ -3040,8 +3066,8 @@ msgid "extra positional arguments given" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3372,7 +3398,7 @@ msgstr "" msgid "invalid micropython decorator" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "" @@ -3629,7 +3655,7 @@ msgstr "" msgid "no response from SD card" msgstr "" -#: ports/espressif/common-hal/esp32_camera/Camera.c py/objobject.c py/runtime.c +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" msgstr "" @@ -3765,6 +3791,10 @@ msgstr "" 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 "" @@ -3826,11 +3856,7 @@ msgstr "" msgid "out must be a float dense array" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "" @@ -3855,14 +3881,10 @@ msgstr "" msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "" @@ -4110,10 +4132,6 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4149,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 "" @@ -4281,10 +4297,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4372,6 +4384,56 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "64 bit types" +#~ msgstr "64 bit tipler" + +#~ 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" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 8599c77f2eef..dffbea185d5e 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-11-30 16:14+0000\n" +"PO-Revision-Date: 2023-04-09 17:51+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.15-dev\n" +"X-Generator: Weblate 4.17-dev\n" #: main.c msgid "" @@ -37,12 +37,28 @@ 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 "" "\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\"" @@ -96,7 +112,7 @@ msgstr "" #: 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/alarm/__init__.c -#: ports/stm/common-hal/rtc/RTC.c +#: ports/stm/common-hal/canio/Listener.c ports/stm/common-hal/rtc/RTC.c msgid "%q" msgstr "%q" @@ -116,7 +132,12 @@ 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/mimxrt10xx/common-hal/audiobusio/__init__.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/microcontroller/Pin.c @@ -131,13 +152,13 @@ msgstr "%q suǒyǐn chāochū fànwéi" msgid "%q init failed" msgstr "%q chūshǐhuà shībài" -#: shared-bindings/dualbank/__init__.c +#: ports/espressif/bindings/espnow/Peer.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 "" +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" @@ -177,20 +198,29 @@ msgstr "%q bìxū >= %d" #: shared-bindings/analogbufio/BufferedIn.c msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "" +msgstr "%q bì xū shì zì jié shù zǔ huò lèi xíng wéi 'H' huò 'B' de shù zǔ" #: 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 py/obj.c py/objstrunicode.c -msgid "%q must be of type %q" -msgstr "%q bì xū shì %q lèi xíng" +#: 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/synthio/MidiTrack.c shared-bindings/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "%q bìxū shì lèixíng wéi 'h' de shùzǔ" + +#: 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" -#: py/objexcept.c 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" @@ -209,13 +239,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" - #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" -msgstr "" +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" @@ -229,7 +255,7 @@ msgstr "%q, %q, hé %q bì xū cháng dù xiāng tóng" msgid "%q=%q" msgstr "%q=%q" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format msgid "%s error 0x%x" msgstr "%s cuò wù 0x%x" @@ -395,10 +421,6 @@ msgstr "0.0 de fùshù cì mì" msgid "3-arg pow() not supported" msgstr "bù zhī chí 3-arg pow()" -#: shared-module/msgpack/__init__.c -msgid "64 bit types" -msgstr "64 wèi lèixíng" - #: 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 @@ -416,7 +438,7 @@ msgstr "dìzhǐ chángdù bìxū shì %d zìjié" #: ports/espressif/common-hal/memorymap/AddressRange.c msgid "Address range not allowed" -msgstr "" +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" @@ -445,7 +467,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" @@ -498,6 +519,7 @@ msgstr "Mùqián zhèngzài guǎngbō." msgid "Already have all-matches listener" msgstr "yǐjīng yǒu all-matches jiāntīng qì" +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c @@ -512,7 +534,7 @@ 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 "" +msgstr "jiǎn suǒ '%s' shí chū cuò:\n" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" @@ -537,10 +559,6 @@ msgstr "shùzǔ de zhí yīnggāi shì dān'gè zìjié." 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" @@ -591,20 +609,13 @@ msgid "Bitmap size and bits per value must match" 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" msgstr "RX hé TX dōu xū yào liúliàng kòngzhì" -#: 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 "Both buttons were pressed at start up.\n" -msgstr "qǐ dòng shí àn xià le liǎng gè àn niǔ.\n" - #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" msgstr "liǎnggè yǐnjiǎo dōu bìxū zhīchí yìngjiàn zhōngduàn" @@ -670,11 +681,6 @@ msgstr "huǎnchōng qū bìxū dàxiǎo xiāngtóng" msgid "Bus pin %d is already in use" msgstr "Zǒngxiàn yǐnjiǎo %d yǐjīng zài shǐyòng zhōng" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -msgid "Button A was pressed at start up.\n" -msgstr "qǐ dòng shí àn xià àn niǔ A.\n" - #: shared-bindings/_bleio/UUID.c msgid "Byte buffer must be 16 bytes." msgstr "Zìjié huǎnchōng qū bìxū shì 16 zìjié." @@ -687,7 +693,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "CRC huò jiàoyàn hé wúxiào" @@ -808,10 +814,6 @@ msgstr "Wèi tígōng zìfú huǎncún xiěrù" 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 yánzhǎn guòcháng" @@ -826,6 +828,14 @@ 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 "zuòbiāo shùzǔ jùyǒu bùtóng de chángdù" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "zuòbiāo shùzǔ lèixíng jùyǒu bùtóng de dàxiǎo" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "sǔnhuài de .mpy wénjiàn" @@ -850,10 +860,6 @@ msgstr "Wúfǎ qǐdòng zhōngduàn,RX máng" msgid "Couldn't allocate decoder" msgstr "wúfǎ fēnpèi jiěmǎ qì" -#: supervisor/shared/safe_mode.c -msgid "Crash into the HardFault_Handler." -msgstr "gu4zhang4, jin4ru4 HardFault_Handler." - #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "DAC tōngdào chūshǐhuà cuòwù" @@ -920,6 +926,7 @@ 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" @@ -946,25 +953,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/espressif/bindings/espulp/ULP.c py/enum.c -#: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c -#: shared-bindings/alarm/__init__.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" - -#: ports/raspberrypi/bindings/cyw43/__init__.c -msgid "Expected a %q or %q" -msgstr "yù qī wéi %q huò %q" - #: shared-bindings/alarm/__init__.c -msgid "Expected an %q" -msgstr "yù qī wéi %q" +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 @@ -1031,8 +1030,8 @@ 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" @@ -1040,7 +1039,7 @@ msgstr "Wénjiàn cúnzài" #: shared-module/os/getenv.c msgid "File not found" -msgstr "" +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 @@ -1094,7 +1093,7 @@ msgstr "Hánshù xūyào suǒdìng" msgid "GNSS init" msgstr "GNSS chūshǐhuà" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "tōng yòng gù zhàng" @@ -1123,6 +1122,15 @@ 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ò" @@ -1140,11 +1148,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" @@ -1249,10 +1252,19 @@ msgstr "nèi bù cuò wù #%d" msgid "Internal watchdog timer expired." msgstr "Nèibù kān mén gǒu dìngshí qì chāoshí." -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "zhōng duàn cuò wù." + +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c 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 +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c msgid "Invalid %q pin" msgstr "Wúxiào de %q yǐn jiǎo" @@ -1270,12 +1282,15 @@ msgstr "wú xiào BLE cān shù" msgid "Invalid BSSID" msgstr "Wúxiào de BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "wú xiào CIRCUITPY_PYSTACK_SIZE\n" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "wú xiào de MAC dì zhǐ" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c -#: py/moduerrno.c +#: ports/espressif/common-hal/espidf/__init__.c py/moduerrno.c msgid "Invalid argument" msgstr "Wúxiào de cānshù" @@ -1286,26 +1301,26 @@ msgstr "Měi gè zhí de wèi wúxiào" #: shared-module/os/getenv.c #, c-format msgid "Invalid byte %.*s" -msgstr "" +msgstr "wú xiào zì jié %.*s" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" msgstr "wú xiào data_pins[%d]" +#: shared-module/msgpack/__init__.c +msgid "Invalid format" +msgstr "géshì wúxiào" + #: shared-module/audiocore/WaveFile.c 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ǐ" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" msgstr "dà xiǎo wú xiào" @@ -1314,13 +1329,13 @@ msgstr "dà xiǎo wú xiào" msgid "Invalid socket for TLS" msgstr "TLS de chā zuò wú xiào" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid state" msgstr "wú xiào zhuàng tài" #: shared-module/os/getenv.c msgid "Invalid unicode escape" -msgstr "" +msgstr "wú xiào de unicode zhuǎn yì" #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" @@ -1328,7 +1343,7 @@ 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 "" +msgstr "wèi zhǎo dào mì yào" #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" @@ -1346,7 +1361,7 @@ msgstr "tú céng yǐ zài zǔ zhōng" msgid "Layer must be a Group or TileGrid subclass" msgstr "tú céng bìxū shì zǔ huò píng pū wǎng gé zi lèi" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "MAC dì zhǐ wú xiào" @@ -1439,7 +1454,7 @@ msgstr "NVS cuò wù" #: shared-bindings/socketpool/SocketPool.c msgid "Name or service not known" -msgstr "" +msgstr "míng chēng huò fú wù wèi zhī" #: py/qstr.c msgid "Name too long" @@ -1547,10 +1562,6 @@ msgstr "chéng xù zhōng méi yǒu" msgid "No in or out in program" msgstr "chéng xù zhōng méi yǒu jìn chū" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "Wèi zhǐdìng mì yào" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "Méiyǒu zhǎng zhěngshù zhīchí" @@ -1590,10 +1601,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" @@ -1613,10 +1620,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" @@ -1690,7 +1693,7 @@ msgstr "zài shēn dù shuì mián zhōng zhǐ néng shè zhì yí gè %q." #: ports/espressif/common-hal/espulp/ULPAlarm.c msgid "Only one %q can be set." -msgstr "" +msgstr "zhǐ néng shè zhì yí gè %q." #: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c @@ -1716,11 +1719,11 @@ msgstr "Yīcì zhǐ néng yǒuyī zhǒng yánsè shì tòumíng de" msgid "Operation not permitted" msgstr "bù yǔnxǔ cāozuò" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" msgstr "bù zhī chí cāo zuò huò gōng néng" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" msgstr "cāo zuò yǐ fēn shí" @@ -1728,7 +1731,7 @@ msgstr "cāo zuò yǐ fēn shí" 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 +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "nèi cún bù zú" @@ -1858,7 +1861,7 @@ msgstr "chéng xù dà xiǎo wú xiào" #: ports/espressif/common-hal/espulp/ULP.c msgid "Program too long" -msgstr "" +msgstr "chéng xù tài cháng" #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." @@ -1899,6 +1902,7 @@ 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-module/displayio/Bitmap.c msgid "Read-only" @@ -1908,7 +1912,7 @@ msgstr "Zhǐ dú" msgid "Read-only filesystem" msgstr "Zhǐ dú wénjiàn xìtǒng" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" msgstr "shōu dào de xiǎng yìng wú xiào" @@ -1928,7 +1932,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" msgstr "wèi zhǎo dào qǐng qiú de zī yuán" @@ -1980,8 +1984,8 @@ msgstr "bǐ lì chǐ cùn bì xū chú yǐ 3" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nrf/common-hal/_bleio/Adapter.c -msgid "Scan already in progess. Stop with stop_scan." -msgstr "Zhèngzài jìn háng sǎomiáo. Shǐyòng stop_scan tíngzhǐ." +msgid "Scan already in progress. Stop with stop_scan." +msgstr "Sǎomiáo yǐ zài jìnxíng zhōng. Shǐyòng stop_scan tíngzhǐ." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -2039,11 +2043,7 @@ msgstr "lì tǐ shēng yòu cè bì xū zài PWM tōng dào B shàng" #: 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 "Dìngyì zhìshǎo yīgè UART yǐn jiǎo" +msgstr "bù zhī chí tíng zhǐ AP." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -2058,58 +2058,20 @@ msgid "Temperature read timed out" msgstr "Wēndù dòu qǔ chāoshí" #: supervisor/shared/safe_mode.c -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" - -#: 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:" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "The SW38 button was pressed at start up.\n" -msgstr "qǐ dòng shí àn xià le SW38 àn niǔ .\n" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -msgid "The VOLUME button was pressed at start up.\n" -msgstr "qǐ dòng shí àn xià yīn liàng àn niǔ.\n" - -#: 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ì." +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ì." #: py/obj.c msgid "The above exception was the direct cause of the following exception:" -msgstr "" - -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -msgid "The central button was pressed at start up.\n" -msgstr "qǐ dòng shí àn xià zhōng yāng àn niǔ.\n" - -#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h -msgid "The left button was pressed at start up.\n" -msgstr "qǐ dòng shí àn xià zuǒ àn niǔ.\n" +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" @@ -2127,6 +2089,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ò." @@ -2161,12 +2127,6 @@ 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 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." - #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "yàngběn zhōng de tōngdào tài duō" @@ -2211,6 +2171,10 @@ msgstr "UART qù chūshǐhuà" msgid "UART init" 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 "UART chóngxīn qǐdòng" @@ -2258,6 +2222,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ǒ" @@ -2276,10 +2249,20 @@ 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" @@ -2287,7 +2270,7 @@ msgstr "wú fǎ qǐ dòng mDNS chá xún" #: shared-bindings/memorymap/AddressRange.c msgid "Unable to write to address." -msgstr "" +msgstr "Wú fǎ xiě rù dì zhǐ." #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." @@ -2316,6 +2299,11 @@ msgstr "%s:%d: %d chù chū xiàn wèi zhī BLE cuò wù" msgid "Unknown BLE error: %d" msgstr "wèi zhī de BLE cuò wù: %d" +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "Wèizhī cuòwù dàimǎ %d" + #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" @@ -2351,11 +2339,6 @@ 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 @@ -2404,7 +2387,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/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" msgstr "bǎn běn wú xiào" @@ -2452,15 +2435,15 @@ msgstr "Wi-Fi: " #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "Wifi is in access point mode." -msgstr "" +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 "" +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 "" +msgstr "wú xiàn wǎng luò wèi qǐ yòng" #: main.c msgid "Woken up by alarm.\n" @@ -2471,16 +2454,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ù" +#: 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 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 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 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 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" @@ -2551,6 +2575,10 @@ msgstr "shù zǔ hé suǒ yǐn cháng dù bì xū xiāng děng" msgid "array has too many dimensions" 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/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" @@ -2771,9 +2799,9 @@ msgstr "wúfǎ shèzhì 512 kuài dàxiǎo" msgid "can't set attribute" msgstr "wúfǎ shèzhì shǔxìng" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" -msgstr "" +msgstr "wú fǎ shè zhì shǔ xìng '%q'" #: py/emitnative.c msgid "can't store '%q'" @@ -2985,6 +3013,10 @@ 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" +#: extmod/ulab/code/numpy/create.c +msgid "divide by zero" +msgstr "chú yǐ líng" + #: py/runtime.c msgid "division by zero" msgstr "bèi líng chú" @@ -3026,26 +3058,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/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "" -"esp32_camera.Camera requires reserved PSRAM to be configured. See the " +"espcamera.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." +"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í ':'" @@ -3083,8 +3107,8 @@ msgid "extra positional arguments given" msgstr "gěi chūle éwài de wèizhì cānshù" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "wénjiàn bìxū shì zài zì jié móshì xià dǎkāi de wénjiàn" @@ -3258,7 +3282,7 @@ msgstr "suǒyǐn chāochū fànwéi" #: shared-bindings/_pixelmap/PixelMap.c msgid "index must be tuple or int" -msgstr "" +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 @@ -3415,7 +3439,7 @@ msgstr "wúxiào de mì yào" msgid "invalid micropython decorator" msgstr "wúxiào de MicroPython zhuāngshì qì" -#: ports/espressif/common-hal/esp32_camera/Camera.c +#: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" msgstr "shèzhì wúxiào" @@ -3638,7 +3662,7 @@ msgstr "fù zhuǎnyí jìshù" #: shared-bindings/_pixelmap/PixelMap.c msgid "nested index must be int" -msgstr "" +msgstr "qiàn tào suǒ yǐn bì xū shì int" #: shared-module/sdcardio/SDCard.c msgid "no SD card" @@ -3673,7 +3697,7 @@ 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" -#: ports/espressif/common-hal/esp32_camera/Camera.c 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" @@ -3809,6 +3833,10 @@ msgstr "Jǐn zhīchí wèi shēndù = 16" 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" @@ -3870,11 +3898,7 @@ msgstr "chū zhèn liè tài xiǎo" msgid "out must be a float dense array" msgstr "chū bì xū shì yí gè fú dòng mì jí zhèn liè" -#: shared-bindings/displayio/Bitmap.c -msgid "out of range of source" -msgstr "yuán fàn wéi wài" - -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" msgstr "mù biāo fàn wéi wài" @@ -3899,14 +3923,10 @@ msgstr "cānshù bìxū shì xùliè a2 zhì a5 de dēngjì shù" msgid "parameters must be registers in sequence r0 to r3" msgstr "cānshù bìxū shì xùliè r0 zhì r3 de dēngjì qì" -#: shared-bindings/bitmaptools/__init__.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/bitmaptools/__init__.c msgid "pixel coordinates out of bounds" msgstr "xiàngsù zuòbiāo chāochū biānjiè" -#: shared-bindings/displayio/Bitmap.c -msgid "pixel value requires too many bits" -msgstr "xiàngsù zhí xūyào tài duō wèi" - #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c msgid "pixel_shader must be displayio.Palette or displayio.ColorConverter" msgstr "pixel_shader bìxū shì displayio.Palette huò displayio.ColorConverter" @@ -4157,10 +4177,6 @@ msgstr "time_t shíjiān chuō chāochū píngtái fànwéi" msgid "tobytes can be invoked for dense arrays only" msgstr "tobytes zhǐ néng duì mì jí shù zǔ diào yòng" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "tígōng jǐ dìng géshì de cānshù tài duō" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "chǐ cùn tài duō" @@ -4196,8 +4212,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ú" @@ -4328,10 +4342,6 @@ msgstr "Zhí bìxū fúhé %d zì jié" msgid "value out of range of target" msgstr "zhí fàn wéi wài de mù biāo" -#: shared-bindings/displayio/Bitmap.c -msgid "value_count must be > 0" -msgstr "zhí jìshù bìxū wèi > 0" - #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "wèi chū shǐ huà jiān shì qì" @@ -4419,6 +4429,171 @@ 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 "out of range of source" +#~ msgstr "yuán fàn wéi wài" + +#~ msgid "pixel value requires too many bits" +#~ msgstr "xiàngsù zhí xūyào tài duō wèi" + +#~ msgid "value_count must be > 0" +#~ msgstr "zhí jìshù bìxū wèi > 0" + +#~ msgid "64 bit types" +#~ msgstr "64 wèi lèixíng" + +#~ msgid "No key was specified" +#~ msgstr "Wèi zhǐdìng mì yào" + +#~ msgid "Scan already in progess. Stop with stop_scan." +#~ msgstr "Zhèngzài jìn háng sǎomiáo. Shǐyòng stop_scan tíngzhǐ." + +#, c-format +#~ msgid "Unkown error code %d" +#~ msgstr "wèi zhī cuò wù dài %d" + +#~ msgid "too many arguments provided with the given format" +#~ msgstr "tígōng jǐ dìng géshì de cānshù tài duō" + +#~ msgid "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "wú xiào CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\n" + +#~ 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" @@ -4459,9 +4634,6 @@ msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" #~ msgid "complex division by zero" #~ msgstr "fùzá de fēngé wèi 0" -#~ msgid "divide by zero" -#~ msgstr "chú yǐ líng" - #~ msgid "int() arg 2 must be >= 2 and <= 36" #~ msgstr "zhěngshù() cānshù 2 bìxū > = 2 qiě <= 36" diff --git a/main.c b/main.c index d70e718b6da7..6ff6202d6dc0 100644 --- a/main.c +++ b/main.c @@ -122,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) { @@ -132,7 +132,24 @@ static void reset_devices(void) { #endif } -STATIC void start_mp(supervisor_allocation *heap) { +#if MICROPY_ENABLE_PYSTACK +STATIC supervisor_allocation *allocate_pystack(safe_mode_t safe_mode) { + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SETTABLE_PYSTACK + if (safe_mode == SAFE_MODE_NONE) { + mp_int_t pystack_size = CIRCUITPY_PYSTACK_SIZE; + (void)common_hal_os_getenv_int("CIRCUITPY_PYSTACK_SIZE", &pystack_size); + supervisor_allocation *pystack = allocate_memory(pystack_size >= 384 ? pystack_size : 0, false, false); + if (pystack) { + return pystack; + } + serial_write_compressed(translate("Invalid CIRCUITPY_PYSTACK_SIZE\n")); + } + #endif + return allocate_memory(CIRCUITPY_PYSTACK_SIZE, false, false); +} +#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 @@ -160,7 +177,7 @@ STATIC void start_mp(supervisor_allocation *heap) { 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 @@ -264,7 +281,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" @@ -345,6 +362,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. @@ -358,7 +378,7 @@ 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")); } } @@ -384,11 +404,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) { // 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()) { + if (safe_mode == SAFE_MODE_NONE && !autoreload_pending()) { static const char *const supported_filenames[] = { "code.txt", "code.py", "main.py", "main.txt" }; @@ -399,10 +419,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) { }; #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. - start_mp(heap); + start_mp(heap, pystack); #if CIRCUITPY_USB usb_setup_with_vm(); @@ -450,7 +472,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) { // Finished executing python code. Cleanup includes filesystem flush and a board reset. - cleanup_after_vm(heap, _exec_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 @@ -510,7 +532,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) { } else #endif if (_exec_result.return_code != PYEXEC_EXCEPTION) { - if (safe_mode == NO_SAFE_MODE) { + if (safe_mode == SAFE_MODE_NONE) { color = ALL_DONE; blink_count = ALL_DONE_BLINKS; } else { @@ -730,8 +752,38 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) { 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; } @@ -739,16 +791,19 @@ 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[] = {"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(); - - start_mp(heap); + start_mp(heap, pystack); #if CIRCUITPY_USB // Set up default USB values after boot.py VM starts but before running boot.py. @@ -834,7 +889,7 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { port_post_boot_py(true); - cleanup_after_vm(heap, _exec_result.exception); + cleanup_after_vm(heap, pystack, _exec_result.exception); _exec_result.exception = NULL; port_post_boot_py(false); @@ -845,12 +900,16 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { #endif } -STATIC int run_repl(void) { +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); + start_mp(heap, pystack); #if CIRCUITPY_USB usb_setup_with_vm(); @@ -893,7 +952,7 @@ STATIC int run_repl(void) { 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. @@ -912,8 +971,9 @@ STATIC int run_repl(void) { } 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(); @@ -925,9 +985,12 @@ 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(); @@ -941,9 +1004,6 @@ int __attribute__((used)) main(void) { 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 @@ -956,8 +1016,8 @@ 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); } #if CIRCUITPY_ALARM @@ -982,16 +1042,23 @@ int __attribute__((used)) main(void) { 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(); @@ -1005,18 +1072,19 @@ int __attribute__((used)) main(void) { bool simulate_reset = true; for (;;) { if (!skip_repl) { - exit_code = run_repl(); + exit_code = run_repl(get_safe_mode()); supervisor_set_run_reason(RUN_REASON_REPL_RELOAD); } if (exit_code == PYEXEC_FORCED_EXIT) { if (!simulate_reset) { serial_write_compressed(translate("soft reboot\n")); } + simulate_reset = false; if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { // 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(safe_mode, &simulate_reset); + skip_repl = run_code_py(get_safe_mode(), &simulate_reset); } else { skip_repl = false; } @@ -1043,6 +1111,8 @@ void gc_collect(void) { // have lost their references in the VM even though they are mounted. gc_collect_root((void **)&MP_STATE_VM(vfs_mount_table), sizeof(mp_vfs_mount_t) / sizeof(mp_uint_t)); + port_gc_collect(); + background_callback_gc_collect(); #if CIRCUITPY_ALARM @@ -1075,15 +1145,19 @@ void gc_collect(void) { gc_collect_end(); } +// Ports may provide an implementation of this function if it is needed +MP_WEAK void port_gc_collect() { +} + 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/main.c b/mpy-cross/main.c index c00829be1041..077e84f4733a 100644 --- a/mpy-cross/main.c +++ b/mpy-cross/main.c @@ -310,7 +310,7 @@ int main(int argc, char **argv) { return main_(argc, argv); } -uint mp_import_stat(const char *path) { +mp_import_stat_t mp_import_stat(const char *path) { (void)path; return MP_IMPORT_STAT_NO_EXIST; } diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 68beeaf12994..ca906ab98f86 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -59,6 +59,7 @@ INC += -I. \ ifeq ($(CHIP_FAMILY), samd21) PERIPHERALS_CHIP_FAMILY=samd21 OPTIMIZATION_FLAGS ?= -Os + # TinyUSB defines CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=128 -DCFG_TUD_MSC_BUFSIZE=512 endif @@ -101,24 +102,23 @@ ifeq ($(DEBUG), 1) endif else CFLAGS += -DNDEBUG + + # Do a default shrink for small builds, including all SAMD21 builds. # -finline-limit can shrink the image size. # -finline-limit=80 or so is similar to not having it on. # There is no simple default value, though. - - # Do a default shrink for small builds. - ifndef CFLAGS_INLINE_LIMIT - ifeq ($(CIRCUITPY_FULL_BUILD),0) - CFLAGS_INLINE_LIMIT = 50 + ifeq ($(CIRCUITPY_FULL_BUILD),0) + CFLAGS += -finline-limit=45 + else + ifeq ($(CHIP_FAMILY), samd21) + # max-inline-insns-auto increases the size of SAMD51 builds. + CFLAGS += -finline-limit=45 --param max-inline-insns-auto=110 endif endif - ifdef CFLAGS_INLINE_LIMIT - CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT) - endif - - ifeq ($(CIRCUITPY_FULL_BUILD),0) - CFLAGS += --param inline-unit-growth=15 --param max-inline-insns-auto=20 - endif + # We used to do this but it seems to not reduce space any more, at least in gcc 11. + # Leave it here, commented out, just for reference. + # --param inline-unit-growth=15 ifdef CFLAGS_BOARD CFLAGS += $(CFLAGS_BOARD) @@ -366,8 +366,8 @@ all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 $(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)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group + $(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/asf4_conf/samd21/hpl_tc_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_tc_config.h index d651ca33a830..706c7f4b6754 100644 --- a/ports/atmel-samd/asf4_conf/samd21/hpl_tc_config.h +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_tc_config.h @@ -49,7 +49,7 @@ #define CONF_TC3_WAVE_DUTY_VAL 0x1f4 #endif -/* Caculate pwm ccx register value based on WAVE_PER_VAL and Waveform Duty Value */ +/* Calculate pwm ccx register value based on WAVE_PER_VAL and Waveform Duty Value */ #if CONF_TC3_PRESCALER < TC_CTRLA_PRESCALER_DIV64_Val #define CONF_TC3_CC0 \ ((uint32_t)(((double)CONF_TC3_WAVE_PER_VAL * CONF_GCLK_TC3_FREQUENCY) / 1000000 / (1 << CONF_TC3_PRESCALER) - 1)) diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_tc_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_tc_config.h index 3bc688295bdf..dc08b6eb23f3 100644 --- a/ports/atmel-samd/asf4_conf/samd51/hpl_tc_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_tc_config.h @@ -42,7 +42,7 @@ #define CONF_TC0_WAVE_DUTY_VAL 0x1f4 #endif -/* Caculate pwm ccx register value based on WAVE_PER_VAL and Waveform Duty Value */ +/* Calculate pwm ccx register value based on WAVE_PER_VAL and Waveform Duty Value */ #if CONF_TC0_PRESCALER < TC_CTRLA_PRESCALER_DIV64_Val #define CONF_TC0_CC0 \ ((uint32_t)(((double)CONF_TC0_WAVE_PER_VAL * CONF_GCLK_TC0_FREQUENCY) / 1000000 / (1 << CONF_TC0_PRESCALER) - 1)) diff --git a/ports/atmel-samd/asf4_conf/same51/hpl_tc_config.h b/ports/atmel-samd/asf4_conf/same51/hpl_tc_config.h index 3bc688295bdf..dc08b6eb23f3 100644 --- a/ports/atmel-samd/asf4_conf/same51/hpl_tc_config.h +++ b/ports/atmel-samd/asf4_conf/same51/hpl_tc_config.h @@ -42,7 +42,7 @@ #define CONF_TC0_WAVE_DUTY_VAL 0x1f4 #endif -/* Caculate pwm ccx register value based on WAVE_PER_VAL and Waveform Duty Value */ +/* Calculate pwm ccx register value based on WAVE_PER_VAL and Waveform Duty Value */ #if CONF_TC0_PRESCALER < TC_CTRLA_PRESCALER_DIV64_Val #define CONF_TC0_CC0 \ ((uint32_t)(((double)CONF_TC0_WAVE_PER_VAL * CONF_GCLK_TC0_FREQUENCY) / 1000000 / (1 << CONF_TC0_PRESCALER) - 1)) diff --git a/ports/atmel-samd/asf4_conf/same54/hpl_tc_config.h b/ports/atmel-samd/asf4_conf/same54/hpl_tc_config.h index 3bc688295bdf..dc08b6eb23f3 100644 --- a/ports/atmel-samd/asf4_conf/same54/hpl_tc_config.h +++ b/ports/atmel-samd/asf4_conf/same54/hpl_tc_config.h @@ -42,7 +42,7 @@ #define CONF_TC0_WAVE_DUTY_VAL 0x1f4 #endif -/* Caculate pwm ccx register value based on WAVE_PER_VAL and Waveform Duty Value */ +/* Calculate pwm ccx register value based on WAVE_PER_VAL and Waveform Duty Value */ #if CONF_TC0_PRESCALER < TC_CTRLA_PRESCALER_DIV64_Val #define CONF_TC0_CC0 \ ((uint32_t)(((double)CONF_TC0_WAVE_PER_VAL * CONF_GCLK_TC0_FREQUENCY) / 1000000 / (1 << CONF_TC0_PRESCALER) - 1)) diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 9dcedf3f9b29..2f8357d07b1c 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -42,20 +42,23 @@ // PB03 is physical pin "SCL" on the Metro M4 express // so you can't use this code AND an i2c peripheral // at the same time unless you change this -void port_start_background_task(void) { +void port_start_background_tick(void) { REG_PORT_DIRSET1 = (1 << 3); REG_PORT_OUTSET1 = (1 << 3); } -void port_finish_background_task(void) { +void port_finish_background_tick(void) { REG_PORT_OUTCLR1 = (1 << 3); } #else -void port_start_background_task(void) { +void port_start_background_tick(void) { } -void port_finish_background_task(void) { +void port_finish_background_tick(void) { } #endif +void port_background_tick(void) { +} + void port_background_task(void) { } diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h index 33910221a042..d7ca2a107c2b 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("Both buttons were pressed 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.h b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h index 7f0e041f25ca..6ee5e0504ba8 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("Both buttons were pressed 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.h b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h index 12fd30e0052c..c0f2d07e9df9 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("Both buttons were pressed 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/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index 701dc4a8ece1..aeea62d2a2df 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -51,7 +51,7 @@ uint8_t display_init_sequence[] = { 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V 0x2a, 0, // _INVOFF 0x36, 1, 0x18, // _MADCTL bottom to top refresh - // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 cycle osc equalie, // fix on VTL 0x3a, 1, 0x05, // COLMOD - 16bit color 0xe0, 16, 0x02, 0x1c, 0x07, 0x12, // _GMCTRP1 Gamma diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk index 6017b551f1fe..1c032f02c09c 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/kicksat-sprite/mpconfigboard.mk b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk index 9bc50ab4293c..9ca925974772 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/meowmeow/mpconfigboard.h b/ports/atmel-samd/boards/meowmeow/mpconfigboard.h index ad6901230f88..ab5f652d1e78 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("Both buttons were pressed 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/openbook_m4/board.c b/ports/atmel-samd/boards/openbook_m4/board.c index 30537dd3f459..ec1ba9f95611 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,13 +97,15 @@ 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 } diff --git a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk index 32be4805d741..49be084ddfd7 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 @@ -31,18 +32,20 @@ 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 CIRCUITPY_KEYPAD = 1 +CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS = 0 +CIRCUITPY_KEYPAD_KEYMATRIX = 0 CIRCUITPY_MATH = 1 CIRCUITPY_STAGE = 1 CIRCUITPY_SYNTHIO = 1 @@ -53,3 +56,13 @@ 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/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index a1cb3a07147b..11db1ba0a8bf 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -50,7 +50,7 @@ uint8_t display_init_sequence[] = { 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V 0x2a, 0, // _INVOFF 0x36, 1, 0b10100000, // _MADCTL for rotation 0 - // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 cycle osc equalie, // fix on VTL 0x3a, 1, 0x05, // COLMOD - 16bit color 0xe0, 16, 0x02, 0x1c, 0x07, 0x12, // _GMCTRP1 Gamma diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c index 8ff34f24c56c..141365a4a1aa 100644 --- a/ports/atmel-samd/boards/pygamer/board.c +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -52,7 +52,7 @@ uint8_t display_init_sequence[] = { 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V 0x2a, 0, // _INVOFF 0x36, 1, 0b10100000, // _MADCTL for rotation 0 - // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 cycle osc equalie, // fix on VTL 0x3a, 1, 0x05, // COLMOD - 16bit color 0xe0, 16, 0x02, 0x1c, 0x07, 0x12, // _GMCTRP1 Gamma diff --git a/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c b/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c index 5a35a60e82b8..e39272b41e15 100644 --- a/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c +++ b/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c @@ -77,8 +77,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { // MicroMod UART1 pins { MP_ROM_QSTR(MP_QSTR_UART_TX1), MP_ROM_PTR(&pin_PB31) }, // MicroMod UART_TX1 | CircuitPython TX (PB31) { MP_ROM_QSTR(MP_QSTR_UART_RX1), MP_ROM_PTR(&pin_PB30) }, // MicroMod UART_RX1 | CircuitPython RX (PB30) - // { MP_ROM_QSTR(MP_QSTR_UART_RTS1), MP_ROM_PTR() }, // MicroMod RTS1 (not connected) - // { MP_ROM_QSTR(MP_QSTR_UART_CTS1), MP_ROM_PTR() }, // MicroMod CTS1 (not connected) + { MP_ROM_QSTR(MP_QSTR_UART_RTS1), MP_ROM_PTR(&pin_PB00) }, // MicroMod RTS1 + { MP_ROM_QSTR(MP_QSTR_UART_CTS1), MP_ROM_PTR(&pin_PB01) }, // MicroMod CTS1 // CircuitPython default UART pins { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB31) }, // CircuitPython TX | MicroMod UART_TX1 (PB31) diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index 90cf9dff208e..9953f27d02c1 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -52,7 +52,7 @@ uint8_t display_init_sequence[] = { 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V 0x2a, 0, // _INVOFF 0x36, 1, 0xa8, // _MADCTL bottom to top refresh - // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 cycle osc equalie, // fix on VTL 0x3a, 1, 0x05, // COLMOD - 16bit color 0xe0, 16, 0x02, 0x1c, 0x07, 0x12, // _GMCTRP1 Gamma diff --git a/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c b/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c index 2ead87428b7e..4c1d05feb28e 100644 --- a/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c +++ b/ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c @@ -36,7 +36,7 @@ STATIC volatile bool woke_up = false; STATIC mp_float_t wakeup_time; void common_hal_alarm_time_timealarm_construct(alarm_time_timealarm_obj_t *self, mp_float_t monotonic_time) { - // TODO: when issueing light/seep sleep, throw a ValueError if the + // TODO: when issuing light/seep sleep, throw a ValueError if the // time exceeds the maximum value. For light sleep, max = // 2**32 / 16384 = 3 days. For deep sleep, max = 2**32 / 32 // = 1550 days. diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 3bb0cabf9efb..02776928ca19 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 6027b6a5fa17..280e8d10b685 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -58,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, @@ -92,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); } @@ -107,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) { @@ -115,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) || @@ -160,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; @@ -204,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. diff --git a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c index 22200c5d1cec..df26379170e9 100644 --- a/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +++ b/ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c @@ -156,7 +156,7 @@ void frequencyin_interrupt_handler(uint8_t index) { } // Check if we've reached the upper limit of detection - if (!supervisor_background_tasks_ok() || self->errored_too_fast) { + if (!supervisor_background_ticks_ok() || self->errored_too_fast) { self->errored_too_fast = true; frequencyin_emergency_cancel_capture(i); } @@ -482,7 +482,7 @@ uint32_t common_hal_frequencyio_frequencyin_get_item(frequencyio_frequencyin_obj float time_each_event = self->factor / self->frequency; // get the time for each event during actual period float capture_diff = self->factor - self->capture_period; // get the difference of actual and base periods // we only need to adjust if the capture_diff can contain 1 or more events - // if so, we add how many events could have occured during the diff time + // if so, we add how many events could have occurred during the diff time if (time_each_event > capture_diff) { frequency_adjustment = capture_diff / time_each_event; } diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index b36286e5f268..d70de336186e 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/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index 60b35a2c5c69..d1c02b360f8a 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 c6e9e07304e9..1bb955fce82f 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/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 9d4ddd71348c..73686e1445fc 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -60,7 +60,9 @@ X(EISDIR) \ X(EINVAL) \ -#define MICROPY_FATFS_EXFAT 0 +#define MICROPY_FATFS_EXFAT (0) +// FAT32 mkfs takes about 500 bytes. +#define MICROPY_FF_MKFS_FAT32 (0) // Only support simpler HID descriptors on SAMD21. #define CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR (1) @@ -187,7 +189,7 @@ // - firmware // - internal CIRCUITPY flash filesystem (optional) // - internal config, used to store crystalless clock calibration info (optional) -// - microntroller.nvm (optional) +// - microcontroller.nvm (optional) // Define these regions starting up from the bottom of flash: diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index 57f7ca339f28..032e49ce3696 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -57,6 +57,7 @@ CIRCUITPY_ZLIB = 0 ifeq ($(INTERNAL_FLASH_FILESYSTEM),1) CIRCUITPY_ONEWIREIO ?= 0 +CIRCUITPY_SAFEMODE_PY ?= 0 CIRCUITPY_USB_IDENTIFICATION ?= 0 endif @@ -77,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 ###################################################################### @@ -101,11 +100,12 @@ endif CIRCUITPY_ALARM ?= 1 -CIRCUITPY_PS2IO ?= 1 -CIRCUITPY_SAMD ?= 1 CIRCUITPY_FLOPPYIO ?= $(CIRCUITPY_FULL_BUILD) CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD) +CIRCUITPY_PS2IO ?= 1 CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FRAMEBUFFERIO) +CIRCUITPY_SAMD ?= 1 +CIRCUITPY_SYNTHIO_MAX_CHANNELS = 12 CIRCUITPY_WATCHDOG ?= 1 endif # samd51 diff --git a/ports/atmel-samd/sd_mmc/sd_mmc.c b/ports/atmel-samd/sd_mmc/sd_mmc.c index de5a3cfe1711..b558922d1f14 100644 --- a/ports/atmel-samd/sd_mmc/sd_mmc.c +++ b/ports/atmel-samd/sd_mmc/sd_mmc.c @@ -1073,7 +1073,7 @@ static void sd_mmc_deselect_slot(void) { * \note * This function runs the initialization procedure and the identification * process, then it sets the SD/MMC card in transfer state. - * At last, it will automaticly enable maximum bus width and transfer speed. + * At last, it will automatically enable maximum bus width and transfer speed. * * \return true if success, otherwise false */ @@ -1205,7 +1205,7 @@ static bool sd_mmc_mci_card_init(void) { * \note * This function runs the initialization procedure and the identification * process, then it sets the SD/MMC card in transfer state. - * At last, it will automaticly enable maximum bus width and transfer speed. + * At last, it will automatically enable maximum bus width and transfer speed. * * \return true if success, otherwise false */ @@ -1270,7 +1270,7 @@ static bool sd_mmc_mci_install_mmc(void) { uint8_t retry = 10; while (retry--) { /* Retry is a WORKAROUND for no compliance card (Atmel Internal ref. MMC19): - * These cards seem not ready immediatly + * These cards seem not ready immediately * after the end of busy of mmc_cmd6_set_high_speed()*/ /* Set default block size */ @@ -1427,7 +1427,7 @@ sd_mmc_err_t sd_mmc_wait_end_of_read_blocks(bool abort) { return SD_MMC_OK; } - /* All blocks are transfered then stop read operation */ + /* All blocks are transferred then stop read operation */ if (sd_mmc_nb_block_to_tranfer == 1) { /* Single block transfer, then nothing to do */ sd_mmc_deselect_slot(); @@ -1506,7 +1506,7 @@ sd_mmc_err_t sd_mmc_wait_end_of_write_blocks(bool abort) { return SD_MMC_OK; } - /* All blocks are transfered then stop write operation */ + /* All blocks are transferred then stop write operation */ if (sd_mmc_nb_block_to_tranfer == 1) { /* Single block transfer, then nothing to do */ sd_mmc_deselect_slot(); diff --git a/ports/atmel-samd/sd_mmc/sd_mmc.h b/ports/atmel-samd/sd_mmc/sd_mmc.h index e51bf17e802d..667520317cd8 100644 --- a/ports/atmel-samd/sd_mmc/sd_mmc.h +++ b/ports/atmel-samd/sd_mmc/sd_mmc.h @@ -67,7 +67,7 @@ typedef uint8_t sd_mmc_err_t; /**< Type of return error code */ #define SD_MMC_INIT_ONGOING 1 /**< Card not initialized */ #define SD_MMC_ERR_NO_CARD 2 /**< No SD/MMC card inserted */ #define SD_MMC_ERR_UNUSABLE 3 /**< Unusable card */ -#define SD_MMC_ERR_SLOT 4 /**< Slot unknow */ +#define SD_MMC_ERR_SLOT 4 /**< Slot unknown */ #define SD_MMC_ERR_COMM 5 /**< General communication error */ #define SD_MMC_ERR_PARAM 6 /**< Illeage input parameter */ #define SD_MMC_ERR_WP 7 /**< Card write protected */ @@ -166,7 +166,7 @@ uint32_t sd_mmc_get_capacity(uint8_t slot); * * \param[in] slot Card slot * - * \return true, if write portected + * \return true, if write protected */ bool sd_mmc_is_write_protected(uint8_t slot); diff --git a/ports/atmel-samd/sd_mmc/sd_mmc_protocol.h b/ports/atmel-samd/sd_mmc/sd_mmc_protocol.h index 9b4d8e8e7469..c205415559bc 100644 --- a/ports/atmel-samd/sd_mmc/sd_mmc_protocol.h +++ b/ports/atmel-samd/sd_mmc/sd_mmc_protocol.h @@ -73,8 +73,8 @@ extern "C" { * Responses types: * * R1, R3, R4 & R5 use a 48 bits response protected by a 7bit CRC checksum - * - R1 receiv data not specified - * - R3 receiv OCR + * - R1 receive data not specified + * - R3 receive OCR * - R4, R5 RCA management (MMC only) * - R6, R7 RCA management (SD only) * @@ -115,14 +115,14 @@ typedef uint32_t sdmmc_cmd_def_t; #define SDMMC_RESP_CRC (1lu << 12) // ! Card may send busy #define SDMMC_RESP_BUSY (1lu << 13) -// Open drain for a braodcast command (bc) +// Open drain for a broadcast command (bc) // or to enter in inactive state (MCI only) #define SDMMC_CMD_OPENDRAIN (1lu << 14) // ! To signal a data write operation #define SDMMC_CMD_WRITE (1lu << 15) -// ! To signal a SDIO tranfer in multi byte mode +// ! To signal a SDIO transfer in multi byte mode #define SDMMC_CMD_SDIO_BYTE (1lu << 16) -// ! To signal a SDIO tranfer in block mode +// ! To signal a SDIO transfer in block mode #define SDMMC_CMD_SDIO_BLOCK (1lu << 17) // ! To signal a data transfer in stream mode #define SDMMC_CMD_STREAM (1lu << 18) @@ -132,7 +132,7 @@ typedef uint32_t sdmmc_cmd_def_t; #define SDMMC_CMD_MULTI_BLOCK (1lu << 20) // ! @} -// ! \name Set of flags to define a reponse type +// ! \name Set of flags to define a response type // ! @{ #define SDMMC_CMD_NO_RESP (0) #define SDMMC_CMD_R1 (SDMMC_RESP_PRESENT | SDMMC_RESP_CRC) @@ -324,7 +324,7 @@ typedef uint32_t sdmmc_cmd_def_t; #define SD_MCI_ACMD41_SD_SEND_OP_COND (41 | SDMMC_CMD_R3 | SDMMC_CMD_OPENDRAIN) /** * ACMD41(R1): Send host capacity support information (HCS) and activates the - * card's initilization process + * card's initialization process */ #define SD_SPI_ACMD41_SD_SEND_OP_COND (41 | SDMMC_CMD_R1) /** @@ -440,7 +440,7 @@ typedef uint32_t sdmmc_cmd_def_t; #define SDIO_R5_ERROR (1lu << 11) /**< General error */ #define SDIO_R5_FUNC_NUM (1lu << 9) /**< Invalid function number */ #define SDIO_R5_OUT_OF_RANGE (1lu << 8) /**< Argument out of range */ -#define SDIO_R5_STATUS_ERR (SDIO_R5_ERROR | SDIO_R5_FUNC_NUM | SDIO_R5_OUT_OF_RANGE) // !< Errro status bits mask +#define SDIO_R5_STATUS_ERR (SDIO_R5_ERROR | SDIO_R5_FUNC_NUM | SDIO_R5_OUT_OF_RANGE) // !< Error status bits mask // ! @} // ! \name SDIO state (in R6) diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 2c63e28a1751..8cba5c61e06e 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -307,7 +307,7 @@ safe_mode_t port_init(void) { // because it was hard enough to figure out, and maybe there's // a mistake that could make it work in the future. #if 0 - // Designate QSPI memory mapped region as not cachable. + // Designate QSPI memory mapped region as not cacheable. // Turn off MPU in case it is on. MPU->CTRL = 0; @@ -320,7 +320,7 @@ safe_mode_t port_init(void) { 0b011 << MPU_RASR_AP_Pos | // full read/write access for privileged and user mode 0b000 << MPU_RASR_TEX_Pos | // caching not allowed, strongly ordered 1 << MPU_RASR_S_Pos | // sharable - 0 << MPU_RASR_C_Pos | // not cachable + 0 << MPU_RASR_C_Pos | // not cacheable 0 << MPU_RASR_B_Pos | // not bufferable 0b10111 << MPU_RASR_SIZE_Pos | // 16MB region size 1 << MPU_RASR_ENABLE_Pos // enable this region @@ -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) { @@ -720,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/background.c b/ports/broadcom/background.c index 4b5190aa2740..9074a80400a4 100644 --- a/ports/broadcom/background.c +++ b/ports/broadcom/background.c @@ -28,9 +28,12 @@ #include "py/runtime.h" #include "supervisor/port.h" -void port_start_background_task(void) { +void port_start_background_tick(void) { } -void port_finish_background_task(void) { +void port_finish_background_tick(void) { +} + +void port_background_tick(void) { } void port_background_task(void) { diff --git a/ports/broadcom/common-hal/busio/I2C.c b/ports/broadcom/common-hal/busio/I2C.c index 3142fda145d8..64187f434bd3 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 017674dfc002..5780ebe801ab 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 9f51f15acb72..5be098cf035a 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) { @@ -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; } @@ -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/microcontroller/__init__.c b/ports/broadcom/common-hal/microcontroller/__init__.c index a1491d9668b6..53f04ebec3d7 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 0cd76ebca993..245244614f4c 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/broadcom/common-hal/rtc/RTC.c b/ports/broadcom/common-hal/rtc/RTC.c new file mode 100644 index 000000000000..8f6743cb0528 --- /dev/null +++ b/ports/broadcom/common-hal/rtc/RTC.c @@ -0,0 +1,58 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * 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 + * 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/timeutils/timeutils.h" +#include "supervisor/port.h" + +// 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 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 000000000000..09ae4ea86f30 --- /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 000000000000..e69de29bb2d1 diff --git a/ports/broadcom/common-hal/sdioio/SDCard.c b/ports/broadcom/common-hal/sdioio/SDCard.c index 27b36041de3b..cf8bfb1faa61 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.mk b/ports/broadcom/mpconfigport.mk index 839ef0051427..b992d24f0e37 100644 --- a/ports/broadcom/mpconfigport.mk +++ b/ports/broadcom/mpconfigport.mk @@ -15,7 +15,6 @@ CIRCUITPY_PARALLELDISPLAY = 0 CIRCUITPY_PULSEIO = 0 CIRCUITPY_PWMIO = 0 CIRCUITPY_ROTARYIO = 0 -CIRCUITPY_RTC = 0 CIRCUITPY_SDIOIO = 1 CIRCUITPY_VIDEOCORE = 1 diff --git a/ports/broadcom/peripherals b/ports/broadcom/peripherals index 083700860807..d3a6b50a21e7 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 e036a76cef30..ec6feb870376 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/README.md b/ports/cxd56/README.md index 0656ad1f1abe..4266c61c0c8f 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 644a5d7b0bef..8425f8cfa201 100644 --- a/ports/cxd56/background.c +++ b/ports/cxd56/background.c @@ -30,9 +30,11 @@ #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) { +void port_start_background_tick(void) { } -void port_finish_background_task(void) { +void port_finish_background_tick(void) { } diff --git a/ports/cxd56/common-hal/camera/Camera.c b/ports/cxd56/common-hal/camera/Camera.c index f304ed8f74dd..606ad0f1e647 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/microcontroller/__init__.c b/ports/cxd56/common-hal/microcontroller/__init__.c index dd9a54063fdc..c77a8829f283 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 7e27817aab5a..10689dc55af4 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 6a7c39cba8b4..92e282649b9b 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/spresense-exported-sdk b/ports/cxd56/spresense-exported-sdk index 6a148be84977..4f902ca3ffeb 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 10fa4112e885..36d46dbad8f6 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/CMakeLists.txt b/ports/espressif/CMakeLists.txt index ea4de9f3436f..ce2935a502c6 100644 --- a/ports/espressif/CMakeLists.txt +++ b/ports/espressif/CMakeLists.txt @@ -8,7 +8,7 @@ set(ENV{IDF_PATH} ${CMAKE_SOURCE_DIR}/esp-idf) # can build. 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_ESP32_CAMERA}") +if("${CIRCUITPY_ESPCAMERA}") message("Including esp32-camera") set(EXTRA_COMPONENT_DIRS "esp32-camera") list(APPEND COMPONENTS "esp32-camera") diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index ddfcaeeb6e7f..2151c8e03cd6 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -126,9 +126,13 @@ ifeq ($(DEBUG), 1) # CFLAGS += -fno-inline -fno-ipa-sra else CFLAGS += -DNDEBUG -ggdb3 - OPTIMIZATION_FLAGS ?= -O2 # RISC-V is larger than xtensa # Use -Os for RISC-V when it overflows + ifeq ($(IDF_TARGET_ARCH),riscv) + OPTIMIZATION_FLAGS ?= -Os + else + OPTIMIZATION_FLAGS ?= -O2 + endif endif # option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk @@ -214,7 +218,6 @@ endif SRC_C += \ background.c \ mphalport.c \ - bindings/espidf/__init__.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ shared/netutils/netutils.c \ @@ -248,17 +251,29 @@ ifneq ($(CIRCUITPY_BLEIO),0) SRC_C += common-hal/_bleio/ble_events.c endif -SRC_C += $(wildcard common-hal/espidf/*.c) - -ifneq ($(CIRCUITPY_ESP32_CAMERA),0) +ifneq ($(CIRCUITPY_ESPCAMERA),0) SRC_CAMERA := \ - $(wildcard common-hal/esp32_camera/*.c) \ - $(wildcard bindings/esp32_camera/*.c) + $(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_ESPIDF),0) +SRC_ESPIDF := \ + $(wildcard common-hal/espidf/*.c) \ + $(wildcard bindings/espidf/*.c) +SRC_C += $(SRC_ESPIDF) +endif + +ifneq ($(CIRCUITPY_ESPNOW),0) +SRC_ESPNOW := \ + $(wildcard common-hal/espnow/*.c) \ + $(wildcard bindings/espnow/*.c) +SRC_C += $(SRC_ESPNOW) +endif + ifneq ($(CIRCUITPY_ESPULP),0) SRC_ULP := \ $(wildcard common-hal/espulp/*.c) \ @@ -333,7 +348,7 @@ endif .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_ESP32_CAMERA=$(CIRCUITPY_ESP32_CAMERA) + 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 @@ -385,7 +400,7 @@ 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_ESP32_CAMERA),0) +ifneq ($(CIRCUITPY_ESPCAMERA),0) ESP_IDF_COMPONENTS_EXPANDED += $(BUILD)/esp-idf/esp-idf/esp32-camera/libesp32-camera.a #$(error $(ESP_IDF_COMPONENTS_EXPANDED)) endif @@ -434,7 +449,7 @@ $(BUILD)/firmware.elf: $(OBJ) | esp-idf-stamp $(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/README.rst b/ports/espressif/README.rst index 949f3533ae3e..49f372359b6b 100644 --- a/ports/espressif/README.rst +++ b/ports/espressif/README.rst @@ -55,7 +55,7 @@ Connect these pins using a `USB adapter ` **UART Connection:** -A `USB to UART convertor `_ can be used for connecting to ESP32-C3 to get access to the serial console and REPL and for flashing CircuitPython. +A `USB to UART converter `_ can be used for connecting to ESP32-C3 to get access to the serial console and REPL and for flashing CircuitPython. The following connections need to be made in this case: @@ -92,7 +92,7 @@ Connect these pins using a `USB adapter ` **UART Connection:** -A `USB to UART convertor `_ can be used for connecting to ESP32-S2 to get access to the serial console and REPL and for flashing CircuitPython. +A `USB to UART converter `_ can be used for connecting to ESP32-S2 to get access to the serial console and REPL and for flashing CircuitPython. The following connections need to be made in this case: @@ -129,7 +129,7 @@ Connect these pins using a `USB adapter ` **UART Connection:** -A `USB to UART convertor `_ can be used for connecting to ESP32-S3 to get access to the serial console and REPL and for flashing CircuitPython. +A `USB to UART converter `_ can be used for connecting to ESP32-S3 to get access to the serial console and REPL and for flashing CircuitPython. The following connections need to be made in this case: diff --git a/ports/espressif/background.c b/ports/espressif/background.c index 0b5bb96a3b71..f9069e98a488 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,8 +48,11 @@ void port_background_task(void) { #endif } -void port_start_background_task(void) { +void port_background_task(void) { +} + +void port_start_background_tick(void) { } -void port_finish_background_task(void) { +void port_finish_background_tick(void) { } diff --git a/ports/espressif/bindings/esp32_camera/Camera.c b/ports/espressif/bindings/esp32_camera/Camera.c deleted file mode 100644 index 687a389fc3ab..000000000000 --- a/ports/espressif/bindings/esp32_camera/Camera.c +++ /dev/null @@ -1,994 +0,0 @@ -/* - * 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/esp32_camera/__init__.h" -#include "bindings/esp32_camera/Camera.h" -#include "common-hal/esp32_camera/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 esp32_camera_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); - const mcu_pin_obj_t *vsync_pin = validate_obj_is_free_pin(args[ARG_vsync_pin].u_obj); - const mcu_pin_obj_t *href_pin = validate_obj_is_free_pin(args[ARG_href_pin].u_obj); - 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); - const mcu_pin_obj_t *powerdown_pin = validate_obj_is_free_pin_or_none(args[ARG_powerdown_pin].u_obj); - const mcu_pin_obj_t *reset_pin = validate_obj_is_free_pin_or_none(args[ARG_reset_pin].u_obj); - const mp_int_t external_clock_frequency = mp_arg_validate_int_range(args[ARG_external_clock_frequency].u_int, 0, 40000000, MP_QSTR_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); - - esp32_camera_camera_obj_t *self = m_new_obj(esp32_camera_camera_obj_t); - self->base.type = &esp32_camera_camera_type; - common_hal_esp32_camera_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 esp32_camera_camera_deinit(mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_esp32_camera_camera_deinit(self); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_deinit_obj, esp32_camera_camera_deinit); - -STATIC void check_for_deinit(esp32_camera_camera_obj_t *self) { - if (common_hal_esp32_camera_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 esp32_camera_camera_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - return esp32_camera_camera_deinit(args[0]); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp32_camera_camera___exit___obj, 4, 4, esp32_camera_camera_obj___exit__); - -//| frame_available: bool -//| """True if a frame is available, False otherwise""" - -STATIC mp_obj_t esp32_camera_camera_frame_available_get(const mp_obj_t self_in) { - esp32_camera_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(esp32_camera_camera_frame_available_get_obj, esp32_camera_camera_frame_available_get); - -MP_PROPERTY_GETTER(esp32_camera_camera_frame_available_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_take(size_t n_args, const mp_obj_t *args) { - esp32_camera_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_esp32_camera_camera_take(self, (int)MICROPY_FLOAT_C_FUN(round)(timeout * 1000)); - if (!result) { - return mp_const_none; - } - pixformat_t format = common_hal_esp32_camera_camera_get_pixel_format(self); - if (format == PIXFORMAT_JPEG) { - return mp_obj_new_memoryview('b', result->len, result->buf); - } else { - int width = common_hal_esp32_camera_camera_get_width(self); - int height = common_hal_esp32_camera_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(esp32_camera_camera_take_obj, 1, 2, esp32_camera_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 esp32_camera_camera_reconfigure(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - esp32_camera_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_esp32_camera_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_esp32_camera_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_esp32_camera_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_esp32_camera_camera_get_framebuffer_count(self); - - common_hal_esp32_camera_camera_reconfigure(self, frame_size, pixel_format, grab_mode, framebuffer_count); - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(esp32_camera_camera_reconfigure_obj, 1, esp32_camera_camera_reconfigure); - -//| pixel_format: PixelFormat -//| """The pixel format of captured frames""" - -STATIC mp_obj_t esp32_camera_camera_get_pixel_format(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return cp_enum_find(&esp32_camera_pixel_format_type, common_hal_esp32_camera_camera_get_pixel_format(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_pixel_format_obj, esp32_camera_camera_get_pixel_format); - -MP_PROPERTY_GETTER(esp32_camera_camera_pixel_format_obj, - (mp_obj_t)&esp32_camera_camera_get_pixel_format_obj); - - -//| frame_size: FrameSize -//| """The size of captured frames""" - -STATIC mp_obj_t esp32_camera_camera_get_frame_size(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return cp_enum_find(&esp32_camera_frame_size_type, common_hal_esp32_camera_camera_get_frame_size(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_frame_size_obj, esp32_camera_camera_get_frame_size); - -MP_PROPERTY_GETTER(esp32_camera_camera_frame_size_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_contrast(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_contrast(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_contrast_obj, esp32_camera_camera_get_contrast); - -STATIC mp_obj_t esp32_camera_camera_set_contrast(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_contrast(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_contrast_obj, esp32_camera_camera_set_contrast); -MP_PROPERTY_GETSET(esp32_camera_camera_contrast_obj, - (mp_obj_t)&esp32_camera_camera_get_contrast_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_brightness(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_brightness(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_brightness_obj, esp32_camera_camera_get_brightness); - -STATIC mp_obj_t esp32_camera_camera_set_brightness(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_brightness(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_brightness_obj, esp32_camera_camera_set_brightness); -MP_PROPERTY_GETSET(esp32_camera_camera_brightness_obj, - (mp_obj_t)&esp32_camera_camera_get_brightness_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_saturation(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_saturation(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_saturation_obj, esp32_camera_camera_get_saturation); - -STATIC mp_obj_t esp32_camera_camera_set_saturation(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_saturation(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_saturation_obj, esp32_camera_camera_set_saturation); -MP_PROPERTY_GETSET(esp32_camera_camera_saturation_obj, - (mp_obj_t)&esp32_camera_camera_get_saturation_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_sharpness(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_sharpness(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_sharpness_obj, esp32_camera_camera_get_sharpness); - -STATIC mp_obj_t esp32_camera_camera_set_sharpness(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_sharpness(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_sharpness_obj, esp32_camera_camera_set_sharpness); -MP_PROPERTY_GETSET(esp32_camera_camera_sharpness_obj, - (mp_obj_t)&esp32_camera_camera_get_sharpness_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_denoise(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_denoise(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_denoise_obj, esp32_camera_camera_get_denoise); - -STATIC mp_obj_t esp32_camera_camera_set_denoise(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_denoise(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_denoise_obj, esp32_camera_camera_set_denoise); -MP_PROPERTY_GETSET(esp32_camera_camera_denoise_obj, - (mp_obj_t)&esp32_camera_camera_get_denoise_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_gain_ceiling(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return cp_enum_find(&esp32_camera_gain_ceiling_type, common_hal_esp32_camera_camera_get_gainceiling(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_gain_ceiling_obj, esp32_camera_camera_get_gain_ceiling); - -STATIC mp_obj_t esp32_camera_camera_set_gain_ceiling(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_gainceiling(self, validate_gain_ceiling(arg, MP_QSTR_gain_ceiling)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_gain_ceiling_obj, esp32_camera_camera_set_gain_ceiling); -MP_PROPERTY_GETSET(esp32_camera_camera_gain_ceiling_obj, - (mp_obj_t)&esp32_camera_camera_get_gain_ceiling_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_quality(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_quality(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_quality_obj, esp32_camera_camera_get_quality); - -STATIC mp_obj_t esp32_camera_camera_set_quality(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_quality(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_quality_obj, esp32_camera_camera_set_quality); -MP_PROPERTY_GETSET(esp32_camera_camera_quality_obj, - (mp_obj_t)&esp32_camera_camera_get_quality_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_colorbar(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_colorbar(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_colorbar_obj, esp32_camera_camera_get_colorbar); - -STATIC mp_obj_t esp32_camera_camera_set_colorbar(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_colorbar(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_colorbar_obj, esp32_camera_camera_set_colorbar); -MP_PROPERTY_GETSET(esp32_camera_camera_colorbar_obj, - (mp_obj_t)&esp32_camera_camera_get_colorbar_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_whitebal(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_whitebal(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_whitebal_obj, esp32_camera_camera_get_whitebal); - -STATIC mp_obj_t esp32_camera_camera_set_whitebal(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_whitebal(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_whitebal_obj, esp32_camera_camera_set_whitebal); -MP_PROPERTY_GETSET(esp32_camera_camera_whitebal_obj, - (mp_obj_t)&esp32_camera_camera_get_whitebal_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_gain_ctrl(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_gain_ctrl(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_gain_ctrl_obj, esp32_camera_camera_get_gain_ctrl); - -STATIC mp_obj_t esp32_camera_camera_set_gain_ctrl(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_gain_ctrl(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_gain_ctrl_obj, esp32_camera_camera_set_gain_ctrl); -MP_PROPERTY_GETSET(esp32_camera_camera_gain_ctrl_obj, - (mp_obj_t)&esp32_camera_camera_get_gain_ctrl_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_exposure_ctrl(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_exposure_ctrl(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_exposure_ctrl_obj, esp32_camera_camera_get_exposure_ctrl); - -STATIC mp_obj_t esp32_camera_camera_set_exposure_ctrl(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_exposure_ctrl(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_exposure_ctrl_obj, esp32_camera_camera_set_exposure_ctrl); -MP_PROPERTY_GETSET(esp32_camera_camera_exposure_ctrl_obj, - (mp_obj_t)&esp32_camera_camera_get_exposure_ctrl_obj, - (mp_obj_t)&esp32_camera_camera_set_exposure_ctrl_obj); - -//| hmirror: bool -//| """When `True` the camera image is mirrored left-to-right""" - -STATIC mp_obj_t esp32_camera_camera_get_hmirror(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_hmirror(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_hmirror_obj, esp32_camera_camera_get_hmirror); - -STATIC mp_obj_t esp32_camera_camera_set_hmirror(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_hmirror(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_hmirror_obj, esp32_camera_camera_set_hmirror); -MP_PROPERTY_GETSET(esp32_camera_camera_hmirror_obj, - (mp_obj_t)&esp32_camera_camera_get_hmirror_obj, - (mp_obj_t)&esp32_camera_camera_set_hmirror_obj); - -//| vflip: bool -//| """When `True` the camera image is flipped top-to-bottom""" - -STATIC mp_obj_t esp32_camera_camera_get_vflip(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_vflip(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_vflip_obj, esp32_camera_camera_get_vflip); - -STATIC mp_obj_t esp32_camera_camera_set_vflip(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_vflip(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_vflip_obj, esp32_camera_camera_set_vflip); -MP_PROPERTY_GETSET(esp32_camera_camera_vflip_obj, - (mp_obj_t)&esp32_camera_camera_get_vflip_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_aec2(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_aec2(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_aec2_obj, esp32_camera_camera_get_aec2); - -STATIC mp_obj_t esp32_camera_camera_set_aec2(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_aec2(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_aec2_obj, esp32_camera_camera_set_aec2); -MP_PROPERTY_GETSET(esp32_camera_camera_aec2_obj, - (mp_obj_t)&esp32_camera_camera_get_aec2_obj, - (mp_obj_t)&esp32_camera_camera_set_aec2_obj); - -//| awb_gain: bool -//| """Access the awb_gain property of the camera sensor""" - -STATIC mp_obj_t esp32_camera_camera_get_awb_gain(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_awb_gain(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_awb_gain_obj, esp32_camera_camera_get_awb_gain); - -STATIC mp_obj_t esp32_camera_camera_set_awb_gain(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_awb_gain(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_awb_gain_obj, esp32_camera_camera_set_awb_gain); -MP_PROPERTY_GETSET(esp32_camera_camera_awb_gain_obj, - (mp_obj_t)&esp32_camera_camera_get_awb_gain_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_agc_gain(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_agc_gain(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_agc_gain_obj, esp32_camera_camera_get_agc_gain); - -STATIC mp_obj_t esp32_camera_camera_set_agc_gain(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_agc_gain(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_agc_gain_obj, esp32_camera_camera_set_agc_gain); -MP_PROPERTY_GETSET(esp32_camera_camera_agc_gain_obj, - (mp_obj_t)&esp32_camera_camera_get_agc_gain_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_aec_value(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_aec_value(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_aec_value_obj, esp32_camera_camera_get_aec_value); - -STATIC mp_obj_t esp32_camera_camera_set_aec_value(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_aec_value(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_aec_value_obj, esp32_camera_camera_set_aec_value); -MP_PROPERTY_GETSET(esp32_camera_camera_aec_value_obj, - (mp_obj_t)&esp32_camera_camera_get_aec_value_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_special_effect(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_special_effect(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_special_effect_obj, esp32_camera_camera_get_special_effect); - -STATIC mp_obj_t esp32_camera_camera_set_special_effect(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_special_effect(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_special_effect_obj, esp32_camera_camera_set_special_effect); -MP_PROPERTY_GETSET(esp32_camera_camera_special_effect_obj, - (mp_obj_t)&esp32_camera_camera_get_special_effect_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_wb_mode(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_wb_mode(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_wb_mode_obj, esp32_camera_camera_get_wb_mode); - -STATIC mp_obj_t esp32_camera_camera_set_wb_mode(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_wb_mode(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_wb_mode_obj, esp32_camera_camera_set_wb_mode); -MP_PROPERTY_GETSET(esp32_camera_camera_wb_mode_obj, - (mp_obj_t)&esp32_camera_camera_get_wb_mode_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_ae_level(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_ae_level(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_ae_level_obj, esp32_camera_camera_get_ae_level); - -STATIC mp_obj_t esp32_camera_camera_set_ae_level(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_ae_level(self, mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_ae_level_obj, esp32_camera_camera_set_ae_level); -MP_PROPERTY_GETSET(esp32_camera_camera_ae_level_obj, - (mp_obj_t)&esp32_camera_camera_get_ae_level_obj, - (mp_obj_t)&esp32_camera_camera_set_ae_level_obj); - -//| dcw: bool -//| """When `True` an advanced white balance mode is selected.""" - -STATIC mp_obj_t esp32_camera_camera_get_dcw(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_dcw(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_dcw_obj, esp32_camera_camera_get_dcw); - -STATIC mp_obj_t esp32_camera_camera_set_dcw(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_dcw(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_dcw_obj, esp32_camera_camera_set_dcw); -MP_PROPERTY_GETSET(esp32_camera_camera_dcw_obj, - (mp_obj_t)&esp32_camera_camera_get_dcw_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_bpc(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_bpc(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_bpc_obj, esp32_camera_camera_get_bpc); - -STATIC mp_obj_t esp32_camera_camera_set_bpc(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_bpc(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_bpc_obj, esp32_camera_camera_set_bpc); -MP_PROPERTY_GETSET(esp32_camera_camera_bpc_obj, - (mp_obj_t)&esp32_camera_camera_get_bpc_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_wpc(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_wpc(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_wpc_obj, esp32_camera_camera_get_wpc); - -STATIC mp_obj_t esp32_camera_camera_set_wpc(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_wpc(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_wpc_obj, esp32_camera_camera_set_wpc); -MP_PROPERTY_GETSET(esp32_camera_camera_wpc_obj, - (mp_obj_t)&esp32_camera_camera_get_wpc_obj, - (mp_obj_t)&esp32_camera_camera_set_wpc_obj); - -//| raw_gma: bool -//| """When `True`, raw gamma mode is enabled.""" - -STATIC mp_obj_t esp32_camera_camera_get_raw_gma(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_raw_gma(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_raw_gma_obj, esp32_camera_camera_get_raw_gma); - -STATIC mp_obj_t esp32_camera_camera_set_raw_gma(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_raw_gma(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_raw_gma_obj, esp32_camera_camera_set_raw_gma); -MP_PROPERTY_GETSET(esp32_camera_camera_raw_gma_obj, - (mp_obj_t)&esp32_camera_camera_get_raw_gma_obj, - (mp_obj_t)&esp32_camera_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 esp32_camera_camera_get_lenc(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_lenc(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_lenc_obj, esp32_camera_camera_get_lenc); - -STATIC mp_obj_t esp32_camera_camera_set_lenc(const mp_obj_t self_in, const mp_obj_t arg) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_esp32_camera_camera_set_lenc(self, mp_obj_is_true(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_lenc_obj, esp32_camera_camera_set_lenc); -MP_PROPERTY_GETSET(esp32_camera_camera_lenc_obj, - (mp_obj_t)&esp32_camera_camera_get_lenc_obj, - (mp_obj_t)&esp32_camera_camera_set_lenc_obj); - -//| max_frame_size: FrameSize -//| """The maximum frame size that can be captured""" -STATIC mp_obj_t esp32_camera_camera_get_max_frame_size(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return cp_enum_find(&esp32_camera_frame_size_type, common_hal_esp32_camera_camera_get_max_frame_size(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_max_frame_size_obj, esp32_camera_camera_get_max_frame_size); - -MP_PROPERTY_GETTER(esp32_camera_camera_max_frame_size_obj, - (mp_obj_t)&esp32_camera_camera_get_max_frame_size_obj); - - -//| address: int -//| """The I2C (SCCB) address of the sensor""" -STATIC mp_obj_t esp32_camera_camera_get_address(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_address(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_address_obj, esp32_camera_camera_get_address); - -MP_PROPERTY_GETTER(esp32_camera_camera_address_obj, - (mp_obj_t)&esp32_camera_camera_get_address_obj); - - -//| sensor_name: str -//| """The name of the sensor""" -STATIC mp_obj_t esp32_camera_camera_get_sensor_name(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - const char *sensor_name = common_hal_esp32_camera_camera_get_sensor_name(self); - return mp_obj_new_str(sensor_name, strlen(sensor_name)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_sensor_name_obj, esp32_camera_camera_get_sensor_name); - -MP_PROPERTY_GETTER(esp32_camera_camera_sensor_name_obj, - (mp_obj_t)&esp32_camera_camera_get_sensor_name_obj); - - -//| supports_jpeg: bool -//| """True if the sensor can capture images in JPEG format""" -STATIC mp_obj_t esp32_camera_camera_get_supports_jpeg(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return mp_obj_new_bool(common_hal_esp32_camera_camera_get_supports_jpeg(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_supports_jpeg_obj, esp32_camera_camera_get_supports_jpeg); - -MP_PROPERTY_GETTER(esp32_camera_camera_supports_jpeg_obj, - (mp_obj_t)&esp32_camera_camera_get_supports_jpeg_obj); - -//| height: int -//| """The height of the image being captured""" -STATIC mp_obj_t esp32_camera_camera_get_height(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_height(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_height_obj, esp32_camera_camera_get_height); - -MP_PROPERTY_GETTER(esp32_camera_camera_height_obj, - (mp_obj_t)&esp32_camera_camera_get_height_obj); - -//| width: int -//| """The width of the image being captured""" -STATIC mp_obj_t esp32_camera_camera_get_width(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_width(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_width_obj, esp32_camera_camera_get_width); - -MP_PROPERTY_GETTER(esp32_camera_camera_width_obj, - (mp_obj_t)&esp32_camera_camera_get_width_obj); - -//| grab_mode: GrabMode -//| """The grab mode of the camera""" -STATIC mp_obj_t esp32_camera_camera_get_grab_mode(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return cp_enum_find(&esp32_camera_grab_mode_type, common_hal_esp32_camera_camera_get_grab_mode(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_grab_mode_obj, esp32_camera_camera_get_grab_mode); - -MP_PROPERTY_GETTER(esp32_camera_camera_grab_mode_obj, - (mp_obj_t)&esp32_camera_camera_get_grab_mode_obj); - - -//| framebuffer_count: int -//| """True if double buffering is used""" -//| -STATIC mp_obj_t esp32_camera_camera_get_framebuffer_count(const mp_obj_t self_in) { - esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_framebuffer_count(self)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_framebuffer_count_obj, esp32_camera_camera_get_framebuffer_count); - -MP_PROPERTY_GETTER(esp32_camera_camera_framebuffer_count_obj, - (mp_obj_t)&esp32_camera_camera_get_framebuffer_count_obj); - - -STATIC const mp_rom_map_elem_t esp32_camera_camera_locals_table[] = { - { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&esp32_camera_camera_address_obj) }, - { MP_ROM_QSTR(MP_QSTR_aec2), MP_ROM_PTR(&esp32_camera_camera_aec2_obj) }, - { MP_ROM_QSTR(MP_QSTR_aec_value), MP_ROM_PTR(&esp32_camera_camera_aec_value_obj) }, - { MP_ROM_QSTR(MP_QSTR_ae_level), MP_ROM_PTR(&esp32_camera_camera_ae_level_obj) }, - { MP_ROM_QSTR(MP_QSTR_agc_gain), MP_ROM_PTR(&esp32_camera_camera_agc_gain_obj) }, - { MP_ROM_QSTR(MP_QSTR_awb_gain), MP_ROM_PTR(&esp32_camera_camera_awb_gain_obj) }, - { MP_ROM_QSTR(MP_QSTR_bpc), MP_ROM_PTR(&esp32_camera_camera_bpc_obj) }, - { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&esp32_camera_camera_brightness_obj) }, - { MP_ROM_QSTR(MP_QSTR_colorbar), MP_ROM_PTR(&esp32_camera_camera_colorbar_obj) }, - { MP_ROM_QSTR(MP_QSTR_contrast), MP_ROM_PTR(&esp32_camera_camera_contrast_obj) }, - { MP_ROM_QSTR(MP_QSTR_dcw), MP_ROM_PTR(&esp32_camera_camera_dcw_obj) }, - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&esp32_camera_camera_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_denoise), MP_ROM_PTR(&esp32_camera_camera_denoise_obj) }, - { MP_ROM_QSTR(MP_QSTR_framebuffer_count), MP_ROM_PTR(&esp32_camera_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(&esp32_camera_camera___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_exposure_ctrl), MP_ROM_PTR(&esp32_camera_camera_exposure_ctrl_obj) }, - { MP_ROM_QSTR(MP_QSTR_frame_available), MP_ROM_PTR(&esp32_camera_camera_frame_available_obj) }, - { MP_ROM_QSTR(MP_QSTR_frame_size), MP_ROM_PTR(&esp32_camera_camera_frame_size_obj) }, - { MP_ROM_QSTR(MP_QSTR_gain_ceiling), MP_ROM_PTR(&esp32_camera_camera_gain_ceiling_obj) }, - { MP_ROM_QSTR(MP_QSTR_gain_ctrl), MP_ROM_PTR(&esp32_camera_camera_gain_ctrl_obj) }, - { MP_ROM_QSTR(MP_QSTR_grab_mode), MP_ROM_PTR(&esp32_camera_camera_grab_mode_obj) }, - { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&esp32_camera_camera_height_obj) }, - { MP_ROM_QSTR(MP_QSTR_hmirror), MP_ROM_PTR(&esp32_camera_camera_hmirror_obj) }, - { MP_ROM_QSTR(MP_QSTR_lenc), MP_ROM_PTR(&esp32_camera_camera_lenc_obj) }, - { MP_ROM_QSTR(MP_QSTR_max_frame_size), MP_ROM_PTR(&esp32_camera_camera_max_frame_size_obj) }, - { MP_ROM_QSTR(MP_QSTR_pixel_format), MP_ROM_PTR(&esp32_camera_camera_pixel_format_obj) }, - { MP_ROM_QSTR(MP_QSTR_quality), MP_ROM_PTR(&esp32_camera_camera_quality_obj) }, - { MP_ROM_QSTR(MP_QSTR_raw_gma), MP_ROM_PTR(&esp32_camera_camera_raw_gma_obj) }, - { MP_ROM_QSTR(MP_QSTR_reconfigure), MP_ROM_PTR(&esp32_camera_camera_reconfigure_obj) }, - { MP_ROM_QSTR(MP_QSTR_saturation), MP_ROM_PTR(&esp32_camera_camera_saturation_obj) }, - { MP_ROM_QSTR(MP_QSTR_sensor_name), MP_ROM_PTR(&esp32_camera_camera_sensor_name_obj) }, - { MP_ROM_QSTR(MP_QSTR_sharpness), MP_ROM_PTR(&esp32_camera_camera_sharpness_obj) }, - { MP_ROM_QSTR(MP_QSTR_special_effect), MP_ROM_PTR(&esp32_camera_camera_special_effect_obj) }, - { MP_ROM_QSTR(MP_QSTR_supports_jpeg), MP_ROM_PTR(&esp32_camera_camera_supports_jpeg_obj) }, - { MP_ROM_QSTR(MP_QSTR_take), MP_ROM_PTR(&esp32_camera_camera_take_obj) }, - { MP_ROM_QSTR(MP_QSTR_vflip), MP_ROM_PTR(&esp32_camera_camera_vflip_obj) }, - { MP_ROM_QSTR(MP_QSTR_wb_mode), MP_ROM_PTR(&esp32_camera_camera_wb_mode_obj) }, - { MP_ROM_QSTR(MP_QSTR_whitebal), MP_ROM_PTR(&esp32_camera_camera_whitebal_obj) }, - { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&esp32_camera_camera_width_obj) }, - { MP_ROM_QSTR(MP_QSTR_wpc), MP_ROM_PTR(&esp32_camera_camera_wpc_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(esp32_camera_camera_locals_dict, esp32_camera_camera_locals_table); - -const mp_obj_type_t esp32_camera_camera_type = { - .base = { &mp_type_type }, - .name = MP_QSTR_Camera, - .make_new = esp32_camera_camera_make_new, - .locals_dict = (mp_obj_t)&esp32_camera_camera_locals_dict, -}; diff --git a/ports/espressif/bindings/espcamera/Camera.c b/ports/espressif/bindings/espcamera/Camera.c new file mode 100644 index 000000000000..5fb9576e5886 --- /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 framebuffer(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 available 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/esp32_camera/Camera.h b/ports/espressif/bindings/espcamera/Camera.h similarity index 72% rename from ports/espressif/bindings/esp32_camera/Camera.h rename to ports/espressif/bindings/espcamera/Camera.h index f1908085317b..c6d8182090d2 100644 --- a/ports/espressif/bindings/esp32_camera/Camera.h +++ b/ports/espressif/bindings/espcamera/Camera.h @@ -33,11 +33,11 @@ #include "shared-bindings/busio/I2C.h" -extern const mp_obj_type_t esp32_camera_camera_type; -typedef struct esp32_camera_camera_obj esp32_camera_camera_obj_t; +extern const mp_obj_type_t espcamera_camera_type; +typedef struct espcamera_camera_obj espcamera_camera_obj_t; -extern void common_hal_esp32_camera_camera_construct( - esp32_camera_camera_obj_t *self, +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, @@ -53,11 +53,11 @@ extern void common_hal_esp32_camera_camera_construct( mp_int_t framebuffer_count, camera_grab_mode_t grab_mode); -extern void common_hal_esp32_camera_camera_deinit(esp32_camera_camera_obj_t *self); -extern bool common_hal_esp32_camera_camera_deinited(esp32_camera_camera_obj_t *self); -extern bool common_hal_esp32_camera_camera_available(esp32_camera_camera_obj_t *self); -extern camera_fb_t *common_hal_esp32_camera_camera_take(esp32_camera_camera_obj_t *self, int timeout_ms); -extern void common_hal_esp32_camera_camera_reconfigure(esp32_camera_camera_obj_t *self, framesize_t frame_size, pixformat_t pixel_format, camera_grab_mode_t grab_mode, mp_int_t framebuffer_count); +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) \ @@ -70,10 +70,10 @@ extern void common_hal_esp32_camera_camera_reconfigure(esp32_camera_camera_obj_t 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_esp32_camera_camera_get_##name(esp32_camera_camera_obj_t * self); + 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_esp32_camera_camera_set_##name(esp32_camera_camera_obj_t * self, type value); + 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) @@ -104,13 +104,13 @@ 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_esp32_camera_camera_get_grab_mode(esp32_camera_camera_obj_t *self); -extern int common_hal_esp32_camera_camera_get_framebuffer_count(esp32_camera_camera_obj_t *self); +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_esp32_camera_camera_get_address(esp32_camera_camera_obj_t *self); -extern const char *common_hal_esp32_camera_camera_get_sensor_name(esp32_camera_camera_obj_t *self); -extern const bool common_hal_esp32_camera_camera_get_supports_jpeg(esp32_camera_camera_obj_t *self); -extern framesize_t common_hal_esp32_camera_camera_get_max_frame_size(esp32_camera_camera_obj_t *self); -extern int common_hal_esp32_camera_camera_get_width(esp32_camera_camera_obj_t *self); -extern int common_hal_esp32_camera_camera_get_height(esp32_camera_camera_obj_t *self); +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/esp32_camera/__init__.c b/ports/espressif/bindings/espcamera/__init__.c similarity index 52% rename from ports/espressif/bindings/esp32_camera/__init__.c rename to ports/espressif/bindings/espcamera/__init__.c index f1ee4b68914d..633f547fe912 100644 --- a/ports/espressif/bindings/esp32_camera/__init__.c +++ b/ports/espressif/bindings/espcamera/__init__.c @@ -29,13 +29,13 @@ #include "py/mphal.h" #include "bindings/espidf/__init__.h" -#include "bindings/esp32_camera/__init__.h" -#include "bindings/esp32_camera/Camera.h" +#include "bindings/espcamera/__init__.h" +#include "bindings/espcamera/Camera.h" #include "esp_camera.h" #include "sensor.h" -//| """Wrapper for the esp32_camera library +//| """Wrapper for the espcamera library //| //| This library enables access to any camera sensor supported by the library, //| including OV5640 and OV2640. @@ -45,6 +45,7 @@ //| Non-Espressif microcontrollers use the `imagecapture` module together with wrapper libraries such as `adafruit_ov5640 `_. //| //| """ +//| //| class GrabMode: //| """Controls when a new frame is grabbed.""" @@ -56,20 +57,20 @@ //| """Except when 1 frame buffer is used, queue will always contain the last ``fb_count`` frames""" //| -MAKE_ENUM_VALUE(esp32_camera_grab_mode_type, grab_mode, WHEN_EMPTY, CAMERA_GRAB_WHEN_EMPTY); -MAKE_ENUM_VALUE(esp32_camera_grab_mode_type, grab_mode, LATEST, CAMERA_GRAB_LATEST); +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(esp32_camera_grab_mode) { +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(esp32_camera_grab_mode_locals_dict, esp32_camera_grab_mode_locals_table); -MAKE_PRINTER(esp32_camera, esp32_camera_grab_mode); -MAKE_ENUM_TYPE(esp32_camera, GrabMode, esp32_camera_grab_mode); +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(&esp32_camera_grab_mode_type, mp_arg_validate_type(obj, &esp32_camera_grab_mode_type, arg_name)); + return cp_enum_value(&espcamera_grab_mode_type, obj, arg_name); } //| class PixelFormat: @@ -85,22 +86,22 @@ camera_grab_mode_t validate_grab_mode(mp_obj_t obj, qstr arg_name) { //| """A compressed format""" //| -MAKE_ENUM_VALUE(esp32_camera_pixel_format_type, pixel_format, RGB565, PIXFORMAT_RGB565); -MAKE_ENUM_VALUE(esp32_camera_pixel_format_type, pixel_format, GRAYSCALE, PIXFORMAT_GRAYSCALE); -MAKE_ENUM_VALUE(esp32_camera_pixel_format_type, pixel_format, JPEG, PIXFORMAT_JPEG); +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(esp32_camera_pixel_format) { +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(esp32_camera_pixel_format_locals_dict, esp32_camera_pixel_format_locals_table); -MAKE_PRINTER(esp32_camera, esp32_camera_pixel_format); -MAKE_ENUM_TYPE(esp32_camera, PixelFormat, esp32_camera_pixel_format); +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(&esp32_camera_pixel_format_type, mp_arg_validate_type(obj, &esp32_camera_pixel_format_type, arg_name)); + return cp_enum_value(&espcamera_pixel_format_type, obj, arg_name); } //| class FrameSize: @@ -173,29 +174,29 @@ pixformat_t validate_pixel_format(mp_obj_t obj, qstr arg_name) { //| """2560x1920""" //| -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, R96X96, FRAMESIZE_96X96); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, R240X240, FRAMESIZE_240X240); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, QQVGA, FRAMESIZE_QQVGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, QCIF, FRAMESIZE_QCIF); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, HQVGA, FRAMESIZE_HQVGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, QVGA, FRAMESIZE_QVGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, CIF, FRAMESIZE_CIF); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, HVGA, FRAMESIZE_HVGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, VGA, FRAMESIZE_VGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, SVGA, FRAMESIZE_SVGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, XGA, FRAMESIZE_XGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, HD, FRAMESIZE_HD); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, SXGA, FRAMESIZE_SXGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, UXGA, FRAMESIZE_UXGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, FHD, FRAMESIZE_FHD); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, P_HD, FRAMESIZE_P_HD); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, P_3MP, FRAMESIZE_P_3MP); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, QXGA, FRAMESIZE_QXGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, QHD, FRAMESIZE_QHD); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, WQXGA, FRAMESIZE_WQXGA); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, P_FHD, FRAMESIZE_P_FHD); -MAKE_ENUM_VALUE(esp32_camera_frame_size_type, frame_size, QSXGA, FRAMESIZE_QSXGA); -MAKE_ENUM_MAP(esp32_camera_frame_size) { +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), @@ -220,12 +221,12 @@ MAKE_ENUM_MAP(esp32_camera_frame_size) { MAKE_ENUM_MAP_ENTRY(frame_size, QSXGA), }; -STATIC MP_DEFINE_CONST_DICT(esp32_camera_frame_size_locals_dict, esp32_camera_frame_size_locals_table); -MAKE_PRINTER(esp32_camera, esp32_camera_frame_size); -MAKE_ENUM_TYPE(esp32_camera, FrameSize, esp32_camera_frame_size); +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(&esp32_camera_frame_size_type, mp_arg_validate_type(obj, &esp32_camera_frame_size_type, arg_name)); + return cp_enum_value(&espcamera_frame_size_type, obj, arg_name); } //| class GainCeiling: @@ -242,15 +243,15 @@ framesize_t validate_frame_size(mp_obj_t obj, qstr arg_name) { //| GAIN_128X: GainCeiling //| -MAKE_ENUM_VALUE(esp32_camera_gain_ceiling_type, gain_ceiling, GAIN_2X, GAINCEILING_2X); -MAKE_ENUM_VALUE(esp32_camera_gain_ceiling_type, gain_ceiling, GAIN_4X, GAINCEILING_4X); -MAKE_ENUM_VALUE(esp32_camera_gain_ceiling_type, gain_ceiling, GAIN_8X, GAINCEILING_8X); -MAKE_ENUM_VALUE(esp32_camera_gain_ceiling_type, gain_ceiling, GAIN_16X, GAINCEILING_16X); -MAKE_ENUM_VALUE(esp32_camera_gain_ceiling_type, gain_ceiling, GAIN_32X, GAINCEILING_32X); -MAKE_ENUM_VALUE(esp32_camera_gain_ceiling_type, gain_ceiling, GAIN_64X, GAINCEILING_64X); -MAKE_ENUM_VALUE(esp32_camera_gain_ceiling_type, gain_ceiling, GAIN_128X, GAINCEILING_128X); +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(esp32_camera_gain_ceiling) { +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), @@ -260,28 +261,28 @@ MAKE_ENUM_MAP(esp32_camera_gain_ceiling) { MAKE_ENUM_MAP_ENTRY(gain_ceiling, GAIN_128X) }; -STATIC MP_DEFINE_CONST_DICT(esp32_camera_gain_ceiling_locals_dict, esp32_camera_gain_ceiling_locals_table); -MAKE_PRINTER(esp32_camera, esp32_camera_gain_ceiling); -MAKE_ENUM_TYPE(esp32_camera, GainCeiling, esp32_camera_gain_ceiling); +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(&esp32_camera_gain_ceiling_type, mp_arg_validate_type(obj, &esp32_camera_gain_ceiling_type, arg_name)); + return cp_enum_value(&espcamera_gain_ceiling_type, obj, arg_name); } -STATIC const mp_rom_map_elem_t esp32_camera_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp32_camera) }, - { MP_ROM_QSTR(MP_QSTR_Camera), MP_ROM_PTR(&esp32_camera_camera_type), }, - { MP_ROM_QSTR(MP_QSTR_FrameSize), &esp32_camera_frame_size_type }, - { MP_ROM_QSTR(MP_QSTR_GainCeiling), &esp32_camera_gain_ceiling_type }, - { MP_ROM_QSTR(MP_QSTR_GrabMode), &esp32_camera_grab_mode_type }, - { MP_ROM_QSTR(MP_QSTR_PixelFormat), &esp32_camera_pixel_format_type }, +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(esp32_camera_module_globals, esp32_camera_module_globals_table); +STATIC MP_DEFINE_CONST_DICT(espcamera_module_globals, espcamera_module_globals_table); -const mp_obj_module_t esp32_camera_module = { +const mp_obj_module_t espcamera_module = { .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&esp32_camera_module_globals, + .globals = (mp_obj_dict_t *)&espcamera_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_esp32_camera, esp32_camera_module, CIRCUITPY_ESP32_CAMERA); +MP_REGISTER_MODULE(MP_QSTR_espcamera, espcamera_module, CIRCUITPY_ESPCAMERA); diff --git a/ports/espressif/bindings/esp32_camera/__init__.h b/ports/espressif/bindings/espcamera/__init__.h similarity index 88% rename from ports/espressif/bindings/esp32_camera/__init__.h rename to ports/espressif/bindings/espcamera/__init__.h index a0e7290ff90b..6e55ac38707d 100644 --- a/ports/espressif/bindings/esp32_camera/__init__.h +++ b/ports/espressif/bindings/espcamera/__init__.h @@ -31,13 +31,13 @@ #include "esp_camera.h" -extern const mp_obj_type_t esp32_camera_grab_mode_type; +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 esp32_camera_pixel_format_type; +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 esp32_camera_frame_size_type; +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 esp32_camera_gain_ceiling_type; +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); diff --git a/ports/espressif/bindings/espidf/__init__.c b/ports/espressif/bindings/espidf/__init__.c index 12781000ae43..65b7f12a1801 100644 --- a/ports/espressif/bindings/espidf/__init__.c +++ b/ports/espressif/bindings/espidf/__init__.c @@ -34,9 +34,12 @@ #include "nvs_flash.h" #include "components/heap/include/esp_heap_caps.h" +//| import builtins +//| //| """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 +75,8 @@ 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()); @@ -93,6 +97,13 @@ STATIC void espidf_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_pr mp_obj_exception_print(print, o_in, kind); } +//| class IDFError(builtins.OSError): +//| """Raised when an ``ESP-IDF`` function returns an error code. +//| `esp_err_t `_ +//| """ +//| +//| ... +//| const mp_obj_type_t mp_type_espidf_IDFError = { { &mp_type_type }, .name = MP_QSTR_IDFError, @@ -102,11 +113,8 @@ const mp_obj_type_t mp_type_espidf_IDFError = { .parent = &mp_type_OSError, }; - -//| import builtins -//| //| class MemoryError(builtins.MemoryError): -//| """Raised when an ESP IDF memory allocation fails.""" +//| """Raised when an ``ESP-IDF`` memory allocation fails.""" //| //| ... //| diff --git a/ports/espressif/bindings/espnow/ESPNow.c b/ports/espressif/bindings/espnow/ESPNow.c new file mode 100644 index 000000000000..78d80924fdd6 --- /dev/null +++ b/ports/espressif/bindings/espnow/ESPNow.c @@ -0,0 +1,373 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017-2020 Nick Moore + * Copyright (c) 2018 shawwwn + * Copyright (c) 2020-2021 Glenn Moloney @glenn20 + * 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/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" + +#include "shared-bindings/util.h" + +#include "bindings/espnow/ESPNow.h" +#include "bindings/espnow/Peer.h" + +#include "common-hal/espnow/__init__.h" +#include "common-hal/espnow/ESPNow.h" + +#include "esp_now.h" + +// Raise ValueError if the ESPNow object is deinited +static void espnow_check_for_deinit(espnow_obj_t *self) { + if (common_hal_espnow_deinited(self)) { + raise_deinited_error(); + } +} + +// --- Initialisation and Config functions --- + +//| class ESPNow: +//| """Provides access to the ESP-NOW protocol.""" +//| +//| def __init__(self, buffer_size: int = 526, phy_rate: int = 0) -> None: +//| """Allocate and initialize `ESPNow` instance as a singleton. +//| +//| :param int buffer_size: The size of the internal ring buffer. Default: 526 bytes. +//| :param int phy_rate: The ESP-NOW physical layer rate. Default: 1 Mbps. +//| `wifi_phy_rate_t `_ +//| """ +//| ... +STATIC mp_obj_t espnow_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_size, ARG_phy_rate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer_size, MP_ARG_INT, { .u_int = 526 } }, + { MP_QSTR_phy_rate, MP_ARG_INT, { .u_int = WIFI_PHY_RATE_1M_L } }, + }; + + 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); + + espnow_obj_t *self = MP_STATE_PORT(espnow_singleton); + + if (!common_hal_espnow_deinited(self)) { + mp_raise_RuntimeError(translate("Already running")); + } + + // Allocate a new object + self = m_new_obj(espnow_obj_t); + self->base.type = &espnow_type; + + // Construct the object + common_hal_espnow_construct(self, args[ARG_buffer_size].u_int, args[ARG_phy_rate].u_int); + + // Set the global singleton pointer for the espnow protocol. + MP_STATE_PORT(espnow_singleton) = self; + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitializes ESP-NOW and releases it for another program.""" +//| ... +STATIC mp_obj_t espnow_deinit(mp_obj_t self_in) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + espnow_check_for_deinit(self); + common_hal_espnow_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_deinit_obj, espnow_deinit); + +//| def __enter__(self) -> ESPNow: +//| """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 espnow_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + return espnow_deinit(args[0]); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow___exit___obj, 4, 4, espnow_obj___exit__); + +// --- Send and Read messages --- + +//| def send( +//| self, +//| message: ReadableBuffer, +//| peer: Optional[Peer] = None, +//| ) -> None: +//| """Send a message to the peer's mac address. +//| +//| This blocks until a timeout of ``2`` seconds if the ESP-NOW internal buffers are full. +//| +//| :param ReadableBuffer message: The message to send (length <= 250 bytes). +//| :param Peer peer: Send message to this peer. If `None`, send to all registered peers. +//| """ +//| ... +STATIC mp_obj_t espnow_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_message, ARG_peer }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_message, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_peer, MP_ARG_OBJ, { .u_obj = mp_const_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); + + espnow_obj_t *self = pos_args[0]; + espnow_check_for_deinit(self); + + // Get a pointer to the data buffer of the message + mp_buffer_info_t message; + mp_get_buffer_raise(args[ARG_message].u_obj, &message, MP_BUFFER_READ); + + const uint8_t *mac = NULL; + if (args[ARG_peer].u_obj != mp_const_none) { + const espnow_peer_obj_t *peer = MP_OBJ_FROM_PTR(mp_arg_validate_type_or_none(args[ARG_peer].u_obj, &espnow_peer_type, MP_QSTR_peer)); + mac = peer->peer_info.peer_addr; + } + + return common_hal_espnow_send(self, &message, mac); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(espnow_send_obj, 2, espnow_send); + +//| def read(self) -> Optional[ESPNowPacket]: +//| """Read a packet from the receive buffer. +//| +//| This is non-blocking, the packet is received asynchronously from the peer(s). +//| +//| :returns: An `ESPNowPacket` if available in the buffer, otherwise `None`.""" +//| ... +STATIC mp_obj_t espnow_read(mp_obj_t self_in) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + espnow_check_for_deinit(self); + + return common_hal_espnow_read(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_read_obj, espnow_read); + +//| send_success: int +//| """The number of tx packets received by the peer(s) ``ESP_NOW_SEND_SUCCESS``. (read-only)""" +//| +STATIC mp_obj_t espnow_get_send_success(const mp_obj_t self_in) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int_from_uint(self->send_success); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_get_send_success_obj, espnow_get_send_success); + +MP_PROPERTY_GETTER(espnow_send_success_obj, + (mp_obj_t)&espnow_get_send_success_obj); + +//| send_failure: int +//| """The number of failed tx packets ``ESP_NOW_SEND_FAIL``. (read-only)""" +//| +STATIC mp_obj_t espnow_send_get_failure(const mp_obj_t self_in) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int_from_uint(self->send_failure); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_send_get_failure_obj, espnow_send_get_failure); + +MP_PROPERTY_GETTER(espnow_send_failure_obj, + (mp_obj_t)&espnow_send_get_failure_obj); + +//| read_success: int +//| """The number of rx packets captured in the buffer. (read-only)""" +//| +STATIC mp_obj_t espnow_get_read_success(const mp_obj_t self_in) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int_from_uint(self->read_success); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_get_read_success_obj, espnow_get_read_success); + +MP_PROPERTY_GETTER(espnow_read_success_obj, + (mp_obj_t)&espnow_get_read_success_obj); + +//| read_failure: int +//| """The number of dropped rx packets due to buffer overflow. (read-only)""" +//| +STATIC mp_obj_t espnow_read_get_failure(const mp_obj_t self_in) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int_from_uint(self->read_failure); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_read_get_failure_obj, espnow_read_get_failure); + +MP_PROPERTY_GETTER(espnow_read_failure_obj, + (mp_obj_t)&espnow_read_get_failure_obj); + +//| def set_pmk(self, pmk: ReadableBuffer) -> None: +//| """Set the ESP-NOW Primary Master Key (pmk) for encrypted communications. +//| +//| :param ReadableBuffer pmk: The ESP-NOW Primary Master Key (length = 16 bytes).""" +//| ... +STATIC mp_obj_t espnow_set_pmk(mp_obj_t self_in, mp_obj_t key) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + espnow_check_for_deinit(self); + common_hal_espnow_set_pmk(self, common_hal_espnow_get_bytes_len(key, ESP_NOW_KEY_LEN)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espnow_set_pmk_obj, espnow_set_pmk); + +//| buffer_size: int +//| """The size of the internal ring buffer. (read-only)""" +//| +STATIC mp_obj_t espnow_get_buffer_size(const mp_obj_t self_in) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int_from_uint(self->recv_buffer_size); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_get_buffer_size_obj, espnow_get_buffer_size); + +MP_PROPERTY_GETTER(espnow_buffer_size_obj, + (mp_obj_t)&espnow_get_buffer_size_obj); + +//| phy_rate: int +//| """The ESP-NOW physical layer rate. +//| `wifi_phy_rate_t `_ +//| """ +//| +STATIC mp_obj_t espnow_get_phy_rate(const mp_obj_t self_in) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(self->phy_rate); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_get_phy_rate_obj, espnow_get_phy_rate); + +STATIC mp_obj_t espnow_set_phy_rate(const mp_obj_t self_in, const mp_obj_t value) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + espnow_check_for_deinit(self); + common_hal_espnow_set_phy_rate(self, mp_obj_get_int(value)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(espnow_set_phy_rate_obj, espnow_set_phy_rate); + +MP_PROPERTY_GETSET(espnow_phy_rate_obj, + (mp_obj_t)&espnow_get_phy_rate_obj, + (mp_obj_t)&espnow_set_phy_rate_obj); + +// --- Peer Related Properties --- + +//| peers: Peers +//| """The peer info records for all registered `ESPNow` peers. (read-only)""" +//| +STATIC mp_obj_t espnow_get_peers(mp_obj_t self_in) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_FROM_PTR(self->peers); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_get_peers_obj, espnow_get_peers); + +MP_PROPERTY_GETTER(espnow_peers_obj, + (mp_obj_t)&espnow_get_peers_obj); + +STATIC const mp_rom_map_elem_t espnow_locals_dict_table[] = { + // Context managers + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&espnow___exit___obj) }, + + // Deinit the object + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espnow_deinit_obj) }, + + // Send messages + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&espnow_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_send_success),MP_ROM_PTR(&espnow_send_success_obj)}, + { MP_ROM_QSTR(MP_QSTR_send_failure),MP_ROM_PTR(&espnow_send_failure_obj)}, + + // Read messages + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&espnow_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_success),MP_ROM_PTR(&espnow_read_success_obj)}, + { MP_ROM_QSTR(MP_QSTR_read_failure),MP_ROM_PTR(&espnow_read_failure_obj)}, + + // Config parameters + { MP_ROM_QSTR(MP_QSTR_set_pmk), MP_ROM_PTR(&espnow_set_pmk_obj) }, + { MP_ROM_QSTR(MP_QSTR_buffer_size), MP_ROM_PTR(&espnow_buffer_size_obj) }, + { MP_ROM_QSTR(MP_QSTR_phy_rate), MP_ROM_PTR(&espnow_phy_rate_obj) }, + + // Peer related properties + { MP_ROM_QSTR(MP_QSTR_peers), MP_ROM_PTR(&espnow_peers_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(espnow_locals_dict, espnow_locals_dict_table); + +// --- Dummy Buffer Protocol support --- +// ...so asyncio can poll.ipoll() on this device + +// Support ioctl(MP_STREAM_POLL, ) for asyncio +STATIC mp_uint_t espnow_stream_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + espnow_check_for_deinit(self); + switch (request) { + case MP_STREAM_POLL: { + mp_uint_t flags = arg; + mp_uint_t ret = 0; + if ((flags & MP_STREAM_POLL_RD) && ringbuf_num_filled(self->recv_buffer) > 0) { + ret |= MP_STREAM_POLL_RD; + } + return ret; + } + default: + *errcode = MP_EINVAL; + return MP_STREAM_ERROR; + } +} + +STATIC const mp_stream_p_t espnow_stream_p = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) + .ioctl = espnow_stream_ioctl, +}; + +//| def __bool__(self) -> bool: +//| """``True`` if `len()` is greater than zero. +//| This is an easy way to check if the buffer is empty. +//| """ +//| ... +//| def __len__(self) -> int: +//| """Return the number of `bytes` available to read. Used to implement ``len()``.""" +//| ... +//| +STATIC mp_obj_t espnow_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); + espnow_check_for_deinit(self); + size_t len = ringbuf_num_filled(self->recv_buffer); + switch (op) { + case MP_UNARY_OP_BOOL: + return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: + return mp_obj_new_int_from_uint(len); + default: + return MP_OBJ_NULL; // op not supported + } +} + +const mp_obj_type_t espnow_type = { + { &mp_type_type }, + .name = MP_QSTR_ESPNow, + .make_new = espnow_make_new, + .locals_dict = (mp_obj_t)&espnow_locals_dict, + .flags = MP_TYPE_FLAG_EXTENDED, + MP_TYPE_EXTENDED_FIELDS( + .protocol = &espnow_stream_p, + .unary_op = &espnow_unary_op + ), +}; diff --git a/ports/espressif/bindings/espnow/ESPNow.h b/ports/espressif/bindings/espnow/ESPNow.h new file mode 100644 index 000000000000..6aa011c5017d --- /dev/null +++ b/ports/espressif/bindings/espnow/ESPNow.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Glenn Moloney @glenn20 + * 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. + */ + +#pragma once + +#include "py/obj.h" +extern const mp_obj_type_t espnow_type; diff --git a/ports/espressif/bindings/espnow/ESPNowPacket.c b/ports/espressif/bindings/espnow/ESPNowPacket.c new file mode 100644 index 000000000000..f8bc8e8418d0 --- /dev/null +++ b/ports/espressif/bindings/espnow/ESPNowPacket.c @@ -0,0 +1,70 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * 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 "bindings/espnow/ESPNowPacket.h" + +//| class ESPNowPacket: +//| """A packet retrieved from ESP-NOW communication protocol. A namedtuple.""" +//| +//| mac: ReadableBuffer +//| """The sender's mac address (length = 6 bytes).""" +//| +//| msg: ReadableBuffer +//| """The message sent by the peer (length <= 250 bytes).""" +//| +//| rssi: int +//| """The received signal strength indication (in dBm from -127 to 0).""" +//| +//| time: int +//| """The time in milliseconds since the device last booted when the packet was received.""" +//| + +const mp_obj_namedtuple_type_t espnow_packet_type_obj = { + .base = { + .base = { + .type = &mp_type_type + }, + .flags = MP_TYPE_FLAG_EXTENDED, + .name = MP_QSTR_ESPNowPacket, + .print = namedtuple_print, + .parent = &mp_type_tuple, + .make_new = namedtuple_make_new, + .attr = namedtuple_attr, + MP_TYPE_EXTENDED_FIELDS( + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, + ), + }, + .n_fields = 4, + .fields = { + MP_QSTR_mac, + MP_QSTR_msg, + MP_QSTR_rssi, + MP_QSTR_time, + }, +}; diff --git a/ports/espressif/bindings/espnow/ESPNowPacket.h b/ports/espressif/bindings/espnow/ESPNowPacket.h new file mode 100644 index 000000000000..87fc51ee9232 --- /dev/null +++ b/ports/espressif/bindings/espnow/ESPNowPacket.h @@ -0,0 +1,30 @@ +/* + * This file is part of the Micro Python 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. + */ + +#pragma once + +#include "py/objnamedtuple.h" +extern const mp_obj_namedtuple_type_t espnow_packet_type_obj; diff --git a/ports/espressif/bindings/espnow/Peer.c b/ports/espressif/bindings/espnow/Peer.c new file mode 100644 index 000000000000..f69bec01e6a5 --- /dev/null +++ b/ports/espressif/bindings/espnow/Peer.c @@ -0,0 +1,229 @@ +/* + * This file is part of the Micro Python 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/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "bindings/espnow/Peer.h" +#include "common-hal/espnow/__init__.h" + +//| class Peer: +//| """A data class to store parameters specific to a peer.""" +//| +//| def __init__( +//| self, +//| mac: bytes, +//| *, +//| lmk: Optional[bytes], +//| channel: int = 0, +//| interface: int = 0, +//| encrypted: bool = False, +//| ) -> None: +//| """Construct a new peer object. +//| +//| :param bytes mac: The mac address of the peer. +//| :param bytes lmk: The Local Master Key (lmk) of the peer. +//| :param int channel: The peer's channel. Default: 0 ie. use the current channel. +//| :param int interface: The WiFi interface to use. Default: 0 ie. STA. +//| :param bool encrypted: Whether or not to use encryption. +//| """ +//| ... +STATIC mp_obj_t espnow_peer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_mac, ARG_lmk, ARG_channel, ARG_interface, ARG_encrypted }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_mac, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_lmk, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = mp_const_none } }, + { MP_QSTR_channel, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } }, + { MP_QSTR_interface,MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } }, + { MP_QSTR_encrypted,MP_ARG_BOOL | MP_ARG_KW_ONLY,{ .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); + + espnow_peer_obj_t *self = m_new_obj(espnow_peer_obj_t); + self->base.type = &espnow_peer_type; + self->peer_info = (esp_now_peer_info_t) { + .channel = 0, + .ifidx = WIFI_IF_STA, + .encrypt = false + }; + + memcpy(self->peer_info.peer_addr, common_hal_espnow_get_bytes_len(args[ARG_mac].u_obj, ESP_NOW_ETH_ALEN), ESP_NOW_ETH_ALEN); + + self->peer_info.channel = mp_arg_validate_int_range(args[ARG_channel].u_int, 0, 14, MP_QSTR_channel); + + self->peer_info.ifidx = (wifi_interface_t)mp_arg_validate_int_range(args[ARG_interface].u_int, 0, 1, MP_QSTR_interface); + + self->peer_info.encrypt = args[ARG_encrypted].u_bool; + + const mp_obj_t lmk = args[ARG_lmk].u_obj; + if (lmk != mp_const_none) { + memcpy(self->peer_info.lmk, common_hal_espnow_get_bytes_len(lmk, ESP_NOW_KEY_LEN), ESP_NOW_KEY_LEN); + } else if (self->peer_info.encrypt && !self->peer_info.lmk) { + mp_raise_ValueError_varg(translate("%q is %q"), MP_QSTR_lmk, MP_QSTR_None); + } + + return self; +} + +//| mac: ReadableBuffer +//| """The WiFi mac to use.""" +//| +STATIC mp_obj_t espnow_peer_get_mac(const mp_obj_t self_in) { + espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bytes(self->peer_info.peer_addr, MP_ARRAY_SIZE(self->peer_info.peer_addr)); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_peer_get_mac_obj, espnow_peer_get_mac); + +STATIC mp_obj_t espnow_peer_set_mac(const mp_obj_t self_in, const mp_obj_t value) { + espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); + + memcpy(self->peer_info.peer_addr, common_hal_espnow_get_bytes_len(value, ESP_NOW_ETH_ALEN), ESP_NOW_ETH_ALEN); + esp_now_mod_peer(&self->peer_info); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(espnow_peer_set_mac_obj, espnow_peer_set_mac); + +MP_PROPERTY_GETSET(espnow_peer_mac_obj, + (mp_obj_t)&espnow_peer_get_mac_obj, + (mp_obj_t)&espnow_peer_set_mac_obj); + +//| lmk: ReadableBuffer +//| """The WiFi lmk to use.""" +//| +STATIC mp_obj_t espnow_peer_get_lmk(const mp_obj_t self_in) { + espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bytes(self->peer_info.lmk, MP_ARRAY_SIZE(self->peer_info.lmk)); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_peer_get_lmk_obj, espnow_peer_get_lmk); + +STATIC mp_obj_t espnow_peer_set_lmk(const mp_obj_t self_in, const mp_obj_t value) { + espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); + + memcpy(self->peer_info.lmk, common_hal_espnow_get_bytes_len(value, ESP_NOW_KEY_LEN), ESP_NOW_KEY_LEN); + esp_now_mod_peer(&self->peer_info); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(espnow_peer_set_lmk_obj, espnow_peer_set_lmk); + +MP_PROPERTY_GETSET(espnow_peer_lmk_obj, + (mp_obj_t)&espnow_peer_get_lmk_obj, + (mp_obj_t)&espnow_peer_set_lmk_obj); + +//| channel: int +//| """The WiFi channel to use.""" +//| +STATIC mp_obj_t espnow_peer_get_channel(const mp_obj_t self_in) { + espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(self->peer_info.channel); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_peer_get_channel_obj, espnow_peer_get_channel); + +STATIC mp_obj_t espnow_peer_set_channel(const mp_obj_t self_in, const mp_obj_t value) { + espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->peer_info.channel = mp_arg_validate_int_range(mp_obj_get_int(value), 0, 14, MP_QSTR_channel); + esp_now_mod_peer(&self->peer_info); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(espnow_peer_set_channel_obj, espnow_peer_set_channel); + +MP_PROPERTY_GETSET(espnow_peer_channel_obj, + (mp_obj_t)&espnow_peer_get_channel_obj, + (mp_obj_t)&espnow_peer_set_channel_obj); + +//| interface: int +//| """The WiFi interface to use.""" +//| +STATIC mp_obj_t espnow_peer_get_interface(const mp_obj_t self_in) { + espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(self->peer_info.ifidx); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_peer_get_interface_obj, espnow_peer_get_interface); + +STATIC mp_obj_t espnow_peer_set_interface(const mp_obj_t self_in, const mp_obj_t value) { + espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->peer_info.ifidx = (wifi_interface_t)mp_arg_validate_int_range(mp_obj_get_int(value), 0, 1, MP_QSTR_interface); + esp_now_mod_peer(&self->peer_info); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(espnow_peer_set_interface_obj, espnow_peer_set_interface); + +MP_PROPERTY_GETSET(espnow_peer_interface_obj, + (mp_obj_t)&espnow_peer_get_interface_obj, + (mp_obj_t)&espnow_peer_set_interface_obj); + +//| encrypted: bool +//| """Whether or not to use encryption.""" +//| +STATIC mp_obj_t espnow_peer_get_encrypted(const mp_obj_t self_in) { + espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(self->peer_info.encrypt); +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_peer_get_encrypted_obj, espnow_peer_get_encrypted); + +STATIC mp_obj_t espnow_peer_set_encrypted(const mp_obj_t self_in, const mp_obj_t value) { + espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->peer_info.encrypt = mp_obj_is_true(value); + + if (!self->peer_info.lmk) { + mp_raise_ValueError_varg(translate("%q is %q"), MP_QSTR_lmk, MP_QSTR_None); + } + + esp_now_mod_peer(&self->peer_info); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(espnow_peer_set_encrypted_obj, espnow_peer_set_encrypted); + +MP_PROPERTY_GETSET(espnow_peer_encrypted_obj, + (mp_obj_t)&espnow_peer_get_encrypted_obj, + (mp_obj_t)&espnow_peer_set_encrypted_obj); + +STATIC const mp_rom_map_elem_t espnow_peer_locals_dict_table[] = { + // Peer parameters + { MP_ROM_QSTR(MP_QSTR_mac), MP_ROM_PTR(&espnow_peer_mac_obj) }, + { MP_ROM_QSTR(MP_QSTR_lmk), MP_ROM_PTR(&espnow_peer_lmk_obj) }, + { MP_ROM_QSTR(MP_QSTR_channel), MP_ROM_PTR(&espnow_peer_channel_obj) }, + { MP_ROM_QSTR(MP_QSTR_interface), MP_ROM_PTR(&espnow_peer_interface_obj) }, + { MP_ROM_QSTR(MP_QSTR_encrypted), MP_ROM_PTR(&espnow_peer_encrypted_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(espnow_peer_locals_dict, espnow_peer_locals_dict_table); + +const mp_obj_type_t espnow_peer_type = { + { &mp_type_type }, + .name = MP_QSTR_Peer, + .make_new = espnow_peer_make_new, + .locals_dict = (mp_obj_t)&espnow_peer_locals_dict, +}; diff --git a/ports/espressif/bindings/espnow/Peer.h b/ports/espressif/bindings/espnow/Peer.h new file mode 100644 index 000000000000..e4cb828472a4 --- /dev/null +++ b/ports/espressif/bindings/espnow/Peer.h @@ -0,0 +1,37 @@ +/* + * This file is part of the Micro Python 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. + */ + +#pragma once + +#include "py/obj.h" +#include "esp_now.h" + +typedef struct { + mp_obj_base_t base; + esp_now_peer_info_t peer_info; +} espnow_peer_obj_t; + +const mp_obj_type_t espnow_peer_type; diff --git a/ports/espressif/bindings/espnow/Peers.c b/ports/espressif/bindings/espnow/Peers.c new file mode 100644 index 000000000000..6fda9aed7a5e --- /dev/null +++ b/ports/espressif/bindings/espnow/Peers.c @@ -0,0 +1,138 @@ +/* + * This file is part of the Micro Python 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/obj.h" +#include "py/objlist.h" +#include "py/runtime.h" + +#include "bindings/espidf/__init__.h" + +#include "bindings/espnow/Peer.h" +#include "bindings/espnow/Peers.h" + +#include "esp_now.h" + +//| class Peers: +//| """Maintains a `list` of `Peer` internally and only exposes a subset of `list` methods.""" +//| +//| def __init__(self) -> None: +//| """You cannot create an instance of `Peers`.""" +//| ... + +//| def append(self, peer: Peer) -> None: +//| """Append peer. +//| +//| :param Peer peer: The peer object to append. +//| """ +//| ... +STATIC mp_obj_t espnow_peers_append(mp_obj_t self_in, mp_obj_t arg) { + espnow_peer_obj_t *peer = MP_OBJ_TO_PTR(mp_arg_validate_type(arg, &espnow_peer_type, MP_QSTR_Peer)); + CHECK_ESP_RESULT(esp_now_add_peer(&peer->peer_info)); + espnow_peers_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_list_append(self->list, arg); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espnow_peers_append_obj, espnow_peers_append); + +//| def remove(self, peer: Peer) -> None: +//| """Remove peer. +//| +//| :param Peer peer: The peer object to remove. +//| """ +//| ... +//| +STATIC mp_obj_t espnow_peers_remove(mp_obj_t self_in, mp_obj_t arg) { + espnow_peer_obj_t *peer = MP_OBJ_TO_PTR(mp_arg_validate_type(arg, &espnow_peer_type, MP_QSTR_Peer)); + CHECK_ESP_RESULT(esp_now_del_peer(peer->peer_info.peer_addr)); + espnow_peers_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_list_remove(self->list, arg); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espnow_peers_remove_obj, espnow_peers_remove); + +STATIC const mp_rom_map_elem_t espnow_peers_locals_dict_table[] = { + // Peer management functions + { MP_ROM_QSTR(MP_QSTR_append), MP_ROM_PTR(&espnow_peers_append_obj) }, + { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&espnow_peers_remove_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(espnow_peers_locals_dict, espnow_peers_locals_dict_table); + +/******************************************************************************/ +/* peers print */ + +STATIC void espnow_peers_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + espnow_peers_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_list_t *list = MP_OBJ_TO_PTR(self->list); + return list->base.type->print(print, self->list, kind); +} + +/******************************************************************************/ +/* peers unary_op */ + +STATIC mp_obj_t espnow_peers_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + espnow_peers_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_list_t *list = MP_OBJ_TO_PTR(self->list); + return list->base.type->ext->unary_op(op, self->list); +} + +/******************************************************************************/ +/* peers subscript */ + +STATIC mp_obj_t espnow_peers_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { + if (value != MP_OBJ_SENTINEL) { + return MP_OBJ_NULL; // op not supported + } + espnow_peers_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_list_t *list = MP_OBJ_TO_PTR(self->list); + return list->base.type->ext->subscr(self->list, index, value); +} + +/******************************************************************************/ +/* peers iterator */ + +STATIC mp_obj_t espnow_peers_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) { + espnow_peers_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_list_t *list = MP_OBJ_TO_PTR(self->list); + return list->base.type->ext->getiter(self->list, iter_buf); +} + +espnow_peers_obj_t *espnow_peers_new(void) { + espnow_peers_obj_t *self = m_new_obj(espnow_peers_obj_t); + self->base.type = &espnow_peers_type; + self->list = mp_obj_new_list(0, NULL); + return self; +} + +const mp_obj_type_t espnow_peers_type = { + { &mp_type_type }, + .name = MP_QSTR_Peers, + .print = espnow_peers_print, + .locals_dict = (mp_obj_t)&espnow_peers_locals_dict, + .flags = MP_TYPE_FLAG_EXTENDED, + MP_TYPE_EXTENDED_FIELDS( + .unary_op = espnow_peers_unary_op, + .subscr = espnow_peers_subscr, + .getiter = espnow_peers_getiter, + ), +}; diff --git a/ports/espressif/bindings/espnow/Peers.h b/ports/espressif/bindings/espnow/Peers.h new file mode 100644 index 000000000000..e871ae86c0e9 --- /dev/null +++ b/ports/espressif/bindings/espnow/Peers.h @@ -0,0 +1,37 @@ +/* + * This file is part of the Micro Python 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. + */ + +#pragma once + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t list; +} espnow_peers_obj_t; + +extern const mp_obj_type_t espnow_peers_type; +extern espnow_peers_obj_t *espnow_peers_new(void); diff --git a/ports/espressif/bindings/espnow/__init__.c b/ports/espressif/bindings/espnow/__init__.c new file mode 100644 index 000000000000..31358586012f --- /dev/null +++ b/ports/espressif/bindings/espnow/__init__.c @@ -0,0 +1,94 @@ +/* + * This file is part of the Micro Python 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 "bindings/espnow/__init__.h" +#include "bindings/espnow/ESPNow.h" +#include "bindings/espnow/ESPNowPacket.h" +#include "bindings/espnow/Peer.h" +#include "bindings/espnow/Peers.h" + +//| """ESP-NOW Module +//| +//| The `espnow` module provides an interface to the +//| `ESP-NOW `_ +//| protocol provided by Espressif on its SoCs. +//| +//| **Sender** +//| +//| .. code-block:: python +//| +//| import espnow +//| +//| e = espnow.ESPNow() +//| peer = espnow.Peer(mac=b'\xaa\xaa\xaa\xaa\xaa\xaa') +//| e.peers.append(peer) +//| +//| e.send("Starting...") +//| for i in range(10): +//| e.send(str(i)*20) +//| e.send(b'end') +//| +//| **Receiver** +//| +//| .. code-block:: python +//| +//| import espnow +//| +//| e = espnow.ESPNow() +//| packets = [] +//| +//| while True: +//| if e: +//| packet = e.read() +//| packets.append(packet) +//| if packet.msg == b'end': +//| break +//| +//| print("packets:", f"length={len(packets)}") +//| for packet in packets: +//| print(packet) +//| """ +//| ... +//| + +STATIC const mp_rom_map_elem_t espnow_module_globals_table[] = { + // module name + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_espnow) }, + + // module classes + { MP_ROM_QSTR(MP_QSTR_ESPNow), MP_ROM_PTR(&espnow_type) }, + { MP_ROM_QSTR(MP_QSTR_ESPNowPacket),MP_ROM_PTR(&espnow_packet_type_obj) }, + { MP_ROM_QSTR(MP_QSTR_Peer), MP_ROM_PTR(&espnow_peer_type) }, + { MP_ROM_QSTR(MP_QSTR_Peers), MP_ROM_PTR(&espnow_peers_type) }, +}; +STATIC MP_DEFINE_CONST_DICT(espnow_module_globals, espnow_module_globals_table); + +const mp_obj_module_t espnow_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&espnow_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_espnow, espnow_module, CIRCUITPY_ESPNOW); diff --git a/ports/espressif/bindings/espnow/__init__.h b/ports/espressif/bindings/espnow/__init__.h new file mode 100644 index 000000000000..fb814a434f07 --- /dev/null +++ b/ports/espressif/bindings/espnow/__init__.h @@ -0,0 +1,29 @@ +/* + * This file is part of the Micro Python 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. + */ + +#pragma once + +void espnow_reset(void); diff --git a/ports/espressif/bindings/espulp/Architecture.c b/ports/espressif/bindings/espulp/Architecture.c new file mode 100644 index 000000000000..d87691716c57 --- /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 000000000000..54c0677f05bf --- /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 index 15af22dca82a..c9666fb1435b 100644 --- a/ports/espressif/bindings/espulp/ULP.c +++ b/ports/espressif/bindings/espulp/ULP.c @@ -28,38 +28,49 @@ #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): +//| 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.""" +//| 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); + + common_hal_espulp_ulp_construct(self, arch); + return MP_OBJ_FROM_PTR(self); } -STATIC espulp_ulp_obj_t *get_ulp_obj(mp_obj_t self_in) { - if (!mp_obj_is_type(self_in, &espulp_ulp_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), MP_QSTR_ULP); - } - espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC void check_for_deinit(espulp_ulp_obj_t *self) { if (common_hal_espulp_ulp_deinited(self)) { raise_deinited_error(); } - return self; } //| 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 = get_ulp_obj(self_in); + espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_espulp_ulp_deinit(self); return mp_const_none; } @@ -89,6 +100,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espulp_ulp___exit___obj, 4, 4, espulp //| 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}, @@ -96,7 +110,6 @@ STATIC mp_obj_t espulp_ulp_run(size_t n_args, const mp_obj_t *pos_args, mp_map_t }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - espulp_ulp_obj_t *self = get_ulp_obj(pos_args[0]); 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; @@ -111,7 +124,7 @@ STATIC mp_obj_t espulp_ulp_run(size_t n_args, const mp_obj_t *pos_args, mp_map_t 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); + 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(); @@ -127,19 +140,36 @@ 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) { - common_hal_espulp_ulp_halt(get_ulp_obj(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_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); diff --git a/ports/espressif/bindings/espulp/ULP.h b/ports/espressif/bindings/espulp/ULP.h index 9f9c3ecf7f56..490cbef1ca75 100644 --- a/ports/espressif/bindings/espulp/ULP.h +++ b/ports/espressif/bindings/espulp/ULP.h @@ -29,10 +29,9 @@ #include "py/obj.h" #include "common-hal/espulp/ULP.h" - extern const mp_obj_type_t espulp_ulp_type; -void common_hal_espulp_ulp_construct(espulp_ulp_obj_t *self); +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); diff --git a/ports/espressif/bindings/espulp/ULPAlarm.c b/ports/espressif/bindings/espulp/ULPAlarm.c index e77fe7f83471..6efd1c98ef55 100644 --- a/ports/espressif/bindings/espulp/ULPAlarm.c +++ b/ports/espressif/bindings/espulp/ULPAlarm.c @@ -27,25 +27,36 @@ #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) -> None: +//| 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) { +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; - common_hal_espulp_ulpalarm_construct(self); + + 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); } diff --git a/ports/espressif/bindings/espulp/ULPAlarm.h b/ports/espressif/bindings/espulp/ULPAlarm.h index 75e96c0a457e..f2b2e69bba3e 100644 --- a/ports/espressif/bindings/espulp/ULPAlarm.h +++ b/ports/espressif/bindings/espulp/ULPAlarm.h @@ -30,4 +30,4 @@ extern const mp_obj_type_t espulp_ulpalarm_type; -void common_hal_espulp_ulpalarm_construct(espulp_ulpalarm_obj_t *self); +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 index 06c62175fab3..f2b688dda4f0 100644 --- a/ports/espressif/bindings/espulp/__init__.c +++ b/ports/espressif/bindings/espulp/__init__.c @@ -25,9 +25,11 @@ */ #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" @@ -61,7 +63,7 @@ //| 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); + 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; @@ -80,6 +82,7 @@ STATIC const mp_rom_map_elem_t espulp_module_globals_table[] = { // 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); diff --git a/ports/espressif/boards/01space_lcd042_esp32c3/board.c b/ports/espressif/boards/01space_lcd042_esp32c3/board.c new file mode 100644 index 000000000000..56df21ab57c9 --- /dev/null +++ b/ports/espressif/boards/01space_lcd042_esp32c3/board.c @@ -0,0 +1,102 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * Copyright (c) 2021 skieast/Bruce Segal + * + * 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/board/__init__.h" +#include "shared-bindings/displayio/I2CDisplay.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/board.h" +#include "supervisor/shared/board.h" +#include "shared-bindings/board/__init__.h" + +uint8_t display_init_sequence[] = { // SSD1306 + 0xAE, 0, // DISPLAY_OFF + 0x20, 1, 0x00, // Set memory addressing to horizontal mode. + 0x81, 1, 0xcf, // set contrast control + 0xA1, 0, // Column 127 is segment 0 + 0xA6, 0, // Normal display + 0xc8, 0, // Normal display + 0xA8, 1, 0x3f, // Mux ratio is 1/64 + 0xd5, 1, 0x80, // Set divide ratio + 0xd9, 1, 0xf1, // Set pre-charge period + 0xda, 1, 0x12, // Set com configuration + 0xdb, 1, 0x40, // Set vcom configuration + 0x8d, 1, 0x14, // Enable charge pump + 0xAF, 0, // DISPLAY_ON +}; + +void board_init(void) { + busio_i2c_obj_t *i2c = common_hal_board_create_i2c(0); + + // What we would do if it wasn't the shared board I2C: (for reference) + // busio_i2c_obj_t *i2c = &displays[0].i2cdisplay_bus.inline_bus; + // common_hal_busio_i2c_construct(i2c, &pin_GPIO23, &pin_GPIO22, 100000, 0); + // common_hal_busio_i2c_never_reset(i2c); + + displayio_i2cdisplay_obj_t *bus = &displays[0].i2cdisplay_bus; + bus->base.type = &displayio_i2cdisplay_type; + common_hal_displayio_i2cdisplay_construct(bus, + i2c, + 0x3c, + NULL + ); + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 72, // Width + 40, // Height + 28, // column start + 28, // row start + 0, // rotation + 1, // Color depth + true, // grayscale + false, // pixels in byte share row. Only used with 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 + 0x21, // Set column command + 0x22, // Set row command + 44, // Write ram command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // no backlight pin + 0x81, // brightness command + 1.0f, // brightness + true, // single_byte_bounds + true, // data as commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 0); // backlight pwm frequency +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.h b/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.h new file mode 100644 index 000000000000..cae80fa78c8f --- /dev/null +++ b/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Neradoc + * + * 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 "01Space 0.42 OLED ESP32C3" +#define MICROPY_HW_MCU_NAME "ESP32-C3FH4" + +// Status LED +#define MICROPY_HW_NEOPIXEL (&pin_GPIO2) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO6, .sda = &pin_GPIO5}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) + +#define CIRCUITPY_ESP_USB_SERIAL_JTAG (1) diff --git a/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.mk b/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.mk new file mode 100644 index 000000000000..e4467a3bbf22 --- /dev/null +++ b/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x01011ACE +CIRCUITPY_CREATION_ID = 0x00C30042 + +IDF_TARGET = esp32c3 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/01space_lcd042_esp32c3/pins.c b/ports/espressif/boards/01space_lcd042_esp32c3/pins.c new file mode 100644 index 000000000000..a28ffca6d265 --- /dev/null +++ b/ports/espressif/boards/01space_lcd042_esp32c3/pins.c @@ -0,0 +1,68 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Neradoc + * + * 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/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_NEOPIXEL), MP_ROM_PTR(&pin_GPIO2) }, + { 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_SDA), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO6) }, + { 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_BUTTON), MP_ROM_PTR(&pin_GPIO9) }, + { 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_IO20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + { 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_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/01space_lcd042_esp32c3/sdkconfig b/ports/espressif/boards/01space_lcd042_esp32c3/sdkconfig new file mode 100644 index 000000000000..24f7d625ea6a --- /dev/null +++ b/ports/espressif/boards/01space_lcd042_esp32c3/sdkconfig @@ -0,0 +1,6 @@ +# chip is ESP32-C3 FH4 +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="01Space-LCD042-ESP32C3" +# end of LWIP diff --git a/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h index b7f25132171f..4e9e679e5ffb 100644 --- a/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h @@ -47,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("The SW38 button was pressed 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_esp32s2_reverse_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c new file mode 100644 index 000000000000..360c71804c74 --- /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_reverse_tft/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h new file mode 100644 index 000000000000..d170bba4876b --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s2_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-S2 Reverse TFT" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#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_esp32s2_reverse_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk new file mode 100644 index 000000000000..920b748e3da9 --- /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_reverse_tft/pins.c b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/pins.c new file mode 100644 index 000000000000..32718700b194 --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s2_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_esp32s2_reverse_tft/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig new file mode 100644 index 000000000000..f19afafa3d23 --- /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_tftback_nopsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.mk deleted file mode 100644 index b07161cee3be..000000000000 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.mk +++ /dev/null @@ -1,15 +0,0 @@ -USB_VID = 0x239A -USB_PID = 0x80EE -USB_PRODUCT = "Feather ESP32S2 TFT no PSRAM" -USB_MANUFACTURER = "Adafruit" - -IDF_TARGET = esp32s2 - -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 -CIRCUITPY_ESP32_CAMERA = 0 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 5b9c86dcc346..000000000000 --- 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/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk index 4ecf6aa969d3..6d789995321d 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk @@ -9,5 +9,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -OPTIMIZATION_FLAGS = -Os -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk index 3c1cf0d60921..582ed4409c14 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESP32_CAMERA = 0 +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 000000000000..360c71804c74 --- /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 000000000000..cb0237c3e5be --- /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 000000000000..d027443f5679 --- /dev/null +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk @@ -0,0 +1,13 @@ +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 + +CIRCUITPY_ESPCAMERA = 0 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 000000000000..32718700b194 --- /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 000000000000..9a05ab0205e7 --- /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/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk index baff69b1ac88..d801afd4931d 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk @@ -10,5 +10,4 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -OPTIMIZATION_FLAGS = -Os -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk index 221543547cbb..8fafc183731a 100644 --- a/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk @@ -6,4 +6,5 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 + +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk b/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk index 8b08c9402270..7d5c91f154da 100644 --- a/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk @@ -9,7 +9,7 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_PortalBase 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 000000000000..164430c88c92 --- /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 000000000000..0c6132c7ff8b --- /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 000000000000..ecf07e8e7088 --- /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 000000000000..f0d6f3118a25 --- /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 000000000000..6c0168c829de --- /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 0c859225245b..681efc1ceaa6 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,13 +159,14 @@ 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 } 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 ee2bfdb069ec..d941039078d8 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.mk @@ -9,7 +9,7 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_PortalBase diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk index 15dd51e5ffa5..e695bae6350a 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk @@ -13,4 +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_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/sdkconfig b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/sdkconfig index a162344cfb16..9d924272ec4e 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/sdkconfig +++ b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/sdkconfig @@ -5,4 +5,3 @@ CONFIG_ESP32S3_SPIRAM_SUPPORT=n # CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP - diff --git a/ports/espressif/boards/bpi_bit_s2/mpconfigboard.h b/ports/espressif/boards/bpi_bit_s2/mpconfigboard.h index 522532545412..ddb51cdb6d6d 100644 --- a/ports/espressif/boards/bpi_bit_s2/mpconfigboard.h +++ b/ports/espressif/boards/bpi_bit_s2/mpconfigboard.h @@ -30,6 +30,7 @@ #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) diff --git a/ports/espressif/boards/brainboardz_neuron/board.c b/ports/espressif/boards/brainboardz_neuron/board.c new file mode 100755 index 000000000000..3b1f5efd8747 --- /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 000000000000..72cda83c9b53 --- /dev/null +++ b/ports/espressif/boards/brainboardz_neuron/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 "Neuron" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO14) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO13) diff --git a/ports/espressif/boards/brainboardz_neuron/mpconfigboard.mk b/ports/espressif/boards/brainboardz_neuron/mpconfigboard.mk new file mode 100755 index 000000000000..1083b1826464 --- /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 000000000000..5c198c20a707 --- /dev/null +++ b/ports/espressif/boards/brainboardz_neuron/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_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_MISO), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_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_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/brainboardz_neuron/sdkconfig b/ports/espressif/boards/brainboardz_neuron/sdkconfig new file mode 100755 index 000000000000..39bd2cdb4e61 --- /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/mpconfigboard.mk b/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.mk index 3921140b5c79..5862ee119258 100644 --- a/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.mk +++ b/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.mk @@ -6,7 +6,7 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 # Include these Python libraries in firmware FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests diff --git a/ports/espressif/boards/deneyap_kart/board.c b/ports/espressif/boards/deneyap_kart/board.c new file mode 100644 index 000000000000..8c0c8b8b0b57 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart/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/deneyap_kart/mpconfigboard.h b/ports/espressif/boards/deneyap_kart/mpconfigboard.h new file mode 100644 index 000000000000..c2251c3dcb4b --- /dev/null +++ b/ports/espressif/boards/deneyap_kart/mpconfigboard.h @@ -0,0 +1,50 @@ +/* + * 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 "Deneyap Kart" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO4) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO15, .sda = &pin_GPIO4}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO19, .mosi = &pin_GPIO5, .miso = &pin_GPIO18}} + +#define CIRCUITPY_BOARD_UART (0) + +// For entering safe mode, use BUT 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 BUT 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/deneyap_kart/mpconfigboard.mk b/ports/espressif/boards/deneyap_kart/mpconfigboard.mk new file mode 100644 index 000000000000..ea8c9a852229 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x19231923 +CIRCUITPY_CREATION_ID = 0x00320001 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/deneyap_kart/pins.c b/ports/espressif/boards/deneyap_kart/pins.c new file mode 100644 index 000000000000..9408d4470cbf --- /dev/null +++ b/ports/espressif/boards/deneyap_kart/pins.c @@ -0,0 +1,99 @@ +#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, right side, then left side + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_CAMD4), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_CAMD3), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_LEDG), 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_LEDR), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_CAMD5), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_CAMD2), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_CAMD6), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_CAMPC), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GPKEY), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IMUSD), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_LEDB), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IMUSC), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_T5), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_MICC), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_T4), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_MICD), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_T3), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_T2), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_CAMV), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_CAMH), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_CAMD9), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_CAMD8), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_T0), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_CAMXC), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_T1), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_CAMSD), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_CAMSC), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_CAMD7), MP_ROM_PTR(&pin_GPIO26) }, + + { 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/deneyap_kart/sdkconfig b/ports/espressif/boards/deneyap_kart/sdkconfig new file mode 100644 index 000000000000..7ec0461dcf6f --- /dev/null +++ b/ports/espressif/boards/deneyap_kart/sdkconfig @@ -0,0 +1,19 @@ +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=8388608 +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/deneyap_kart_1a/board.c b/ports/espressif/boards/deneyap_kart_1a/board.c new file mode 100644 index 000000000000..8c0c8b8b0b57 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_1a/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/deneyap_kart_1a/mpconfigboard.h b/ports/espressif/boards/deneyap_kart_1a/mpconfigboard.h new file mode 100644 index 000000000000..ba7c216c89d2 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_1a/mpconfigboard.h @@ -0,0 +1,50 @@ +/* + * 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 "Deneyap Kart 1A" +#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_GPIO15, .sda = &pin_GPIO4}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO19, .mosi = &pin_GPIO5, .miso = &pin_GPIO18}} + +#define CIRCUITPY_BOARD_UART (0) + +// For entering safe mode, use BUT 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 BUT 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/deneyap_kart_1a/mpconfigboard.mk b/ports/espressif/boards/deneyap_kart_1a/mpconfigboard.mk new file mode 100644 index 000000000000..976083217ed4 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_1a/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x19231923 +CIRCUITPY_CREATION_ID = 0x00320002 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/deneyap_kart_1a/pins.c b/ports/espressif/boards/deneyap_kart_1a/pins.c new file mode 100644 index 000000000000..c4b1d5184095 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_1a/pins.c @@ -0,0 +1,97 @@ +#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, right side, then left side + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_CAMD4), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_CAMD3), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D2), 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_D4), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_CAMD5), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_CAMD2), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_CAMD6), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_CAMPC), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GPKEY), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SDMI), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_T5), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_RGBLED), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_T4), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SDCS), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_T3), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SDMO), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_T2), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_SDCK), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_CAMV), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_CAMH), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_CAMD9), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_CAMD8), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_T0), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_CAMXC), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_T1), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_CAMSD), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_CAMSC), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_CAMD7), MP_ROM_PTR(&pin_GPIO26) }, + + { 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/deneyap_kart_1a/sdkconfig b/ports/espressif/boards/deneyap_kart_1a/sdkconfig new file mode 100644 index 000000000000..7ec0461dcf6f --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_1a/sdkconfig @@ -0,0 +1,19 @@ +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=8388608 +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/deneyap_kart_1a_v2/board.c b/ports/espressif/boards/deneyap_kart_1a_v2/board.c new file mode 100644 index 000000000000..2287dbaaa722 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_1a_v2/board.c @@ -0,0 +1,32 @@ +/* + * 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" + + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.h b/ports/espressif/boards/deneyap_kart_1a_v2/mpconfigboard.h similarity index 89% rename from ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.h rename to ports/espressif/boards/deneyap_kart_1a_v2/mpconfigboard.h index b4034568c09e..088bfbfd412f 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/mpconfigboard.h +++ b/ports/espressif/boards/deneyap_kart_1a_v2/mpconfigboard.h @@ -26,8 +26,8 @@ // Micropython setup -#define MICROPY_HW_BOARD_NAME "Feather ESP32S2 without PSRAM" -#define MICROPY_HW_MCU_NAME "ESP32S2" +#define MICROPY_HW_BOARD_NAME "Deneyap Kart 1A v2" +#define MICROPY_HW_MCU_NAME "ESP32S3" #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21) @@ -41,4 +41,7 @@ #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) #define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) +#define DEFAULT_UART_BUS_RX (&pin_GPIO38) +#define DEFAULT_UART_BUS_TX (&pin_GPIO39) + #define DOUBLE_TAP_PIN (&pin_GPIO34) diff --git a/ports/espressif/boards/deneyap_kart_1a_v2/mpconfigboard.mk b/ports/espressif/boards/deneyap_kart_1a_v2/mpconfigboard.mk new file mode 100644 index 000000000000..5fa5d4822f8d --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_1a_v2/mpconfigboard.mk @@ -0,0 +1,12 @@ +USB_VID = 0x303A +USB_PID = 0x8148 + +USB_PRODUCT = "Deneyap Kart 1A v2" +USB_MANUFACTURER = "Turkish Technology Team Foundation" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/pins.c b/ports/espressif/boards/deneyap_kart_1a_v2/pins.c similarity index 87% rename from ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/pins.c rename to ports/espressif/boards/deneyap_kart_1a_v2/pins.c index 54b9051d734b..cf4c915e7ff2 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/pins.c +++ b/ports/espressif/boards/deneyap_kart_1a_v2/pins.c @@ -1,25 +1,26 @@ #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_D0), MP_ROM_PTR(&pin_GPIO0) }, - { 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_D3), 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_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_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_I2C_POWER), MP_ROM_PTR(&pin_GPIO7) }, + { 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_A5), MP_ROM_PTR(&pin_GPIO8) }, + { 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_D10), MP_ROM_PTR(&pin_GPIO10) }, @@ -30,46 +31,43 @@ 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_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_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_D38), MP_ROM_PTR(&pin_GPIO38) }, - { 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_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_D39), MP_ROM_PTR(&pin_GPIO39) }, { 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_DISPLAY), MP_ROM_PTR(&displays[0].display)} + { 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/deneyap_kart_1a_v2/sdkconfig b/ports/espressif/boards/deneyap_kart_1a_v2/sdkconfig new file mode 100644 index 000000000000..2cdb172e06d1 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_1a_v2/sdkconfig @@ -0,0 +1,47 @@ +# +# Component config +# +# +# ESP32S3-Specific +# +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_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +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 +# end of SPI RAM config + +# end of ESP32S3-Specific + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="DeneyapKart1A_v2" +# end of LWIP + +# end of Component config diff --git a/ports/espressif/boards/deneyap_kart_g/board.c b/ports/espressif/boards/deneyap_kart_g/board.c new file mode 100644 index 000000000000..9b26fe466d4f --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_g/board.c @@ -0,0 +1,31 @@ +/* + * 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 "shared-bindings/microcontroller/Pin.h" +#include "supervisor/board.h" + + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/deneyap_kart_g/mpconfigboard.h b/ports/espressif/boards/deneyap_kart_g/mpconfigboard.h new file mode 100644 index 000000000000..ce2969bbda04 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_g/mpconfigboard.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * Copyright (c) 2021 skieast/Bruce Segal + * + * 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 "Deneyap Kart G" +#define MICROPY_HW_MCU_NAME "ESP32-C3FN4" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO2, .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}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) + +#define CIRCUITPY_ESP_USB_SERIAL_JTAG (1) diff --git a/ports/espressif/boards/deneyap_kart_g/mpconfigboard.mk b/ports/espressif/boards/deneyap_kart_g/mpconfigboard.mk new file mode 100644 index 000000000000..a470d7a088da --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_g/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x19231923 +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/deneyap_kart_g/pins.c b/ports/espressif/boards/deneyap_kart_g/pins.c new file mode 100644 index 000000000000..c8b7ef499624 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_g/pins.c @@ -0,0 +1,51 @@ +#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_RX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GPKEY), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_BT), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_RGBLED), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_PWM2), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO6) }, + + { 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/deneyap_kart_g/sdkconfig b/ports/espressif/boards/deneyap_kart_g/sdkconfig new file mode 100644 index 000000000000..a988de5fea87 --- /dev/null +++ b/ports/espressif/boards/deneyap_kart_g/sdkconfig @@ -0,0 +1,5 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="DeneyapKartG" +# end of LWIP diff --git a/ports/espressif/boards/deneyap_mini/board.c b/ports/espressif/boards/deneyap_mini/board.c new file mode 100644 index 000000000000..ac27ce4970f0 --- /dev/null +++ b/ports/espressif/boards/deneyap_mini/board.c @@ -0,0 +1,31 @@ +/* + * 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" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/deneyap_mini/mpconfigboard.h b/ports/espressif/boards/deneyap_mini/mpconfigboard.h new file mode 100644 index 000000000000..0e47285238ae --- /dev/null +++ b/ports/espressif/boards/deneyap_mini/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 "Deneyap Mini" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO37, .sda = &pin_GPIO36}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO38, .mosi = &pin_GPIO40, .miso = &pin_GPIO39}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO43, .rx = &pin_GPIO44}} diff --git a/ports/espressif/boards/deneyap_mini/mpconfigboard.mk b/ports/espressif/boards/deneyap_mini/mpconfigboard.mk new file mode 100644 index 000000000000..f6944b7d7ae8 --- /dev/null +++ b/ports/espressif/boards/deneyap_mini/mpconfigboard.mk @@ -0,0 +1,12 @@ +USB_VID = 0x303A +USB_PID = 0x8142 + +USB_PRODUCT = "Deneyap Mini" +USB_MANUFACTURER = "Turkish Technology Team Foundation" + +IDF_TARGET = esp32s2 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/deneyap_mini/pins.c b/ports/espressif/boards/deneyap_mini/pins.c new file mode 100644 index 000000000000..6c0466146711 --- /dev/null +++ b/ports/espressif/boards/deneyap_mini/pins.c @@ -0,0 +1,89 @@ +#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_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_MO), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_MI), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_MC), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_SC), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_SD), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_DA1), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_DA0), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_DAC0), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_BT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GPKEY), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_LEDB), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_LEDG), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_LEDR), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_T0), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_T1), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_T2), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_T3), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_T4), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_T5), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO16) }, + + { 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/deneyap_mini/sdkconfig b/ports/espressif/boards/deneyap_mini/sdkconfig new file mode 100644 index 000000000000..7dfaf3052cc0 --- /dev/null +++ b/ports/espressif/boards/deneyap_mini/sdkconfig @@ -0,0 +1,4 @@ +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="DeneyapMini" +# end of LWIP diff --git a/ports/espressif/boards/deneyap_mini_v2/board.c b/ports/espressif/boards/deneyap_mini_v2/board.c new file mode 100644 index 000000000000..2287dbaaa722 --- /dev/null +++ b/ports/espressif/boards/deneyap_mini_v2/board.c @@ -0,0 +1,32 @@ +/* + * 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" + + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/deneyap_mini_v2/mpconfigboard.h b/ports/espressif/boards/deneyap_mini_v2/mpconfigboard.h new file mode 100644 index 000000000000..be6cbd86b7e4 --- /dev/null +++ b/ports/espressif/boards/deneyap_mini_v2/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 "Deneyap Mini v2" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO37, .sda = &pin_GPIO36}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO38, .mosi = &pin_GPIO40, .miso = &pin_GPIO39}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO43, .rx = &pin_GPIO44}} diff --git a/ports/espressif/boards/deneyap_mini_v2/mpconfigboard.mk b/ports/espressif/boards/deneyap_mini_v2/mpconfigboard.mk new file mode 100644 index 000000000000..fa9c6b40ea50 --- /dev/null +++ b/ports/espressif/boards/deneyap_mini_v2/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x303A +USB_PID = 0x8145 + +USB_PRODUCT = "Deneyap Mini v2" +USB_MANUFACTURER = "Turkish Technology Team Foundation" + +IDF_TARGET = esp32s2 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/deneyap_mini_v2/pins.c b/ports/espressif/boards/deneyap_mini_v2/pins.c new file mode 100644 index 000000000000..ab3250769d11 --- /dev/null +++ b/ports/espressif/boards/deneyap_mini_v2/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_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_MO), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_MI), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_MC), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_SC), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_SD), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_DA1), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_DA0), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_DAC0), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GPKEY), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_RGBLED), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_T0), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_T1), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_T2), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_T3), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_T4), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_T5), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_T6), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO16) }, + + { 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/deneyap_mini_v2/sdkconfig b/ports/espressif/boards/deneyap_mini_v2/sdkconfig new file mode 100644 index 000000000000..613b744ef22d --- /dev/null +++ b/ports/espressif/boards/deneyap_mini_v2/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="DeneyapMini_v2" +# end of LWIP diff --git a/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk b/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk index 7aa352e16e59..23f905dfdf02 100644 --- a/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk +++ b/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk @@ -6,4 +6,4 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +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 index 78c37897ac71..8381fa064471 100644 --- a/ports/espressif/boards/doit_esp32_devkit_v1/pins.c +++ b/ports/espressif/boards/doit_esp32_devkit_v1/pins.c @@ -3,9 +3,10 @@ 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 + // External pins are in silkscreen order, from top to bottom, left 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_D4), MP_ROM_PTR(&pin_GPIO4)}, {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)}, @@ -16,6 +17,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { {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)}, + // External pins are in silkscreen order, from top to bottom, right side {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)}, @@ -26,6 +28,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { {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_VN), MP_ROM_PTR(&pin_GPIO39)}, + {MP_ROM_QSTR(MP_QSTR_VP), MP_ROM_PTR(&pin_GPIO36)}, {MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2)}, @@ -39,6 +43,11 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { {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_D1), MP_ROM_PTR(&pin_GPIO1)}, + {MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3)}, + {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_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)} diff --git a/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk b/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk index 67e88a1639ad..73acab519c85 100644 --- a/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk +++ b/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk @@ -10,4 +10,4 @@ CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32_eye/sdkconfig b/ports/espressif/boards/espressif_esp32_eye/sdkconfig index a73d92e0a232..26db1e808768 100644 --- a/ports/espressif/boards/espressif_esp32_eye/sdkconfig +++ b/ports/espressif/boards/espressif_esp32_eye/sdkconfig @@ -69,4 +69,3 @@ CONFIG_CAMERA_DMA_BUFFER_SIZE_MAX=32768 # 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 000000000000..8c0c8b8b0b57 --- /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 000000000000..7835e93f2127 --- /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 000000000000..e9fcd24e61d6 --- /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 000000000000..afef90e48096 --- /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 000000000000..4b2981ba62a9 --- /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_esp32s2_devkitc_1_n4/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk index 31e79b24255a..d92eff48d03d 100644 --- a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk index 7ffb076348be..5a2a4794bd8e 100644 --- a/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk @@ -9,4 +9,4 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 16MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk index f4a746026a6b..a4bd29fa522d 100644 --- a/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk @@ -9,4 +9,4 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 16MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 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 000000000000..ff9418ec86cb --- /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 000000000000..26410bb210cd --- /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 000000000000..78423955bb6f --- /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 000000000000..919deca8b48f --- /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 000000000000..f915462e113d --- /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/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk index 7ae39254b4b0..6f56013e09a3 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 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 ac58db8aedf7..55ad75473605 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 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 dd8403f77928..868e29bf60e2 100644 --- a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk b/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk index 4748b1c306b3..03feef98cea9 100644 --- a/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk b/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk index 193a867fb234..76661511e2b8 100644 --- a/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk b/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk index a7d4d9fb7ce2..801bd8b508e3 100644 --- a/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk +++ b/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk b/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk index bbcbfde29aae..b57f74f23d9e 100644 --- a/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk +++ b/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h b/ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h index 7de90b0ae89f..49d49f242745 100644 --- a/ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +++ b/ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h @@ -35,7 +35,7 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) // Explanation of how a user got into safe mode -#define BOARD_USER_SAFE_MODE_ACTION translate("The VOLUME button was pressed at start up.\n") +#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) diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/board.c b/ports/espressif/boards/lilygo_tembed_esp32s3/board.c similarity index 71% rename from ports/espressif/boards/adafruit_feather_esp32s2_tftback_nopsram/board.c rename to ports/espressif/boards/lilygo_tembed_esp32s3/board.c index e0edec2fa2a6..ed49eb504cba 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,7 +78,7 @@ 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 false, // single_byte_bounds @@ -100,9 +86,14 @@ void board_init(void) { 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 } // 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 000000000000..307c103e33a3 --- /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 000000000000..2b8f67b56051 --- /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 000000000000..94c57f162f54 --- /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 000000000000..f508f4a67c3f --- /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_t8_esp32_s2_wroom/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/mpconfigboard.mk index b5cc1bae7c21..3244d3886961 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 @@ -8,4 +8,4 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c new file mode 100644 index 000000000000..630de0b63f93 --- /dev/null +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c @@ -0,0 +1,114 @@ +/* + * 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 LilyGO example app +uint8_t display_init_sequence[] = { + 0x01, DELAY, 0x96, // _SWRESET and Delay 150ms + 0x11, DELAY, 0xFF, // _SLPOUT and Delay 500ms + 0x3A, DELAY | 1, 0x55, 0x0A, // _COLMOD and Delay 10ms + 0x36, 0x01, 0x08, // _MADCTL + 0x21, DELAY, 0x0A, // _INVON Hack and Delay 10ms + 0x13, DELAY, 0x0A, // _NORON and Delay 10ms + 0x36, 0x01, 0xC0, // _MADCTL + 0x29, DELAY, 0xFF, // _DISPON and Delay 500ms +}; + +static void display_init(void) { + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + + common_hal_busio_spi_construct( + spi, + &pin_GPIO18, // CLK + &pin_GPIO19, // 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_GPIO16, // DC + &pin_GPIO5, // CS + &pin_GPIO23, // RST + 24000000, // baudrate (default from the driver) + // 40000000, + 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) + 53, // column start + 40, // 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_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_GPIO4, // 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) { + // Display + display_init(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.h b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.h new file mode 100644 index 000000000000..39febafb6a32 --- /dev/null +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.h @@ -0,0 +1,34 @@ +/* + * 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 TTGO T-DISPLAY v1.1" +#define MICROPY_HW_MCU_NAME "ESP32" + +// 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/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.mk new file mode 100644 index 000000000000..dd177ec1c900 --- /dev/null +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0xC3C30000 +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/lilygo_ttgo_tdisplay_esp32_16m/pins.c b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/pins.c new file mode 100644 index 000000000000..5a72b0f416bd --- /dev/null +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/pins.c @@ -0,0 +1,41 @@ +#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_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { 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_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { 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_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_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + + // 1.14 inch LCD ST7789 + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BCKL), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D_C), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + + // Battery Sense + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO34) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/sdkconfig b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/sdkconfig new file mode 100644 index 000000000000..55052e98cab5 --- /dev/null +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/sdkconfig @@ -0,0 +1,5 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="TTGO-TDISPLAY" +# end of LWIP diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/board.c b/ports/espressif/boards/lilygo_twatch_2020_v3/board.c new file mode 100644 index 000000000000..6a60ada6b04f --- /dev/null +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/board.c @@ -0,0 +1,161 @@ +/* + * 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 for ST7789 (works in python) +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 0x96, + // sleep out + 0x11, 0 | DELAY, 0xFF, + 0x3A, 1 | DELAY, 0x55, 10, + 0x36, 1, 0x08, + 0x21, 0 | DELAY, 10, + 0x13, 0 | DELAY, 10, + 0x36, 1, 0xC0, + // display on + 0x29, 0 | DELAY, 255, +}; + +static void display_init(void) { + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + + common_hal_busio_spi_construct( + spi, + &pin_GPIO18, // CLK + &pin_GPIO19, // 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_GPIO27, // DC + &pin_GPIO5, // CS + NULL, // RST + 24000000, // 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 + 80, // 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_GPIO15, // 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 + 5000 // backlight pwm frequency + ); +} + +/* +#define APX202_ADDRESS (0x35) +#define AXP202_LDO2 (2) +#define AXP202_ON (1) +#define AXP202_OFF (0) +#define AXP202_DCDC3 (1) +#define AXP202_IC_TYPE (0x03) +#define AXP202_LDO234_DC23_CTL (0x12) +#define AXP_PASS (1) +#define AXP_FAIL (-1) +#define AXP202_CHIP_ID (0x41) +#define AXP192_CHIP_ID (0x03) +#define FORCED_OPEN_DCDC3(x) (x |= (AXP202_ON << AXP202_DCDC3)) + +static void backlight_init(void) { + // Turn LDO2 on for display + busio_i2c_obj_t *i2c = common_hal_board_create_i2c(0); + uint8_t data = 0; + uint8_t outputReg = 0; + uint8_t read = 0; + // lock + // _readByte(AXP202_LDO234_DC23_CTL, 1, &outputReg) + // time.sleep(0.001) + // _readByte(AXP202_LDO234_DC23_CTL, 1, &data) + // time.sleep(0.001) + // data |= 1 << AXP202_LDO2 + // FORCED_OPEN_DCDC3(data) + // _writeByte(AXP202_LDO234_DC23_CTL, 1, &data) + // time.sleep(0.001) + // unlock +} +*/ + +void board_init(void) { + // Display + display_init(); + // backlight_init(); +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + if (pin_number == MOTOR_PIN) { + // no motor + gpio_set_direction(pin_number, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(pin_number, false); + return true; + } + return false; +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.h b/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.h new file mode 100644 index 000000000000..bf65b394f720 --- /dev/null +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.h @@ -0,0 +1,44 @@ +/* + * 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 "Lilygo T-watch 2020 V3" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MOTOR_PIN (4) +#define MICROPY_HW_LED_STATUS (&pin_GPIO4) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}, \ + {.scl = &pin_GPIO32, .sda = &pin_GPIO23}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO19, .miso = NULL}} + +// 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/lilygo_twatch_2020_v3/mpconfigboard.mk b/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.mk new file mode 100644 index 000000000000..9d6c8dc25b98 --- /dev/null +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0xC3C30000 +CIRCUITPY_CREATION_ID = 0x00320001 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/pins.c b/ports/espressif/boards/lilygo_twatch_2020_v3/pins.c new file mode 100644 index 000000000000..8dd20b1a6998 --- /dev/null +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/pins.c @@ -0,0 +1,54 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(touch_i2c, i2c, 1) + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // buzz buzz + { MP_ROM_QSTR(MP_QSTR_VIBRATE), MP_ROM_PTR(&pin_GPIO4) }, + + // I2S out + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_I2S_OUT), MP_ROM_PTR(&pin_GPIO33) }, + + // PDM in + { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_GPIO2) }, + + // IR send + { MP_ROM_QSTR(MP_QSTR_IR_LED), MP_ROM_PTR(&pin_GPIO13) }, + + // main I2C port, for the AXP202, and 2 others + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // interrupt pins for sensors + { MP_ROM_QSTR(MP_QSTR_BMA423_INT), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_PCF8563_INT), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_AXP202_INT), MP_ROM_PTR(&pin_GPIO35) }, + + // I2C port for the FT6336 touch sensor + { MP_ROM_QSTR(MP_QSTR_TOUCH_SCL), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_SDA), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_RST), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_INT), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_TOUCH_I2C), MP_ROM_PTR(&board_touch_i2c_obj) }, + + // LCD display + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BRIGHTNESS), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_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/lilygo_twatch_2020_v3/sdkconfig b/ports/espressif/boards/lilygo_twatch_2020_v3/sdkconfig new file mode 100644 index 000000000000..89647ab5a148 --- /dev/null +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/sdkconfig @@ -0,0 +1,31 @@ +# SPI RAM config +# +CONFIG_ESP32_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 +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_MEMTEST=y +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=1 +CONFIG_ESP_CONSOLE_UART_RX_GPIO=3 +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/lolin_s2_mini/pins.c b/ports/espressif/boards/lolin_s2_mini/pins.c index a4b18c4e9b2b..ee81e00d9e5a 100644 --- a/ports/espressif/boards/lolin_s2_mini/pins.c +++ b/ports/espressif/boards/lolin_s2_mini/pins.c @@ -4,7 +4,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS // S2 Mini Board bottom, right, top-bottom - // GPIO0-GPIO14: broken out as a bloc on ESP32-S2FN4R2 SoC + // GPIO0-GPIO14: broken out as a block on ESP32-S2FN4R2 SoC // mpconfigboard.h: GPIO0: CIRCUITPY_BOOT_BUTTON { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, // RTC_GPIO0,GPIO0 @@ -57,7 +57,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { // skip GPIO22-GPIO25: not broken out on ESP32-S2FN4R2 SoC // skip GPIO26-GPIO32: SPI Flash & RAM, not broken out on S2 Mini (internal to ESP32-S2FN4R2 SoC?) - // GPIO33-GPIO40: broken out as a bloc on ESP32-S2FN4R2 SoC, last 2 half of JTAG + // GPIO33-GPIO40: broken out as a block on ESP32-S2FN4R2 SoC, last 2 half of JTAG { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) },// SPIIO4,GPIO33,FSPIHD { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO33) },// def from Wemos MP { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO33) },// D1 mini pin D2 GPIO4 diff --git a/ports/espressif/boards/lolin_s2_pico/board.c b/ports/espressif/boards/lolin_s2_pico/board.c index b3c8cb41914e..e2c24bb22acf 100644 --- a/ports/espressif/boards/lolin_s2_pico/board.c +++ b/ports/espressif/boards/lolin_s2_pico/board.c @@ -27,8 +27,76 @@ #include "supervisor/board.h" #include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/displayio/I2CDisplay.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/busio/I2C.h" +#include "supervisor/shared/board.h" +#include "shared-bindings/board/__init__.h" + +uint8_t display_init_sequence[] = { // SSD1306 + 0xAE, 0, // DISPLAY_OFF + 0x20, 1, 0x00, // Set memory addressing to horizontal mode. + 0x81, 1, 0xcf, // set contrast control + 0xA1, 0, // Column 127 is segment 0 + 0xA6, 0, // Normal display + 0xc8, 0, // Normal display + 0xA8, 1, 0x1f, // Mux ratio is height-1 + 0xd5, 1, 0x80, // Set divide ratio + 0xd9, 1, 0xf1, // Set pre-charge period + 0xda, 1, 0x02, // Set com configuration to 2 if height is 32 and width not 64 + 0xdb, 1, 0x40, // Set vcom configuration + 0x8d, 1, 0x14, // Enable charge pump + 0xAF, 0, // DISPLAY_ON +}; + +static void display_init(void) { + busio_i2c_obj_t *i2c = common_hal_board_create_i2c(0); + + displayio_i2cdisplay_obj_t *bus = &displays[0].i2cdisplay_bus; + bus->base.type = &displayio_i2cdisplay_type; + common_hal_displayio_i2cdisplay_construct(bus, + i2c, + 0x3c, + &pin_GPIO18 // reset + ); + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 128, // Width + 32, // Height + 0, // column start + 0, // row start + 0, // rotation + 1, // Color depth + true, // grayscale + false, // pixels in byte share row. Only used with 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 + 0x21, // Set column command + 0x22, // Set row command + 44, // Write ram command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // no backlight pin + 0x81, // brightness command + 1.0f, // brightness + true, // single_byte_bounds + true, // data as commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 0); // backlight pwm frequency +} void board_init(void) { + // init display + display_init(); // Debug UART #ifdef DEBUG common_hal_never_reset_pin(&pin_GPIO43); diff --git a/ports/espressif/boards/lolin_s2_pico/pins.c b/ports/espressif/boards/lolin_s2_pico/pins.c index 5c3f1f4db535..1afd508f033e 100644 --- a/ports/espressif/boards/lolin_s2_pico/pins.c +++ b/ports/espressif/boards/lolin_s2_pico/pins.c @@ -1,4 +1,5 @@ #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 @@ -52,5 +53,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, // Not labelled on booard, on schematic { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) },// Not labelled on booard, on schematic { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_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/lolin_s3/mpconfigboard.mk b/ports/espressif/boards/lolin_s3/mpconfigboard.mk index b0b146b03c81..56b42a419c3d 100644 --- a/ports/espressif/boards/lolin_s3/mpconfigboard.mk +++ b/ports/espressif/boards/lolin_s3/mpconfigboard.mk @@ -9,5 +9,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 16MB -OPTIMIZATION_FLAGS = -Os -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h b/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h index 7d672678975d..426d5c3bf7b5 100644 --- a/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +++ b/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h @@ -38,7 +38,7 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) // Explanation of how a user got into safe mode -#define BOARD_USER_SAFE_MODE_ACTION translate("The central button was pressed at start up.\n") +#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) diff --git a/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk index 663ceaad8132..63ed093f0aba 100644 --- a/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk @@ -7,4 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h b/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h index dfa12b53b011..9ec15fa0f2ed 100644 --- a/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +++ b/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h @@ -42,7 +42,7 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) // Explanation of how a user got into safe mode -#define BOARD_USER_SAFE_MODE_ACTION translate("The central button was pressed at start up.\n") +#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) diff --git a/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk index 6adf65d2bcb1..e1ba503b8c3a 100644 --- a/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk @@ -7,4 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h b/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h index 926b7efbc4e9..77eba4ab922c 100644 --- a/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +++ b/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h @@ -42,7 +42,7 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) // Explanation of how a user got into safe mode -#define BOARD_USER_SAFE_MODE_ACTION translate("The central button was pressed at start up.\n") +#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) diff --git a/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk index c34fa9d836fa..ecf931958457 100644 --- a/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk @@ -7,4 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_u/mpconfigboard.h b/ports/espressif/boards/m5stack_atom_u/mpconfigboard.h index b3b0a650ab7a..b5b21011348d 100644 --- a/ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +++ b/ports/espressif/boards/m5stack_atom_u/mpconfigboard.h @@ -41,7 +41,7 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) // Explanation of how a user got into safe mode -#define BOARD_USER_SAFE_MODE_ACTION translate("The central button was pressed at start up.\n") +#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) diff --git a/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk index 18bb6d3dc052..f27167111304 100644 --- a/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk @@ -7,4 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atoms3_lite/board.c b/ports/espressif/boards/m5stack_atoms3_lite/board.c new file mode 100644 index 000000000000..164430c88c92 --- /dev/null +++ b/ports/espressif/boards/m5stack_atoms3_lite/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_atoms3_lite/mpconfigboard.h b/ports/espressif/boards/m5stack_atoms3_lite/mpconfigboard.h new file mode 100644 index 000000000000..43dd43634552 --- /dev/null +++ b/ports/espressif/boards/m5stack_atoms3_lite/mpconfigboard.h @@ -0,0 +1,36 @@ +/* + * 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 "M5Stack AtomS3 Lite" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO35) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO39, .sda = &pin_GPIO38}, \ + {.scl = &pin_GPIO1, .sda = &pin_GPIO2}} diff --git a/ports/espressif/boards/m5stack_atoms3_lite/mpconfigboard.mk b/ports/espressif/boards/m5stack_atoms3_lite/mpconfigboard.mk new file mode 100644 index 000000000000..8bb5ab76d856 --- /dev/null +++ b/ports/espressif/boards/m5stack_atoms3_lite/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x303A +USB_PID = 0x815F +USB_PRODUCT = "M5Stack AtomS3 Lite" +USB_MANUFACTURER = "M5Stack" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atoms3_lite/pins.c b/ports/espressif/boards/m5stack_atoms3_lite/pins.c new file mode 100644 index 000000000000..052c15e69fad --- /dev/null +++ b/ports/espressif/boards/m5stack_atoms3_lite/pins.c @@ -0,0 +1,42 @@ +#include "shared-bindings/board/__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 + + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), 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_PORTA_SDA), 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_A4), 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_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { 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_A7), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + + + { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_BTN), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_IR_LED), MP_ROM_PTR(&pin_GPIO4) }, + + { 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_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_atoms3_lite/sdkconfig b/ports/espressif/boards/m5stack_atoms3_lite/sdkconfig new file mode 100644 index 000000000000..9d924272ec4e --- /dev/null +++ b/ports/espressif/boards/m5stack_atoms3_lite/sdkconfig @@ -0,0 +1,7 @@ +CONFIG_ESP32S3_SPIRAM_SUPPORT=n + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" +# end of LWIP diff --git a/ports/espressif/boards/m5stack_core_basic/mpconfigboard.h b/ports/espressif/boards/m5stack_core_basic/mpconfigboard.h index c974c6487466..0135b66661e9 100755 --- a/ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +++ b/ports/espressif/boards/m5stack_core_basic/mpconfigboard.h @@ -42,7 +42,7 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) // Explanation of how a user got into safe mode -#define BOARD_USER_SAFE_MODE_ACTION translate("Button A was pressed at start up.\n") +#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) diff --git a/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk b/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk index 1abf68428cfb..dedcde81e63b 100644 --- a/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk @@ -6,4 +6,4 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 16MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_core_fire/mpconfigboard.h b/ports/espressif/boards/m5stack_core_fire/mpconfigboard.h index f56a8fe901e1..2073473e1aa2 100755 --- a/ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +++ b/ports/espressif/boards/m5stack_core_fire/mpconfigboard.h @@ -43,7 +43,7 @@ #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO39) // Explanation of how a user got into safe mode -#define BOARD_USER_SAFE_MODE_ACTION translate("Button A was pressed at start up.\n") +#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) diff --git a/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk b/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk index 7a66a977b10c..82e462012c7d 100644 --- a/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk @@ -6,4 +6,4 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 16MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_stick_c/axp192.h b/ports/espressif/boards/m5stack_stick_c/axp192.h new file mode 100755 index 000000000000..aa8f6367a7d2 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c/axp192.h @@ -0,0 +1,263 @@ +/* + * + * 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_APS_LOW_BATT_LEVEL_1 0x3A +#define AXP192_APS_LOW_BATT_LEVEL_2 0x3B +#define AXP192_APS_LOW_BATT_VOLTAGE_3_695V 0b10010100 +#define AXP192_APS_LOW_BATT_VOLTAGE_3_600V 0b10000011 + +#define AXP192_IRQ_1_ENABLE 0x40 +#define AXP192_IRQ_2_ENABLE 0x41 +#define AXP192_IRQ_3_ENABLE 0x42 +#define AXP192_IRQ_3_PEK_SHORT_PRESS 0b00000010 +#define AXP192_IRQ_3_PEK_LONG_PRESS 0b00000001 +#define AXP192_IRQ_4_ENABLE 0x43 +#define AXP192_IRQ_4_LOW_VOLTAGE_WARNING 0b00000001 +#define AXP192_IRQ_5_ENABLE 0x4a + +#define AXP192_IRQ_X_DISABLE_ALL 0b00000000 + +#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_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 100755 index 000000000000..2f993d4a05f3 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c/board.c @@ -0,0 +1,361 @@ +/* + * 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: 3Ah + // APS Low battery warning level 1: 3.695V + write_buf[0] = AXP192_APS_LOW_BATT_LEVEL_1; + write_buf[1] = AXP192_APS_LOW_BATT_VOLTAGE_3_695V; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 3Bh + // APS Low battery warning level 2: 3.600V + write_buf[0] = AXP192_APS_LOW_BATT_LEVEL_2; + write_buf[1] = AXP192_APS_LOW_BATT_VOLTAGE_3_600V; + 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 CTRL_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: 26h + // 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; + } + + // Reg: 40h + // IRQ enable control register 1 + write_buf[0] = AXP192_IRQ_1_ENABLE; + write_buf[1] = AXP192_IRQ_X_DISABLE_ALL; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 41h + // IRQ enable control register 2 + write_buf[0] = AXP192_IRQ_2_ENABLE; + write_buf[1] = AXP192_IRQ_X_DISABLE_ALL; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 42h + // IRQ enable control register 3 + // Enable power on key short and long press interrupt + write_buf[0] = AXP192_IRQ_2_ENABLE; + write_buf[1] = AXP192_IRQ_3_PEK_SHORT_PRESS | + AXP192_IRQ_3_PEK_LONG_PRESS; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 43h + // IRQ enable control register 4 + // Enable power on key short and long press interrupt + write_buf[0] = AXP192_IRQ_2_ENABLE; + write_buf[1] = AXP192_IRQ_4_LOW_VOLTAGE_WARNING; + rc = common_hal_busio_i2c_write(internal_i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 44h + // IRQ enable control register 5 + write_buf[0] = AXP192_IRQ_2_ENABLE; + write_buf[1] = AXP192_IRQ_X_DISABLE_ALL; + 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 the display"); + return; + } +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Set IR led gpio high to prevent power drain from the led + if (pin_number == 9) { + gpio_set_direction(pin_number, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(pin_number, true); + return true; + } + return false; +} 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 000000000000..1614a9ddada8 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c/mpconfigboard.h @@ -0,0 +1,47 @@ +/* + * 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 MICROPY_HW_LED_STATUS_INVERTED (1) + +#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 000000000000..5910605915f6 --- /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 000000000000..5c8b89761865 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c/pins.c @@ -0,0 +1,59 @@ +#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) }, + + // pmu AXP192 + { MP_ROM_QSTR(MP_QSTR_PMU_N_VBUSEN), MP_ROM_PTR(&pin_GPIO27) }, + + // 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 000000000000..7ec6f90c157e --- /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/espressif/boards/maker_badge/mpconfigboard.mk b/ports/espressif/boards/maker_badge/mpconfigboard.mk index 75d713d9044d..687f91ad603c 100644 --- a/ports/espressif/boards/maker_badge/mpconfigboard.mk +++ b/ports/espressif/boards/maker_badge/mpconfigboard.mk @@ -3,7 +3,7 @@ USB_PID = 0x2030 USB_PRODUCT = "Maker badge" USB_MANUFACTURER = "Czech maker" -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=40m diff --git a/ports/espressif/boards/microdev_micro_c3/pins.c b/ports/espressif/boards/microdev_micro_c3/pins.c index 240966404f53..ab3abdb39ca4 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/mixgo_ce_serial/mpconfigboard.mk b/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk index 490675e4671f..1e4ed0b859a9 100644 --- a/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk +++ b/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk @@ -9,9 +9,9 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +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_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk b/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk index 5c6649ce6eec..e9cd0c6d4a1c 100644 --- a/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk +++ b/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk @@ -9,9 +9,9 @@ CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +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_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk b/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk index abd2fc12e989..18dd435c539a 100644 --- a/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk +++ b/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk b/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk index f2a622bc0835..04fde1e56202 100644 --- a/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk b/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk index 68722982ab84..d7325cf44e1e 100644 --- a/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk +++ b/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk @@ -3,6 +3,6 @@ CIRCUITPY_CREATION_ID = 0x00C30001 IDF_TARGET = esp32c3 -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/smartbeedesigns_bee_motion_s3/mpconfigboard.mk b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.mk index 8a5fab0c1a38..7e58f9979d74 100644 --- a/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.mk +++ b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.mk @@ -11,4 +11,4 @@ CIRCUITPY_ESP_FLASH_SIZE = 8MB FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk b/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk index 25a1db15ec8a..9d0974517d46 100644 --- a/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk +++ b/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk @@ -11,4 +11,4 @@ CIRCUITPY_ESP_FLASH_SIZE = 8MB FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk b/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk index 316332020871..e13c654aa661 100644 --- a/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk @@ -8,4 +8,4 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = dio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c index 070e3418da66..359263df81ac 100644 --- a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c @@ -51,7 +51,7 @@ uint8_t display_init_sequence[] = { 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, + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 cycle 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 diff --git a/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h index 6a10db6061cf..bb8b00f327aa 100644 --- a/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h +++ b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h @@ -30,3 +30,14 @@ #define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_LED_STATUS (&pin_GPIO9) +#define MICROPY_HW_LED_STATUS_INVERTED (1) + +#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_esp32s2_pico/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.mk index 70f4bf008f15..2db911fb26d6 100644 --- a/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.mk +++ b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.mk @@ -5,6 +5,6 @@ USB_MANUFACTURER = "Waveshare Electronics" IDF_TARGET = esp32s2 -CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig b/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig index e1635f6d1785..c81fbb4837ef 100644 --- a/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig +++ b/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig @@ -1,10 +1,13 @@ +# +# 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_SPEED_80M=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 diff --git a/ports/espressif/boards/yd_esp32_s3_n16r8/board.c b/ports/espressif/boards/yd_esp32_s3_n16r8/board.c new file mode 100644 index 000000000000..e218345f5916 --- /dev/null +++ b/ports/espressif/boards/yd_esp32_s3_n16r8/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Bill Sideris, independently providing these changes. + * + * 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/yd_esp32_s3_n16r8/mpconfigboard.h b/ports/espressif/boards/yd_esp32_s3_n16r8/mpconfigboard.h new file mode 100644 index 000000000000..4a0ea02809dd --- /dev/null +++ b/ports/espressif/boards/yd_esp32_s3_n16r8/mpconfigboard.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Bill Sideris, independently providing these changes. + * + * 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 "VCC-GND YD-ESP32-S3 (N16R8)" +#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) diff --git a/ports/espressif/boards/yd_esp32_s3_n16r8/mpconfigboard.mk b/ports/espressif/boards/yd_esp32_s3_n16r8/mpconfigboard.mk new file mode 100644 index 000000000000..2120ba97cb74 --- /dev/null +++ b/ports/espressif/boards/yd_esp32_s3_n16r8/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x303A +USB_PID = 0x8166 +USB_PRODUCT = "YD-ESP32-S3" +USB_MANUFACTURER = "VCC-GND" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/yd_esp32_s3_n16r8/pins.c b/ports/espressif/boards/yd_esp32_s3_n16r8/pins.c new file mode 100644 index 000000000000..46a579fc2058 --- /dev/null +++ b/ports/espressif/boards/yd_esp32_s3_n16r8/pins.c @@ -0,0 +1,60 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Left header, module facing up. + { 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_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_GPIO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GPIO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GPIO46), MP_ROM_PTR(&pin_GPIO46) }, + { 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) }, + + + // Right header, module facing up. + { MP_ROM_QSTR(MP_QSTR_GPIO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_GPIO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { 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_GPIO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GPIO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_GPIO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_GPIO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_GPIO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_GPIO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_GPIO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_GPIO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_GPIO35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_GPIO45), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_ROM_QSTR(MP_QSTR_GPIO48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, + // For the neopixel to work, please bridge the "RGB" pad + // or use external neopixels. + + { MP_ROM_QSTR(MP_QSTR_GPIO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_GPIO21), MP_ROM_PTR(&pin_GPIO21) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/yd_esp32_s3_n16r8/sdkconfig b/ports/espressif/boards/yd_esp32_s3_n16r8/sdkconfig new file mode 100644 index 000000000000..5aff7f49b15c --- /dev/null +++ b/ports/espressif/boards/yd_esp32_s3_n16r8/sdkconfig @@ -0,0 +1,16 @@ +CONFIG_ESP32S3_SPIRAM_SUPPORT=y + +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y + +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 + +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_USE_MEMMAP=y +CONFIG_SPIRAM_MEMTEST=y + +CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" diff --git a/ports/espressif/boards/yd_esp32_s3_n8r8/board.c b/ports/espressif/boards/yd_esp32_s3_n8r8/board.c new file mode 100644 index 000000000000..e218345f5916 --- /dev/null +++ b/ports/espressif/boards/yd_esp32_s3_n8r8/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Bill Sideris, independently providing these changes. + * + * 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/yd_esp32_s3_n8r8/mpconfigboard.h b/ports/espressif/boards/yd_esp32_s3_n8r8/mpconfigboard.h new file mode 100644 index 000000000000..349931740dd7 --- /dev/null +++ b/ports/espressif/boards/yd_esp32_s3_n8r8/mpconfigboard.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Bill Sideris, independently providing these changes. + * + * 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 "VCC-GND YD-ESP32-S3 (N8R8)" +#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) diff --git a/ports/espressif/boards/yd_esp32_s3_n8r8/mpconfigboard.mk b/ports/espressif/boards/yd_esp32_s3_n8r8/mpconfigboard.mk new file mode 100644 index 000000000000..766e71dc2d89 --- /dev/null +++ b/ports/espressif/boards/yd_esp32_s3_n8r8/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x303A +USB_PID = 0x8166 +USB_PRODUCT = "YD-ESP32-S3" +USB_MANUFACTURER = "VCC-GND" + +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/yd_esp32_s3_n8r8/pins.c b/ports/espressif/boards/yd_esp32_s3_n8r8/pins.c new file mode 100644 index 000000000000..46a579fc2058 --- /dev/null +++ b/ports/espressif/boards/yd_esp32_s3_n8r8/pins.c @@ -0,0 +1,60 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Left header, module facing up. + { 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_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_GPIO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GPIO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GPIO46), MP_ROM_PTR(&pin_GPIO46) }, + { 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) }, + + + // Right header, module facing up. + { MP_ROM_QSTR(MP_QSTR_GPIO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_GPIO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { 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_GPIO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GPIO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_GPIO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_GPIO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_GPIO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_GPIO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_GPIO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_GPIO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_GPIO35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_GPIO45), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_ROM_QSTR(MP_QSTR_GPIO48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, + // For the neopixel to work, please bridge the "RGB" pad + // or use external neopixels. + + { MP_ROM_QSTR(MP_QSTR_GPIO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_GPIO21), MP_ROM_PTR(&pin_GPIO21) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/yd_esp32_s3_n8r8/sdkconfig b/ports/espressif/boards/yd_esp32_s3_n8r8/sdkconfig new file mode 100644 index 000000000000..5aff7f49b15c --- /dev/null +++ b/ports/espressif/boards/yd_esp32_s3_n8r8/sdkconfig @@ -0,0 +1,16 @@ +CONFIG_ESP32S3_SPIRAM_SUPPORT=y + +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y + +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 + +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_USE_MEMMAP=y +CONFIG_SPIRAM_MEMTEST=y + +CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" diff --git a/ports/espressif/common-hal/_bleio/Adapter.c b/ports/espressif/common-hal/_bleio/Adapter.c index 3239c501cc6e..01adae3adb1b 100644 --- a/ports/espressif/common-hal/_bleio/Adapter.c +++ b/ports/espressif/common-hal/_bleio/Adapter.c @@ -221,7 +221,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active) { if (self->scan_results != NULL) { if (!shared_module_bleio_scanresults_get_done(self->scan_results)) { - mp_raise_bleio_BluetoothError(translate("Scan already in progess. Stop with stop_scan.")); + mp_raise_bleio_BluetoothError(translate("Scan already in progress. Stop with stop_scan.")); } self->scan_results = NULL; } diff --git a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c index 48be3abd67c9..cfc6018708ed 100644 --- a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c +++ b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c @@ -27,17 +27,20 @@ #include #include -#include "shared/runtime/interrupt_char.h" #include "py/ringbuf.h" #include "py/runtime.h" #include "py/stream.h" +#include "shared/runtime/interrupt_char.h" + #include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/Connection.h" -#include "supervisor/shared/tick.h" -#include "common-hal/_bleio/CharacteristicBuffer.h" #include "shared-bindings/_bleio/CharacteristicBuffer.h" +#include "supervisor/shared/tick.h" + +#include "common-hal/_bleio/ble_events.h" + STATIC int characteristic_buffer_on_ble_evt(struct ble_gap_event *event, void *param) { bleio_characteristic_buffer_obj_t *self = (bleio_characteristic_buffer_obj_t *)param; switch (event->type) { @@ -49,7 +52,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,9 +84,11 @@ 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; ringbuf_init(&self->ringbuf, buffer, buffer_size); if (static_handler_entry != NULL) { @@ -87,7 +104,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) { diff --git a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.h b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.h index e5247c20f777..30c3c426e61a 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/Connection.c b/ports/espressif/common-hal/_bleio/Connection.c index 63c85099e691..5e3e02d8e559 100644 --- a/ports/espressif/common-hal/_bleio/Connection.c +++ b/ports/espressif/common-hal/_bleio/Connection.c @@ -30,21 +30,24 @@ #include #include -#include "shared/runtime/interrupt_char.h" #include "py/gc.h" #include "py/objlist.h" #include "py/objstr.h" #include "py/qstr.h" #include "py/runtime.h" + +#include "shared/runtime/interrupt_char.h" + #include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/Adapter.h" #include "shared-bindings/_bleio/Attribute.h" #include "shared-bindings/_bleio/Characteristic.h" #include "shared-bindings/_bleio/Service.h" #include "shared-bindings/_bleio/UUID.h" + #include "supervisor/shared/tick.h" -// #include "common-hal/_bleio/bonding.h" +#include "common-hal/_bleio/ble_events.h" #include "host/ble_att.h" @@ -245,7 +248,7 @@ STATIC int _discovered_characteristic_cb(uint16_t conn_handle, ((chr->properties & BLE_GATT_CHR_PROP_WRITE) != 0 ? CHAR_PROP_WRITE : 0) | ((chr->properties & BLE_GATT_CHR_PROP_WRITE_NO_RSP) != 0 ? CHAR_PROP_WRITE_NO_RESPONSE : 0); - // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. + // Call common_hal_bleio_characteristic_construct() to initialize some fields and set up evt handler. common_hal_bleio_characteristic_construct( characteristic, service, chr->val_handle, uuid, props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, diff --git a/ports/espressif/common-hal/_bleio/PacketBuffer.c b/ports/espressif/common-hal/_bleio/PacketBuffer.c index 3b3e51df6173..d1d8c24123df 100644 --- a/ports/espressif/common-hal/_bleio/PacketBuffer.c +++ b/ports/espressif/common-hal/_bleio/PacketBuffer.c @@ -27,17 +27,20 @@ #include #include -#include "shared/runtime/interrupt_char.h" #include "py/runtime.h" #include "py/stream.h" +#include "shared/runtime/interrupt_char.h" + #include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/Connection.h" #include "shared-bindings/_bleio/PacketBuffer.h" -#include "supervisor/shared/tick.h" +#include "supervisor/shared/tick.h" #include "supervisor/shared/bluetooth/serial.h" +#include "common-hal/_bleio/ble_events.h" + #include "host/ble_att.h" STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, const struct os_mbuf *mbuf) { diff --git a/ports/espressif/common-hal/alarm/__init__.c b/ports/espressif/common-hal/alarm/__init__.c index 574fab0151bc..0c288d89b45f 100644 --- a/ports/espressif/common-hal/alarm/__init__.c +++ b/ports/espressif/common-hal/alarm/__init__.c @@ -76,7 +76,7 @@ void alarm_reset(void) { 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; @@ -94,17 +94,20 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) { #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_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_record_wake_alarm(); @@ -154,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); diff --git a/ports/espressif/common-hal/alarm/touch/TouchAlarm.c b/ports/espressif/common-hal/alarm/touch/TouchAlarm.c index 232614ce3274..b58234c9a81f 100644 --- a/ports/espressif/common-hal/alarm/touch/TouchAlarm.c +++ b/ports/espressif/common-hal/alarm/touch/TouchAlarm.c @@ -119,7 +119,7 @@ void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alar for (uint8_t i = 1; i <= 14; i++) { if ((touch_channel_mask & 1 << i) != 0) { touch_pad_t touch_channel = (touch_pad_t)i; - // intialize touchpad + // initialize touchpad peripherals_touch_init(touch_channel); // wait for touch data to reset @@ -166,7 +166,7 @@ void alarm_touch_touchalarm_prepare_for_deep_sleep(void) { peripherals_touch_never_reset(false); peripherals_touch_reset(); - // intialize touchpad + // initialize touchpad peripherals_touch_init(touch_channel); #if !defined(CONFIG_IDF_TARGET_ESP32) diff --git a/ports/espressif/common-hal/analogbufio/BufferedIn.c b/ports/espressif/common-hal/analogbufio/BufferedIn.c new file mode 100644 index 000000000000..3a8d8d0defbf --- /dev/null +++ b/ports/espressif/common-hal/analogbufio/BufferedIn.c @@ -0,0 +1,314 @@ +/* + * 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_11 +#define ADC_READ_TIMEOUT_MS 2000 +#define ADC_PIN_MAX_VALUE 0xfff + +#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; + uint32_t adc_reading = 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) + adc_reading = pResult->type1.data; + #endif + } else { + adc_reading = pResult->type2.data; + } + adc_reading = adc_reading * ((1 << 16) - 1) / ADC_PIN_MAX_VALUE; + *pBuffer = (uint16_t)adc_reading; + 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 000000000000..909455ca067c --- /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 000000000000..b6c74b985b21 --- /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 d6c3676d6a81..e58aeefe88a1 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 0b894fa215b6..da9170a5b099 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; - spi_device_transmit(spi_handle[self->host_id], &transaction); - bits_remaining -= transaction.length; + if (data_out != NULL) { + transactions[cur_trans].tx_buffer = data_out + offset; + } + if (data_in != NULL) { + transactions[cur_trans].rx_buffer = data_in + offset; + } - // doesn't need ceil(); loop ends when bits_remaining is 0 - offset += transaction.length / 8; + 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++; + } - RUN_BACKGROUND_TASKS; + for (int i = 0; i < cur_trans; i++) { + spi_device_queue_trans(spi_handle[self->host_id], &transactions[i], portMAX_DELAY); + } + + 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 f025c15b3e1e..c13bdedac031 100644 --- a/ports/espressif/common-hal/busio/UART.c +++ b/ports/espressif/common-hal/busio/UART.c @@ -112,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/esp32_camera/Camera.c b/ports/espressif/common-hal/espcamera/Camera.c similarity index 82% rename from ports/espressif/common-hal/esp32_camera/Camera.c rename to ports/espressif/common-hal/espcamera/Camera.c index 34ad1fbbb9d1..574b4e846be7 100644 --- a/ports/espressif/common-hal/esp32_camera/Camera.c +++ b/ports/espressif/common-hal/espcamera/Camera.c @@ -27,9 +27,9 @@ #include "py/mperrno.h" #include "py/runtime.h" -#include "bindings/esp32_camera/Camera.h" +#include "bindings/espcamera/Camera.h" #include "bindings/espidf/__init__.h" -#include "common-hal/esp32_camera/Camera.h" +#include "common-hal/espcamera/Camera.h" #include "shared-bindings/busio/I2C.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" @@ -38,10 +38,10 @@ #include "esp32-camera/driver/private_include/cam_hal.h" #if !CONFIG_SPIRAM -#error esp32_camera only works on boards configured with spiram, disable it in mpconfigboard.mk +#error espcamera only works on boards configured with spiram, disable it in mpconfigboard.mk #endif -static void i2c_lock(esp32_camera_camera_obj_t *self) { +static void i2c_lock(espcamera_camera_obj_t *self) { if (common_hal_busio_i2c_deinited(self->i2c)) { raise_deinited_error(); } @@ -50,7 +50,7 @@ static void i2c_lock(esp32_camera_camera_obj_t *self) { } } -static void i2c_unlock(esp32_camera_camera_obj_t *self) { +static void i2c_unlock(espcamera_camera_obj_t *self) { common_hal_busio_i2c_unlock(self->i2c); } @@ -60,8 +60,8 @@ static void maybe_claim_pin(const mcu_pin_obj_t *pin) { } } -void common_hal_esp32_camera_camera_construct( - esp32_camera_camera_obj_t *self, +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, @@ -79,8 +79,7 @@ void common_hal_esp32_camera_camera_construct( if (common_hal_espidf_get_reserved_psram() == 0) { mp_raise_msg(&mp_type_MemoryError, translate( - "esp32_camera.Camera requires reserved PSRAM to be configured. " - "See the documentation for instructions.")); + "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]); @@ -140,8 +139,8 @@ void common_hal_esp32_camera_camera_construct( CHECK_ESP_RESULT(result); } -extern void common_hal_esp32_camera_camera_deinit(esp32_camera_camera_obj_t *self) { - if (common_hal_esp32_camera_camera_deinited(self)) { +extern void common_hal_espcamera_camera_deinit(espcamera_camera_obj_t *self) { + if (common_hal_espcamera_camera_deinited(self)) { return; } @@ -165,15 +164,15 @@ extern void common_hal_esp32_camera_camera_deinit(esp32_camera_camera_obj_t *sel self->camera_config.xclk_freq_hz = 0; } -bool common_hal_esp32_camera_camera_deinited(esp32_camera_camera_obj_t *self) { +bool common_hal_espcamera_camera_deinited(espcamera_camera_obj_t *self) { return !self->camera_config.xclk_freq_hz; } -bool common_hal_esp32_camera_camera_available(esp32_camera_camera_obj_t *self) { +bool common_hal_espcamera_camera_available(espcamera_camera_obj_t *self) { return esp_camera_fb_available(); } -camera_fb_t *common_hal_esp32_camera_camera_take(esp32_camera_camera_obj_t *self, int timeout_ms) { +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; @@ -189,7 +188,7 @@ camera_fb_t *common_hal_esp32_camera_camera_take(esp32_camera_camera_obj_t *self 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_esp32_camera_camera_get_##name(esp32_camera_camera_obj_t * self) { \ + 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); \ @@ -200,7 +199,7 @@ camera_fb_t *common_hal_esp32_camera_camera_take(esp32_camera_camera_obj_t *self } #define SENSOR_SET(type, name, setter_function_name) \ - void common_hal_esp32_camera_camera_set_##name(esp32_camera_camera_obj_t * self, type value) { \ + 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); \ @@ -212,15 +211,15 @@ camera_fb_t *common_hal_esp32_camera_camera_take(esp32_camera_camera_obj_t *self } \ } -pixformat_t common_hal_esp32_camera_camera_get_pixel_format(esp32_camera_camera_obj_t *self) { +pixformat_t common_hal_espcamera_camera_get_pixel_format(espcamera_camera_obj_t *self) { return self->camera_config.pixel_format; } -framesize_t common_hal_esp32_camera_camera_get_frame_size(esp32_camera_camera_obj_t *self) { +framesize_t common_hal_espcamera_camera_get_frame_size(espcamera_camera_obj_t *self) { return self->camera_config.frame_size; } -void common_hal_esp32_camera_camera_reconfigure(esp32_camera_camera_obj_t *self, framesize_t frame_size, pixformat_t pixel_format, camera_grab_mode_t grab_mode, mp_int_t framebuffer_count) { +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); @@ -272,46 +271,46 @@ 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_esp32_camera_camera_get_sensor_name(esp32_camera_camera_obj_t *self) { +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_esp32_camera_camera_get_supports_jpeg(esp32_camera_camera_obj_t *self) { +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_esp32_camera_camera_get_max_frame_size(esp32_camera_camera_obj_t *self) { +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_esp32_camera_camera_get_address(esp32_camera_camera_obj_t *self) { +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_esp32_camera_camera_get_width(esp32_camera_camera_obj_t *self) { +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_esp32_camera_camera_get_height(esp32_camera_camera_obj_t *self) { +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_esp32_camera_camera_get_grab_mode(esp32_camera_camera_obj_t *self) { +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_esp32_camera_camera_get_framebuffer_count(esp32_camera_camera_obj_t *self) { +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/esp32_camera/Camera.h b/ports/espressif/common-hal/espcamera/Camera.h similarity index 96% rename from ports/espressif/common-hal/esp32_camera/Camera.h rename to ports/espressif/common-hal/espcamera/Camera.h index 4f34fa54cdd5..007686a5231c 100644 --- a/ports/espressif/common-hal/esp32_camera/Camera.h +++ b/ports/espressif/common-hal/espcamera/Camera.h @@ -31,10 +31,10 @@ #include "shared-bindings/pwmio/PWMOut.h" #include "common-hal/busio/I2C.h" -typedef struct esp32_camera_camera_obj { +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; -} esp32_camera_obj_t; +} espcamera_obj_t; diff --git a/ports/espressif/common-hal/espidf/__init__.c b/ports/espressif/common-hal/espidf/__init__.c index 183ebb381707..d2d00ebc5618 100644 --- a/ports/espressif/common-hal/espidf/__init__.c +++ b/ports/espressif/common-hal/espidf/__init__.c @@ -29,7 +29,9 @@ #include "supervisor/memory.h" #include "py/runtime.h" +#include "esp_now.h" #include "esp_log.h" + #define TAG "espidf" #ifdef CONFIG_SPIRAM @@ -180,14 +182,19 @@ void raise_esp_error(esp_err_t err) { // 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); + MP_STATIC_ASSERT(ESP_ERR_MESH_BASE > ESP_ERR_ESPNOW_BASE); + MP_STATIC_ASSERT(ESP_ERR_ESPNOW_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_ESPNOW_BASE) { + group = "ESP-NOW"; } else if (err >= ESP_ERR_WIFI_BASE) { group = "WiFi"; } + mp_raise_msg_varg(exception_type, translate("%s error 0x%x"), group, err); } diff --git a/ports/espressif/common-hal/espnow/ESPNow.c b/ports/espressif/common-hal/espnow/ESPNow.c new file mode 100644 index 000000000000..a048c7f9f1c0 --- /dev/null +++ b/ports/espressif/common-hal/espnow/ESPNow.c @@ -0,0 +1,240 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017-2020 Nick Moore + * Copyright (c) 2018 shawwwn + * Copyright (c) 2020-2021 Glenn Moloney @glenn20 + * 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/mperrno.h" +#include "py/runtime.h" + +#include "bindings/espidf/__init__.h" +#include "bindings/espnow/ESPNowPacket.h" + +#include "shared-bindings/wifi/__init__.h" + +#include "common-hal/espnow/ESPNow.h" + +#include "mphalport.h" + +#include "esp_now.h" + +#define ESPNOW_MAGIC 0x99 + +// TODO: deinit wifi? + +// The min/max length of an espnow packet (bytes) +#define MIN_PACKET_LEN (sizeof(espnow_packet_t)) +#define MAX_PACKET_LEN (sizeof(espnow_packet_t) + ESP_NOW_MAX_DATA_LEN) + +// Enough for 2 full-size packets: 2 * (6 + 7 + 250) = 526 bytes +// Will allocate an additional 7 bytes for buffer overhead +#define DEFAULT_RECV_BUFFER_SIZE (2 * MAX_PACKET_LEN) + +// Time to wait (millisec) for responses from sent packets: (2 seconds). +#define DEFAULT_SEND_TIMEOUT_MS (2000) + +// ESPNow packet format for the receive buffer. +// Use this for peeking at the header of the next packet in the buffer. +typedef struct { + uint8_t magic; // = ESPNOW_MAGIC + uint8_t msg_len; // Length of the message + uint32_t time_ms; // Timestamp (ms) when packet is received + int8_t rssi; // RSSI value (dBm) (-127 to 0) +} __attribute__((packed)) espnow_header_t; + +typedef struct { + espnow_header_t header; // The header + uint8_t peer[6]; // Peer address + uint8_t msg[0]; // Message is up to 250 bytes +} __attribute__((packed)) espnow_packet_t; + +// --- The ESP-NOW send and recv callback routines --- + +// Callback triggered when a sent packet is acknowledged by the peer (or not). +// Just count the number of responses and number of failures. +// These are used in the send() logic. +static void send_cb(const uint8_t *mac, esp_now_send_status_t status) { + espnow_obj_t *self = MP_STATE_PORT(espnow_singleton); + if (status == ESP_NOW_SEND_SUCCESS) { + self->send_success++; + } else { + self->send_failure++; + } +} + +// Callback triggered when an ESP-NOW packet is received. +// Write the peer MAC address and the message into the recv_buffer as an ESPNow packet. +// If the buffer is full, drop the message and increment the dropped count. +static void recv_cb(const uint8_t *mac, const uint8_t *msg, int msg_len) { + espnow_obj_t *self = MP_STATE_PORT(espnow_singleton); + ringbuf_t *buf = self->recv_buffer; + + if (sizeof(espnow_packet_t) + msg_len > ringbuf_num_empty(buf)) { + self->read_failure++; + return; + } + + // Get the RSSI value from the wifi packet header + // Secret magic to get the rssi from the wifi packet header + // See espnow.c:espnow_recv_cb() at https://github.com/espressif/esp-now/ + // In the wifi packet the msg comes after a wifi_promiscuous_pkt_t + // and a espnow_frame_format_t. + // Backtrack to get a pointer to the wifi_promiscuous_pkt_t. + #define SIZEOF_ESPNOW_FRAME_FORMAT 39 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + wifi_promiscuous_pkt_t *wifi_packet = (wifi_promiscuous_pkt_t *)( + msg - SIZEOF_ESPNOW_FRAME_FORMAT - sizeof(wifi_promiscuous_pkt_t)); + #pragma GCC diagnostic pop + + espnow_header_t header; + header.magic = ESPNOW_MAGIC; + header.msg_len = msg_len; + header.rssi = wifi_packet->rx_ctrl.rssi; + header.time_ms = mp_hal_ticks_ms(); + + ringbuf_put_n(buf, (uint8_t *)&header, sizeof(header)); + ringbuf_put_n(buf, mac, ESP_NOW_ETH_ALEN); + ringbuf_put_n(buf, msg, msg_len); + + self->read_success++; +} + +bool common_hal_espnow_deinited(espnow_obj_t *self) { + return self == NULL || self->recv_buffer == NULL; +} + +// Construct the ESPNow object +void common_hal_espnow_construct(espnow_obj_t *self, mp_int_t buffer_size, mp_int_t phy_rate) { + common_hal_espnow_set_phy_rate(self, phy_rate); + self->recv_buffer_size = mp_arg_validate_int_min(buffer_size, MIN_PACKET_LEN, MP_QSTR_buffer_size); + self->peers = espnow_peers_new(); + common_hal_espnow_init(self); +} + +// Initialize the ESP-NOW software stack, +// register callbacks and allocate the recv data buffers. +void common_hal_espnow_init(espnow_obj_t *self) { + if (!common_hal_espnow_deinited(self)) { + return; + } + + self->recv_buffer = m_new_obj(ringbuf_t); + if (!ringbuf_alloc(self->recv_buffer, self->recv_buffer_size, true)) { + m_malloc_fail(self->recv_buffer_size); + } + + 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); + } + + CHECK_ESP_RESULT(esp_wifi_config_espnow_rate(ESP_IF_WIFI_STA, self->phy_rate)); + CHECK_ESP_RESULT(esp_wifi_config_espnow_rate(ESP_IF_WIFI_AP, self->phy_rate)); + + CHECK_ESP_RESULT(esp_now_init()); + CHECK_ESP_RESULT(esp_now_register_send_cb(send_cb)); + CHECK_ESP_RESULT(esp_now_register_recv_cb(recv_cb)); +} + +// De-initialize the ESP-NOW software stack, +// disable callbacks and deallocate the recv data buffer. +void common_hal_espnow_deinit(espnow_obj_t *self) { + if (common_hal_espnow_deinited(self)) { + return; + } + + CHECK_ESP_RESULT(esp_now_unregister_send_cb()); + CHECK_ESP_RESULT(esp_now_unregister_recv_cb()); + CHECK_ESP_RESULT(esp_now_deinit()); + + self->recv_buffer->buf = NULL; + self->recv_buffer = NULL; +} + +void espnow_reset(void) { + common_hal_espnow_deinit(MP_STATE_PORT(espnow_singleton)); + MP_STATE_PORT(espnow_singleton) = NULL; +} + +void common_hal_espnow_set_phy_rate(espnow_obj_t *self, mp_int_t value) { + self->phy_rate = mp_arg_validate_int_range(value, 0, WIFI_PHY_RATE_MAX - 1, MP_QSTR_phy_rate); +}; + +void common_hal_espnow_set_pmk(espnow_obj_t *self, const uint8_t *key) { + CHECK_ESP_RESULT(esp_now_set_pmk(key)); +} + +// --- Send and Receive ESP-NOW data --- + + +mp_obj_t common_hal_espnow_send(espnow_obj_t *self, const mp_buffer_info_t *message, const uint8_t *mac) { + // Send the packet - keep trying until timeout if the internal esp-now buffers are full. + esp_err_t err; + mp_uint_t start = mp_hal_ticks_ms(); + + while ((ESP_ERR_ESPNOW_NO_MEM == (err = esp_now_send(mac, message->buf, message->len))) && + (mp_hal_ticks_ms() - start) <= DEFAULT_SEND_TIMEOUT_MS) { + RUN_BACKGROUND_TASKS; + } + CHECK_ESP_RESULT(err); + + return mp_const_none; +} + +mp_obj_t common_hal_espnow_read(espnow_obj_t *self) { + if (!ringbuf_num_filled(self->recv_buffer)) { + return mp_const_none; + } + + // Read the packet header from the incoming buffer + espnow_header_t header; + if (ringbuf_get_n(self->recv_buffer, (uint8_t *)&header, sizeof(header)) != sizeof(header)) { + mp_arg_error_invalid(MP_QSTR_buffer); + } + + uint8_t msg_len = header.msg_len; + + uint8_t mac_buf[ESP_NOW_ETH_ALEN]; + uint8_t msg_buf[msg_len]; + + // Check the message packet header format and read the message data + if (header.magic != ESPNOW_MAGIC || + msg_len > ESP_NOW_MAX_DATA_LEN || + ringbuf_get_n(self->recv_buffer, mac_buf, ESP_NOW_ETH_ALEN) != ESP_NOW_ETH_ALEN || + ringbuf_get_n(self->recv_buffer, msg_buf, msg_len) != msg_len) { + mp_arg_error_invalid(MP_QSTR_buffer); + } + + mp_obj_t elems[4] = { + mp_obj_new_bytes(mac_buf, ESP_NOW_ETH_ALEN), + mp_obj_new_bytes(msg_buf, msg_len), + MP_OBJ_NEW_SMALL_INT(header.rssi), + mp_obj_new_int(header.time_ms), + }; + + return namedtuple_make_new((const mp_obj_type_t *)&espnow_packet_type_obj, 4, 0, elems); +} diff --git a/ports/espressif/common-hal/espnow/ESPNow.h b/ports/espressif/common-hal/espnow/ESPNow.h new file mode 100644 index 000000000000..624078860361 --- /dev/null +++ b/ports/espressif/common-hal/espnow/ESPNow.h @@ -0,0 +1,59 @@ +/* + * This file is part of the Micro Python 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. + */ + +#pragma once + +#include "py/obj.h" +#include "py/ringbuf.h" + +#include "bindings/espnow/Peers.h" + +#include "esp_wifi.h" + +typedef struct _espnow_obj_t { + mp_obj_base_t base; + ringbuf_t *recv_buffer; + size_t recv_buffer_size; + wifi_phy_rate_t phy_rate; + espnow_peers_obj_t *peers; + volatile size_t send_success; + volatile size_t send_failure; + volatile size_t read_success; + volatile size_t read_failure; +} espnow_obj_t; + +extern void espnow_reset(void); + +extern void common_hal_espnow_construct(espnow_obj_t *self, mp_int_t buffer_size, mp_int_t phy_rate); +extern void common_hal_espnow_init(espnow_obj_t *self); +extern void common_hal_espnow_deinit(espnow_obj_t *self); +extern bool common_hal_espnow_deinited(espnow_obj_t *self); + +extern void common_hal_espnow_set_phy_rate(espnow_obj_t *self, mp_int_t value); +extern void common_hal_espnow_set_pmk(espnow_obj_t *self, const uint8_t *key); + +extern mp_obj_t common_hal_espnow_send(espnow_obj_t *self, const mp_buffer_info_t *message, const uint8_t *mac); +extern mp_obj_t common_hal_espnow_read(espnow_obj_t *self); diff --git a/ports/espressif/common-hal/espnow/__init__.c b/ports/espressif/common-hal/espnow/__init__.c new file mode 100644 index 000000000000..effc752f79f3 --- /dev/null +++ b/ports/espressif/common-hal/espnow/__init__.c @@ -0,0 +1,38 @@ +/* + * This file is part of the Micro Python 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 "common-hal/espnow/__init__.h" + +#include "py/runtime.h" + +// Return C pointer to byte memory string/bytes/bytearray in obj. +// Raise ValueError if the length does not match expected len. +const uint8_t *common_hal_espnow_get_bytes_len(mp_obj_t obj, size_t len) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ); + mp_arg_validate_length(bufinfo.len, len, MP_QSTR_buffer); + return (uint8_t *)bufinfo.buf; +} diff --git a/ports/espressif/common-hal/espnow/__init__.h b/ports/espressif/common-hal/espnow/__init__.h new file mode 100644 index 000000000000..bb1950d98c7a --- /dev/null +++ b/ports/espressif/common-hal/espnow/__init__.h @@ -0,0 +1,30 @@ +/* + * This file is part of the Micro Python 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. + */ + +#pragma once + +#include "py/obj.h" +extern const uint8_t *common_hal_espnow_get_bytes_len(mp_obj_t obj, size_t len); diff --git a/ports/espressif/common-hal/espulp/ULP.c b/ports/espressif/common-hal/espulp/ULP.c index 4d30a94dfca2..3350f6d45ca7 100644 --- a/ports/espressif/common-hal/espulp/ULP.c +++ b/ports/espressif/common-hal/espulp/ULP.c @@ -31,7 +31,10 @@ #include "shared-bindings/microcontroller/Pin.h" -#if defined(CONFIG_IDF_TARGET_ESP32S2) +#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) @@ -56,7 +59,14 @@ void common_hal_espulp_ulp_run(espulp_ulp_obj_t *self, uint32_t *program, size_t if (length > ULP_COPROC_RESERVE_MEM) { mp_raise_ValueError(translate("Program too long")); } - if (GET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN)) { + + 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")); } @@ -78,13 +88,29 @@ void common_hal_espulp_ulp_run(espulp_ulp_obj_t *self, uint32_t *program, size_t } pins_used = pin_mask; - - ulp_riscv_load_binary((const uint8_t *)program, length); ulp_set_wakeup_period(0, 20000); - ulp_riscv_run(); + + 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(); @@ -97,6 +123,7 @@ void common_hal_espulp_ulp_halt(espulp_ulp_obj_t *self) { // 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++) { @@ -106,13 +133,21 @@ void common_hal_espulp_ulp_halt(espulp_ulp_obj_t *self) { } } -void common_hal_espulp_ulp_construct(espulp_ulp_obj_t *self) { +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; } diff --git a/ports/espressif/common-hal/espulp/ULP.h b/ports/espressif/common-hal/espulp/ULP.h index f73b21d12303..360dd0c9fdf6 100644 --- a/ports/espressif/common-hal/espulp/ULP.h +++ b/ports/espressif/common-hal/espulp/ULP.h @@ -27,8 +27,10 @@ #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 index ec1fb8bc45db..3717d2ab7132 100644 --- a/ports/espressif/common-hal/espulp/ULPAlarm.c +++ b/ports/espressif/common-hal/espulp/ULPAlarm.c @@ -37,8 +37,8 @@ static volatile bool woke_up = false; static bool alarm_set = false; -void common_hal_espulp_ulpalarm_construct(espulp_ulpalarm_obj_t *self) { - +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) { @@ -52,7 +52,6 @@ mp_obj_t espulp_ulpalarm_find_triggered_alarm(const size_t n_alarms, const mp_ob 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; } @@ -81,8 +80,25 @@ void espulp_ulpalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, con } // enable ulp interrupt - rtc_isr_register(&ulp_interrupt, NULL, RTC_CNTL_COCPU_INT_ST); - REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_COCPU_INT_ENA); + 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; } @@ -91,9 +107,13 @@ 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(); diff --git a/ports/espressif/common-hal/espulp/ULPAlarm.h b/ports/espressif/common-hal/espulp/ULPAlarm.h index 5d2610c6a3a6..99d21180fd12 100644 --- a/ports/espressif/common-hal/espulp/ULPAlarm.h +++ b/ports/espressif/common-hal/espulp/ULPAlarm.h @@ -29,8 +29,11 @@ #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); diff --git a/ports/espressif/common-hal/mdns/Server.c b/ports/espressif/common-hal/mdns/Server.c index d657a84eb712..18c0f0f5e4e0 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) { diff --git a/ports/espressif/common-hal/mdns/Server.h b/ports/espressif/common-hal/mdns/Server.h index 770f55ece4fd..ee463657f18c 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/microcontroller/Processor.c b/ports/espressif/common-hal/microcontroller/Processor.c index 1f0974295535..c0e72c85b995 100644 --- a/ports/espressif/common-hal/microcontroller/Processor.c +++ b/ports/espressif/common-hal/microcontroller/Processor.c @@ -64,7 +64,7 @@ float common_hal_mcu_processor_get_voltage(void) { uint32_t common_hal_mcu_processor_get_frequency(void) { #if defined(CONFIG_IDF_TARGET_ESP32) - return CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 100000; + return CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000; #elif defined(CONFIG_IDF_TARGET_ESP32C3) return CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ * 1000000; #elif defined(CONFIG_IDF_TARGET_ESP32S2) diff --git a/ports/espressif/common-hal/microcontroller/__init__.c b/ports/espressif/common-hal/microcontroller/__init__.c index 68479dc46f7a..23c7c153e901 100644 --- a/ports/espressif/common-hal/microcontroller/__init__.c +++ b/ports/espressif/common-hal/microcontroller/__init__.c @@ -108,7 +108,7 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { 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 diff --git a/ports/espressif/common-hal/paralleldisplay/ParallelBus.c b/ports/espressif/common-hal/paralleldisplay/ParallelBus.c index 1b6ee41c40bf..c9ba3edd06b3 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 bb6ef7f9752c..42db2f18bd61 100644 --- a/ports/espressif/common-hal/pulseio/PulseIn.c +++ b/ports/espressif/common-hal/pulseio/PulseIn.c @@ -123,7 +123,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu rmt_config_t config = RMT_DEFAULT_CONFIG_RX(pin->number, channel); config.rx_config.filter_en = true; config.rx_config.idle_threshold = 30000; // 30*3=90ms idle required to register a sequence - config.clk_div = 240; // All measurements are divided by 3 to accomodate 65ms pulses + config.clk_div = 240; // All measurements are divided by 3 to accommodate 65ms pulses rmt_config(&config); rmt_driver_install(channel, 1000, 0); // TODO: pick a more specific buffer size? diff --git a/ports/espressif/common-hal/pwmio/PWMOut.c b/ports/espressif/common-hal/pwmio/PWMOut.c index 68518fbd256d..519885a03261 100644 --- a/ports/espressif/common-hal/pwmio/PWMOut.c +++ b/ports/espressif/common-hal/pwmio/PWMOut.c @@ -164,24 +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; - // Search if any other channel is using the timer and is never reset. - // Otherwise, we clear never_reset for the timer as well. - bool other_never_reset = false; - for (size_t i = 0; i < LEDC_CHANNEL_MAX; i++) { - if (i != self->chan_handle.channel && - reserved_channels[i] == self->tim_handle.timer_num && - never_reset_chan[i]) { - other_never_reset = true; - break; - } - } - if (!other_never_reset) { - never_reset_chan[self->chan_handle.channel] = false; - } -} - bool common_hal_pwmio_pwmout_deinited(pwmio_pwmout_obj_t *self) { return self->deinited == true; } @@ -196,19 +178,26 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { } 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 + // if timer isn't varfreq this will be off already varfreq_timers[self->tim_handle.timer_num] = false; never_reset_tim[self->tim_handle.timer_num] = false; } diff --git a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c index 07b97cf9a31d..088f4a15dc13 100644 --- a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c @@ -69,7 +69,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode .unit = unit, }; - // Reinitalize same unit, CHANNEL_1 with different parameters. + // Reinitialize same unit, CHANNEL_1 with different parameters. peripherals_pcnt_reinit(&pcnt_config_channel_1); self->pin_a = pin_a->number; diff --git a/ports/espressif/common-hal/socketpool/Socket.c b/ports/espressif/common-hal/socketpool/Socket.c index ccb01116d867..ef564806720c 100644 --- a/ports/espressif/common-hal/socketpool/Socket.c +++ b/ports/espressif/common-hal/socketpool/Socket.c @@ -45,70 +45,78 @@ StackType_t socket_select_stack[2 * configMINIMAL_STACK_SIZE]; -STATIC int open_socket_fds[CONFIG_LWIP_MAX_SOCKETS]; +/* Socket state table: + * 0 := Closed (unused) + * 1 := Open + * 2 := Closing (remove from rfds) + * Index into socket_fd_state is calculated from actual lwip fd. idx := fd - LWIP_SOCKET_OFFSET +*/ +#define FDSTATE_CLOSED 0 +#define FDSTATE_OPEN 1 +#define FDSTATE_CLOSING 2 +STATIC uint8_t socket_fd_state[CONFIG_LWIP_MAX_SOCKETS]; + STATIC socketpool_socket_obj_t *user_socket[CONFIG_LWIP_MAX_SOCKETS]; -StaticTask_t socket_select_task_handle; +StaticTask_t socket_select_task_buffer; +TaskHandle_t socket_select_task_handle; STATIC int socket_change_fd = -1; STATIC void socket_select_task(void *arg) { uint64_t signal; + fd_set readfds; + fd_set excptfds; while (true) { - fd_set readfds; - fd_set errfds; FD_ZERO(&readfds); - FD_ZERO(&errfds); + FD_ZERO(&excptfds); FD_SET(socket_change_fd, &readfds); - 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++) { - int sockfd = open_socket_fds[i]; - if (sockfd < 0) { - continue; + for (size_t i = 0; i < MP_ARRAY_SIZE(socket_fd_state); i++) { + if ((socket_fd_state[i] == FDSTATE_OPEN) && (user_socket[i] == NULL)) { + int sockfd = i + LWIP_SOCKET_OFFSET; + max_fd = MAX(max_fd, sockfd); + FD_SET(sockfd, &readfds); + FD_SET(sockfd, &excptfds); } - 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); - // 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; - } + int num_triggered = select(max_fd + 1, &readfds, NULL, &excptfds, NULL); + // Hard error (or someone closed a socket on another thread) + if (num_triggered == -1) { + assert(errno == EBADF); + continue; } - assert(num_triggered >= 0); + assert(num_triggered > 0); + + // Notice event trigger if (FD_ISSET(socket_change_fd, &readfds)) { read(socket_change_fd, &signal, sizeof(signal)); - num_triggered -= 1; + num_triggered--; } - if (num_triggered > 0) { - supervisor_workflow_request_background(); - // Wake up CircuitPython. We know it is asleep because we are lower - // priority. - port_wake_main_task(); + // Handle active FDs, close the dead ones + for (size_t i = 0; i < MP_ARRAY_SIZE(socket_fd_state); i++) { + int sockfd = i + LWIP_SOCKET_OFFSET; + if (socket_fd_state[i] != FDSTATE_CLOSED) { + if (FD_ISSET(sockfd, &readfds) || FD_ISSET(sockfd, &excptfds)) { + if (socket_fd_state[i] == FDSTATE_CLOSING) { + socket_fd_state[i] = FDSTATE_CLOSED; + num_triggered--; + } + } + } } + if (num_triggered > 0) { + // Wake up CircuitPython by queuing request + supervisor_workflow_request_background(); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + } } + close(socket_change_fd); + socket_change_fd = -1; vTaskDelete(NULL); } @@ -117,33 +125,36 @@ void socket_user_reset(void) { esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_vfs_eventfd_register(&config)); - for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_fds); i++) { - open_socket_fds[i] = -1; + // Clear initial socket states + for (size_t i = 0; i < MP_ARRAY_SIZE(socket_fd_state); i++) { + socket_fd_state[i] = FDSTATE_CLOSED; user_socket[i] = NULL; } socket_change_fd = eventfd(0, 0); // 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_task_handle = xTaskCreateStaticPinnedToCore(socket_select_task, "socket_select", 2 * configMINIMAL_STACK_SIZE, NULL, uxTaskPriorityGet(NULL), socket_select_stack, - &socket_select_task_handle, + &socket_select_task_buffer, xPortGetCoreID()); + } else { + // Not init - close open user sockets + for (size_t i = 0; i < MP_ARRAY_SIZE(socket_fd_state); i++) { + if ((socket_fd_state[i] == FDSTATE_OPEN) && user_socket[i]) { + common_hal_socketpool_socket_close(user_socket[i]); + } + } } +} - 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] = NULL; - } +// Unblock select task (ok if not blocked yet) +void socketpool_socket_poll_resume(void) { + if (socket_select_task_handle) { + xTaskNotifyGive(socket_select_task_handle); } } @@ -151,39 +162,25 @@ void socket_user_reset(void) { // select with the new open socket set. STATIC bool register_open_socket(int fd) { - for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_fds); i++) { - if (open_socket_fds[i] == -1) { - open_socket_fds[i] = fd; - user_socket[i] = false; - uint64_t signal = 1; - write(socket_change_fd, &signal, sizeof(signal)); - return true; - } - } - return false; -} + if (fd < FD_SETSIZE) { + socket_fd_state[fd - LWIP_SOCKET_OFFSET] = FDSTATE_OPEN; + user_socket[fd - LWIP_SOCKET_OFFSET] = NULL; -STATIC void unregister_open_socket(int fd) { - for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_fds); i++) { - if (open_socket_fds[i] == fd) { - open_socket_fds[i] = -1; - user_socket[i] = false; - write(socket_change_fd, &fd, sizeof(fd)); - return; - } + uint64_t signal = 1; + write(socket_change_fd, &signal, sizeof(signal)); + socketpool_socket_poll_resume(); + return true; } + return false; } 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] = obj; - return; - } - } + socket_fd_state[fd - LWIP_SOCKET_OFFSET] = FDSTATE_OPEN; + user_socket[fd - LWIP_SOCKET_OFFSET] = obj; + // No need to wakeup select task } -bool socketpool_socket(socketpool_socketpool_obj_t *self, +STATIC bool _socketpool_socket(socketpool_socketpool_obj_t *self, socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type, socketpool_socket_obj_t *sock) { int addr_family; @@ -191,9 +188,11 @@ bool socketpool_socket(socketpool_socketpool_obj_t *self, if (family == SOCKETPOOL_AF_INET) { addr_family = AF_INET; ipproto = IPPROTO_IP; + #if LWIP_IPV6 } else { // INET6 addr_family = AF_INET6; ipproto = IPPROTO_IPV6; + #endif } int socket_type; @@ -216,14 +215,28 @@ bool socketpool_socket(socketpool_socketpool_obj_t *self, if (socknum < 0) { return false; } - // This shouldn't happen since we have room for the same number of sockets as LWIP. - if (!register_open_socket(socknum)) { - lwip_close(socknum); - return false; - } + sock->num = socknum; // Sockets should be nonblocking in most cases lwip_fcntl(socknum, F_SETFL, O_NONBLOCK); + + return true; +} + +// special entry for workflow listener (register system socket) +bool socketpool_socket(socketpool_socketpool_obj_t *self, + socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type, + socketpool_socket_obj_t *sock) { + + if (!_socketpool_socket(self, family, type, sock)) { + return false; + } + + // This shouldn't happen since we have room for the same number of sockets as LWIP. + if (!register_open_socket(sock->num)) { + lwip_close(sock->num); + return false; + } return true; } @@ -236,7 +249,7 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_ socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t); sock->base.type = &socketpool_socket_type; - if (!socketpool_socket(self, family, type, sock)) { + if (!_socketpool_socket(self, family, type, sock)) { mp_raise_RuntimeError(translate("Out of sockets")); } mark_user_socket(sock->num, sock); @@ -273,22 +286,24 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_ if (newsoc < 0) { return -MP_EBADF; } - if (!register_open_socket(newsoc)) { - lwip_close(newsoc); - return -MP_EBADF; - } + // We got a socket. New client socket will not be non-blocking by default, so make it non-blocking. + lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK); 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); + // Error if called with open socket object. + assert(common_hal_socketpool_socket_get_closed(accepted)); + + // Register if system socket + if (!register_open_socket(newsoc)) { + lwip_close(newsoc); + return -MP_EBADF; } - // Create the socket + + // Replace the old accepted socket with the new one. accepted->num = newsoc; accepted->pool = self->pool; accepted->connected = true; - lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK); } return newsoc; @@ -348,12 +363,21 @@ void socketpool_socket_close(socketpool_socket_obj_t *self) { return; } self->connected = false; - if (self->num >= 0) { - lwip_shutdown(self->num, SHUT_RDWR); - lwip_close(self->num); - unregister_open_socket(self->num); - self->num = -1; + int fd = self->num; + // Ignore bogus/closed sockets + if (fd >= LWIP_SOCKET_OFFSET) { + if (user_socket[fd - LWIP_SOCKET_OFFSET] == NULL) { + socket_fd_state[fd - LWIP_SOCKET_OFFSET] = FDSTATE_CLOSING; + lwip_shutdown(fd, SHUT_RDWR); + lwip_close(fd); + } else { + lwip_shutdown(fd, SHUT_RDWR); + lwip_close(fd); + socket_fd_state[fd - LWIP_SOCKET_OFFSET] = FDSTATE_CLOSED; + user_socket[fd - LWIP_SOCKET_OFFSET] = NULL; + } } + self->num = -1; } void common_hal_socketpool_socket_close(socketpool_socket_obj_t *self) { @@ -415,7 +439,7 @@ bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t *self) { } bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *self, int backlog) { - return lwip_listen(self->num, backlog); + return lwip_listen(self->num, backlog) == 0; } mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *self, @@ -474,10 +498,9 @@ int socketpool_socket_recv_into(socketpool_socket_obj_t *self, } RUN_BACKGROUND_TASKS; received = lwip_recv(self->num, (void *)buf, len, 0); - // In non-blocking mode, fail instead of looping - if (received == -1 && self->timeout_ms == 0) { - if (errno == ENOTCONN) { + if (received < 1 && self->timeout_ms == 0) { + if ((received == 0) || (errno == ENOTCONN)) { self->connected = false; return -MP_ENOTCONN; } diff --git a/ports/espressif/common-hal/socketpool/Socket.h b/ports/espressif/common-hal/socketpool/Socket.h index 45e36e58caf7..dfd1cbfc110a 100644 --- a/ports/espressif/common-hal/socketpool/Socket.h +++ b/ports/espressif/common-hal/socketpool/Socket.h @@ -48,3 +48,5 @@ typedef struct { } socketpool_socket_obj_t; void socket_user_reset(void); +// Unblock workflow socket select thread (platform specific) +void socketpool_socket_poll_resume(void); diff --git a/ports/espressif/common-hal/wifi/Radio.c b/ports/espressif/common-hal/wifi/Radio.c index acd6ae53bc27..0ce535899a57 100644 --- a/ports/espressif/common-hal/wifi/Radio.c +++ b/ports/espressif/common-hal/wifi/Radio.c @@ -242,6 +242,10 @@ void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_ esp_wifi_set_config(WIFI_IF_AP, config); } +bool common_hal_wifi_radio_get_ap_active(wifi_radio_obj_t *self) { + return self->ap_mode && esp_netif_is_netif_up(self->ap_netif); +} + void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self) { set_mode_ap(self, false); } @@ -347,6 +351,10 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t return WIFI_RADIO_ERROR_NONE; } +bool common_hal_wifi_radio_get_connected(wifi_radio_obj_t *self) { + return self->sta_mode && esp_netif_is_netif_up(self->netif); +} + mp_obj_t common_hal_wifi_radio_get_ap_info(wifi_radio_obj_t *self) { if (!esp_netif_is_netif_up(self->netif)) { return mp_const_none; diff --git a/ports/espressif/esp-idf b/ports/espressif/esp-idf index 8d0f1abce769..630c2724fc8c 160000 --- a/ports/espressif/esp-idf +++ b/ports/espressif/esp-idf @@ -1 +1 @@ -Subproject commit 8d0f1abce769ad4a212c1bb0337999cacd7ee83d +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 index 8e73e8d0568c..c4b103aed11c 100644 --- a/ports/espressif/esp-idf-config/partitions-16MB-no-uf2.csv +++ b/ports/espressif/esp-idf-config/partitions-16MB-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, 0, ota_0, 0x10000, 2048K, -ota_1, 0, ota_1, 0x210000, 2048K, -user_fs, data, fat, 0x410000, 12224K, +# 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 13ea81bea501..16c73da32b24 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 index 869e7ac86e23..1c38195565f4 100644 --- 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 @@ -1,7 +1,6 @@ -# 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, +# 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-32MB.csv b/ports/espressif/esp-idf-config/partitions-32MB.csv new file mode 100644 index 000000000000..42c4084f6cb1 --- /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 6dc2dcf2e98d..6d27e22e7691 100644 --- a/ports/espressif/esp-idf-config/partitions-4MB-no-uf2.csv +++ b/ports/espressif/esp-idf-config/partitions-4MB-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, 0, ota_0, 0x10000, 1408K, -ota_1, 0, ota_1, 0x170000, 1408K, -user_fs, data, fat, 0x2d0000, 1216K, +# 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 cf9b3cca8464..981aee0b17d1 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 ba92d9fc73f1..6d78fe8af591 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 f4ba9b60a180..40674d322c2f 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-32MB.defaults b/ports/espressif/esp-idf-config/sdkconfig-32MB.defaults new file mode 100644 index 000000000000..bbdd32afb810 --- /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-esp32.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults index 483e0f9b87f3..b6c5a938b1c9 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults @@ -313,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 diff --git a/ports/espressif/esp_error.c b/ports/espressif/esp_error.c deleted file mode 100644 index 4bc44674b7fb..000000000000 --- a/ports/espressif/esp_error.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 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 "esp_error.h" -#include "py/runtime.h" - -#include "bindings/espidf/__init__.h" - -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); -} diff --git a/ports/espressif/i2s_lcd_driver.h b/ports/espressif/i2s_lcd_driver.h index 0002d6b5649d..27c4e66b067d 100644 --- a/ports/espressif/i2s_lcd_driver.h +++ b/ports/espressif/i2s_lcd_driver.h @@ -44,7 +44,7 @@ typedef struct { } i2s_lcd_config_t; /** - * @brief Initilize i2s lcd driver. + * @brief Initialize i2s lcd driver. * * @param config configuration of i2s * diff --git a/ports/espressif/mpconfigport.h b/ports/espressif/mpconfigport.h index c296be202495..e4733356bb30 100644 --- a/ports/espressif/mpconfigport.h +++ b/ports/espressif/mpconfigport.h @@ -38,18 +38,22 @@ #include "py/circuitpy_mpconfig.h" #if CIRCUITPY_BLEIO -#include "common-hal/_bleio/ble_events.h" +#define BLEIO_ROOT_POINTERS struct ble_event_handler_entry *ble_event_handler_entries; +#else +#define BLEIO_ROOT_POINTERS #endif -#if CIRCUITPY_BLEIO -#define MICROPY_PORT_ROOT_POINTERS \ - CIRCUITPY_COMMON_ROOT_POINTERS \ - ble_event_handler_entry_t *ble_event_handler_entries; +#if CIRCUITPY_ESPNOW +#define ESPNOW_ROOT_POINTERS struct _espnow_obj_t *espnow_singleton; #else -#define MICROPY_PORT_ROOT_POINTERS \ - CIRCUITPY_COMMON_ROOT_POINTERS +#define ESPNOW_ROOT_POINTERS #endif +#define MICROPY_PORT_ROOT_POINTERS \ + CIRCUITPY_COMMON_ROOT_POINTERS \ + BLEIO_ROOT_POINTERS \ + ESPNOW_ROOT_POINTERS + #define MICROPY_NLR_SETJMP (1) #define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000 diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk index c5c73c77bd99..4637d971a4d6 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -12,6 +12,7 @@ CIRCUITPY_FULL_BUILD ?= 1 # These modules are implemented in ports//common-hal: CIRCUITPY_ALARM ?= 1 +CIRCUITPY_ANALOGBUFIO ?= 1 CIRCUITPY_AUDIOBUSIO ?= 1 CIRCUITPY_AUDIOBUSIO_I2SOUT ?= 1 CIRCUITPY_AUDIOBUSIO_PDMIN ?= 0 @@ -24,13 +25,15 @@ CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_CANIO ?= 1 CIRCUITPY_COUNTIO ?= 1 CIRCUITPY_DUALBANK ?= 1 -CIRCUITPY_ESP32_CAMERA ?= 1 +CIRCUITPY_ESPCAMERA ?= 1 CIRCUITPY_ESPIDF ?= 1 +CIRCUITPY_ESPULP ?= 1 CIRCUITPY_FRAMEBUFFERIO ?= 1 CIRCUITPY_FREQUENCYIO ?= 1 CIRCUITPY_HASHLIB ?= 1 CIRCUITPY_I2CTARGET ?= 1 CIRCUITPY_IMAGECAPTURE = 0 +CIRCUITPY_MEMORYMAP ?= 1 CIRCUITPY_NVM ?= 1 CIRCUITPY_PS2IO ?= 1 CIRCUITPY_RGBMATRIX ?= 1 @@ -53,8 +56,10 @@ else ifeq ($(IDF_TARGET),esp32c3) CIRCUITPY_ALARM = 0 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_COUNTIO = 0 -CIRCUITPY_ESP32_CAMERA = 0 +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_ESPULP = 0 CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_MEMORYMAP = 0 CIRCUITPY_PARALLELDISPLAY = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_TOUCHIO ?= 1 @@ -65,14 +70,10 @@ CIRCUITPY_USB = 0 else ifeq ($(IDF_TARGET),esp32s2) # Modules CIRCUITPY_BLEIO = 0 -CIRCUITPY_ESPULP = 1 -CIRCUITPY_MEMORYMAP = 1 else ifeq ($(IDF_TARGET),esp32s3) # Modules CIRCUITPY_PARALLELDISPLAY = 0 -CIRCUITPY_ESPULP = 1 -CIRCUITPY_MEMORYMAP = 1 endif # No room for dualbank on boards with 2MB flash @@ -81,8 +82,9 @@ CIRCUITPY_DUALBANK = 0 endif # Modules dependent on other modules -CIRCUITPY_GIFIO ?= $(CIRCUITPY_ESP32_CAMERA) -CIRCUITPY_QRIO ?= $(CIRCUITPY_ESP32_CAMERA) +CIRCUITPY_ESPNOW ?= $(CIRCUITPY_WIFI) +CIRCUITPY_GIFIO ?= $(CIRCUITPY_ESPCAMERA) +CIRCUITPY_QRIO ?= $(CIRCUITPY_ESPCAMERA) # Features dependent on other features ifneq ($(CIRCUITPY_USB),0) diff --git a/ports/espressif/peripherals/rmt.c b/ports/espressif/peripherals/rmt.c index 362bf85748ba..8dea2c0ab1bc 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/supervisor/port.c b/ports/espressif/supervisor/port.c index 6dd09ed238f9..db4a436b13e2 100644 --- a/ports/espressif/supervisor/port.c +++ b/ports/espressif/supervisor/port.c @@ -37,6 +37,7 @@ #include "freertos/task.h" #include "bindings/espidf/__init__.h" +#include "bindings/espnow/__init__.h" #include "bindings/espulp/__init__.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/analogio/AnalogOut.h" @@ -78,7 +79,7 @@ #include "shared-bindings/_bleio/__init__.h" #endif -#if CIRCUITPY_ESP32_CAMERA +#if CIRCUITPY_ESPCAMERA #include "esp_camera.h" #endif @@ -318,30 +319,30 @@ 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) { // TODO deinit for esp32-camera - #if CIRCUITPY_ESP32_CAMERA + #if CIRCUITPY_ESPCAMERA esp_camera_deinit(); #endif @@ -369,6 +370,10 @@ void reset_port(void) { dualbank_reset(); #endif + #if CIRCUITPY_ESPNOW + espnow_reset(); + #endif + #if CIRCUITPY_ESPULP espulp_reset(); #endif diff --git a/ports/espressif/tools/build_memory_info.py b/ports/espressif/tools/build_memory_info.py index df9d6a801e15..a11bef82bcc7 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 @@ def find_region(start_address): # 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/Makefile b/ports/litex/Makefile index efe99dc5b42e..5556dea11da1 100644 --- a/ports/litex/Makefile +++ b/ports/litex/Makefile @@ -136,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 d2e94c5b8d01..e641daf53be4 100644 --- a/ports/litex/background.c +++ b/ports/litex/background.c @@ -32,7 +32,9 @@ void port_background_task(void) { } -void port_start_background_task(void) { +void port_background_tick(void) { } -void port_finish_background_task(void) { +void port_start_background_tick(void) { +} +void port_finish_background_tick(void) { } diff --git a/ports/litex/boards/fomu/fomu-spi.ld b/ports/litex/boards/fomu/fomu-spi.ld index e7db25b0c5b4..33ba3db686b1 100644 --- a/ports/litex/boards/fomu/fomu-spi.ld +++ b/ports/litex/boards/fomu/fomu-spi.ld @@ -93,7 +93,7 @@ SECTIONS . = ALIGN(4); _etext = .; /* define a global symbol at end of code */ - _sidata = _etext; /* This is used by the startup in order to initialize the .data secion */ + _sidata = _etext; /* This is used by the startup in order to initialize the .data section */ } >FLASH_FIRMWARE /* Uninitialized data section */ diff --git a/ports/litex/common-hal/microcontroller/__init__.c b/ports/litex/common-hal/microcontroller/__init__.c index 0a496d804eed..1de55653fbe2 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/common-hal/neopixel_write/__init__.c b/ports/litex/common-hal/neopixel_write/__init__.c index e7e5600fb1ed..b26bbac69507 100644 --- a/ports/litex/common-hal/neopixel_write/__init__.c +++ b/ports/litex/common-hal/neopixel_write/__init__.c @@ -72,7 +72,7 @@ static void ledda_init(void) { // Set clock register to 12 MHz / 64 kHz - 1 ledda_write((12000000 / 64000) - 1, LEDDBR); - // Ensure LED "breathe" effect is diabled + // Ensure LED "breathe" effect is disabled ledda_write(0, LEDDBCRR); ledda_write(0, LEDDBCFR); diff --git a/ports/litex/crt0-vexriscv.S b/ports/litex/crt0-vexriscv.S index 0419acf8511d..0517711865c2 100644 --- a/ports/litex/crt0-vexriscv.S +++ b/ports/litex/crt0-vexriscv.S @@ -6,7 +6,7 @@ _start: j crt_init - # This sentinal ensures that this program is loaded + # This sentinel ensures that this program is loaded # to RAM when loaded using dfu-util. #.word 0x17ab0f23 #.word 0x10001000 diff --git a/ports/litex/supervisor/port.c b/ports/litex/supervisor/port.c index 42d3a639203c..45f9b91976ed 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/Makefile b/ports/mimxrt10xx/Makefile index 080a65e8fea3..72f4d191effc 100644 --- a/ports/mimxrt10xx/Makefile +++ b/ports/mimxrt10xx/Makefile @@ -30,8 +30,7 @@ CROSS_COMPILE = arm-none-eabi- INC += \ -I. \ -I../.. \ - -I../lib/mp-readline \ - -I../shared/timeutils \ + -I../../lib/cmsis/inc \ -I../../lib/tinyusb/src \ -I../../supervisor/shared/usb \ -I$(BUILD) \ @@ -39,17 +38,21 @@ INC += \ -Iboards/$(BOARD) \ -Iperipherals/ \ -Iperipherals/mimxrt10xx/ \ - -Isdk/CMSIS/Include \ -Isdk/devices/$(CHIP_FAMILY) \ -Isdk/devices/$(CHIP_FAMILY)/drivers \ - -Isdk/devices/$(CHIP_FAMILY)/xip \ + -Isdk/drivers/common # NDEBUG disables assert() statements. This reduces code size pretty dramatically, per tannewt. CFLAGS += -ftree-vrp -DNDEBUG # TinyUSB defines -CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX -DCFG_TUD_MIDI_RX_BUFSIZE=512 -DCFG_TUD_CDC_RX_BUFSIZE=512 -DCFG_TUD_MIDI_TX_BUFSIZE=512 -DCFG_TUD_CDC_TX_BUFSIZE=512 -DCFG_TUD_MSC_BUFSIZE=1024 +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX -DCFG_TUD_CDC_RX_BUFSIZE=512 -DCFG_TUD_CDC_TX_BUFSIZE=512 +ifeq ($(CHIP_FAMILY), MIMXRT1011) +CFLAGS += -DCFG_TUD_MIDI_RX_BUFSIZE=64 -DCFG_TUD_MIDI_TX_BUFSIZE=64 -DCFG_TUD_MSC_BUFSIZE=512 +else +CFLAGS += -DCFG_TUD_MIDI_RX_BUFSIZE=512 -DCFG_TUD_MIDI_TX_BUFSIZE=512 -DCFG_TUD_MSC_BUFSIZE=1024 +endif #Debugging/Optimization # Never set -fno-inline because we use inline to move small functions into routines that must be @@ -76,11 +79,15 @@ CFLAGS += \ -g3 -Wno-unused-parameter \ -ffunction-sections -fdata-sections -fstack-usage -OPTIMIZATION_FLAGS ?= -O2 -fno-inline-functions +OPTIMIZATION_FLAGS ?= -O2 # option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk CFLAGS += $(OPTIMIZATION_FLAGS) +ifeq ($(CIRCUITPY_SWO_TRACE), 1) + CFLAGS += -finstrument-functions -finstrument-functions-exclude-file-list=tinyusb -finstrument-functions-exclude-function-list='USB_OTG1_IRQHandler,usb_irq_handler,nlr_push,CLOCK_EnableClock,CLOCK_SetDiv,CLOCK_SetMux,__DMB,__ISB,__DSB,SCB_EnableICache,SCB_EnableDCache,ARM_MPU_Disable,ARM_MPU_Enable,SCB_DisableDCache,SCB_DisableICache,__enable_irq,__disable_irq,__set_MSP,port_get_raw_ticks,supervisor_ticks_ms64' +endif + LD_FILES = $(wildcard boards/$(BOARD)/*.ld) $(addprefix linking/, flash/$(FLASH).ld chip_family/$(CHIP_FAMILY).ld common.ld) LD_SCRIPT_FLAG := -Wl,-T, @@ -97,24 +104,27 @@ LDFLAGS += -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-sp-d16 -mthumb -mapcs BOOTLOADER_SIZE := 0x6000C000 SRC_SDK := \ - drivers/fsl_adc.c \ - drivers/fsl_cache.c \ - drivers/fsl_clock.c \ - drivers/fsl_common.c \ - drivers/fsl_flexspi.c \ - drivers/fsl_gpio.c \ - drivers/fsl_lpi2c.c \ - drivers/fsl_lpspi.c \ - drivers/fsl_lpuart.c \ - drivers/fsl_ocotp.c \ - drivers/fsl_pwm.c \ - drivers/fsl_snvs_hp.c \ - drivers/fsl_tempmon.c \ - drivers/fsl_trng.c \ - system_$(CHIP_FAMILY).c \ - -SRC_SDK := $(addprefix sdk/devices/$(CHIP_FAMILY)/, $(SRC_SDK)) -$(addprefix $(BUILD)/, $(SRC_SDK:.c=.o)): CFLAGS += -Wno-undef -Wno-missing-prototypes -Wno-cast-align + devices/$(CHIP_FAMILY)/drivers/fsl_clock.c \ + devices/$(CHIP_FAMILY)/system_$(CHIP_FAMILY).c \ + devices/$(CHIP_FAMILY)/xip/fsl_flexspi_nor_boot.c \ + drivers/adc_12b1msps_sar/fsl_adc.c \ + drivers/cache/armv7-m7/fsl_cache.c \ + drivers/common/fsl_common_arm.c \ + drivers/common/fsl_common.c \ + drivers/flexspi/fsl_flexspi.c \ + drivers/igpio/fsl_gpio.c \ + drivers/lpi2c/fsl_lpi2c.c \ + drivers/lpspi/fsl_lpspi.c \ + drivers/lpuart/fsl_lpuart.c \ + drivers/ocotp/fsl_ocotp.c \ + drivers/pwm/fsl_pwm.c \ + drivers/sai/fsl_sai.c \ + drivers/snvs_hp/fsl_snvs_hp.c \ + drivers/snvs_lp/fsl_snvs_lp.c \ + drivers/tempmon/fsl_tempmon.c \ + drivers/trng/fsl_trng.c \ + +SRC_SDK := $(addprefix sdk/, $(SRC_SDK)) SRC_C += \ background.c \ @@ -126,6 +136,7 @@ SRC_C += \ peripherals/mimxrt10xx/$(CHIP_FAMILY)/clocks.c \ peripherals/mimxrt10xx/$(CHIP_FAMILY)/periph.c \ peripherals/mimxrt10xx/$(CHIP_FAMILY)/pins.c \ + peripherals/mimxrt10xx/pins.c \ reset.c \ supervisor/flexspi_nor_flash_ops.c @@ -136,11 +147,6 @@ SRC_C += \ endif -# TODO -#ifeq ($(CIRCUITPY_AUDIOBUSIO),1) -#SRC_C += peripherals/samd/i2s.c peripherals/samd/$(CHIP_FAMILY)/i2s.c -#endif -# SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ $(addprefix common-hal/, $(SRC_COMMON_HAL)) @@ -170,20 +176,21 @@ all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 $(BUILD)/firmware.hex $(BUILD)/firmware.elf: $(OBJ) $(LD_FILES) $(STEPECHO) "LINK $@" - $(Q)$(CC) -o $@ $(LDFLAGS) $(filter-out %.ld, $^) -Wl,--start-group $(LIBS) -Wl,--end-group + $(Q)$(CC) -o $@ $(LDFLAGS) $(filter-out %.ld, $^) -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group +# -R excludes sections from the output files. $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(STEPECHO) "Create $@" - $(Q)$(OBJCOPY) -O binary -j .flash_config -j .ivt -j .text -j .ARM.exidx -j .data -j .itcm -j .dtcm_data $^ $@ + $(Q)$(OBJCOPY) -O binary -R .stack -R .dtcm_bss $^ $@ $(BUILD)/firmware.uf2: $(BUILD)/firmware.elf $(STEPECHO) "Create $@" - $(Q)$(OBJCOPY) -O binary -j .text -j .ARM.exidx -j .data -j .itcm -j .dtcm_data $^ $@-binpart + $(Q)$(OBJCOPY) -O binary -R .stack -R .dtcm_bss -R .ivt -R .flash_config $^ $@-binpart $(Q)$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -b $(BOOTLOADER_SIZE) -f MIMXRT10XX -c -o $@ $@-binpart $(Q)rm $@-binpart $(BUILD)/firmware.hex: $(BUILD)/firmware.elf - $(Q)$(OBJCOPY) -O ihex -j .flash_config -j .ivt -j .text -j .ARM.exidx -j .data -j .itcm -j .dtcm_data $< $@ + $(Q)$(OBJCOPY) -O ihex -R .stack -R .dtcm_bss $< $@ include $(TOP)/py/mkrules.mk diff --git a/ports/mimxrt10xx/background.c b/ports/mimxrt10xx/background.c index 9e531cea23e4..04de4c1c1c07 100644 --- a/ports/mimxrt10xx/background.c +++ b/ports/mimxrt10xx/background.c @@ -27,12 +27,18 @@ #include "supervisor/port.h" -void port_background_task(void) { - #if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO - audio_dma_background(); - #endif +#include "supervisor/linker.h" + +#include "fsl_common.h" + +void PLACE_IN_ITCM(port_background_task)(void) { +} + +void port_background_tick(void) { } -void port_start_background_task(void) { + +void port_start_background_tick(void) { } -void port_finish_background_task(void) { + +void port_finish_background_tick(void) { } diff --git a/ports/mimxrt10xx/board.h b/ports/mimxrt10xx/board.h deleted file mode 100644 index 1c9596e7d2dd..000000000000 --- a/ports/mimxrt10xx/board.h +++ /dev/null @@ -1 +0,0 @@ -// Empty but needed for the SDK diff --git a/ports/mimxrt10xx/boards/board.h b/ports/mimxrt10xx/boards/board.h new file mode 100644 index 000000000000..e6736806ed8c --- /dev/null +++ b/ports/mimxrt10xx/boards/board.h @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 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 "mpconfigboard.h" + +#define XIP_BOOT_HEADER_ENABLE (1) diff --git a/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c b/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c index 5871dda963ea..4e189590d0ab 100644 --- a/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c +++ b/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c @@ -7,47 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q32JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -61,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, // Bit pattern for setting Quad Enable. - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, + .serialClkFreq = kFLEXSPISerialClk_133MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -78,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -101,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status -2 - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01 /* number of bytes to write */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -128,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -147,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c b/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c index 7460615c4c9a..2c6fa962aaab 100644 --- a/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c +++ b/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c @@ -7,47 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q64JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -61,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, + .serialClkFreq = kFLEXSPISerialClk_133MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -78,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -101,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -128,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -147,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c b/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c index d6cfc07e627d..2c6fa962aaab 100644 --- a/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c +++ b/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c @@ -7,48 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q64JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -62,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, + .serialClkFreq = kFLEXSPISerialClk_133MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -79,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -102,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -129,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -148,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/flash_config.h b/ports/mimxrt10xx/boards/flash_config.h index 25f1550ae8ba..b0be0a93c08b 100644 --- a/ports/mimxrt10xx/boards/flash_config.h +++ b/ports/mimxrt10xx/boards/flash_config.h @@ -34,7 +34,41 @@ #include "mpconfigboard.h" // For flash size settings #include "fsl_common.h" -#include "fsl_flexspi_nor_config.h" +#ifdef CPU_MIMXRT1011DAE5A +// TODO: Remove this when the 1011 has a romapi header that matches the others. +#include "sdk/boards/evkmimxrt1010/xip/evkmimxrt1010_flexspi_nor_config.h" +typedef enum _flexspi_serial_clk_freq_caps +{ + kFLEXSPISerialClk_NoChange = 0U, + kFLEXSPISerialClk_30MHz = 1U, + kFLEXSPISerialClk_50MHz = 2U, + kFLEXSPISerialClk_60MHz = 3U, + kFLEXSPISerialClk_75MHz = 4U, + kFLEXSPISerialClk_80MHz = 5U, + kFLEXSPISerialClk_100MHz = 6U, + kFLEXSPISerialClk_133MHz = 7U, + kFLEXSPISerialClk_166MHz = 8U, + kFLEXSPISerialClk_200MHz = 9U, +} caps_flexspi_serial_clk_freq_t; + +/*! @brief FLEXSPI Read Sample Clock Source definition */ +typedef enum _flexspi_read_sample_clk_caps +{ + kFLEXSPIReadSampleClk_LoopbackInternally = 0U, + kFLEXSPIReadSampleClk_LoopbackFromDqsPad = 1U, + kFLEXSPIReadSampleClk_LoopbackFromSckPad = 2U, + kFLEXSPIReadSampleClk_ExternalInputFromDqsPad = 3U, +} caps_flexspi_read_sample_clk_t; + +enum +{ + kFLEXSPIDeviceType_SerialNOR = 1U, /*!< Flash device is Serial NOR */ +}; + +#define FSL_ROM_FLEXSPI_LUT_SEQ FLEXSPI_LUT_SEQ +#else +#include "fsl_romapi.h" +#endif #define SEQUENCE(first, second, third, fourth) first, second, third, fourth #define TWO_EMPTY_STEPS 0x00000000 diff --git a/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c b/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c index 9c88f689d8e4..f15a3f345911 100644 --- a/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c +++ b/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c @@ -7,48 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for AT25SF128A with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -62,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -79,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -102,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -129,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -148,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h b/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h index 77d458d75b6b..192c265f883e 100644 --- a/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h +++ b/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h @@ -16,3 +16,8 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO_09) #define DEFAULT_UART_BUS_TX (&pin_GPIO_10) + +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO_09) +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO_10) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO_11) diff --git a/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c b/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c index 6589ad9c4875..2ae8ae9b7646 100644 --- a/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c +++ b/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c @@ -7,48 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for IS25LP064A with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -62,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x40, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_30MHz, + .serialClkFreq = kFLEXSPISerialClk_30MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -79,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - // SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + // SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, // RADDR_SDR, FLEXSPI_4PAD, 24 bits to transmit ), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, // READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -102,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -129,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -148,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c b/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c index 40db33444fb0..c75174d1c4a1 100644 --- a/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c +++ b/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c @@ -7,48 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for IS25WP064A with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -62,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x40, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -79,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -102,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -129,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -148,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/metro_m7_1011/board.c b/ports/mimxrt10xx/boards/metro_m7_1011/board.c index 27cbd3eb9657..62be2303a5f6 100644 --- a/ports/mimxrt10xx/boards/metro_m7_1011/board.c +++ b/ports/mimxrt10xx/boards/metro_m7_1011/board.c @@ -47,3 +47,18 @@ const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { }; // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. + +bool mimxrt10xx_board_reset_pin_number(const mcu_pin_obj_t *pin) { + #if CIRCUITPY_SWO_TRACE + if (pin == &pin_GPIO_AD_09) { + IOMUXC_SetPinMux( /* Add these lines*/ + IOMUXC_GPIO_AD_09_ARM_TRACE_SWO, + 0U); + IOMUXC_SetPinConfig( /* Add these lines*/ + IOMUXC_GPIO_AD_09_ARM_TRACE_SWO, + 0x00F9U); + return true; + } + #endif + return false; +} diff --git a/ports/mimxrt10xx/boards/metro_m7_1011/flash_config.c b/ports/mimxrt10xx/boards/metro_m7_1011/flash_config.c index b2894d766962..e4562c19650c 100644 --- a/ports/mimxrt10xx/boards/metro_m7_1011/flash_config.c +++ b/ports/mimxrt10xx/boards/metro_m7_1011/flash_config.c @@ -7,48 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q32JV with QSPI routed. (compatible with GD25Q32) __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -68,13 +41,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqId = 2u, .seqNum = 1u, }, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -85,48 +58,48 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 2: Empty - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35 /* the command to send */, DUMMY_SDR, FLEXSPI_1PAD, 8), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -139,17 +112,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -158,7 +131,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/metro_m7_1011/mpconfigboard.h b/ports/mimxrt10xx/boards/metro_m7_1011/mpconfigboard.h index 23009f353fa7..589b2a2b6528 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 2655217c7880..56155aa4d024 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/metro_m7_1011/pins.c b/ports/mimxrt10xx/boards/metro_m7_1011/pins.c index 886909e1ddd7..98082e3c1172 100644 --- a/ports/mimxrt10xx/boards/metro_m7_1011/pins.c +++ b/ports/mimxrt10xx/boards/metro_m7_1011/pins.c @@ -38,8 +38,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_GPIO_SD_05) }, { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_GPIO_AD_11) }, { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_GPIO_AD_07) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_GPIO_09) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_GPIO_10) }, + // These RX and TX are from the point of view of the i.MX microcontroller. + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_GPIO_09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_GPIO_10) }, // SPI { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO_AD_06) }, @@ -56,5 +57,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { 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_I2S_WSEL), MP_ROM_PTR(&pin_GPIO_06) }, // D10 + { MP_ROM_QSTR(MP_QSTR_I2S_BCLK), MP_ROM_PTR(&pin_GPIO_07) }, // D9 + { MP_ROM_QSTR(MP_QSTR_I2S_DOUT), MP_ROM_PTR(&pin_GPIO_04) }, // D12 }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/flash_config.c b/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/flash_config.c index e0f5a5bd7db2..abc26a2bcd39 100644 --- a/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/flash_config.c +++ b/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/flash_config.c @@ -7,50 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - 0x432000D1, /* Teensy bootloader looks for this value*/ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -extern unsigned long _flashimagelen; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - (uint32_t)&_flashimagelen, /* actual size of image */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q64JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -64,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -81,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -104,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -131,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -150,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/teensy40/flash_config.c b/ports/mimxrt10xx/boards/teensy40/flash_config.c index d878124b40a1..30d40d7c8486 100644 --- a/ports/mimxrt10xx/boards/teensy40/flash_config.c +++ b/ports/mimxrt10xx/boards/teensy40/flash_config.c @@ -7,50 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - 0x432000D1, /* Teensy bootloader looks for this value*/ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -extern unsigned long _flashimagelen; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - (uint32_t)&_flashimagelen, /* actual size of image */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q16JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -70,13 +41,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqId = 2u, .seqNum = 1u, }, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -87,48 +58,48 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 2: Empty - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35 /* the command to send */, DUMMY_SDR, FLEXSPI_1PAD, 8), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -141,17 +112,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -160,7 +131,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/teensy41/flash_config.c b/ports/mimxrt10xx/boards/teensy41/flash_config.c index e0f5a5bd7db2..abc26a2bcd39 100644 --- a/ports/mimxrt10xx/boards/teensy41/flash_config.c +++ b/ports/mimxrt10xx/boards/teensy41/flash_config.c @@ -7,50 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - 0x432000D1, /* Teensy bootloader looks for this value*/ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -extern unsigned long _flashimagelen; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - (uint32_t)&_flashimagelen, /* actual size of image */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q64JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -64,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -81,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -104,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -131,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -150,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c b/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c index f5d2e7f42eb3..237566b1f017 100644 --- a/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c +++ b/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c @@ -33,7 +33,7 @@ #include "py/runtime.h" -#include "fsl_adc.h" +#include "sdk/drivers/adc_12b1msps_sar/fsl_adc.h" #define ADC_CHANNEL_GROUP 0 diff --git a/ports/mimxrt10xx/common-hal/audiobusio/I2SOut.c b/ports/mimxrt10xx/common-hal/audiobusio/I2SOut.c new file mode 100644 index 000000000000..06765afe0284 --- /dev/null +++ b/ports/mimxrt10xx/common-hal/audiobusio/I2SOut.c @@ -0,0 +1,154 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 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 + +#include "mpconfigport.h" + +// Some boards don't implement I2SOut, so suppress any routines from here. +#if CIRCUITPY_AUDIOBUSIO_I2SOUT + +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "common-hal/audiobusio/I2SOut.h" +#include "shared-bindings/audiobusio/I2SOut.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/translate/translate.h" +#include "supervisor/shared/tick.h" + +// Where required we use identifier names that are required by NXP's +// API, even though they do not conform to the naming standards that Adafruit +// strives to adhere to. https://www.adafruit.com/blacklivesmatter +#include "sdk/drivers/sai/fsl_sai.h" + +STATIC void config_periph_pin(const mcu_periph_obj_t *periph) { + if (!periph) { + return; + } + if (periph->pin->mux_reg) { + IOMUXC_SetPinMux( + periph->pin->mux_reg, periph->mux_mode, + periph->input_reg, periph->input_idx, + 0, + 1); + } + + IOMUXC_SetPinConfig(0, 0, 0, 0, + periph->pin->cfg_reg, + IOMUXC_SW_PAD_CTL_PAD_HYS(0) + | IOMUXC_SW_PAD_CTL_PAD_PUS(0) + | IOMUXC_SW_PAD_CTL_PAD_PUE(0) + | IOMUXC_SW_PAD_CTL_PAD_PKE(1) + | IOMUXC_SW_PAD_CTL_PAD_ODE(0) + | IOMUXC_SW_PAD_CTL_PAD_SPEED(2) + | IOMUXC_SW_PAD_CTL_PAD_DSE(4) + | IOMUXC_SW_PAD_CTL_PAD_SRE(0)); +} + +// Caller validates that pins are free. +void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, + const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, + const mcu_pin_obj_t *data, bool left_justified) { + + int instance = -1; + const mcu_periph_obj_t *bclk_periph = find_pin_function(mcu_sai_tx_bclk_list, bit_clock, &instance, MP_QSTR_bit_clock); + const mcu_periph_obj_t *sync_periph = find_pin_function(mcu_sai_tx_sync_list, word_select, &instance, MP_QSTR_word_select); + const mcu_periph_obj_t *data_periph = find_pin_function(mcu_sai_tx_data0_list, data, &instance, MP_QSTR_data); + + sai_transceiver_t config; + SAI_GetClassicI2SConfig(&config, 16, kSAI_Stereo, 1); + config.syncMode = kSAI_ModeAsync; + config.fifo.fifoPacking = kSAI_FifoPackingDisabled; + // These identifier names are required by NXP's API, even though they do + // not conform to the naming standards that Adafruit strives to adhere to. + // https://www.adafruit.com/blacklivesmatter + config.masterSlave = kSAI_Master; + port_i2s_initialize(&self->i2s, instance, &config); + + self->bit_clock = bit_clock; + self->word_select = word_select; + self->data = data; + claim_pin(bit_clock); + claim_pin(word_select); + claim_pin(data); + config_periph_pin(data_periph); + config_periph_pin(sync_periph); + config_periph_pin(bclk_periph); +} + +bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t *self) { + return port_i2s_deinited(&self->i2s); +} + +void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t *self) { + if (common_hal_audiobusio_i2sout_deinited(self)) { + return; + } + + port_i2s_deinit(&self->i2s); + + common_hal_reset_pin(self->bit_clock); + self->bit_clock = NULL; + + common_hal_reset_pin(self->word_select); + self->word_select = NULL; + + common_hal_reset_pin(self->data); + self->data = NULL; +} + +void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, + mp_obj_t sample, bool loop) { + if (common_hal_audiobusio_i2sout_get_playing(self)) { + common_hal_audiobusio_i2sout_stop(self); + } + port_i2s_play(&self->i2s, sample, loop); +} + +void common_hal_audiobusio_i2sout_pause(audiobusio_i2sout_obj_t *self) { + port_i2s_pause(&self->i2s); +} + +void common_hal_audiobusio_i2sout_resume(audiobusio_i2sout_obj_t *self) { + port_i2s_resume(&self->i2s); +} + +bool common_hal_audiobusio_i2sout_get_paused(audiobusio_i2sout_obj_t *self) { + return port_i2s_get_paused(&self->i2s); +} + +void common_hal_audiobusio_i2sout_stop(audiobusio_i2sout_obj_t *self) { + port_i2s_stop(&self->i2s); +} + +bool common_hal_audiobusio_i2sout_get_playing(audiobusio_i2sout_obj_t *self) { + return port_i2s_get_playing(&self->i2s); +} + +#endif // CIRCUITPY_AUDIOBUSIO_I2SOUT diff --git a/ports/mimxrt10xx/common-hal/audiobusio/I2SOut.h b/ports/mimxrt10xx/common-hal/audiobusio/I2SOut.h new file mode 100644 index 000000000000..319e52c1592f --- /dev/null +++ b/ports/mimxrt10xx/common-hal/audiobusio/I2SOut.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 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 + +// Some boards don't implement I2SOut, so suppress any routines from here. +#if CIRCUITPY_AUDIOBUSIO_I2SOUT +#include "supervisor/background_callback.h" +#include "common-hal/microcontroller/Pin.h" + +#include "common-hal/audiobusio/__init__.h" + +typedef struct { + mp_obj_base_t base; + i2s_t i2s; + const mcu_pin_obj_t *bit_clock; + const mcu_pin_obj_t *word_select; + const mcu_pin_obj_t *data; +} audiobusio_i2sout_obj_t; + +#endif diff --git a/ports/mimxrt10xx/common-hal/audiobusio/PDMIn.c b/ports/mimxrt10xx/common-hal/audiobusio/PDMIn.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ports/mimxrt10xx/common-hal/audiobusio/PDMIn.h b/ports/mimxrt10xx/common-hal/audiobusio/PDMIn.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ports/mimxrt10xx/common-hal/audiobusio/__init__.c b/ports/mimxrt10xx/common-hal/audiobusio/__init__.c new file mode 100644 index 000000000000..13ae64d27cb6 --- /dev/null +++ b/ports/mimxrt10xx/common-hal/audiobusio/__init__.c @@ -0,0 +1,464 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 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/runtime.h" + +#include "common-hal/audiobusio/__init__.h" +#include "shared-module/audiocore/__init__.h" + +#define SAI_CLOCK_SOURCE_SELECT (2U) +#define SAI_CLOCK_SOURCE_DIVIDER (63U) +#define SAI_CLOCK_SOURCE_PRE_DIVIDER (0U) + +#define SAI_CLOCK_FREQ (CLOCK_GetFreq(kCLOCK_AudioPllClk) / (SAI_CLOCK_SOURCE_DIVIDER + 1U) / \ + (SAI_CLOCK_SOURCE_PRE_DIVIDER + 1U)) + +#define AUDIO_BUFFER_FRAME_COUNT (128) // in uint32_t; there are 4, giving 2048 bytes. In all they hold 10ms @ stereo 16-bit 48kHz before all buffers drain + +/* + * AUDIO PLL setting: Frequency = Fref * (DIV_SELECT + NUM / DENOM) + * = 24 * (32 + 96 / 125) = 24 * (32.768) + * = 786.432 MHz = 48kHz * 16384 + * + * This default clocking is used during initial configuration; it also works well for + * frequencies that evenly divide 192kHz, such as 8/12/24/48kHz. However, it doesn't work + * well for 44.1/22/11kHz, so there's the possibility of using a different + * setting when playing a particular sample. + */ +const clock_audio_pll_config_t audioPllConfig = { + .loopDivider = 32, /* PLL loop divider. Valid range for DIV_SELECT divider value: 27~54. */ + .postDivider = 1, /* Divider after the PLL, should only be 1, 2, 4, 8, 16. */ + .numerator = 96, /* 30 bit numerator of fractional loop divider. */ + .denominator = 125, /* 30 bit denominator of fractional loop divider */ +}; + +static I2S_Type *const i2s_instances[] = I2S_BASE_PTRS; +static uint8_t i2s_in_use, i2s_playing; + +static I2S_Type *SAI_GetPeripheral(int idx) { + if (idx < 0 || idx >= (int)MP_ARRAY_SIZE(i2s_instances)) { + return NULL; + } + return i2s_instances[idx]; +} + +static int SAI_GetInstance(I2S_Type *peripheral) { + for (size_t i = 0; i < MP_ARRAY_SIZE(i2s_instances); i++) { if (peripheral == i2s_instances[i]) { + return i; + } + } + return -1; +} + +static bool i2s_clock_off(I2S_Type *peripheral) { + int index = SAI_GetInstance(peripheral); + switch (index) { + #if defined(SAI0) + case 0: + CLOCK_DisableClock(kCLOCK_Sai0); + return true; + #endif + #if defined(SAI1) + case 1: + CLOCK_DisableClock(kCLOCK_Sai1); + return true; + #endif + #if defined(SAI2) + case 2: + CLOCK_DisableClock(kCLOCK_Sai2); + return true; + #endif + #if defined(SAI3) + case 3: + CLOCK_DisableClock(kCLOCK_Sai3); + return true; + #endif + #if defined(SAI4) + case 4: + CLOCK_DisableClock(kCLOCK_Sai4); + return true; + #endif + #if defined(SAI5) + case 5: + CLOCK_DisableClock(kCLOCK_Sai5); + return true; + #endif + #if defined(SAI6) + case 6: + CLOCK_DisableClock(kCLOCK_Sai6); + return true; + #endif + #if defined(SAI7) + case 7: + CLOCK_DisableClock(kCLOCK_Sai7); + return true; + #endif + } + return false; +} + +static bool i2s_clocking(I2S_Type *peripheral) { + int index = SAI_GetInstance(peripheral); + switch (index) { + #if defined(SAI0) + case 0: + CLOCK_SetDiv(kCLOCK_Sai0PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER); + CLOCK_SetDiv(kCLOCK_Sai0Div, SAI_CLOCK_SOURCE_DIVIDER); + CLOCK_SetMux(kCLOCK_Sai0Mux, SAI_CLOCK_SOURCE_SELECT); + CLOCK_EnableClock(kCLOCK_Sai0); + return true; + #endif + #if defined(SAI1) + case 1: + CLOCK_SetDiv(kCLOCK_Sai1PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER); + CLOCK_SetDiv(kCLOCK_Sai1Div, SAI_CLOCK_SOURCE_DIVIDER); + CLOCK_SetMux(kCLOCK_Sai1Mux, SAI_CLOCK_SOURCE_SELECT); + CLOCK_EnableClock(kCLOCK_Sai1); + return true; + #endif + #if defined(SAI2) + case 2: + CLOCK_SetDiv(kCLOCK_Sai2PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER); + CLOCK_SetDiv(kCLOCK_Sai2Div, SAI_CLOCK_SOURCE_DIVIDER); + CLOCK_SetMux(kCLOCK_Sai2Mux, SAI_CLOCK_SOURCE_SELECT); + CLOCK_EnableClock(kCLOCK_Sai2); + return true; + #endif + #if defined(SAI3) + case 3: + CLOCK_SetDiv(kCLOCK_Sai3PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER); + CLOCK_SetDiv(kCLOCK_Sai3Div, SAI_CLOCK_SOURCE_DIVIDER); + CLOCK_SetMux(kCLOCK_Sai3Mux, SAI_CLOCK_SOURCE_SELECT); + CLOCK_EnableClock(kCLOCK_Sai3); + return true; + #endif + #if defined(SAI4) + case 4: + CLOCK_SetDiv(kCLOCK_Sai4PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER); + CLOCK_SetDiv(kCLOCK_Sai4Div, SAI_CLOCK_SOURCE_DIVIDER); + CLOCK_SetMux(kCLOCK_Sai4Mux, SAI_CLOCK_SOURCE_SELECT); + CLOCK_EnableClock(kCLOCK_Sai4); + return true; + #endif + #if defined(SAI5) + case 5: + CLOCK_SetDiv(kCLOCK_Sai5PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER); + CLOCK_SetDiv(kCLOCK_Sai5Div, SAI_CLOCK_SOURCE_DIVIDER); + CLOCK_SetMux(kCLOCK_Sai5Mux, SAI_CLOCK_SOURCE_SELECT); + CLOCK_EnableClock(kCLOCK_Sai5); + return true; + #endif + #if defined(SAI6) + case 6: + CLOCK_SetDiv(kCLOCK_Sai6PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER); + CLOCK_SetDiv(kCLOCK_Sai6Div, SAI_CLOCK_SOURCE_DIVIDER); + CLOCK_SetMux(kCLOCK_Sai6Mux, SAI_CLOCK_SOURCE_SELECT); + CLOCK_EnableClock(kCLOCK_Sai6); + return true; + #endif + #if defined(SAI7) + case 7: + CLOCK_SetDiv(kCLOCK_Sai7PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER); + CLOCK_SetDiv(kCLOCK_Sai7Div, SAI_CLOCK_SOURCE_DIVIDER); + CLOCK_SetMux(kCLOCK_Sai7Mux, SAI_CLOCK_SOURCE_SELECT); + CLOCK_EnableClock(kCLOCK_Sai7); + return true; + #endif + } + return false; +} + + +static bool i2s_queue_available(i2s_t *self) { + return !self->handle.saiQueue[self->handle.queueUser].data; +} + +static void i2s_fill_buffer(i2s_t *self) { + if (!self->peripheral) { + return; + } + while (i2s_queue_available(self)) { + uint32_t *buffer = self->buffers[self->buffer_idx]; + uint32_t *ptr = buffer, *end = buffer + AUDIO_BUFFER_FRAME_COUNT; + self->buffer_idx = (self->buffer_idx + 1) % SAI_XFER_QUEUE_SIZE; + + while (self->playing && !self->paused && ptr < end) { + if (self->sample_data == self->sample_end) { + if (self->stopping) { + // non-looping sample, previously returned GET_BUFFER_DONE + self->playing = false; + break; + } + uint32_t sample_buffer_length; + audioio_get_buffer_result_t get_buffer_result = + audiosample_get_buffer(self->sample, false, 0, + &self->sample_data, &sample_buffer_length); + self->sample_end = self->sample_data + sample_buffer_length; + if (get_buffer_result == GET_BUFFER_DONE) { + if (self->loop) { + audiosample_reset_buffer(self->sample, false, 0); + } else { + self->stopping = true; + } + } + if (get_buffer_result == GET_BUFFER_ERROR || sample_buffer_length == 0) { + self->stopping = true; + } + } + size_t input_bytecount = self->sample_end - self->sample_data; + size_t bytes_per_input_frame = self->channel_count * self->bytes_per_sample; + size_t framecount = MIN((size_t)(end - ptr), input_bytecount / bytes_per_input_frame); + +#define SAMPLE_TYPE(is_signed, channel_count, bytes_per_sample) ((is_signed) | ((channel_count) << 1) | ((bytes_per_sample) << 3)) + + switch (SAMPLE_TYPE(self->samples_signed, self->channel_count, self->bytes_per_sample)) { + + case SAMPLE_TYPE(true, 2, 2): + memcpy(ptr, self->sample_data, 4 * framecount); + break; + + case SAMPLE_TYPE(false, 2, 2): + audiosample_convert_u16s_s16s((int16_t *)ptr, (uint16_t *)(void *)self->sample_data, framecount); + break; + + case SAMPLE_TYPE(true, 1, 2): + audiosample_convert_s16m_s16s((int16_t *)ptr, (int16_t *)(void *)self->sample_data, framecount); + break; + + case SAMPLE_TYPE(false, 1, 2): + audiosample_convert_u16m_s16s((int16_t *)ptr, (uint16_t *)(void *)self->sample_data, framecount); + break; + + case SAMPLE_TYPE(true, 2, 1): + audiosample_convert_s8s_s16s((int16_t *)ptr, (int8_t *)(void *)self->sample_data, framecount); + memcpy(ptr, self->sample_data, 4 * framecount); + break; + + case SAMPLE_TYPE(false, 2, 1): + audiosample_convert_u8s_s16s((int16_t *)ptr, (uint8_t *)(void *)self->sample_data, framecount); + break; + + case SAMPLE_TYPE(true, 1, 1): + audiosample_convert_s8m_s16s((int16_t *)ptr, (int8_t *)(void *)self->sample_data, framecount); + break; + + case SAMPLE_TYPE(false, 1, 1): + audiosample_convert_u8m_s16s((int16_t *)ptr, (uint8_t *)(void *)self->sample_data, framecount); + break; + } + self->sample_data += bytes_per_input_frame * framecount; // in bytes + ptr += framecount; // in frames + } + // Fill any remaining portion of the buffer with 'no sound' + memset(ptr, 0, (end - ptr) * sizeof(uint32_t)); + sai_transfer_t xfer = { + .data = (uint8_t *)buffer, + .dataSize = AUDIO_BUFFER_FRAME_COUNT * sizeof(uint32_t), + }; + int r = SAI_TransferSendNonBlocking(self->peripheral, &self->handle, &xfer); + if (r != kStatus_Success) { + mp_printf(&mp_plat_print, "transfer returned %d\n", (int)r); + } + } +} + +static void i2s_callback_fun(void *self_in) { + i2s_t *self = self_in; + i2s_fill_buffer(self); +} + +static void i2s_transfer_callback(I2S_Type *base, sai_handle_t *handle, status_t status, void *self_in) { + i2s_t *self = self_in; + if (status == kStatus_SAI_TxIdle) { + // a block has been finished + background_callback_add(&self->callback, i2s_callback_fun, self_in); + } +} + + +void port_i2s_initialize(i2s_t *self, int instance, sai_transceiver_t *config) { + if (!i2s_in_use) { + // need to set audio pll up! + + /* DeInit Audio PLL. */ + CLOCK_DeinitAudioPll(); + /* Bypass Audio PLL. */ + CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1); + /* Set divider for Audio PLL. */ + CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; + CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK; + /* Enable Audio PLL output. */ + CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; + + CLOCK_InitAudioPll(&audioPllConfig); + } + + I2S_Type *peripheral = SAI_GetPeripheral(instance); + if (!peripheral) { + mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_I2SOut); + } + if (i2s_in_use & (1 << instance)) { + mp_raise_ValueError_varg(translate("%q in use"), MP_QSTR_I2SOut); + } + if (!i2s_clocking(peripheral)) { + mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_I2SOut); + } + for (size_t i = 0; i < MP_ARRAY_SIZE(self->buffers); i++) { + self->buffers[i] = m_malloc(AUDIO_BUFFER_FRAME_COUNT * sizeof(uint32_t), false); + } + self->peripheral = peripheral; + SAI_Init(self->peripheral); + SAI_TransferTxCreateHandle(peripheral, &self->handle, i2s_transfer_callback, (void *)self); + SAI_TransferTxSetConfig(peripheral, &self->handle, config); + self->sample_rate = 0; + i2s_in_use |= (1 << instance); +} + +bool port_i2s_deinited(i2s_t *self) { + return !self->peripheral; +} + +void port_i2s_deinit(i2s_t *self) { + if (port_i2s_deinited(self)) { + return; + } + SAI_TransferAbortSend(self->peripheral, &self->handle); + i2s_clock_off(self->peripheral); + + uint32_t instance_mask = 1 << SAI_GetInstance(self->peripheral); + i2s_in_use &= ~instance_mask; + i2s_playing &= ~instance_mask; + + if (!i2s_in_use) { + CCM_ANALOG->PLL_AUDIO = CCM_ANALOG_PLL_AUDIO_BYPASS_MASK | CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK | CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC(kCLOCK_PllClkSrc24M); + } + self->peripheral = NULL; + for (size_t i = 0; i < MP_ARRAY_SIZE(self->buffers); i++) { + self->buffers[i] = NULL; + } +} + +static uint32_t gcd(uint32_t a, uint32_t b) { + while (b) { + uint32_t tmp = a % b; + a = b; + b = tmp; + } + return a; +} + +static void set_sai_clocking_for_sample_rate(uint32_t sample_rate) { + mp_arg_validate_int_range((mp_uint_t)sample_rate, 4000, 192000, MP_QSTR_sample_rate); + + uint32_t target_rate = sample_rate; + // ensure the PWM rate of MQS will be adequately high + while (target_rate < 175000) { + target_rate <<= 1; + } + target_rate *= 4096; // various prescalers divide by this much + uint32_t div = gcd(target_rate % 24000000, 24000000); + clock_audio_pll_config_t config = { + .loopDivider = target_rate / 24000000, + .postDivider = 1, + .numerator = (target_rate % 24000000) / div, + .denominator = 24000000 / div, + }; + CLOCK_InitAudioPll(&config); +} + +void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) { + self->sample = sample; + self->loop = loop; + self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8; + self->channel_count = audiosample_channel_count(sample); + int instance = SAI_GetInstance(self->peripheral); + i2s_playing |= (1 << instance); + uint32_t sample_rate = audiosample_sample_rate(sample); + if (sample_rate != self->sample_rate) { + if (__builtin_popcount(i2s_playing) <= 1) { + // as this is the first/only i2s instance playing audio, we can + // safely change the overall clock used by the SAI peripheral, to + // get more accurate frequency reproduction. If another i2s + // instance is playing, then we can't touch the audio PLL and have + // to live with what we can get, which may be inaccurate + set_sai_clocking_for_sample_rate(sample_rate); + } + SAI_TxSetBitClockRate(self->peripheral, SAI_CLOCK_FREQ, sample_rate, 16, 2); + self->sample_rate = sample_rate; + } + bool single_buffer; + bool samples_signed; + uint32_t max_buffer_length; + uint8_t spacing; + audiosample_get_buffer_structure(sample, false, &single_buffer, &samples_signed, + &max_buffer_length, &spacing); + self->samples_signed = samples_signed; + self->playing = true; + self->paused = false; + self->stopping = false; + self->sample_data = self->sample_end = NULL; + + audiosample_reset_buffer(self->sample, false, 0); + +// TODO + #if 0 + 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; + } + #endif + background_callback_add(&self->callback, i2s_callback_fun, self); +} + +bool port_i2s_get_playing(i2s_t *self) { + return self->playing; +} + +bool port_i2s_get_paused(i2s_t *self) { + return self->paused; +} + +void port_i2s_stop(i2s_t *self) { + self->sample = NULL; + self->paused = false; + self->playing = false; + self->stopping = false; +} + +void port_i2s_pause(i2s_t *self) { + self->paused = true; +} + +void port_i2s_resume(i2s_t *self) { + self->paused = false; +} + +void i2s_reset() { +// this port relies on object finalizers for reset +} diff --git a/ports/mimxrt10xx/common-hal/audiobusio/__init__.h b/ports/mimxrt10xx/common-hal/audiobusio/__init__.h new file mode 100644 index 000000000000..f0663e289740 --- /dev/null +++ b/ports/mimxrt10xx/common-hal/audiobusio/__init__.h @@ -0,0 +1,59 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 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 "sdk/drivers/sai/fsl_sai.h" +#include "py/obj.h" + +#include "supervisor/background_callback.h" + + +typedef struct { + I2S_Type *peripheral; + sai_handle_t handle; + mp_obj_t sample; + uint32_t *buffers[SAI_XFER_QUEUE_SIZE]; + uint8_t *sample_data, *sample_end; + background_callback_t callback; + bool playing, paused, loop, stopping; + bool samples_signed; + uint8_t channel_count, bytes_per_sample; + uint8_t buffer_idx; + uint32_t sample_rate; +} i2s_t; + + +void i2s_reset(void); +void port_i2s_initialize(i2s_t *self, int instance, sai_transceiver_t *config); +void port_i2s_deinit(i2s_t *self); +bool port_i2s_deinited(i2s_t *self); +void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop); +void port_i2s_stop(i2s_t *self); +bool port_i2s_get_playing(i2s_t *self); +bool port_i2s_get_paused(i2s_t *self); +void port_i2s_pause(i2s_t *self); +void port_i2s_resume(i2s_t *self); diff --git a/ports/mimxrt10xx/common-hal/audiopwmio/PWMAudioOut.c b/ports/mimxrt10xx/common-hal/audiopwmio/PWMAudioOut.c new file mode 100644 index 000000000000..8650522b4141 --- /dev/null +++ b/ports/mimxrt10xx/common-hal/audiopwmio/PWMAudioOut.c @@ -0,0 +1,158 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 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 + +#include "mpconfigport.h" + +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "common-hal/audiobusio/__init__.h" +#include "common-hal/audiopwmio/PWMAudioOut.h" +#include "shared-bindings/audiopwmio/PWMAudioOut.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/translate/translate.h" +#include "supervisor/shared/tick.h" + +// Where required we use identifier names that are required by NXP's +// API, even though they do not conform to the naming standards that Adafruit +// strives to adhere to. https://www.adafruit.com/blacklivesmatter +#include "sdk/drivers/sai/fsl_sai.h" + +STATIC void config_periph_pin(const mcu_periph_obj_t *periph) { + if (!periph) { + return; + } + if (periph->pin->mux_reg) { + IOMUXC_SetPinMux( + periph->pin->mux_reg, periph->mux_mode, + periph->input_reg, periph->input_idx, + 0, + 1); + } + + IOMUXC_SetPinConfig(0, 0, 0, 0, + periph->pin->cfg_reg, + IOMUXC_SW_PAD_CTL_PAD_HYS(0) + | IOMUXC_SW_PAD_CTL_PAD_PUS(0) + | IOMUXC_SW_PAD_CTL_PAD_PUE(0) + | IOMUXC_SW_PAD_CTL_PAD_PKE(1) + | IOMUXC_SW_PAD_CTL_PAD_ODE(0) + | IOMUXC_SW_PAD_CTL_PAD_SPEED(2) + | IOMUXC_SW_PAD_CTL_PAD_DSE(4) + | IOMUXC_SW_PAD_CTL_PAD_SRE(0)); +} + +static void config_mqs(void) { + CCM->CCGR0 = (CCM->CCGR0 & (~CCM_CCGR0_CG2_MASK)) | CCM_CCGR0_CG2(3); /* Enable MQS hmclk. */ + + IOMUXC_MQSEnterSoftwareReset(IOMUXC_GPR, true); /* Reset MQS. */ + IOMUXC_MQSEnterSoftwareReset(IOMUXC_GPR, false); /* Release reset MQS. */ + IOMUXC_MQSEnable(IOMUXC_GPR, true); /* Enable MQS. */ + IOMUXC_MQSConfig(IOMUXC_GPR, kIOMUXC_MqsPwmOverSampleRate64, 0u); /* 98.304MHz/64/(0+1) = 1.536MHz + Higher frequency PWM involves less low frequen cy harmonic.*/ + +} + +// Caller validates that pins are free. +void common_hal_audiopwmio_pwmaudioout_construct(audiopwmio_pwmaudioout_obj_t *self, + const mcu_pin_obj_t *left_channel, const mcu_pin_obj_t *right_channel, uint16_t default_value) { + + int instance = -1; + const mcu_periph_obj_t *left_periph = find_pin_function(mcu_mqs_left_list, left_channel, &instance, MP_QSTR_left_channel); + const mcu_periph_obj_t *right_periph = find_pin_function(mcu_mqs_right_list, right_channel, &instance, MP_QSTR_right_channel); + + sai_transceiver_t config; + SAI_GetClassicI2SConfig(&config, kSAI_WordWidth16bits, kSAI_Stereo, 1U << 0u); + config.frameSync.frameSyncEarly = false; + config.frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh; + // config.syncMode = kSAI_ModeAsync; + config.fifo.fifoPacking = kSAI_FifoPackingDisabled; + // These identifier names are required by NXP's API, even though they do + // not conform to the naming standards that Adafruit strives to adhere to. + // https://www.adafruit.com/blacklivesmatter + // config.masterSlave = kSAI_Master; + port_i2s_initialize(&self->i2s, instance, &config); + + self->left_channel = left_channel; + self->right_channel = right_channel; + claim_pin(left_channel); + claim_pin(right_channel); + config_periph_pin(left_periph); + config_periph_pin(right_periph); + config_mqs(); +} + +bool common_hal_audiopwmio_pwmaudioout_deinited(audiopwmio_pwmaudioout_obj_t *self) { + return port_i2s_deinited(&self->i2s); +} + +void common_hal_audiopwmio_pwmaudioout_deinit(audiopwmio_pwmaudioout_obj_t *self) { + if (common_hal_audiopwmio_pwmaudioout_deinited(self)) { + return; + } + + port_i2s_deinit(&self->i2s); + + common_hal_reset_pin(self->left_channel); + self->left_channel = NULL; + + common_hal_reset_pin(self->right_channel); + self->right_channel = NULL; + + IOMUXC_MQSEnterSoftwareReset(IOMUXC_GPR, true); /* Reset MQS. */ + CCM->CCGR0 = CCM->CCGR0 & (~CCM_CCGR0_CG2_MASK); /* Disable MQS hmclk. */ +} + +void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, + mp_obj_t sample, bool loop) { + if (common_hal_audiopwmio_pwmaudioout_get_playing(self)) { + common_hal_audiopwmio_pwmaudioout_stop(self); + } + port_i2s_play(&self->i2s, sample, loop); +} + +void common_hal_audiopwmio_pwmaudioout_pause(audiopwmio_pwmaudioout_obj_t *self) { + port_i2s_pause(&self->i2s); +} + +void common_hal_audiopwmio_pwmaudioout_resume(audiopwmio_pwmaudioout_obj_t *self) { + port_i2s_resume(&self->i2s); +} + +bool common_hal_audiopwmio_pwmaudioout_get_paused(audiopwmio_pwmaudioout_obj_t *self) { + return port_i2s_get_paused(&self->i2s); +} + +void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t *self) { + port_i2s_stop(&self->i2s); +} + +bool common_hal_audiopwmio_pwmaudioout_get_playing(audiopwmio_pwmaudioout_obj_t *self) { + return port_i2s_get_playing(&self->i2s); +} diff --git a/ports/mimxrt10xx/common-hal/audiopwmio/PWMAudioOut.h b/ports/mimxrt10xx/common-hal/audiopwmio/PWMAudioOut.h new file mode 100644 index 000000000000..b9e4279927af --- /dev/null +++ b/ports/mimxrt10xx/common-hal/audiopwmio/PWMAudioOut.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 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 + +#if CIRCUITPY_AUDIOBUSIO_I2SOUT +#include "supervisor/background_callback.h" +#include "common-hal/microcontroller/Pin.h" + +#include "common-hal/audiobusio/__init__.h" + +typedef struct { + mp_obj_base_t base; + i2s_t i2s; + const mcu_pin_obj_t *left_channel, *right_channel; +} audiopwmio_pwmaudioout_obj_t; + +#endif diff --git a/ports/mimxrt10xx/common-hal/audiopwmio/__init__.c b/ports/mimxrt10xx/common-hal/audiopwmio/__init__.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ports/mimxrt10xx/common-hal/audiopwmio/__init__.h b/ports/mimxrt10xx/common-hal/audiopwmio/__init__.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ports/mimxrt10xx/common-hal/busio/I2C.c b/ports/mimxrt10xx/common-hal/busio/I2C.c index 50aae54aba86..6c5bbea416cb 100644 --- a/ports/mimxrt10xx/common-hal/busio/I2C.c +++ b/ports/mimxrt10xx/common-hal/busio/I2C.c @@ -34,8 +34,8 @@ #include "py/runtime.h" #include "periph.h" -#include "fsl_lpi2c.h" -#include "fsl_gpio.h" +#include "sdk/drivers/lpi2c/fsl_lpi2c.h" +#include "sdk/drivers/igpio/fsl_gpio.h" #define I2C_CLOCK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8 / (1 + CLOCK_GetDiv(kCLOCK_Lpi2cDiv))) #define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5 5U diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c index 0048c2aeb27a..d88b71a40395 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.c +++ b/ports/mimxrt10xx/common-hal/busio/SPI.c @@ -32,7 +32,7 @@ #include "py/runtime.h" #include "periph.h" -#include "fsl_lpspi.h" +#include "sdk/drivers/lpspi/fsl_lpspi.h" #include diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c index 871d57648d5f..088b2aefc6c5 100644 --- a/ports/mimxrt10xx/common-hal/busio/UART.c +++ b/ports/mimxrt10xx/common-hal/busio/UART.c @@ -38,8 +38,8 @@ #include "py/stream.h" #include "periph.h" -#include "fsl_lpuart.h" -#include "fsl_gpio.h" +#include "sdk/drivers/lpuart/fsl_lpuart.h" +#include "sdk/drivers/igpio/fsl_gpio.h" // ========================================================== // Debug code // ========================================================== @@ -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/busio/UART.h b/ports/mimxrt10xx/common-hal/busio/UART.h index bc8374aabbf6..f09de935c21f 100644 --- a/ports/mimxrt10xx/common-hal/busio/UART.h +++ b/ports/mimxrt10xx/common-hal/busio/UART.h @@ -34,7 +34,7 @@ #include "py/obj.h" #include "periph.h" -#include "fsl_lpuart.h" +#include "sdk/drivers/lpuart/fsl_lpuart.h" typedef struct { mp_obj_base_t base; diff --git a/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c b/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c index 7639204bc6c6..2b4a78948eb5 100644 --- a/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +++ b/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c @@ -32,7 +32,7 @@ #include "py/runtime.h" #include "py/mphal.h" -#include "fsl_gpio.h" +#include "sdk/drivers/igpio/fsl_gpio.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/digitalio/DigitalInOut.h" @@ -40,7 +40,7 @@ #define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5 5U -STATIC void pin_config(const mcu_pin_obj_t *pin, bool open_drain, digitalio_pull_t pull) { +void pin_config(const mcu_pin_obj_t *pin, bool open_drain, digitalio_pull_t pull) { IOMUXC_SetPinConfig(0, 0, 0, 0, pin->cfg_reg, IOMUXC_SW_PAD_CTL_PAD_HYS(1) | IOMUXC_SW_PAD_CTL_PAD_PUS((pull == PULL_UP) ? 2 : 0) @@ -118,7 +118,12 @@ digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( void common_hal_digitalio_digitalinout_set_value( digitalio_digitalinout_obj_t *self, bool value) { - GPIO_PinWrite(self->pin->gpio, self->pin->number, value); + GPIO_Type *gpio = self->pin->gpio; + if (value) { + gpio->DR_SET = 1 << self->pin->number; + } else { + gpio->DR_CLEAR = 1 << self->pin->number; + } } bool common_hal_digitalio_digitalinout_get_value( diff --git a/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.h b/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.h index 4c19de20b625..06adb93cb829 100644 --- a/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.h +++ b/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.h @@ -40,4 +40,6 @@ typedef struct { digitalio_pull_t pull; } digitalio_digitalinout_obj_t; +void pin_config(const mcu_pin_obj_t *pin, bool open_drain, digitalio_pull_t pull); + #endif // MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_DIGITALIO_DIGITALINOUT_H diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Pin.c b/ports/mimxrt10xx/common-hal/microcontroller/Pin.c index 3c8c7f2b2764..9f9e306dd9cd 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/Pin.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/Pin.c @@ -25,8 +25,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "shared-bindings/microcontroller/__init__.h" +#include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" + +#include "py/gc.h" STATIC bool claimed_pins[IOMUXC_SW_PAD_CTL_PAD_COUNT]; STATIC bool never_reset_pins[IOMUXC_SW_PAD_CTL_PAD_COUNT]; @@ -84,6 +87,7 @@ void common_hal_reset_pin(const mcu_pin_obj_t *pin) { return; } + disable_pin_change_interrupt(pin); never_reset_pins[pin->mux_idx] = false; claimed_pins[pin->mux_idx] = false; *(uint32_t *)pin->mux_reg = pin->mux_reset; @@ -116,3 +120,19 @@ void claim_pin(const mcu_pin_obj_t *pin) { void common_hal_mcu_pin_reset_number(uint8_t pin_no) { common_hal_reset_pin((mcu_pin_obj_t *)(mcu_pin_globals.map.table[pin_no].value)); } + +const mcu_periph_obj_t *find_pin_function_sz(const mcu_periph_obj_t *list, size_t sz, const mcu_pin_obj_t *pin, int *instance, uint16_t name) { + if (!pin) { + return NULL; + } + for (size_t i = 0; i < sz; i++) { + if (*instance != -1 && *instance != list[i].bank_idx) { + continue; + } + if (pin == list[i].pin) { + *instance = list[i].bank_idx; + return &list[i]; + } + } + mp_raise_ValueError_varg(translate("Invalid %q pin"), name); +} diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Pin.h b/ports/mimxrt10xx/common-hal/microcontroller/Pin.h index 1bfbe41a1848..4c66dd4ea50d 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/Pin.h +++ b/ports/mimxrt10xx/common-hal/microcontroller/Pin.h @@ -25,11 +25,9 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_MICROCONTROLLER_PIN_H -#define MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_MICROCONTROLLER_PIN_H - -#include +#pragma once +#include "periph.h" #include "pins.h" void reset_all_pins(void); @@ -45,4 +43,8 @@ extern const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[]; // 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 +// Find the entry in the peripheral list for this pin. If instance is (-1), any instance (bank_idx) may be used. Otherwise, the bank_idx must match the instance. +// If instance was -1, and the function succeeds, then instance is updated with the new bank_idx. +// If the pin is NULL then NULL is always returned. But if it was not NULL, and no match was found, then a ValueError is raised. +const mcu_periph_obj_t *find_pin_function_sz(const mcu_periph_obj_t *list, size_t sz, const mcu_pin_obj_t *pin, int *instance, uint16_t name); +#define find_pin_function(list, pin, instance, name) (find_pin_function_sz((list), MP_ARRAY_SIZE((list)), (pin), (instance), (name))) diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c index 8df21268eca7..52aa91ff6a57 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c @@ -33,8 +33,8 @@ #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/ResetReason.h" -#include "fsl_tempmon.h" -#include "fsl_ocotp.h" +#include "sdk/drivers/tempmon/fsl_tempmon.h" +#include "sdk/drivers/ocotp/fsl_ocotp.h" #include "clocks.h" float common_hal_mcu_processor_get_temperature(void) { diff --git a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c index 8de63061ad5c..1b10b4d4eee9 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c @@ -36,28 +36,25 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Processor.h" +#include "supervisor/linker.h" #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); } -volatile uint32_t nesting_count = 0; -void common_hal_mcu_disable_interrupts(void) { +volatile uint32_t PLACE_IN_DTCM_BSS(nesting_count) = 0; +void PLACE_IN_ITCM(common_hal_mcu_disable_interrupts)(void) { __disable_irq(); __DMB(); nesting_count++; } -void HardFault_Handler(void); -void common_hal_mcu_enable_interrupts(void) { +void PLACE_IN_ITCM(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 +77,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/neopixel_write/__init__.c b/ports/mimxrt10xx/common-hal/neopixel_write/__init__.c index 88d045306536..a26c34ce3247 100644 --- a/ports/mimxrt10xx/common-hal/neopixel_write/__init__.c +++ b/ports/mimxrt10xx/common-hal/neopixel_write/__init__.c @@ -64,9 +64,7 @@ void PLACE_IN_ITCM(common_hal_neopixel_write)(const digitalio_digitalinout_obj_t const uint32_t pin = digitalinout->pin->number; __disable_irq(); - // Enable DWT in debug core. Useable when interrupts disabled, as opposed to Systick->VAL - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + // Use DWT in debug core. Usable when interrupts disabled, as opposed to Systick->VAL DWT->CYCCNT = 0; for (;;) { @@ -88,12 +86,12 @@ void PLACE_IN_ITCM(common_hal_neopixel_write)(const digitalio_digitalinout_obj_t mask = 0x80; } } + // Enable interrupts again + __enable_irq(); // Update the next start. next_start_raw_ticks = port_get_raw_ticks(NULL) + 4; - // Enable interrupts again - __enable_irq(); } #pragma GCC pop_options diff --git a/ports/mimxrt10xx/common-hal/os/__init__.c b/ports/mimxrt10xx/common-hal/os/__init__.c index e2c43e43faf1..921924268535 100644 --- a/ports/mimxrt10xx/common-hal/os/__init__.c +++ b/ports/mimxrt10xx/common-hal/os/__init__.c @@ -33,7 +33,7 @@ #include "shared-bindings/os/__init__.h" -#include "fsl_trng.h" +#include "sdk/drivers/trng/fsl_trng.h" STATIC const qstr os_uname_info_fields[] = { MP_QSTR_sysname, MP_QSTR_nodename, diff --git a/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c b/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c index 97892b1095a7..0bf11403d2e2 100644 --- a/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +++ b/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -33,14 +33,24 @@ #include "shared-bindings/pwmio/PWMOut.h" #include "shared-bindings/microcontroller/Pin.h" -#include "fsl_pwm.h" +#include "sdk/drivers/pwm/fsl_pwm.h" #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,91 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, return PWMOUT_INVALID_FREQUENCY; } - pwmConfig.prescale = self->prescaler; + // 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; + } - DBGPrintf(&mp_plat_print, "\tCall PWM_Init\n"); - if (PWM_Init(self->pwm->pwm, self->pwm->submodule, &pwmConfig) == kStatus_Fail) { - return PWMOUT_INVALID_PIN; - } + // We want variable frequency but another class has already claim a fixed frequency. + if (variable_frequency) { + return PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE; + } - // 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; + // Another pin is already using this output. + if ((flexpwm->OUTEN & outen_mask) != 0) { + return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; } - base->MCTRL |= PWM_MCTRL_LDOK(mask); - } - debug_print_flexpwm_registers(self->pwm->pwm); - PWM_SetPwmLdok(self->pwm->pwm, 1 << self->pwm->submodule, true); + if (frequency != _pwm_sm_frequencies[flexpwm_index][submodule]) { + return PWMOUT_INVALID_FREQUENCY_ON_PIN; + } - PWM_StartTimer(self->pwm->pwm, 1 << self->pwm->submodule); + // 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; + + 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; + } + } - 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 +283,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 +318,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 +367,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 fa4ce46780a8..6542d67e1f8e 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/rotaryio/IncrementalEncoder.c b/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.c new file mode 100644 index 000000000000..043b791b4d9a --- /dev/null +++ b/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.c @@ -0,0 +1,87 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Nick Moore for Adafruit Industries + * Copyright (c) 2023 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/digitalio/DigitalInOut.h" +#include "common-hal/rotaryio/IncrementalEncoder.h" +#include "shared-module/rotaryio/IncrementalEncoder.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/rotaryio/IncrementalEncoder.h" + +#include "py/runtime.h" + +#include "sdk/drivers/igpio/fsl_gpio.h" +static void encoder_change(void *self_in) { + rotaryio_incrementalencoder_obj_t *self = self_in; + + bool value_a = GPIO_PinRead(self->pin_a->gpio, self->pin_a->number); + bool value_b = GPIO_PinRead(self->pin_b->gpio, self->pin_b->number); + uint8_t new_state = (value_a << 1) | value_b; + shared_module_softencoder_state_update(self, new_state); +} + +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) { + + self->pin_a = pin_a; + self->pin_b = pin_b; + + // GPIO is always IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5 until proven otherwise +#define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5 5U + IOMUXC_SetPinMux(pin_a->mux_reg, IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5, 0, 0, 0, 0); + IOMUXC_SetPinMux(pin_b->mux_reg, IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5, 0, 0, 0, 0); + + const gpio_pin_config_t config = { kGPIO_DigitalInput, 0, kGPIO_IntRisingOrFallingEdge }; + GPIO_PinInit(pin_a->gpio, pin_a->number, &config); + GPIO_PinInit(pin_b->gpio, pin_b->number, &config); + + enable_pin_change_interrupt(pin_a, encoder_change, self); + enable_pin_change_interrupt(pin_b, encoder_change, self); + + pin_config(pin_a, false, PULL_UP); + pin_config(pin_b, false, PULL_UP); + + claim_pin(pin_a); + claim_pin(pin_b); +} + +bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t *self) { + return !self->pin_a; +} + +void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t *self) { + if (common_hal_rotaryio_incrementalencoder_deinited(self)) { + return; + } + disable_pin_change_interrupt(self->pin_a); + disable_pin_change_interrupt(self->pin_b); + + common_hal_reset_pin(self->pin_a); + common_hal_reset_pin(self->pin_b); + + self->pin_a = NULL; + self->pin_b = NULL; +} diff --git a/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.h b/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.h new file mode 100644 index 000000000000..920b32cba96c --- /dev/null +++ b/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2023 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 "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin_a, *pin_b; + uint8_t state; // + int8_t sub_count; // count intermediate transitions between detents + int8_t divisor; // Number of quadrature edges required per count + mp_int_t position; +} rotaryio_incrementalencoder_obj_t; + + +void incrementalencoder_interrupt_handler(uint8_t channel); diff --git a/ports/mimxrt10xx/common-hal/rotaryio/__init__.c b/ports/mimxrt10xx/common-hal/rotaryio/__init__.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ports/mimxrt10xx/common-hal/rotaryio/__init__.h b/ports/mimxrt10xx/common-hal/rotaryio/__init__.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ports/mimxrt10xx/common-hal/rtc/RTC.c b/ports/mimxrt10xx/common-hal/rtc/RTC.c index 7ed65a3499c7..386b6a3ac55f 100644 --- a/ports/mimxrt10xx/common-hal/rtc/RTC.c +++ b/ports/mimxrt10xx/common-hal/rtc/RTC.c @@ -35,19 +35,27 @@ #include "common-hal/rtc/RTC.h" #include "supervisor/shared/translate/translate.h" -#include "fsl_snvs_hp.h" +#include "sdk/drivers/snvs_hp/fsl_snvs_hp.h" +#include "sdk/drivers/snvs_lp/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/linking/common.ld b/ports/mimxrt10xx/linking/common.ld index b6f1acc8d0d8..76c11c8d6fab 100644 --- a/ports/mimxrt10xx/linking/common.ld +++ b/ports/mimxrt10xx/linking/common.ld @@ -6,7 +6,7 @@ Boards can setup reserved flash with _ld_reserved_flash_size in board.ld. */ ENTRY(Reset_Handler) -code_size = 1M; +code_size = _ld_flash_size >= 4M ? 2M : 1M; _ld_default_stack_size = 20K; /* Default reserved flash to nothing. */ @@ -22,9 +22,9 @@ MEMORY FLASH_IVT (rx) : ORIGIN = 0x60001000, LENGTH = 4K /* Place the ISRs 48k in to leave room for the bootloader when it is available. */ FLASH_FIRMWARE (rx) : ORIGIN = 0x6000C000, LENGTH = code_size - 48K - FLASH_FATFS (r) : ORIGIN = 0x60100000, LENGTH = _ld_flash_size - code_size - _ld_reserved_flash_size + FLASH_FATFS (r) : ORIGIN = 0x60000000 + code_size, LENGTH = _ld_flash_size - code_size - _ld_reserved_flash_size /* Teensy uses the last bit of flash for recovery. */ - RESERVED_FLASH : ORIGIN = 0x60100000 + _ld_flash_size - _ld_reserved_flash_size, LENGTH = _ld_reserved_flash_size + RESERVED_FLASH : ORIGIN = 0x60000000 + code_size + _ld_flash_size - _ld_reserved_flash_size, LENGTH = _ld_reserved_flash_size OCRAM (rwx) : ORIGIN = 0x20200000, LENGTH = ram_size - 64K DTCM (x) : ORIGIN = 0x20000000, LENGTH = 32K ITCM (x) : ORIGIN = 0x00000000, LENGTH = 32K @@ -52,24 +52,59 @@ SECTIONS . = ALIGN(4); } > FLASH_IVT - .text : + /* Align for 256 ISR entries and place first in flash. Otherwise the UF2 + bootloader can't find it because it uses its own flash_config and ivt. */ + .isr_vector : ALIGN(4 * 256) { . = ALIGN(4); - __VECTOR_TABLE = .; - __VECTOR_RAM = .; - _ld_isr_table = .; - KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > ITCM AT> FLASH_FIRMWARE + _ld_isr_destination = ADDR(.isr_vector); + _ld_isr_flash_copy = LOADADDR(.isr_vector); + _ld_isr_size = SIZEOF(.isr_vector); + /* Used by the bootloader to start user code. */ + __VECTOR_TABLE = LOADADDR(.isr_vector); + + .text : + { + . = ALIGN(4); *(EXCLUDE_FILE( *fsl_flexspi.o + *dcd_ci_hs.o + *tusb_fifo.o + *usbd.o + *string0.o + *py/nlr*.o + *py/obj.o + *py/gc.o + *py/map.o + *py/runtime.o + *py/objboundmeth.o + *py/objtype.o ) .text*) /* .text* sections (code) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + /* Keep USB processing functions out of RAM because we don't know which will be used. + We try to only keep USB interrupt related functions. */ + *dcd_ci_hs.o(.text.process_*_request .text.dcd_edpt* .text.dcd_init .text.dcd_set_address) + *usbd.o(.text.process_*_request .text.process_[gs]et* .text.tud_* .text.usbd_* .text.configuration_reset .text.invoke_*) + + /* Anything marked cold/unlikely should be in flash. */ + *(.text.unlikely.*) + + *(EXCLUDE_FILE( + *dcd_ci_hs.o + *py/objboundmeth.o + *py/objtype.o + ) .rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } > FLASH_FIRMWARE .ARM.exidx : { + __exidx_start = .; *(.ARM.exidx*) + __exidx_end = .; *(.gnu.linkonce.armexidx.*) _etext = .; /* define a global symbol at end of code */ __etext = .; /* define a global symbol at end of code */ @@ -81,7 +116,6 @@ SECTIONS { . = ALIGN(4); *(.data*) /* .data* sections */ - *fsl_flexspi.o(.text*) . = ALIGN(4); } > OCRAM AT> FLASH_FIRMWARE _ld_ocram_data_destination = ADDR(.data); @@ -93,7 +127,7 @@ SECTIONS { . = ALIGN(4); - *(.bss*) + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) *(COMMON) . = ALIGN(4); @@ -103,11 +137,23 @@ SECTIONS _ld_heap_start = _ld_ocram_bss_start + _ld_ocram_bss_size; _ld_heap_end = ORIGIN(OCRAM) + LENGTH(OCRAM); - .itcm : + + .itcm : ALIGN(4) { . = ALIGN(4); *(.itcm.*) - + *fsl_flexspi.o(.text*) + *dcd_ci_hs.o(.text*) + *tusb_fifo.o(.text*) + *py/objboundmeth.o(.text*) + *py/objtype.o(.text*) + *py/obj.o(.text*) + *py/gc.o(.text*) + *py/map.o(.text*) + *py/nlr*.o(.text*) + *py/runtime.o(.text*) + *(.text.process_*_isr .text.dcd_event_* .text.osal_queue*) + *string0.o(.text*) . = ALIGN(4); } > ITCM AT> FLASH_FIRMWARE _ld_itcm_destination = ADDR(.itcm); @@ -119,6 +165,9 @@ SECTIONS . = ALIGN(4); *(.dtcm_data.*) + *dcd_ci_hs.o(.rodata*) + *py/objboundmeth.o(.rodata*) + *py/objtype.o(.rodata*) . = ALIGN(4); } > DTCM AT> FLASH_FIRMWARE @@ -139,13 +188,15 @@ SECTIONS _ld_dtcm_bss_start = ADDR(.dtcm_bss); _ld_dtcm_bss_size = SIZEOF(.dtcm_bss); - .stack : + .stack (NOLOAD) : { . = ALIGN(8); _ld_stack_bottom = .; . += _ld_default_stack_size; } > DTCM _ld_stack_top = ORIGIN(DTCM) + LENGTH(DTCM); + /* For the SDK's isr vector table */ + __StackTop = ORIGIN(DTCM) + LENGTH(DTCM); .ARM.attributes 0 : { *(.ARM.attributes) } } diff --git a/ports/mimxrt10xx/mpconfigport.mk b/ports/mimxrt10xx/mpconfigport.mk index cee2d9a698ab..ae22cb69f483 100644 --- a/ports/mimxrt10xx/mpconfigport.mk +++ b/ports/mimxrt10xx/mpconfigport.mk @@ -6,11 +6,19 @@ USB_HIGHSPEED = 1 # Number of USB endpoint pairs. USB_NUM_ENDPOINT_PAIRS = 8 +# Align buffers on the cache boundary so we don't inadvertently load them early. +CIRCUITPY_TUSB_MEM_ALIGN = 32 INTERNAL_FLASH_FILESYSTEM = 1 +CIRCUITPY_AUDIOBUSIO = 1 +CIRCUITPY_AUDIOBUSIO_PDMIN = 0 +CIRCUITPY_AUDIOCORE = 1 CIRCUITPY_AUDIOIO = 0 -CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOMIXER = 1 +CIRCUITPY_AUDIOMP3 = 1 +CIRCUITPY_AUDIOPWMIO = 1 +CIRCUITPY_SYNTHIO_MAX_CHANNELS = 12 CIRCUITPY_BUSDEVICE = 1 CIRCUITPY_COUNTIO = 0 CIRCUITPY_FREQUENCYIO = 0 @@ -18,7 +26,8 @@ CIRCUITPY_I2CTARGET = 0 CIRCUITPY_NVM = 0 CIRCUITPY_PARALLELDISPLAY = 0 CIRCUITPY_PULSEIO = 0 -CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_ROTARYIO = 1 +CIRCUITPY_ROTARYIO_SOFTENCODER = 1 CIRCUITPY_USB_MIDI = 1 LONGINT_IMPL = MPZ diff --git a/ports/mimxrt10xx/mphalport.c b/ports/mimxrt10xx/mphalport.c index ad0fb4d9ba05..f160cf1365f7 100644 --- a/ports/mimxrt10xx/mphalport.c +++ b/ports/mimxrt10xx/mphalport.c @@ -35,11 +35,7 @@ #include "fsl_common.h" void mp_hal_delay_us(mp_uint_t delay) { - #if defined(MIMXRT1011_SERIES) || defined(MIMXRT1021_SERIES) SDK_DelayAtLeastUs(delay, SystemCoreClock); - #else - SDK_DelayAtLeastUs(delay); - #endif } void mp_hal_disable_all_interrupts(void) { diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.c index bdf3299217b0..b67f7b117969 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.c @@ -29,7 +29,7 @@ #include "py/mphal.h" #include "mimxrt10xx/periph.h" -LPI2C_Type *mcu_i2c_banks[2] = { LPI2C1, LPI2C2 }; +LPI2C_Type *const mcu_i2c_banks[2] = { LPI2C1, LPI2C2 }; const mcu_periph_obj_t mcu_i2c_sda_list[8] = { PERIPH_PIN(1, 0, kIOMUXC_LPI2C1_SDA_SELECT_INPUT, 0, &pin_GPIO_AD_13), @@ -55,7 +55,7 @@ const mcu_periph_obj_t mcu_i2c_scl_list[8] = { PERIPH_PIN(2, 3, kIOMUXC_LPI2C2_SCL_SELECT_INPUT, 3, &pin_GPIO_10), }; -LPSPI_Type *mcu_spi_banks[2] = { LPSPI1, LPSPI2 }; +LPSPI_Type *const mcu_spi_banks[2] = { LPSPI1, LPSPI2 }; const mcu_periph_obj_t mcu_spi_sck_list[4] = { PERIPH_PIN(1, 0, kIOMUXC_LPSPI1_SCK_SELECT_INPUT, 0, &pin_GPIO_AD_06), @@ -81,7 +81,7 @@ const mcu_periph_obj_t mcu_spi_miso_list[4] = { PERIPH_PIN(2, 1, kIOMUXC_LPSPI2_SDI_SELECT_INPUT, 1, &pin_GPIO_SD_09), }; -LPUART_Type *mcu_uart_banks[4] = { LPUART1, LPUART2, LPUART3, LPUART4 }; +LPUART_Type *const mcu_uart_banks[4] = { LPUART1, LPUART2, LPUART3, LPUART4 }; const mcu_periph_obj_t mcu_uart_rx_list[9] = { PERIPH_PIN(1, 2, kIOMUXC_LPUART1_RXD_SELECT_INPUT, 0, &pin_GPIO_SD_11), @@ -166,3 +166,34 @@ const mcu_pwm_obj_t mcu_pwm_list[20] = { PWM_PIN(PWM1, kPWM_Module_3, kPWM_PwmX, IOMUXC_GPIO_AD_09_FLEXPWM1_PWM3_X, &pin_GPIO_AD_09), }; + +const mcu_periph_obj_t mcu_sai_rx_bclk_list[] = { + PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_08), + PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_00), +}; +const mcu_periph_obj_t mcu_sai_rx_data0_list[] = { + PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_03), + PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_SD_03), +}; +const mcu_periph_obj_t mcu_sai_rx_sync_list[] = { + PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_02), + PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_SD_04), +}; +const mcu_periph_obj_t mcu_sai_tx_bclk_list[] = { + PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_06), + PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_SD_01), +}; +const mcu_periph_obj_t mcu_sai_tx_data0_list[] = { + PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_04), + PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_SD_02), +}; +const mcu_periph_obj_t mcu_sai_tx_sync_list[] = { + PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_07), + PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_SD_00), +}; +const mcu_periph_obj_t mcu_mqs_left_list[] = { + PERIPH_PIN(3, 4, 0, 0, &pin_GPIO_AD_01), +}; +const mcu_periph_obj_t mcu_mqs_right_list[] = { + PERIPH_PIN(3, 4, 0, 0, &pin_GPIO_AD_02), +}; diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h index c50d73294b26..045e33ca0e5f 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h @@ -27,18 +27,18 @@ #ifndef MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H #define MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H -extern LPI2C_Type *mcu_i2c_banks[2]; +extern LPI2C_Type *const mcu_i2c_banks[2]; extern const mcu_periph_obj_t mcu_i2c_sda_list[8]; extern const mcu_periph_obj_t mcu_i2c_scl_list[8]; -extern LPSPI_Type *mcu_spi_banks[2]; +extern LPSPI_Type *const mcu_spi_banks[2]; extern const mcu_periph_obj_t mcu_spi_sck_list[4]; extern const mcu_periph_obj_t mcu_spi_mosi_list[4]; extern const mcu_periph_obj_t mcu_spi_miso_list[4]; -extern LPUART_Type *mcu_uart_banks[4]; +extern LPUART_Type *const mcu_uart_banks[4]; extern const mcu_periph_obj_t mcu_uart_rx_list[9]; extern const mcu_periph_obj_t mcu_uart_tx_list[9]; @@ -47,4 +47,14 @@ extern const mcu_periph_obj_t mcu_uart_cts_list[4]; extern const mcu_pwm_obj_t mcu_pwm_list[20]; +extern const mcu_periph_obj_t mcu_sai_rx_bclk_list[2]; +extern const mcu_periph_obj_t mcu_sai_rx_data0_list[2]; +extern const mcu_periph_obj_t mcu_sai_rx_sync_list[2]; +extern const mcu_periph_obj_t mcu_sai_tx_bclk_list[2]; +extern const mcu_periph_obj_t mcu_sai_tx_data0_list[2]; +extern const mcu_periph_obj_t mcu_sai_tx_sync_list[2]; + +extern const mcu_periph_obj_t mcu_mqs_left_list[1]; +extern const mcu_periph_obj_t mcu_mqs_right_list[1]; + #endif // MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c index 5b21c12c2afb..59bd3cc1054c 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c @@ -30,7 +30,7 @@ #include "py/mphal.h" #include "mimxrt10xx/periph.h" -LPI2C_Type *mcu_i2c_banks[4] = { LPI2C1, LPI2C2, LPI2C3, LPI2C4 }; +LPI2C_Type *const mcu_i2c_banks[4] = { LPI2C1, LPI2C2, LPI2C3, LPI2C4 }; const mcu_periph_obj_t mcu_i2c_sda_list[8] = { PERIPH_PIN(1, 6, kIOMUXC_LPI2C1_SDA_SELECT_INPUT, 0, &pin_GPIO_EMC_03), @@ -60,7 +60,7 @@ const mcu_periph_obj_t mcu_i2c_scl_list[8] = { PERIPH_PIN(4, 3, kIOMUXC_LPI2C4_SCL_SELECT_INPUT, 1, &pin_GPIO_SD_B1_02), }; -LPSPI_Type *mcu_spi_banks[4] = { LPSPI1, LPSPI2, LPSPI3, LPSPI4 }; +LPSPI_Type *const mcu_spi_banks[4] = { LPSPI1, LPSPI2, LPSPI3, LPSPI4 }; const mcu_periph_obj_t mcu_spi_sck_list[8] = { PERIPH_PIN(1, 4, kIOMUXC_LPSPI1_SCK_SELECT_INPUT, 0, &pin_GPIO_SD_B0_02), @@ -104,7 +104,7 @@ const mcu_periph_obj_t mcu_spi_miso_list[8] = { PERIPH_PIN(4, 4, kIOMUXC_LPSPI2_SDI_SELECT_INPUT, 1, &pin_GPIO_EMC_35), }; -LPUART_Type *mcu_uart_banks[8] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8 }; +LPUART_Type *const mcu_uart_banks[8] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8 }; const mcu_periph_obj_t mcu_uart_rx_list[16] = { PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_07), @@ -256,3 +256,68 @@ const mcu_pwm_obj_t mcu_pwm_list[39] = { PWM_PIN(PWM2, kPWM_Module_2, kPWM_PwmX, IOMUXC_GPIO_EMC_12_FLEXPWM2_PWMX02, &pin_GPIO_EMC_12), PWM_PIN(PWM2, kPWM_Module_3, kPWM_PwmX, IOMUXC_GPIO_EMC_13_FLEXPWM2_PWMX03, &pin_GPIO_EMC_13), }; + +const mcu_periph_obj_t mcu_sai_rx_bclk_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_14), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_19), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_06), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_09), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_02), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_29), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_09), +}; +const mcu_periph_obj_t mcu_sai_rx_data0_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_13), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_21), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_05), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_08), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_03), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_30), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_11), +}; +const mcu_periph_obj_t mcu_sai_rx_sync_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_15), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_28), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_04), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_07), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_01), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_30), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_10), +}; +const mcu_periph_obj_t mcu_sai_tx_bclk_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_11), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_26), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_01), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_04), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_04), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_33), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B0_06), +}; +const mcu_periph_obj_t mcu_sai_tx_data0_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_12), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_25), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_03), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_06), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_04), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_32), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_08), +}; +const mcu_periph_obj_t mcu_sai_tx_sync_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_10), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_27), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_02), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_05), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_06), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_34), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_07), +}; +const mcu_periph_obj_t mcu_mqs_left_list[] = { + PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_07), + PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_EMC_17), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_38), +}; +const mcu_periph_obj_t mcu_mqs_right_list[] = { + PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_06), + PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_EMC_16), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_37), +}; diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h index 6c778ad5251c..51c97b3eef2c 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h @@ -25,21 +25,20 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PERIPH_H -#define MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PERIPH_H +#pragma once -extern LPI2C_Type *mcu_i2c_banks[4]; +extern LPI2C_Type *const mcu_i2c_banks[4]; extern const mcu_periph_obj_t mcu_i2c_sda_list[8]; extern const mcu_periph_obj_t mcu_i2c_scl_list[8]; -extern LPSPI_Type *mcu_spi_banks[4]; +extern LPSPI_Type *const mcu_spi_banks[4]; extern const mcu_periph_obj_t mcu_spi_sck_list[8]; extern const mcu_periph_obj_t mcu_spi_mosi_list[8]; extern const mcu_periph_obj_t mcu_spi_miso_list[8]; -extern LPUART_Type *mcu_uart_banks[8]; +extern LPUART_Type *const mcu_uart_banks[8]; extern const mcu_periph_obj_t mcu_uart_rx_list[16]; extern const mcu_periph_obj_t mcu_uart_tx_list[16]; @@ -48,4 +47,12 @@ extern const mcu_periph_obj_t mcu_uart_cts_list[10]; extern const mcu_pwm_obj_t mcu_pwm_list[39]; -#endif // MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PERIP_H +extern const mcu_periph_obj_t mcu_sai_rx_bclk_list[7]; +extern const mcu_periph_obj_t mcu_sai_rx_data0_list[7]; +extern const mcu_periph_obj_t mcu_sai_rx_sync_list[7]; +extern const mcu_periph_obj_t mcu_sai_tx_bclk_list[7]; +extern const mcu_periph_obj_t mcu_sai_tx_data0_list[7]; +extern const mcu_periph_obj_t mcu_sai_tx_sync_list[7]; + +extern const mcu_periph_obj_t mcu_mqs_left_list[3]; +extern const mcu_periph_obj_t mcu_mqs_right_list[3]; diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c index 19ce48f28832..c43f4eb96b6f 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c @@ -29,7 +29,7 @@ #include "py/mphal.h" #include "mimxrt10xx/periph.h" -LPI2C_Type *mcu_i2c_banks[4] = { LPI2C1, LPI2C2, LPI2C3, LPI2C4 }; +LPI2C_Type *const mcu_i2c_banks[4] = { LPI2C1, LPI2C2, LPI2C3, LPI2C4 }; const mcu_periph_obj_t mcu_i2c_sda_list[9] = { PERIPH_PIN(1, 2, kIOMUXC_LPI2C1_SDA_SELECT_INPUT, 0, &pin_GPIO_SD_B1_05), @@ -61,7 +61,7 @@ const mcu_periph_obj_t mcu_i2c_scl_list[9] = { PERIPH_PIN(4, 0, kIOMUXC_LPI2C4_SCL_SELECT_INPUT, 1, &pin_GPIO_AD_B0_12), }; -LPSPI_Type *mcu_spi_banks[4] = { LPSPI1, LPSPI2, LPSPI3, LPSPI4 }; +LPSPI_Type *const mcu_spi_banks[4] = { LPSPI1, LPSPI2, LPSPI3, LPSPI4 }; const mcu_periph_obj_t mcu_spi_sck_list[8] = { PERIPH_PIN(1, 3, kIOMUXC_LPSPI1_SCK_SELECT_INPUT, 0, &pin_GPIO_EMC_27), @@ -105,7 +105,7 @@ const mcu_periph_obj_t mcu_spi_miso_list[8] = { PERIPH_PIN(4, 1, kIOMUXC_LPSPI4_SDI_SELECT_INPUT, 1, &pin_GPIO_B1_05), }; -LPUART_Type *mcu_uart_banks[8] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8 }; +LPUART_Type *const mcu_uart_banks[8] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8 }; const mcu_periph_obj_t mcu_uart_rx_list[18] = { PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_13), @@ -306,3 +306,69 @@ const mcu_pwm_obj_t mcu_pwm_list[67] = { PWM_PIN(PWM4, kPWM_Module_3, kPWM_PwmB, IOMUXC_GPIO_EMC_18_FLEXPWM4_PWMB03, &pin_GPIO_EMC_18), }; + +const mcu_periph_obj_t mcu_sai_rx_bclk_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_11), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B0_15), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_05), + PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_10), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_06), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_35), + PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_00), +}; + +const mcu_periph_obj_t mcu_sai_rx_data0_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B1_00), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_12), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_06), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_08), + PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_08), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_33), + PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_00), +}; +const mcu_periph_obj_t mcu_sai_rx_sync_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_11), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B0_15), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_05), + PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_09), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_06), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_34), + PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_05), +}; +const mcu_periph_obj_t mcu_sai_tx_bclk_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_08), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B1_02), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_14), + PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_AD_B0_05), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_06), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_38), + PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_03), +}; +const mcu_periph_obj_t mcu_sai_tx_data0_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_13), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B1_01), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_07), + PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_04), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_09), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_36), + PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_01), +}; +const mcu_periph_obj_t mcu_sai_tx_sync_list[] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_15), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B1_03), + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_09), + PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_AD_B0_04), + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_05), + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_39), + PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_02), +}; +const mcu_periph_obj_t mcu_mqs_left_list[] = { + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_14), + PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_B0_01), + PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_05), +}; +const mcu_periph_obj_t mcu_mqs_right_list[] = { + PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_13), + PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_B0_00), + PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_04), +}; diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h index 067c05d0d0b7..28ea8e37429b 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h @@ -27,18 +27,18 @@ #ifndef MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H #define MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H -extern LPI2C_Type *mcu_i2c_banks[4]; +extern LPI2C_Type *const mcu_i2c_banks[4]; extern const mcu_periph_obj_t mcu_i2c_sda_list[9]; extern const mcu_periph_obj_t mcu_i2c_scl_list[9]; -extern LPSPI_Type *mcu_spi_banks[4]; +extern LPSPI_Type *const mcu_spi_banks[4]; extern const mcu_periph_obj_t mcu_spi_sck_list[8]; extern const mcu_periph_obj_t mcu_spi_mosi_list[8]; extern const mcu_periph_obj_t mcu_spi_miso_list[8]; -extern LPUART_Type *mcu_uart_banks[8]; +extern LPUART_Type *const mcu_uart_banks[8]; extern const mcu_periph_obj_t mcu_uart_rx_list[18]; extern const mcu_periph_obj_t mcu_uart_tx_list[18]; @@ -47,4 +47,14 @@ extern const mcu_periph_obj_t mcu_uart_cts_list[9]; extern const mcu_pwm_obj_t mcu_pwm_list[67]; +extern const mcu_periph_obj_t mcu_sai_rx_bclk_list[7]; +extern const mcu_periph_obj_t mcu_sai_rx_data0_list[7]; +extern const mcu_periph_obj_t mcu_sai_rx_sync_list[7]; +extern const mcu_periph_obj_t mcu_sai_tx_bclk_list[7]; +extern const mcu_periph_obj_t mcu_sai_tx_data0_list[7]; +extern const mcu_periph_obj_t mcu_sai_tx_sync_list[7]; + +extern const mcu_periph_obj_t mcu_mqs_left_list[3]; +extern const mcu_periph_obj_t mcu_mqs_right_list[3]; + #endif // MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/periph.h index c77497a775f1..8184d5b135c1 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/periph.h @@ -31,7 +31,7 @@ #include "pins.h" typedef struct { - uint8_t bank_idx : 4; + uint8_t bank_idx : 4; // e.g. the peripheral number uint8_t mux_mode : 4; uint32_t input_reg; uint8_t input_idx; @@ -72,9 +72,9 @@ typedef struct { .pin = p_pin, \ } -extern LPI2C_Type *mcu_i2c_banks[]; -extern LPSPI_Type *mcu_spi_banks[]; -extern LPUART_Type *mcu_uart_banks[]; +extern LPI2C_Type *const mcu_i2c_banks[]; +extern LPSPI_Type *const mcu_spi_banks[]; +extern LPUART_Type *const mcu_uart_banks[]; #ifdef MIMXRT1011_SERIES #include "MIMXRT1011/periph.h" diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.c new file mode 100644 index 000000000000..d052711033c9 --- /dev/null +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.c @@ -0,0 +1,99 @@ +#include "peripherals/mimxrt10xx/pins.h" + +typedef struct { + gpio_change_interrupt_t *func; + void *data; +} pin_change_interrupt_data; + +/* Array of GPIO peripheral base address. */ +static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS; +static uint32_t GPIO_GetInstance(GPIO_Type *base) { + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0U; instance < ARRAY_SIZE(s_gpioBases); instance++) + { + if (s_gpioBases[instance] == base) { + break; + } + } + + assert(instance < ARRAY_SIZE(s_gpioBases)); + + return instance; +} + + +/* to find IRQ based on GPIO */ +static const IRQn_Type low_irqs[] = GPIO_COMBINED_LOW_IRQS; +static const IRQn_Type high_irqs[] = GPIO_COMBINED_HIGH_IRQS; + +static volatile pin_change_interrupt_data pcid[MP_ARRAY_SIZE(s_gpioBases)][32]; + +void enable_pin_change_interrupt(const mcu_pin_obj_t *pin, gpio_change_interrupt_t func, void *data) { + int instance = GPIO_GetInstance(pin->gpio); + volatile pin_change_interrupt_data *pci = &pcid[instance][pin->number]; + common_hal_mcu_disable_interrupts(); + pci->data = data; + pci->func = func; + IRQn_Type irq = pin->number < 16 ? low_irqs[instance] : high_irqs[instance]; + if (irq != NotAvail_IRQn) { + EnableIRQ(irq); + } + pin->gpio->IMR |= (1 << pin->number); + common_hal_mcu_enable_interrupts(); +} + +void disable_pin_change_interrupt(const mcu_pin_obj_t *pin) { + volatile pin_change_interrupt_data *pci = &pcid[GPIO_GetInstance(pin->gpio)][pin->number]; + common_hal_mcu_disable_interrupts(); + pin->gpio->IMR &= ~(1 << pin->number); + pci->data = NULL; + pci->func = NULL; + pin->gpio->ISR = (1 << pin->number); // acknowledge any pending interrupt + common_hal_mcu_enable_interrupts(); +} + +static void pin_change_interrupt_common(uint32_t isr, volatile pin_change_interrupt_data *pcr) { + for (uint32_t i = 0; i < 32; i++) { + if (isr & (1 << i)) { + pin_change_interrupt_data cb = pcr[i]; + if (cb.func) { + cb.func(cb.data); + } + } + } +} + +#define GPIO_INTERRUPT_HANDLER(name, ptr, instance, offset) \ + void name(void); \ + __attribute__((used)) void name(void) { \ + uint32_t isr = ptr->ISR; \ + ptr->ISR = isr; \ + pin_change_interrupt_common(isr, pcid[instance]); \ + } + +#if defined(GPIO1) +GPIO_INTERRUPT_HANDLER(GPIO1_Combined_0_15_IRQHandler, GPIO1, 1, 0); +GPIO_INTERRUPT_HANDLER(GPIO1_Combined_16_31_IRQHandler, GPIO1, 1, 16); +#endif +#if defined(GPIO2) +GPIO_INTERRUPT_HANDLER(GPIO2_Combined_0_15_IRQHandler, GPIO2, 2, 0); +GPIO_INTERRUPT_HANDLER(GPIO2_Combined_16_31_IRQHandler, GPIO2, 2, 16); +#endif +#if defined(GPIO3) +GPIO_INTERRUPT_HANDLER(GPIO3_Combined_0_15_IRQHandler, GPIO3, 3, 0); +GPIO_INTERRUPT_HANDLER(GPIO3_Combined_16_31_IRQHandler, GPIO3, 3, 16); +#endif +#if defined(GPIO4) +GPIO_INTERRUPT_HANDLER(GPIO4_Combined_0_15_IRQHandler, GPIO4, 4, 0); +GPIO_INTERRUPT_HANDLER(GPIO4_Combined_16_31_IRQHandler, GPIO4, 4, 16); +#endif +#if defined(GPIO5) +GPIO_INTERRUPT_HANDLER(GPIO5_Combined_0_15_IRQHandler, GPIO5, 5, 0); +GPIO_INTERRUPT_HANDLER(GPIO5_Combined_16_31_IRQHandler, GPIO5, 5, 16); +#endif +#if defined(GPIO6) +GPIO_INTERRUPT_HANDLER(GPIO6_Combined_0_15_IRQHandler, GPIO6, 6, 0); +GPIO_INTERRUPT_HANDLER(GPIO6_Combined_16_31_IRQHandler, GPIO6, 6, 16); +#endif diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h index d6d12771c5da..0457a09a1a04 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h @@ -35,7 +35,7 @@ #include #include "fsl_iomuxc.h" -#include "fsl_pwm.h" +#include "sdk/drivers/pwm/fsl_pwm.h" #include "py/obj.h" extern const mp_obj_type_t mcu_pin_type; @@ -72,6 +72,10 @@ typedef struct { .pad_reset = p_pad_reset, \ } +typedef void (gpio_change_interrupt_t)(void *data); +void disable_pin_change_interrupt(const mcu_pin_obj_t *pin); +void enable_pin_change_interrupt(const mcu_pin_obj_t *pin, gpio_change_interrupt_t func, void *data); + #ifdef MIMXRT1011_SERIES #include "MIMXRT1011/pins.h" #elif defined(MIMXRT1021_SERIES) diff --git a/ports/mimxrt10xx/reset.c b/ports/mimxrt10xx/reset.c index a3a4f667deaa..3d9a0b071b92 100644 --- a/ports/mimxrt10xx/reset.c +++ b/ports/mimxrt10xx/reset.c @@ -26,10 +26,11 @@ #include "reset.h" #include "supervisor/filesystem.h" +#include "supervisor/linker.h" #include "fsl_common.h" -void reset(void) { +void PLACE_IN_ITCM(reset)(void) { filesystem_flush(); NVIC_SystemReset(); } diff --git a/ports/mimxrt10xx/reset.h b/ports/mimxrt10xx/reset.h index ea56df02a179..0d458a907d66 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/sdk b/ports/mimxrt10xx/sdk index 8363ff7bed75..2b9354539e6e 160000 --- a/ports/mimxrt10xx/sdk +++ b/ports/mimxrt10xx/sdk @@ -1 +1 @@ -Subproject commit 8363ff7bed7533b9e7e6a6239aace3d6da14f349 +Subproject commit 2b9354539e6e4f722749e87b0bdc22966dc080d9 diff --git a/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c b/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c index 950e9aa403ea..e32eaf883218 100644 --- a/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c +++ b/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c @@ -7,12 +7,23 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fsl_flexspi.h" +#include "sdk/drivers/flexspi/fsl_flexspi.h" #include "internal_flash.h" #include "boards/flash_config.h" #include "supervisor/internal_flash.h" #include "supervisor/linker.h" +STATIC uint8_t _busy_bit_shift; +STATIC bool _busy_bit_polarity; +STATIC bool _inited = false; + +void flexspi_nor_init(void) { + // Copy busy bit info into RAM so we can use if when flash isn't available. + _busy_bit_shift = qspiflash_config.memConfig.busyOffset; + _busy_bit_polarity = qspiflash_config.memConfig.busyBitPolarity; + _inited = true; +} + STATIC status_t PLACE_IN_ITCM(flexspi_nor_write_enable)(FLEXSPI_Type * base, uint32_t baseAddr) { flexspi_transfer_t flashXfer; @@ -53,9 +64,8 @@ STATIC status_t PLACE_IN_ITCM(flexspi_nor_wait_bus_busy)(FLEXSPI_Type * base) if (status != kStatus_Success) { return status; } - size_t busyBit = readValue & (1U << qspiflash_config.memConfig.busyOffset); - isBusy = (qspiflash_config.memConfig.busyBitPolarity == 0 && busyBit != 0) || - (qspiflash_config.memConfig.busyBitPolarity == 1 && busyBit == 0); + bool busyBit = (readValue >> _busy_bit_shift) & 0x1; + isBusy = busyBit != _busy_bit_polarity; } while (isBusy); return status; diff --git a/ports/mimxrt10xx/supervisor/internal_flash.c b/ports/mimxrt10xx/supervisor/internal_flash.c index 72d57d1dd440..bacb62854a11 100644 --- a/ports/mimxrt10xx/supervisor/internal_flash.c +++ b/ports/mimxrt10xx/supervisor/internal_flash.c @@ -38,8 +38,8 @@ #include "py/runtime.h" #include "lib/oofatfs/ff.h" -#include "fsl_cache.h" -#include "fsl_flexspi.h" +#include "sdk/drivers/cache/armv7-m7/fsl_cache.h" +#include "sdk/drivers/flexspi/fsl_flexspi.h" #include "fsl_iomuxc.h" // defined in linker @@ -53,8 +53,15 @@ uint8_t _flash_cache[SECTOR_SIZE] __attribute__((aligned(4))); uint32_t _flash_page_addr = NO_CACHE; void PLACE_IN_ITCM(supervisor_flash_init)(void) { - // Update the LUT to make sure all entries are available. - FLEXSPI_UpdateLUT(FLEXSPI, 0, (const uint32_t *)&qspiflash_config.memConfig.lookupTable, 64); + // Update the LUT to make sure all entries are available. Copy the values to + // memory first so that we don't read from the flash as we update the LUT. + uint32_t lut_copy[64]; + memcpy(lut_copy, (const uint32_t *)&qspiflash_config.memConfig.lookupTable, 64 * sizeof(uint32_t)); + FLEXSPI_UpdateLUT(FLEXSPI, 0, lut_copy, 64); + // Make sure everything is flushed after updating the LUT. + __DSB(); + __ISB(); + flexspi_nor_init(); } static inline uint32_t lba2addr(uint32_t block) { @@ -79,20 +86,21 @@ void PLACE_IN_ITCM(port_internal_flash_flush)(void) { if (memcmp(_flash_cache, (void *)_flash_page_addr, SECTOR_SIZE) != 0) { volatile uint32_t sector_addr = (_flash_page_addr - FlexSPI_AMBA_BASE); - __disable_irq(); + // Disable interrupts of priority 8+. They likely use code in flash + // itself. Higher priority interrupts (<8) should ensure all of their + // code is in RAM. + __set_BASEPRI(8 << (8 - __NVIC_PRIO_BITS)); status = flexspi_nor_flash_erase_sector(FLEXSPI, sector_addr); - __enable_irq(); + __set_BASEPRI(0U); if (status != kStatus_Success) { - printf("Page erase failure %ld!\r\n", status); return; } for (int i = 0; i < SECTOR_SIZE / FLASH_PAGE_SIZE; ++i) { - __disable_irq(); + __set_BASEPRI(8 << (8 - __NVIC_PRIO_BITS)); status = flexspi_nor_flash_page_program(FLEXSPI, sector_addr + i * FLASH_PAGE_SIZE, (void *)_flash_cache + i * FLASH_PAGE_SIZE); - __enable_irq(); + __set_BASEPRI(0U); if (status != kStatus_Success) { - printf("Page program failure %ld!\r\n", status); return; } } @@ -103,11 +111,17 @@ void PLACE_IN_ITCM(port_internal_flash_flush)(void) { } mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { - // Must write out anything in cache before trying to read. - supervisor_flash_flush(); + for (size_t i = 0; i < num_blocks; i++) { + uint32_t src = lba2addr(block + i); + uint32_t page_addr = src & ~(SECTOR_SIZE - 1); + // Copy from the cache if our page matches the cached one. + if (page_addr == _flash_page_addr) { + src = ((uint32_t)&_flash_cache) + (src - page_addr); + } + + memcpy(dest + FILESYSTEM_BLOCK_SIZE * i, (uint8_t *)src, FILESYSTEM_BLOCK_SIZE); + } - uint32_t src = lba2addr(block); - memcpy(dest, (uint8_t *)src, FILESYSTEM_BLOCK_SIZE * num_blocks); return 0; // success } @@ -141,5 +155,5 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32 return 0; // success } -void supervisor_flash_release_cache(void) { +void PLACE_IN_ITCM(supervisor_flash_release_cache)(void) { } diff --git a/ports/mimxrt10xx/supervisor/internal_flash.h b/ports/mimxrt10xx/supervisor/internal_flash.h index 66d3f73db1a7..c38e2bc4161b 100644 --- a/ports/mimxrt10xx/supervisor/internal_flash.h +++ b/ports/mimxrt10xx/supervisor/internal_flash.h @@ -42,6 +42,7 @@ #define ROM_INDEX_PAGEPROGRAM 9 #define ROM_INDEX_READSTATUSREG 1 +extern void flexspi_nor_init(void); extern status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address); extern status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src); extern status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base); diff --git a/ports/mimxrt10xx/supervisor/port.c b/ports/mimxrt10xx/supervisor/port.c index fbf0e8a9d8aa..feb8566aade3 100644 --- a/ports/mimxrt10xx/supervisor/port.c +++ b/ports/mimxrt10xx/supervisor/port.c @@ -36,25 +36,30 @@ #include "fsl_device_registers.h" +#if CIRCUITPY_AUDIOBUSIO +#include "common-hal/audiobusio/__init__.h" +#endif + #include "common-hal/microcontroller/Pin.h" #include "common-hal/pwmio/PWMOut.h" #include "common-hal/rtc/RTC.h" #include "common-hal/busio/SPI.h" #include "shared-bindings/microcontroller/__init__.h" -#include "reset.h" - -#include "supervisor/background_callback.h" - #if CIRCUITPY_PEW #include "shared-module/_pew/PewPew.h" #endif + +#include "reset.h" + +#include "supervisor/background_callback.h" +#include "supervisor/linker.h" #include "supervisor/shared/tick.h" #include "clocks.h" -#include "fsl_gpio.h" -#include "fsl_lpuart.h" +#include "sdk/drivers/igpio/fsl_gpio.h" +#include "sdk/drivers/lpuart/fsl_lpuart.h" // Device memories must be accessed in order. #define DEVICE 2 @@ -97,16 +102,55 @@ extern uint32_t _ld_dtcm_data_flash_copy; extern uint32_t _ld_itcm_destination; extern uint32_t _ld_itcm_size; extern uint32_t _ld_itcm_flash_copy; +extern uint32_t _ld_isr_destination; +extern uint32_t _ld_isr_size; +extern uint32_t _ld_isr_flash_copy; + +// Remove these once the SDK re-includes them. +// https://github.com/nxp-mcuxpresso/mcux-sdk/issues/110 +/*! @name GPR14 - GPR14 General Purpose Register */ +/*! @{ */ +#define IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_MASK (0xF0000U) +#define IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_SHIFT (16U) +/*! CM7_CFGITCMSZ + * 0b0000..0 KB (No ITCM) + * 0b0011..4 KB + * 0b0100..8 KB + * 0b0101..16 KB + * 0b0110..32 KB + * 0b0111..64 KB + * 0b1000..128 KB + */ +#define IOMUXC_GPR_GPR14_CM7_CFGITCMSZ(x) (((uint32_t)(((uint32_t)(x)) << IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_SHIFT)) & IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_MASK) +#define IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_MASK (0xF00000U) +#define IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_SHIFT (20U) +/*! CM7_CFGDTCMSZ + * 0b0000..0 KB (No DTCM) + * 0b0011..4 KB + * 0b0100..8 KB + * 0b0101..16 KB + * 0b0110..32 KB + * 0b0111..64 KB + * 0b1000..128 KB + */ +#define IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ(x) (((uint32_t)(((uint32_t)(x)) << IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_SHIFT)) & IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_MASK) +/*! @} */ extern void main(void); // This replaces the Reset_Handler in startup_*.S and SystemInit in system_*.c. +// Turn off optimize("no-tree-loop-distribute-patterns") so that this isn't replaced +// by calls to memcpy because we're copying it over now. void Reset_Handler(void); -__attribute__((used, naked)) void Reset_Handler(void) { +__attribute__((used, naked, no_instrument_function, optimize("no-tree-loop-distribute-patterns"))) void Reset_Handler(void) { __disable_irq(); - SCB->VTOR = (uint32_t)&__isr_vector; + // Set the VTOR to the flash copy since we haven't copied it into RAM. + SCB->VTOR = (uint32_t)&_ld_isr_flash_copy; __set_MSP((uint32_t)&_ld_stack_top); + // Turn off any residual ITM outputs. + ITM->TER = 0; + /* Disable I cache and D cache */ SCB_DisableICache(); SCB_DisableDCache(); @@ -128,6 +172,11 @@ __attribute__((used, naked)) void Reset_Handler(void) { current_gpr14 |= IOMUXC_GPR_GPR14_CM7_CFGITCMSZ(0x6); IOMUXC_GPR->GPR14 = current_gpr14; + // Enable FlexRAM interrupts on invalid access. + FLEXRAM->INT_STAT_EN = FLEXRAM_INT_STAT_EN_ITCM_ERR_STAT_EN(1) | + FLEXRAM_INT_STAT_EN_DTCM_ERR_STAT_EN(1) | + FLEXRAM_INT_STAT_EN_OCRAM_ERR_STAT_EN(1); + #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access */ #endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */ @@ -157,6 +206,13 @@ __attribute__((used, naked)) void Reset_Handler(void) { (&_ld_itcm_destination)[i] = (&_ld_itcm_flash_copy)[i]; } + for (uint32_t i = 0; i < ((size_t)&_ld_isr_size) / 4; i++) { + (&_ld_isr_destination)[i] = (&_ld_isr_flash_copy)[i]; + } + + // Now that we've copied the ISR table over, use that VTOR. + SCB->VTOR = (uint32_t)&_ld_isr_destination; + // The first number in RBAR is the region number. When searching for a policy, the region with // the highest number wins. If none match, then the default policy set at enable applies. @@ -170,14 +226,19 @@ __attribute__((used, naked)) void Reset_Handler(void) { // FlexSPI2 is 0x70000000 - // This the first 1MB of flash is the bootloader and CircuitPython read-only data. - MPU->RBAR = ARM_MPU_RBAR(10, 0x60000000U); - MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_1MB); + // This the first portion (1MB, 2MB or 4MB) of flash is the bootloader and CircuitPython read-only data. + MPU->RBAR = ARM_MPU_RBAR(10, FlexSPI_AMBA_BASE); + uint32_t region_size = ARM_MPU_REGION_SIZE_32B; + uint32_t code_size = ((uint32_t)&_ld_filesystem_start) - FlexSPI_AMBA_BASE; + while (code_size > (1u << (region_size + 1))) { + region_size += 1; + } + MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, region_size); // The remainder of flash is the fat filesystem which could have code on it too. Make sure that // we set the region to the minimal size so that bad data doesn't get speculatively fetched. // Thanks to Damien for the tip! - uint32_t region_size = ARM_MPU_REGION_SIZE_32B; + region_size = ARM_MPU_REGION_SIZE_32B; uint32_t filesystem_size = &_ld_filesystem_end - &_ld_filesystem_start; while (filesystem_size > (1u << (region_size + 1))) { region_size += 1; @@ -189,7 +250,7 @@ __attribute__((used, naked)) void Reset_Handler(void) { uint32_t subregion_size = (1u << (region_size + 1)) / 8; uint8_t subregion_mask = (0xff00 >> (remainder / subregion_size)) & 0xff; - MPU->RBAR = ARM_MPU_RBAR(11, 0x60100000U); + MPU->RBAR = ARM_MPU_RBAR(11, (size_t)&_ld_filesystem_start); MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, subregion_mask, region_size); // This the ITCM. Set it to read-only because we've loaded everything already and it's easy to @@ -205,9 +266,10 @@ __attribute__((used, naked)) void Reset_Handler(void) { // cost of 1/4 speed OCRAM accesses. It will leave more room for caching data from the flash // too which might be a net win. MPU->RBAR = ARM_MPU_RBAR(14, 0x20200000U); - MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_512KB); + MPU->RASR = ARM_MPU_RASR(NO_EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_512KB); // We steal 64k from FlexRAM for ITCM and DTCM so disable those memory regions here. + // We use 64k from FlexRAM for ITCM and DTCM so disable those memory regions here. MPU->RBAR = ARM_MPU_RBAR(15, 0x20280000U); MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, 0x80, ARM_MPU_REGION_SIZE_512KB); @@ -239,14 +301,97 @@ __attribute__((used, naked)) void Reset_Handler(void) { } __enable_irq(); + main(); } +void __attribute__((no_instrument_function,section(".itcm.profile_enter"),long_call)) __cyg_profile_func_enter(void *this_fn, + void *call_site) { + if ((ITM->TER & (1 << 3)) == 0) { + return; + } + uint32_t addr = (uint32_t)this_fn; + while (ITM->PORT[3U].u32 == 0UL) { + // addr |= 1; + } + ITM->PORT[3].u32 = addr; +} + +void __attribute__((no_instrument_function,section(".itcm.profile_exit"),long_call)) __cyg_profile_func_exit(void *this_fn, + void *call_site) { + if ((ITM->TER & (1 << 4)) == 0) { + return; + } + uint32_t addr = (uint32_t)this_fn; + while (ITM->PORT[4U].u32 == 0UL) { + // addr |= 1; + } + ITM->PORT[4].u32 = addr; +} + safe_mode_t port_init(void) { CLOCK_SetMode(kCLOCK_ModeRun); clocks_init(); + // Turn on the DWT so that neopixel_write can use CYCCNT for timing. + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CTRL = 0x2 << DWT_CTRL_SYNCTAP_Pos | DWT_CTRL_CYCCNTENA_Msk; + + // Enable SWO if needed. + #if CIRCUITPY_SWO_TRACE + + // Turn on the 528 MHz clock to the TPIU. + CLOCK_EnableClock(kCLOCK_Trace); /* Make these edits*/ + /* Set TRACE_PODF. */ + CLOCK_SetDiv(kCLOCK_TraceDiv, 0); /* Make these edits*/ + /* Set Trace clock source. */ + CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Make these edits*/ + + ITM->TCR = ITM_TCR_TSENA_Msk | ITM_TCR_ITMENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_DWTENA_Msk; + + // Run at 2.75 mbaud. CP2102N says it can do up to 3. + // Base clock is 528 mhz (not 500 like the core). + // TPI->ACPR = 191; + // Run at 1 mbaud so that USB isn't bottlenecked. + TPI->ACPR = 527; + TPI->SPPR = 0x2; // NRZ aka UART + TPI->FFCR = 0; + + IOMUXC_SetPinMux( /* Add these lines*/ + IOMUXC_GPIO_AD_09_ARM_TRACE_SWO, + 0U); + IOMUXC_SetPinConfig( /* Add these lines*/ + IOMUXC_GPIO_AD_09_ARM_TRACE_SWO, + 0x00F9U); + + // Enable ports 0-4: + // * 0 is serial output + // * + // * 3 is addresses of functions beginning. + // * 4 is addresses of functions ending. + ITM->TER |= 0x1f; + ITM->PORT[0].u8 = 'C'; + ITM->PORT[0].u8 = 'P'; + ITM->PORT[0].u8 = '\n'; + #endif + + // Set all peripheral interrupt priorities to the lowest priority by default. + for (uint16_t i = 0; i < NUMBER_OF_INT_VECTORS; i++) { + NVIC_SetPriority(i, (1UL << __NVIC_PRIO_BITS) - 1UL); + } + NVIC_SetPriority(USB_OTG1_IRQn, 1); + #ifdef USBPHY2 + NVIC_SetPriority(USB_OTG2_IRQn, 1); + #endif + + NVIC_SetPriority(FLEXRAM_IRQn, 0); + NVIC_EnableIRQ(FLEXRAM_IRQn); + + // Priorities 8+ will be disabled during flash operations. To run during + // flash operations, ensure all code is in RAM (not flash) and set the + // priority < 8. + #if CIRCUITPY_RTC rtc_init(); #endif @@ -259,10 +404,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) { @@ -273,8 +418,7 @@ void reset_port(void) { audioout_reset(); #endif #if CIRCUITPY_AUDIOBUSIO - i2sout_reset(); - // pdmin_reset(); + i2s_reset(); #endif #if CIRCUITPY_TOUCHIO && CIRCUITPY_TOUCHIO_USE_NATIVE @@ -284,7 +428,7 @@ void reset_port(void) { // eic_reset(); #if CIRCUITPY_PWMIO - pwmout_reset(); + reset_all_flexpwm(); #endif #if CIRCUITPY_RTC @@ -301,11 +445,11 @@ void reset_port(void) { } void reset_to_bootloader(void) { - SNVS->LPGPR[0] = DBL_TAP_MAGIC; + DBL_TAP_REG = DBL_TAP_MAGIC; reset(); } -void reset_cpu(void) { +void PLACE_IN_ITCM(reset_cpu)(void) { reset(); } @@ -332,7 +476,7 @@ uint32_t *port_heap_get_top(void) { } // Place the word into the low power section of the SNVS. -void port_set_saved_word(uint32_t value) { +void PLACE_IN_ITCM(port_set_saved_word)(uint32_t value) { SNVS->LPGPR[1] = value; } @@ -355,7 +499,7 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) { void SNVS_HP_WRAPPER_IRQHandler(void); __attribute__((used)) -void SNVS_HP_WRAPPER_IRQHandler(void) { +void PLACE_IN_ITCM(SNVS_HP_WRAPPER_IRQHandler)(void) { if ((SNVS->HPSR & SNVS_HPSR_PI_MASK) != 0) { supervisor_tick(); SNVS->HPSR = SNVS_HPSR_PI_MASK; @@ -414,45 +558,44 @@ void port_idle_until_interrupt(void) { common_hal_mcu_enable_interrupts(); } -/** - * \brief Default interrupt handler for unused IRQs. - */ +// Catch faults where the memory access violates MPU settings. void MemManage_Handler(void); -__attribute__((used)) void MemManage_Handler(void) { - reset_into_safe_mode(MEM_MANAGE); +__attribute__((used)) void PLACE_IN_ITCM(MemManage_Handler)(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } -/** - * \brief Default interrupt handler for unused IRQs. - */ void BusFault_Handler(void); -__attribute__((used)) void BusFault_Handler(void) { - reset_into_safe_mode(MEM_MANAGE); +__attribute__((used)) void PLACE_IN_ITCM(BusFault_Handler)(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } -/** - * \brief Default interrupt handler for unused IRQs. - */ void UsageFault_Handler(void); -__attribute__((used)) void UsageFault_Handler(void) { - reset_into_safe_mode(MEM_MANAGE); +__attribute__((used)) void PLACE_IN_ITCM(UsageFault_Handler)(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } -/** - * \brief Default interrupt handler for unused IRQs. - */ +// Default fault handler. void HardFault_Handler(void); -__attribute__((used)) void HardFault_Handler(void) { - reset_into_safe_mode(HARD_CRASH); +__attribute__((used)) void PLACE_IN_ITCM(HardFault_Handler)(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); + while (true) { + asm ("nop;"); + } +} + +// Catch access errors to FlexRAM (if the MPU didn't catch it first.) +void FLEXRAM_IRQHandler(void); +__attribute__((used)) void PLACE_IN_ITCM(FLEXRAM_IRQHandler)(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } diff --git a/ports/mimxrt10xx/supervisor/serial.c b/ports/mimxrt10xx/supervisor/serial.c deleted file mode 100644 index cb557d36a82f..000000000000 --- a/ports/mimxrt10xx/supervisor/serial.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries - * Copyright (c) 2019 Lucian Copeland 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 - * 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/serial.h" -#include "py/mphal.h" -#include - -#include "fsl_clock.h" -#include "fsl_lpuart.h" - -#if defined(CIRCUITPY_CONSOLE_UART) -// static LPUART_Type *uart_instance = LPUART1; // evk -static LPUART_Type *uart_instance = LPUART4; // feather 1011 -// static LPUART_Type *uart_instance = LPUART2; // feather 1062 -static uint32_t UartSrcFreq(void) { - uint32_t freq; - - /* To make it simple, we assume default PLL and divider settings, and the only - variable from application is use PLL3 source or OSC source */ - /* PLL3 div6 80M */ - if (CLOCK_GetMux(kCLOCK_UartMux) == 0) { - freq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / - (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); - } else { - freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); - } - - return freq; -} - -void port_serial_init(void) { - lpuart_config_t config; - - LPUART_GetDefaultConfig(&config); - config.baudRate_Bps = 115200; - config.enableTx = true; - config.enableRx = true; - - LPUART_Init(uart_instance, &config, UartSrcFreq()); -} - -bool port_serial_connected(void) { - return true; -} - -char port_serial_read(void) { - uint8_t data; - - LPUART_ReadBlocking(uart_instance, &data, sizeof(data)); - - return data; -} - -bool port_serial_bytes_available(void) { - return LPUART_GetStatusFlags(uart_instance) & kLPUART_RxDataRegFullFlag; -} - -void port_serial_write_substring(const char *text, uint32_t len) { - if (len == 0) { - return; - } - - LPUART_WriteBlocking(uart_instance, (uint8_t *)text, len); -} -#endif // CIRCUITPY_CONSOLE_UART diff --git a/ports/mimxrt10xx/supervisor/usb.c b/ports/mimxrt10xx/supervisor/usb.c index 2094a943b57e..bc6bc5f0cdd9 100644 --- a/ports/mimxrt10xx/supervisor/usb.c +++ b/ports/mimxrt10xx/supervisor/usb.c @@ -27,6 +27,8 @@ #include "fsl_clock.h" #include "tusb.h" + +#include "supervisor/linker.h" #include "supervisor/usb.h" STATIC void init_usb_instance(mp_int_t instance) { @@ -78,13 +80,13 @@ STATIC void init_usb_instance(mp_int_t instance) { // Provide the prototypes for the interrupt handlers. The iMX RT SDK doesn't. // The SDK only links to them from assembly. void USB_OTG1_IRQHandler(void); - void USB_OTG1_IRQHandler(void) { + void PLACE_IN_ITCM(USB_OTG1_IRQHandler)(void) { usb_irq_handler(0); } #ifdef USBPHY2 void USB_OTG2_IRQHandler(void); - void USB_OTG2_IRQHandler(void) { + void PLACE_IN_ITCM(USB_OTG2_IRQHandler)(void) { usb_irq_handler(1); } #endif diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index d1b71799bf77..412ff86cde85 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -212,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 $@" @@ -241,7 +241,7 @@ FLASHER ?= ifeq ($(FLASHER),) -# Also update to bootloader settting to validate application and skip checksum ( app valid = 0x0001, crc = 0x0000 ) +# Also update to bootloader setting to validate application and skip checksum ( app valid = 0x0001, crc = 0x0000 ) flash: $(BUILD)/firmware.hex nrfjprog --program $< --sectorerase -f $(MCU_VARIANT) nrfjprog --erasepage $(BOOT_SETTING_ADDR) -f $(MCU_VARIANT) @@ -275,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 @@ -293,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 f0822de52103..f2df4db0e0bd 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" @@ -42,12 +44,13 @@ #include "common-hal/audiopwmio/PWMAudioOut.h" #endif -void port_start_background_task(void) { +void port_start_background_tick(void) { } -void port_finish_background_task(void) { + +void port_finish_background_tick(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 64a768cf9b79..4fba46d03102 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/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_l2cap.h b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_l2cap.h index d04bec3fbf2d..e0f005d9b0bd 100644 --- a/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_l2cap.h +++ b/ports/nrf/bluetooth/s140_nrf52_6.1.0/s140_nrf52_6.1.0_API/include/ble_l2cap.h @@ -286,7 +286,7 @@ typedef struct /**@brief L2CAP event structure. */ typedef struct { - uint16_t conn_handle; /**< Connection Handle on which the event occured. */ + uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or @ref BLE_L2CAP_CID_INVALID if not present. */ union diff --git a/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/ble_l2cap.h b/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/ble_l2cap.h index 933f398b57bf..a624338ceb75 100644 --- a/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/ble_l2cap.h +++ b/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/ble_l2cap.h @@ -287,7 +287,7 @@ typedef struct /**@brief L2CAP event structure. */ typedef struct { - uint16_t conn_handle; /**< Connection Handle on which the event occured. */ + uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or @ref BLE_L2CAP_CID_INVALID if not present. */ union diff --git a/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/nrf_sdm.h b/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/nrf_sdm.h index 24001fb12a82..3def7d67832e 100644 --- a/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/nrf_sdm.h +++ b/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/nrf_sdm.h @@ -275,8 +275,8 @@ typedef struct * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset(). * * @note It is recommended to either perform a reset in the fault handler or to let the SoftDevice reset the device. - * Otherwise SoC peripherals may behave in an undefined way. For example, the RADIO peripherial may - * continously transmit packets. + * Otherwise SoC peripherals may behave in an undefined way. For example, the RADIO peripheral may + * continuously transmit packets. * * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback. * diff --git a/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/nrf_svc.h b/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/nrf_svc.h index 293001eccf0a..629739ed75e0 100644 --- a/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/nrf_svc.h +++ b/ports/nrf/bluetooth/s140_nrf52_7.0.1/s140_nrf52_7.0.1_API/include/nrf_svc.h @@ -48,7 +48,7 @@ extern "C" { /** @brief Supervisor call declaration. * * A call to a function marked with @ref SVCALL, will trigger a Supervisor Call (SVC) Exception. - * The SVCs with SVC numbers 0x00-0x0F are forwared to the application. All other SVCs are handled by the SoftDevice. + * The SVCs with SVC numbers 0x00-0x0F are forwarded to the application. All other SVCs are handled by the SoftDevice. * * @param[in] number The SVC number to be used. * @param[in] return_type The return type of the SVC function. diff --git a/ports/nrf/boards/aramcon2_badge/mpconfigboard.h b/ports/nrf/boards/aramcon2_badge/mpconfigboard.h index af8e3c35077a..58df3a40587b 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("The left button was pressed 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/espruino_banglejs2/board.c b/ports/nrf/boards/espruino_banglejs2/board.c new file mode 100644 index 000000000000..49a37b7db5b4 --- /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 000000000000..6057cd56e72b --- /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 000000000000..106b85cd7589 --- /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 000000000000..b114c2f13022 --- /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_nrf52840_express/README.md b/ports/nrf/boards/feather_nrf52840_express/README.md index 8d515010f9c3..88a78a20fd91 100644 --- a/ports/nrf/boards/feather_nrf52840_express/README.md +++ b/ports/nrf/boards/feather_nrf52840_express/README.md @@ -104,7 +104,7 @@ Parsing hex file. Erasing user available code and UICR flash areas. Applying system reset. Checking that the area to write is not protected. -Programing device. +Programming device. Applying system reset. Run. ``` diff --git a/ports/nrf/boards/hiibot_bluefi/pins.c b/ports/nrf/boards/hiibot_bluefi/pins.c index ba1910dc9d75..7e0e0a94f4b1 100644 --- a/ports/nrf/boards/hiibot_bluefi/pins.c +++ b/ports/nrf/boards/hiibot_bluefi/pins.c @@ -117,7 +117,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { // { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_P1_13) }, { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_P1_13) }, - // P28~P33/D28~D33 connecte into QSPI FlashROM (W25Q16JV_IQ) + // P28~P33/D28~D33 connected into QSPI FlashROM (W25Q16JV_IQ) { MP_ROM_QSTR(MP_QSTR_P34), MP_ROM_PTR(&pin_P0_22) }, { MP_ROM_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_P0_22) }, diff --git a/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md b/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md index 5c41fdb7cfdb..7040507ba6dd 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md +++ b/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md @@ -8,11 +8,11 @@ We've also routed two I2C buses, 2 SPI buses, eleven GPIO, dedicated ## CircuitPython Pin Defs -CircuitPython pin definitions, while simialr to other boards represent a slight departure from just the typical `A` and `D` pin definitions. The majority of general pins are labled as `G` (or alternatively, `BUS`,) as the MicroMod system they build on uses those names to specify pins that may not be specficially analog or digital. +CircuitPython pin definitions, while similar to other boards represent a slight departure from just the typical `A` and `D` pin definitions. The majority of general pins are labeled as `G` (or alternatively, `BUS`,) as the MicroMod system they build on uses those names to specify pins that may not be specficially analog or digital. This can be somewhat confusing, especially around the analog pins. Here's a quick pin-map: -MicroMod Pin # | ATP Pin Label | Pin Definition | Additional Definitons | Pin/Port Reference | Notes +MicroMod Pin # | ATP Pin Label | Pin Definition | Additional Definitions | Pin/Port Reference | Notes :--------------|:--------------|:--------------|:-----------------------|:-------------------|:------ 8 | G11 | | | (Not Connected) | 10 | D0 | D0 | | P0_27 | diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c index 2c0c343877ea..828ff8806dad 100644 --- a/ports/nrf/common-hal/_bleio/Adapter.c +++ b/ports/nrf/common-hal/_bleio/Adapter.c @@ -91,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]; @@ -190,7 +190,7 @@ STATIC uint32_t ble_stack_enable(void) { return err_code; } - // Increase the GATT Server attribute size to accomodate both the CircuitPython built-in service + // Increase the GATT Server attribute size to accommodate both the CircuitPython built-in service // and anything the user does. memset(&ble_conf, 0, sizeof(ble_conf)); // Each increment to the BLE_GATTS_ATTR_TAB_SIZE_DEFAULT multiplier costs 1408 bytes. @@ -529,7 +529,7 @@ STATIC bool scan_on_ble_evt(ble_evt_t *ble_evt, void *scan_results_in) { mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t *prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active) { if (self->scan_results != NULL) { if (!shared_module_bleio_scanresults_get_done(self->scan_results)) { - mp_raise_bleio_BluetoothError(translate("Scan already in progess. Stop with stop_scan.")); + mp_raise_bleio_BluetoothError(translate("Scan already in progress. Stop with stop_scan.")); } self->scan_results = NULL; } diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c index df86654c70f4..e911e5a1e30f 100644 --- a/ports/nrf/common-hal/_bleio/Characteristic.c +++ b/ports/nrf/common-hal/_bleio/Characteristic.c @@ -283,7 +283,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, } // Write with response will return NRF_ERROR_BUSY if the response has not been received. - // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending. + // Write without response will return NRF_ERROR_RESOURCES if too many writes are pending. if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) { // We could wait for an event indicating the write is complete, but just retrying is easier. RUN_BACKGROUND_TASKS; diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c index d13ffa1a943b..58dc94fe25db 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,10 +95,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->watch_for_interrupt_char = watch_for_interrupt_char; ringbuf_init(&self->ringbuf, buffer, buffer_size); @@ -105,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) { diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.h index f0949251cd24..ba3d7ba3fcee 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/Connection.c b/ports/nrf/common-hal/_bleio/Connection.c index 0d8d8c32f061..69e6945d215b 100644 --- a/ports/nrf/common-hal/_bleio/Connection.c +++ b/ports/nrf/common-hal/_bleio/Connection.c @@ -528,7 +528,7 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio (gattc_char->char_props.write ? CHAR_PROP_WRITE : 0) | (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0); - // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler. + // Call common_hal_bleio_characteristic_construct() to initialize some fields and set up evt handler. common_hal_bleio_characteristic_construct( characteristic, m_char_discovery_service, gattc_char->handle_value, uuid, props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, diff --git a/ports/nrf/common-hal/_bleio/__init__.c b/ports/nrf/common-hal/_bleio/__init__.c index 718b28c7fecc..75bfb60342fd 100644 --- a/ports/nrf/common-hal/_bleio/__init__.c +++ b/ports/nrf/common-hal/_bleio/__init__.c @@ -249,7 +249,7 @@ void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buff } // Write with response will return NRF_ERROR_BUSY if the response has not been received. - // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending. + // Write without response will return NRF_ERROR_RESOURCES if too many writes are pending. if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) { // We could wait for an event indicating the write is complete, but just retrying is easier. MICROPY_VM_HOOK_LOOP; diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index df4a4859996a..10a34e09df38 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); diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c index d84cc584552f..7824175605ac 100644 --- a/ports/nrf/common-hal/microcontroller/__init__.c +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -55,7 +55,7 @@ void common_hal_mcu_disable_interrupts() { // Unlike __disable_irq(), this should only be called the first time // "is_nested_critical_region" is sd's equivalent of our nesting count // so a nested call would store 0 in the global and make the later - // exit call not actually reenable interrupts + // exit call not actually re-enable interrupts // // This only disables interrupts of priority 2 through 7; levels 0, 1, // and 4, are exclusive to softdevice and should never be used, so @@ -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/pwmio/PWMOut.c b/ports/nrf/common-hal/pwmio/PWMOut.c index 1bd38e7a6e7f..6171f5eb76d3 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]; @@ -108,13 +94,19 @@ STATIC void reset_single_pwmout(uint8_t i) { for (int ch = 0; ch < CHANNELS_PER_PWM; ch++) { pwm_seq[i][ch] = (1 << 15); // polarity = 0 - pwm->PSEL.OUT[ch] = 0xFFFFFFFF; // disconnnect from I/O + pwm->PSEL.OUT[ch] = 0xFFFFFFFF; // disconnect from I/O } } 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/espruino_dfu_private_key.pem b/ports/nrf/espruino_dfu_private_key.pem new file mode 100644 index 000000000000..79c70f76eebc --- /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.h b/ports/nrf/mpconfigport.h index 99effcea2f97..4726d51c5565 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -65,7 +65,7 @@ // This also includes mpconfigboard.h. #include "py/circuitpy_mpconfig.h" -// Definitions that might be overriden by mpconfigboard.h +// Definitions that might be overridden by mpconfigboard.h #ifndef CIRCUITPY_INTERNAL_NVM_SIZE #define CIRCUITPY_INTERNAL_NVM_SIZE (8 * 1024) diff --git a/ports/nrf/supervisor/internal_flash.c b/ports/nrf/supervisor/internal_flash.c index cce48a4c32be..4229ec771b6b 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 e67f64190073..313ecd7e447e 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -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,7 +399,7 @@ 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;"); } diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c index df80671e6469..2ae166d3ad29 100644 --- a/ports/nrf/supervisor/qspi_flash.c +++ b/ports/nrf/supervisor/qspi_flash.c @@ -59,7 +59,7 @@ static int sck_delay_saved = 0; void qspi_disable(void) { // If VBUS is detected, no need to disable QSPI if (NRF_QSPI->ENABLE && !(NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_VBUSDETECT_Msk)) { - // Keep CS high when QSPI is diabled + // Keep CS high when QSPI is disabled nrf_gpio_cfg_output(MICROPY_QSPI_CS); nrf_gpio_pin_write(MICROPY_QSPI_CS, 1); diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index 98a5d7d77a63..a834e545d4ca 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -33,17 +33,23 @@ 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/cyw43_driver/cyw43_bus_pio_spi.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_lwip/nosys.c \ - src/rp2_common/pico_lwip/random.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 \ @@ -69,27 +75,15 @@ $(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/cyw43_driver/cyw43_bus_pio_spi.pio $(PIOASM) +$(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/cyw43_driver/cyw43_bus_pio_spi.o: $(BUILD)/cyw43_bus_pio_spi.pio.h - -CYW43_FIRMWARE_BIN = 43439A0-7.95.49.00.combined - -$(BUILD)/cyw43_resource.o: lib/cyw43-driver/firmware/$(CYW43_FIRMWARE_BIN) - $(Q)$(OBJCOPY) -I binary -O elf32-littlearm -B arm \ - --readonly-text \ - --rename-section .data=.big_const,contents,alloc,load,readonly,data \ - --redefine-sym _binary_lib_cyw43_driver_firmware_43439A0_7_95_49_00_combined_start=fw_43439A0_7_95_49_00_start \ - --redefine-sym _binary_lib_cyw43_driver_firmware_43439A0_7_95_49_00_combined_size=fw_43439A0_7_95_49_00_size \ - --redefine-sym _binary_lib_cyw43_driver_firmware_43439A0_7_95_49_00_combined_end=fw_43439A0_7_95_49_00_end \ - $< $@ -OBJ_CYW43 := $(BUILD)/cyw43_resource.o +$(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 := -OBJ_CYW43 := SRC_LWIP := endif @@ -236,7 +230,7 @@ SRC_SDK := \ $(SRC_SDK_CYW43) \ SRC_SDK := $(addprefix sdk/, $(SRC_SDK)) -$(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 +$(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 \ @@ -380,7 +374,7 @@ 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_CYW43) $(OBJ_MBEDTLS) +OBJ += $(OBJ_MBEDTLS) $(BUILD)/%.o: $(BUILD)/%.S $(STEPECHO) "CC $<" @@ -420,7 +414,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(LINK_LD) $(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 -Wl,-lc - $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LINK_LD) + $(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 4b5190aa2740..1024ff7b38e7 100644 --- a/ports/raspberrypi/background.c +++ b/ports/raspberrypi/background.c @@ -28,9 +28,13 @@ #include "py/runtime.h" #include "supervisor/port.h" -void port_start_background_task(void) { +void port_start_background_tick(void) { } -void port_finish_background_task(void) { + +void port_finish_background_tick(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 index c72581a6e445..520d10263c3a 100644 --- a/ports/raspberrypi/bindings/cyw43/__init__.c +++ b/ports/raspberrypi/bindings/cyw43/__init__.c @@ -84,7 +84,7 @@ const mp_obj_type_t cyw43_pin_type = { //| 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 +//| * 2: Power saving with high throughput //| //| 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. //| @@ -116,23 +116,23 @@ STATIC mp_obj_t cyw43_get_power_management() { } 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) { +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("Expected a %q or %q"), mcu_pin_type.name, cyw43_pin_type.name); + 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) { - const mcu_pin_obj_t *pin = validate_obj_is_pin(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) { - const mcu_pin_obj_t *pin = validate_obj_is_pin_including_cyw43(obj); +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; } diff --git a/ports/raspberrypi/bindings/cyw43/__init__.h b/ports/raspberrypi/bindings/cyw43/__init__.h index 65e9813f9979..26c1aa008f27 100644 --- a/ports/raspberrypi/bindings/cyw43/__init__.h +++ b/ports/raspberrypi/bindings/cyw43/__init__.h @@ -31,9 +31,9 @@ #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); -const mcu_pin_obj_t *validate_obj_is_free_pin_or_gpio29(mp_obj_t obj); -const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj); +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 */ \ diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.c b/ports/raspberrypi/bindings/rp2pio/StateMachine.c index 041d02e5cd07..bbf076ba68e6 100644 --- a/ports/raspberrypi/bindings/rp2pio/StateMachine.c +++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.c @@ -94,7 +94,6 @@ //| 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 @@ -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 = @@ -336,7 +341,10 @@ STATIC mp_obj_t rp2pio_statemachine_run(mp_obj_t self_obj, mp_obj_t instruction_ mp_buffer_info_t bufinfo; mp_get_buffer_raise(instruction_obj, &bufinfo, MP_BUFFER_READ); - common_hal_rp2pio_statemachine_run(self, bufinfo.buf, bufinfo.len); + if (bufinfo.len % 2 != 0) { + mp_raise_ValueError(translate("Program size invalid")); + } + common_hal_rp2pio_statemachine_run(self, bufinfo.buf, (size_t)bufinfo.len / 2); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(rp2pio_statemachine_run_obj, rp2pio_statemachine_run); @@ -390,18 +398,23 @@ 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); + 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; + 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; } - 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")); - } - 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()) { return mp_const_none; @@ -597,19 +610,21 @@ 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); + 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; + 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; } - 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")); - } - bool ok = common_hal_rp2pio_statemachine_readinto(self, ((uint8_t *)bufinfo.buf) + start, length, stride_in_bytes, args[ARG_swap].u_bool); if (!ok) { mp_raise_OSError(MP_EIO); @@ -646,7 +661,8 @@ 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) { @@ -668,28 +684,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, diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.h b/ports/raspberrypi/bindings/rp2pio/StateMachine.h index 3ec70a870326..6f07ac1fa1a6 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 6256d4d89813..193a3a202522 100644 --- a/ports/raspberrypi/bindings/rp2pio/__init__.c +++ b/ports/raspberrypi/bindings/rp2pio/__init__.c @@ -38,16 +38,23 @@ //| Learn guide `_. //| //| """ +//| //| def pins_are_sequential(pins: List[microcontroller.Pin]) -> bool: //| """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 89dc7ff98fb2..5cf73cbde3fb 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 000000000000..7d8b03d5f494 --- /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 000000000000..fcc3f7d27705 --- /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 000000000000..db3e55ed1f43 --- /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 000000000000..36da55d45719 --- /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 000000000000..3d1b22b0a41f --- /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/adafruit_feather_rp2040_can/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_can/board.c new file mode 100644 index 000000000000..331653173ecd --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_can/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_can/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_can/mpconfigboard.h new file mode 100644 index 000000000000..a012abec22af --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_can/mpconfigboard.h @@ -0,0 +1,14 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather RP2040 CAN" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO21) + +#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_can/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2040_can/mpconfigboard.mk new file mode 100644 index 000000000000..543b5adcc02b --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_can/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x239A +USB_PID = 0x8130 +USB_PRODUCT = "Feather RP2040 CAN" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_can/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_can/pico-sdk-configboard.h new file mode 100644 index 000000000000..a41131dd22b7 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_can/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_can/pins.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_can/pins.c new file mode 100644 index 000000000000..b64d007a0d2a --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_can/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_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_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_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_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO0) }, + + { 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_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), 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_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_CAN_TX0_RTS), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_CAN_RESET), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_CAN_CS), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_CAN_INTERRUPT), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_CAN_RX0_BF), 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_feather_rp2040_dvi/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/board.c new file mode 100644 index 000000000000..331653173ecd --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/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_dvi/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/mpconfigboard.h new file mode 100644 index 000000000000..55b69b4ad897 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/mpconfigboard.h @@ -0,0 +1,14 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather RP2040 DVI" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO4) + +#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_dvi/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/mpconfigboard.mk new file mode 100644 index 000000000000..a60ff7b9a7d1 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x239A +USB_PID = 0x8128 +USB_PRODUCT = "Feather RP2040 DVI" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/pico-sdk-configboard.h new file mode 100644 index 000000000000..a41131dd22b7 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/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_dvi/pins.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/pins.c new file mode 100644 index 000000000000..c8b4e3474fe5 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/pins.c @@ -0,0 +1,57 @@ +#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_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_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO0) }, + + { 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_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), 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_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_CKN), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_CKP), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D0N), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D0P), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D1N), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_D1P), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D2N), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D2P), 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_feather_rp2040_epd/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/board.c new file mode 100644 index 000000000000..331653173ecd --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/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_epd/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/mpconfigboard.h new file mode 100644 index 000000000000..356f0f5b54a0 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/mpconfigboard.h @@ -0,0 +1,15 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather RP2040 EPD" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO20) +#define MICROPY_HW_NEOPIXEL (&pin_GPIO21) + +#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_epd/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/mpconfigboard.mk new file mode 100644 index 000000000000..3b457b93cb3e --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x239A +USB_PID = 0x812C +USB_PRODUCT = "Feather RP2040 EPD" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/pico-sdk-configboard.h new file mode 100644 index 000000000000..a41131dd22b7 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/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_epd/pins.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/pins.c new file mode 100644 index 000000000000..22ae43adade9 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/pins.c @@ -0,0 +1,51 @@ +#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_EPD_BUSY), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_EPD_RESET), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_EPD_DC), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_EPD_CS), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_EPD_SCK), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_EPD_MOSI), 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_feather_rp2040_rfm/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/board.c new file mode 100644 index 000000000000..331653173ecd --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/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_rfm/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/mpconfigboard.h new file mode 100644 index 000000000000..fff88cc1fa56 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/mpconfigboard.h @@ -0,0 +1,14 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather RP2040 RFM" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO4) + +#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_rfm/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/mpconfigboard.mk new file mode 100644 index 000000000000..161a2b5c2eec --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x239A +USB_PID = 0x812E +USB_PRODUCT = "Feather RP2040 RFM" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/pico-sdk-configboard.h new file mode 100644 index 000000000000..a41131dd22b7 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/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_rfm/pins.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/pins.c new file mode 100644 index 000000000000..71679fb53ba9 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_rfm/pins.c @@ -0,0 +1,57 @@ +#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_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_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO0) }, + + { 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_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), 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_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_RFM_CS), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_RFM_RST), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_RFM_IO5), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_RFM_IO3), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_RFM_IO4), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_RFM_IO0), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_RFM_IO1), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_RFM_IO2), 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_feather_rp2040_usb_host/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/board.c new file mode 100644 index 000000000000..331653173ecd --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/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_usb_host/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/mpconfigboard.h new file mode 100644 index 000000000000..f300bfe71188 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/mpconfigboard.h @@ -0,0 +1,14 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather RP2040 USB Host" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO21) + +#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_usb_host/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/mpconfigboard.mk new file mode 100644 index 000000000000..d249861efbcb --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x239A +USB_PID = 0x812A +USB_PRODUCT = "Feather RP2040 USB Host" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/pico-sdk-configboard.h new file mode 100644 index 000000000000..a41131dd22b7 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/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_usb_host/pins.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/pins.c new file mode 100644 index 000000000000..ab07688f4ca6 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/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_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_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_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_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO0) }, + + { 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_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), 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_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_USB_HOST_DATA_PLUS), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_USB_HOST_DATA_MINUS), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_USB_HOST_5V_POWER), MP_ROM_PTR(&pin_GPIO18) }, + + { 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/boardsource_blok/board.c b/ports/raspberrypi/boards/boardsource_blok/board.c new file mode 100644 index 000000000000..55540c965ac1 --- /dev/null +++ b/ports/raspberrypi/boards/boardsource_blok/board.c @@ -0,0 +1,45 @@ +/* + * 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" +#include "shared-bindings/microcontroller/Pin.h" +#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) { +} diff --git a/ports/raspberrypi/boards/boardsource_blok/mpconfigboard.h b/ports/raspberrypi/boards/boardsource_blok/mpconfigboard.h new file mode 100644 index 000000000000..0ac77bf54e0a --- /dev/null +++ b/ports/raspberrypi/boards/boardsource_blok/mpconfigboard.h @@ -0,0 +1,4 @@ +#define MICROPY_HW_BOARD_NAME "BLOK" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO29) diff --git a/ports/raspberrypi/boards/boardsource_blok/mpconfigboard.mk b/ports/raspberrypi/boards/boardsource_blok/mpconfigboard.mk new file mode 100644 index 000000000000..aba2838864b5 --- /dev/null +++ b/ports/raspberrypi/boards/boardsource_blok/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x2E8A +USB_PID = 0x104A +USB_PRODUCT = "BLOK" +USB_MANUFACTURER = "Boardsource" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel + + +# CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/boardsource_blok/pico-sdk-configboard.h b/ports/raspberrypi/boards/boardsource_blok/pico-sdk-configboard.h new file mode 100644 index 000000000000..a41131dd22b7 --- /dev/null +++ b/ports/raspberrypi/boards/boardsource_blok/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/boardsource_blok/pins.c b/ports/raspberrypi/boards/boardsource_blok/pins.c new file mode 100644 index 000000000000..e3b0ba01692e --- /dev/null +++ b/ports/raspberrypi/boards/boardsource_blok/pins.c @@ -0,0 +1,50 @@ +#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_TX), MP_ROM_PTR(&pin_GPIO0)}, + {MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1)}, + {MP_ROM_QSTR(MP_QSTR_GP02), MP_ROM_PTR(&pin_GPIO2)}, + {MP_ROM_QSTR(MP_QSTR_GP03), MP_ROM_PTR(&pin_GPIO3)}, + {MP_ROM_QSTR(MP_QSTR_GP04), MP_ROM_PTR(&pin_GPIO4)}, + {MP_ROM_QSTR(MP_QSTR_GP05), MP_ROM_PTR(&pin_GPIO5)}, + {MP_ROM_QSTR(MP_QSTR_GP06), MP_ROM_PTR(&pin_GPIO6)}, + {MP_ROM_QSTR(MP_QSTR_GP07), MP_ROM_PTR(&pin_GPIO7)}, + {MP_ROM_QSTR(MP_QSTR_GP08), MP_ROM_PTR(&pin_GPIO8)}, + {MP_ROM_QSTR(MP_QSTR_GP09), 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_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_GP24), MP_ROM_PTR(&pin_GPIO24)}, + {MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25)}, + {MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO25)}, + {MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26)}, + {MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27)}, + {MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28)}, + {MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29)}, + {MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO16)}, + {MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO17)}, + + {MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO26)}, + {MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO28)}, + {MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO27)}, + + {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/raspberrypi/boards/bwshockley_figpi/mpconfigboard.h b/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.h index fbd03379dd26..88847a21bc6a 100644 --- a/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.h +++ b/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.h @@ -2,7 +2,6 @@ #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}, \ diff --git a/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.mk b/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.mk index 95bd9715d69d..06c9f2e958c7 100644 --- a/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.mk +++ b/ports/raspberrypi/boards/bwshockley_figpi/mpconfigboard.mk @@ -6,4 +6,4 @@ USB_MANUFACTURER = "Benjamin Shockley" CHIP_VARIANT = RP2040 CHIP_FAMILY = rp2 -EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" +EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JVxQ" diff --git a/ports/raspberrypi/boards/bwshockley_figpi/pins.c b/ports/raspberrypi/boards/bwshockley_figpi/pins.c index 1bec6fd91ba3..f178e533fb47 100644 --- a/ports/raspberrypi/boards/bwshockley_figpi/pins.c +++ b/ports/raspberrypi/boards/bwshockley_figpi/pins.c @@ -40,23 +40,25 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { 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_D13), MP_ROM_PTR(&pin_GPIO0) }, { 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_LED), MP_ROM_PTR(&pin_GPIO0) }, { 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_D18), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_SCL1), 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_I2C0), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C0), 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_ROM_QSTR(MP_QSTR_STEMMA_I2C1), MP_ROM_PTR(&board_stemma_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C1), MP_ROM_PTR(&board_stemma_i2c_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 000000000000..331653173ecd --- /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 000000000000..d313e6097fc1 --- /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 000000000000..f4278e0c1b4c --- /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 000000000000..36da55d45719 --- /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 000000000000..f2c094cb4d99 --- /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/hack_club_sprig/board.c b/ports/raspberrypi/boards/hack_club_sprig/board.c new file mode 100644 index 000000000000..775e6ca5df46 --- /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 000000000000..442e455c5ea2 --- /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 000000000000..1bde63603111 --- /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 000000000000..36da55d45719 --- /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 000000000000..f82b8fafc521 --- /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_pykey18/board.c b/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c index 4785f742ec0e..5b1190727f92 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c @@ -31,7 +31,7 @@ void reset_board(void) { // turn off any left over LED - board_reset_user_neopixels(&pin_GPIO29, 62); + board_reset_user_neopixels(&pin_GPIO29, 19); } // 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 4785f742ec0e..4e0aa7445032 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey44/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey44/board.c @@ -31,7 +31,7 @@ void reset_board(void) { // turn off any left over LED - board_reset_user_neopixels(&pin_GPIO29, 62); + board_reset_user_neopixels(&pin_GPIO29, 45); } // 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 4785f742ec0e..a77563c66307 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey87/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey87/board.c @@ -31,7 +31,7 @@ void reset_board(void) { // turn off any left over LED - board_reset_user_neopixels(&pin_GPIO29, 62); + board_reset_user_neopixels(&pin_GPIO29, 88); } // 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 48ae66e7cb78..9eea472925dd 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,13 +315,14 @@ 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 } diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c new file mode 100644 index 000000000000..afe3f877878e --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c @@ -0,0 +1,129 @@ +/* + * 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" +#include "mpconfigboard.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 cycle 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_GPIO8, // DC + &pin_GPIO9, // CS + &pin_GPIO12, // 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_GPIO25, // 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) { + // Display + display_init(); +} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/mpconfigboard.h b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/mpconfigboard.h new file mode 100644 index 000000000000..1602656f907c --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/mpconfigboard.h @@ -0,0 +1,11 @@ +#define MICROPY_HW_BOARD_NAME "Waveshare RP2040-LCD-0.96" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO21, .sda = &pin_GPIO20}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO19, .miso = &pin_GPIO16}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO0, .rx = &pin_GPIO1}} diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/mpconfigboard.mk b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/mpconfigboard.mk new file mode 100644 index 000000000000..f441957314d2 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x2E8A +USB_PID = 0x1021 +USB_PRODUCT = "Waveshare RP2040-LCD-0.96" +USB_MANUFACTURER = "Waveshare Electronics" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/pico-sdk-configboard.h b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/pico-sdk-configboard.h new file mode 100644 index 000000000000..36da55d45719 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/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_0_96/pins.c b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/pins.c new file mode 100644 index 000000000000..32fa4c407301 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/pins.c @@ -0,0 +1,57 @@ +#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_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_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + + // ADC + { 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_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + + // 0.96 inch LCD ST7735s + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DIN), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + + // Power pins + { 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_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/common-hal/alarm/SleepMemory.c b/ports/raspberrypi/common-hal/alarm/SleepMemory.c index c1765296dcd3..1f0dddfc51ec 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/analogio/AnalogIn.c b/ports/raspberrypi/common-hal/analogio/AnalogIn.c index 8811cd54e4ef..afa31e3c83af 100644 --- a/ports/raspberrypi/common-hal/analogio/AnalogIn.c +++ b/ports/raspberrypi/common-hal/analogio/AnalogIn.c @@ -44,7 +44,7 @@ #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); + return validate_obj_is_free_pin_or_gpio29(obj, MP_QSTR_pin); } #else #define SPECIAL_PIN(pin) false diff --git a/ports/raspberrypi/common-hal/busio/UART.c b/ports/raspberrypi/common-hal/busio/UART.c index 4212249ec963..156a5e11ce89 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); @@ -339,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/digitalio/DigitalInOut.c b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c index eb498d3f196f..d90c0db81b9f 100644 --- a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +++ b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c @@ -43,7 +43,7 @@ #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); + return validate_obj_is_free_pin_including_cyw43(obj, MP_QSTR_pin); } #endif diff --git a/ports/raspberrypi/common-hal/mdns/Server.c b/ports/raspberrypi/common-hal/mdns/Server.c index 72aedf388931..ab0a7079af20 100644 --- a/ports/raspberrypi/common-hal/mdns/Server.c +++ b/ports/raspberrypi/common-hal/mdns/Server.c @@ -36,18 +36,30 @@ #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 (inited) { + if (object_inited) { + // Mark the object as deinit since another is already using MDNS. + self->inited = false; return; } - mdns_resp_init(); - inited = true; + 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); @@ -68,19 +80,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) { + 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) { - inited = false; + 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 !mdns_resp_netif_active(NETIF_STA); + return !self->inited; } const char *common_hal_mdns_server_get_hostname(mdns_server_obj_t *self) { @@ -215,7 +231,6 @@ STATIC void alloc_search_result_cb(struct mdns_answer *answer, const char *varpa if ((flags & MDNS_SEARCH_RESULT_FIRST) != 0) { // first mdns_remoteservice_obj_t *service = gc_alloc(sizeof(mdns_remoteservice_obj_t), 0, false); - mp_printf(&mp_plat_print, "found service %p\n", service); if (service == NULL) { // alloc fails mdns_search_stop(state->request_id); diff --git a/ports/raspberrypi/common-hal/mdns/Server.h b/ports/raspberrypi/common-hal/mdns/Server.h index 8f28d74d3c5a..a4dab8aa0691 100644 --- a/ports/raspberrypi/common-hal/mdns/Server.h +++ b/ports/raspberrypi/common-hal/mdns/Server.h @@ -34,7 +34,8 @@ 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")]; 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/microcontroller/Processor.c b/ports/raspberrypi/common-hal/microcontroller/Processor.c index 56f2fd7fb14a..697b301953af 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Processor.c +++ b/ports/raspberrypi/common-hal/microcontroller/Processor.c @@ -38,6 +38,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_vreg/include/hardware/vreg.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" @@ -93,7 +94,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) { @@ -111,13 +111,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 327799a6e794..6d9b3d7fa05f 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; diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c index f75c4b34514e..7925a734fb19 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++) { diff --git a/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c b/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c index 0da12e5923ca..7cb4c843823f 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 ecaee90cc2fb..e9cb3d34bb01 100644 --- a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c +++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -289,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}; diff --git a/ports/raspberrypi/common-hal/rp2pio/__init__.c b/ports/raspberrypi/common-hal/rp2pio/__init__.c index 61a77e021cbe..7634001c9874 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]); + const mcu_pin_obj_t *last_pin = pins[0]; for (size_t i = 1; i < len; i++) { - const mcu_pin_obj_t *pin = validate_obj_is_pin(items[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 index fe12f461fbf9..0696cc7ae9af 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.c +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -706,8 +706,6 @@ bool socketpool_socket(socketpool_socketpool_obj_t *self, 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: { @@ -916,10 +914,11 @@ void socketpool_socket_close(socketpool_socket_obj_t *socket) { 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) { + tcp_err(socket->pcb.tcp, NULL); + tcp_recv(socket->pcb.tcp, NULL); + // 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. @@ -977,6 +976,7 @@ void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *socket, // Register our receive callback. MICROPY_PY_LWIP_ENTER tcp_recv(socket->pcb.tcp, _lwip_tcp_recv); + tcp_err(socket->pcb.tcp, _lwip_tcp_error); socket->state = STATE_CONNECTING; err = tcp_connect(socket->pcb.tcp, &dest, port, _lwip_tcp_connected); if (err != ERR_OK) { diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.h b/ports/raspberrypi/common-hal/socketpool/Socket.h index 6e2608767459..c2306d201a1a 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.h +++ b/ports/raspberrypi/common-hal/socketpool/Socket.h @@ -75,4 +75,7 @@ typedef struct _lwip_socket_obj_t { socketpool_socketpool_obj_t *pool; } socketpool_socket_obj_t; +// Not required for RPi socket positive callbacks +#define socketpool_socket_poll_resume(x) + void socket_user_reset(void); diff --git a/ports/raspberrypi/common-hal/ssl/SSLSocket.c b/ports/raspberrypi/common-hal/ssl/SSLSocket.c index 21e2a95c9056..06fe350cb68f 100644 --- a/ports/raspberrypi/common-hal/ssl/SSLSocket.c +++ b/ports/raspberrypi/common-hal/ssl/SSLSocket.c @@ -257,11 +257,11 @@ mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t *self, uint8_t } 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. + // renegotiation. ret = MP_EWOULDBLOCK; } - DEBUG("returning [error case] %d\n", -ret); - return -ret; + 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) { @@ -276,11 +276,11 @@ mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t *self, const uint8_t } 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. + // renegotiation. ret = MP_EWOULDBLOCK; } - DEBUG("returning [error case] %d\n", -ret); - return -ret; + 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) { diff --git a/ports/raspberrypi/common-hal/wifi/Radio.c b/ports/raspberrypi/common-hal/wifi/Radio.c index db21dd333b6c..0ef4f8bb7608 100644 --- a/ports/raspberrypi/common-hal/wifi/Radio.c +++ b/ports/raspberrypi/common-hal/wifi/Radio.c @@ -176,7 +176,7 @@ void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_ common_hal_wifi_radio_stop_ap(self); - // Channel can only be changed after inital powerup and config of ap. + // Channel can only be changed after initial 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); @@ -186,6 +186,10 @@ void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_ bindings_cyw43_wifi_enforce_pm(); } +bool common_hal_wifi_radio_get_ap_active(wifi_radio_obj_t *self) { + return cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_AP) == CYW43_LINK_UP; +} + 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")); @@ -244,7 +248,8 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t common_hal_wifi_radio_stop_station(self); // connect - cyw43_arch_wifi_connect_async((const char *)ssid, (const char *)password, CYW43_AUTH_WPA2_AES_PSK); + 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) { @@ -274,6 +279,10 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t return WIFI_RADIO_ERROR_UNSPECIFIED; } +bool common_hal_wifi_radio_get_connected(wifi_radio_obj_t *self) { + return cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_UP; +} + mp_obj_t common_hal_wifi_radio_get_ap_info(wifi_radio_obj_t *self) { mp_raise_NotImplementedError(NULL); } diff --git a/ports/raspberrypi/common-hal/wifi/__init__.c b/ports/raspberrypi/common-hal/wifi/__init__.c index e5a646f88fea..91a45e8d92c9 100644 --- a/ports/raspberrypi/common-hal/wifi/__init__.c +++ b/ports/raspberrypi/common-hal/wifi/__init__.c @@ -107,7 +107,7 @@ void raise_cyw_error(int err) { mp_errno = MP_ETIMEDOUT; break; default: - mp_raise_OSError_msg_varg(translate("Unkown error code %d"), err); + mp_raise_OSError_msg_varg(translate("Unknown error code %d"), err); } mp_raise_OSError(mp_errno); } diff --git a/ports/raspberrypi/lib/cyw43-driver b/ports/raspberrypi/lib/cyw43-driver index 746e0636033d..e52dd14a15e6 160000 --- a/ports/raspberrypi/lib/cyw43-driver +++ b/ports/raspberrypi/lib/cyw43-driver @@ -1 +1 @@ -Subproject commit 746e0636033d0550b7652688124a77a6a1639cf9 +Subproject commit e52dd14a15e6a53e6263840704470246aa77c5ce diff --git a/ports/raspberrypi/lwip_inc/lwipopts.h b/ports/raspberrypi/lwip_inc/lwipopts.h index 6d116e89b6c1..06df7f13181d 100644 --- a/ports/raspberrypi/lwip_inc/lwipopts.h +++ b/ports/raspberrypi/lwip_inc/lwipopts.h @@ -60,6 +60,7 @@ #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 diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index 7a6b9f21678d..ecd2c89ebf03 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -19,13 +19,14 @@ CIRCUITPY_PWMIO ?= 1 CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_DISPLAYIO) CIRCUITPY_ROTARYIO ?= 1 CIRCUITPY_ROTARYIO_SOFTENCODER = 1 +CIRCUITPY_SYNTHIO_MAX_CHANNELS = 12 # Things that need to be implemented. -# Use PWM interally +# Use PWM internally CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CTARGET = 1 CIRCUITPY_NVM = 1 -# Use PIO interally +# Use PIO internally CIRCUITPY_PULSEIO ?= 1 CIRCUITPY_WATCHDOG ?= 1 diff --git a/ports/raspberrypi/sdk b/ports/raspberrypi/sdk index 2e6142b15b8a..2ccab115de0d 160000 --- a/ports/raspberrypi/sdk +++ b/ports/raspberrypi/sdk @@ -1 +1 @@ -Subproject commit 2e6142b15b8a75c1227dd3edbe839193b2bf9041 +Subproject commit 2ccab115de0d42d31d6611cca19ef0cd0d2ccaa7 diff --git a/ports/raspberrypi/sdk_config/pico/config_autogen.h b/ports/raspberrypi/sdk_config/pico/config_autogen.h index a29ccb458a1a..ee99b1c609d7 100644 --- a/ports/raspberrypi/sdk_config/pico/config_autogen.h +++ b/ports/raspberrypi/sdk_config/pico/config_autogen.h @@ -18,6 +18,8 @@ #define PICO_NO_HARDWARE (0) #define PICO_ON_DEVICE (1) #define PICO_PRINTF_ALWAYS_INCLUDED (1) +#define PICO_RP2040_USB_DEVICE_ENUMERATION_FIX (1) +#define PICO_RP2040_USB_DEVICE_UFRAME_FIX (1) #define PICO_STDIO_IGNORE_NESTED_STDOUT (0) #define PICO_USE_CRT_PRINTF (0) #define PICO_USE_OPTIMISTIC_SBRK (0) diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index 27012f2298e4..f3da71cbd7d1 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -161,10 +161,10 @@ safe_mode_t port_init(void) { } #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) { @@ -312,7 +312,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/raspberrypi/supervisor/usb.c b/ports/raspberrypi/supervisor/usb.c index d0e9b2e466cd..fb4f72134d4f 100644 --- a/ports/raspberrypi/supervisor/usb.c +++ b/ports/raspberrypi/supervisor/usb.c @@ -39,15 +39,8 @@ STATIC void _usb_irq_wrapper(void) { } void post_usb_init(void) { - irq_set_enabled(USBCTRL_IRQ, false); - - irq_handler_t usb_handler = irq_get_exclusive_handler(USBCTRL_IRQ); - if (usb_handler) { - irq_remove_handler(USBCTRL_IRQ, usb_handler); - } - irq_set_exclusive_handler(USBCTRL_IRQ, _usb_irq_wrapper); - - irq_set_enabled(USBCTRL_IRQ, true); + irq_add_shared_handler(USBCTRL_IRQ, _usb_irq_wrapper, + PICO_SHARED_IRQ_HANDLER_LOWEST_ORDER_PRIORITY); // There is a small window where the USB interrupt may be handled by the // pico-sdk instead of CircuitPython. If that is the case, then we'll have diff --git a/ports/silabs/Makefile b/ports/silabs/Makefile new file mode 100644 index 000000000000..06ddf3a57dba --- /dev/null +++ b/ports/silabs/Makefile @@ -0,0 +1,214 @@ +# This file is part of Adafruit for EFR32 project +# +# The MIT License (MIT) +# +# Copyright 2023 Silicon Laboratories Inc. www.silabs.com +# +# 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. +# + +.SUFFIXES: # ignore builtin rules +.PHONY: all clean slc-clean slc-generate dependents +# Values set by the initial generation +PROJECTNAME = circuitpython_efr32 +# If the build directory is not given, make it reflect the board name. +SILABS_BUILD = build-$(BOARD) +# Build dir for CircuitPython +BUILD ?= $(SILABS_BUILD) +# Override Build Directories +OUTPUT_DIR = $(SILABS_BUILD) +# Python script to generate pins and pins functionalities code +PY_GEN_PINS_SRC ?= tools/make_pins.py +# SLC tool path +SLC_PATH = $(realpath $(CURDIR))/tools/slc_cli_linux + +BUILD_VERBOSE ?= 1 + +CFLAGS = $(INCLUDES) $(C_DEFS) $(C_FLAGS) \ + -Wno-expansion-to-defined \ + -Wno-unused-parameter \ + -Wno-missing-field-initializers \ + -Wno-type-limits + +ASMFLAGS = $(INCLUDES) $(ASM_DEFS) $(ASM_FLAGS) $(DEPFLAGS) + +include ../../py/circuitpy_mkenv.mk + +CROSS_COMPILE = arm-none-eabi- + +MCU_SERIES_LOWER = $(shell echo $(MCU_SERIES) | tr '[:upper:]' '[:lower:]') +MCU_VARIANT_LOWER = $(shell echo $(MCU_VARIANT) | tr '[:upper:]' '[:lower:]') + +# Header files folders include +INC += -I. +INC += -I../.. +INC += -I$(BUILD) +INC += -I$(BUILD)/genhdr +INC += -I$(SILABS_BUILD)/autogen +INC += -I$(SILABS_BUILD)/config +INC += -I./boards +INC += -I./peripherals +INC += -I../../lib/mp-readline + +#Debugging/Optimization +ifeq ($(DEBUG), 1) + CFLAGS += -g3 + # You may want to enable these flags to make setting breakpoints easier. + CFLAGS += -fno-inline -fno-ipa-sra -Og +else + CFLAGS += -DNDEBUG + OPTIMIZATION_FLAGS ?= -Os -fno-inline-functions + CFLAGS += -g +endif + +# to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk +CFLAGS += $(OPTIMIZATION_FLAGS) +CFLAGS += $(INC) $(BASE_CFLAGS) $(C_DEFS) $(CFLAGS_MOD) $(COPT) +CFLAGS += -DEFR32_SERIES_LOWER='"$(MCU_VARIANT)"' +CFLAGS += -Wno-undef -Wno-shadow -Wno-cast-align -Wno-nested-externs -Wno-strict-prototypes + +SRC_C += \ + background.c \ + mphalport.c \ + $(SILABS_BUILD)/pins.c\ + +ifeq ('$(BOARD)','brd2601b') +SRC_C += boards/$(BOARD)/sensor.c +endif + +SRC_S = boards/mp_efr32xg24_gchelper.s + +SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ + $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ + $(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_INTERNAL)) + +# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED, +# because a few modules have files both in common-hal/ and shared-module/. +# Doing a $(sort ...) removes duplicates as part of sorting. +SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) + +ifneq ($(FROZEN_MPY_DIR),) +FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') +FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) +endif + +OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) +ifeq ($(INTERNAL_LIBM),1) +OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) +endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) + +$(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os +$(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os + +# List of sources for qstr extraction +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) +# Sources that only hold QSTRs after pre-processing. +SRC_QSTR_PREPROCESSOR += + +MCU_SECTIONS = $^ $@ + +# Include sub-makefiles +-include $(SILABS_BUILD)/$(PROJECTNAME).project.mak + +# Default goal +all: $(OUTPUT_DIR)/firmware.bin + +$(OUTPUT_DIR)/firmware.bin: $(SILABS_BUILD)/$(PROJECTNAME).Makefile $(OUTPUT_DIR)/firmware.hex + +@$(MAKE) --no-print-directory $(OUTPUT_DIR)/firmware.out + @echo 'Done.' + +$(SILABS_BUILD)/$(PROJECTNAME).Makefile: + +@$(MAKE) --no-print-directory slc-generate + +$(OUTPUT_DIR)/firmware.out: $(SILABS_BUILD)/pin_functions.h $(SILABS_BUILD)/pins.c $(OBJ) $(OBJS) $(LIB_FILES) + @echo 'Linking $(OUTPUT_DIR)/firmware.out' + @echo "$(OBJS) $(OBJ)" > $(OUTPUT_DIR)/linker_objs + $(CC) $(LD_FLAGS) @$(OUTPUT_DIR)/linker_objs $(LIBS) -o $(OUTPUT_DIR)/firmware.out + $(OBJCOPY) $(OUTPUT_DIR)/firmware.out -O binary $(OUTPUT_DIR)/firmware.bin + +$(OUTPUT_DIR)/firmware.hex: + +$(SILABS_BUILD)/pin_functions.h: + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_GEN_PINS_SRC) -e $@ boards/$(BOARD)/pins.csv boards/$(BOARD)/pin_functions.csv + @-$(RM) pins.c + +$(SILABS_BUILD)/pins.c: + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_GEN_PINS_SRC) -s $@ boards/$(BOARD)/pins.csv boards/$(BOARD)/pin_functions.csv + @-$(RM) pin_functions.h + +slc-generate: +ifeq (,$(wildcard $(SLC_PATH)/bin/slc-cli/developer/adapter_packs/python/lib/python3.6/jinja2)) + -@ln -s $(SLC_PATH)/bin/slc-cli/developer/adapter_packs/python/lib/python3.6/site-packages/jinja2 \ + $(SLC_PATH)/bin/slc-cli/developer/adapter_packs/python/lib/python3.6/jinja2 + -@ln -s $(SLC_PATH)/bin/slc-cli/developer/adapter_packs/python/lib/python3.6/site-packages/markupsafe \ + $(SLC_PATH)/bin/slc-cli/developer/adapter_packs/python/lib/python3.6/markupsafe +endif + @echo 'SLC generates project' + @$(SLC_PATH)/slc configuration --sdk gecko_sdk + @$(SLC_PATH)/slc signature trust -extpath cp_efr32_extension + @$(SLC_PATH)/slc signature trust --sdk gecko_sdk + @$(SLC_PATH)/slc generate -name=$(PROJECTNAME) $(PROJECTNAME).slcp --sdk gecko_sdk --with $(BOARD_BRD) -tlcn gcc -d=$(SILABS_BUILD) + @sed -i 's/ autogen\// $(SILABS_BUILD)\/autogen\//g' $(SILABS_BUILD)/circuitpython_efr32.project.mak + @sed -i 's/-T"autogen\//-T"$(SILABS_BUILD)\/autogen\//g' $(SILABS_BUILD)/circuitpython_efr32.project.mak + +#Override ECHO +$(OBJS): ECHO = +$(OBJS): + +$(OUTPUT_DIR)/%.o: %.c + @echo 'Building $<' + @$(MKDIR_P) $(@D) + $(ECHO)$(CC) $(CFLAGS) -c -o $@ $< + +$(OUTPUT_DIR)/%.o: %.cpp + @echo 'Building $<' + @$(MKDIR_P) $(@D) + $(ECHO)$(CXX) $(CXXFLAGS) -c -o $@ $< + +$(OUTPUT_DIR)/%.o: %.cc + @echo 'Building $<' + @$(MKDIR_P) $(@D) + $(ECHO)$(CXX) $(CXXFLAGS) -c -o $@ $< + +$(OUTPUT_DIR)/%.o: %.s + @echo 'Building $<' + @$(MKDIR_P) $(@D) + $(ECHO)$(CC) $(ASMFLAGS) -c -o $@ $< + +$(OUTPUT_DIR)/%.o: %.S + @echo 'Building $<' + @$(MKDIR_P) $(@D) + $(ECHO)$(CC) $(ASMFLAGS) -c -o $@ $< + +include $(TOP)/py/mkrules.mk + +# Print out the value of a make variable. +# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile +print-%: + @echo $* = $($*) diff --git a/ports/silabs/README.md b/ports/silabs/README.md new file mode 100644 index 000000000000..626b8e778867 --- /dev/null +++ b/ports/silabs/README.md @@ -0,0 +1,132 @@ +# Circuitpython on EFR32 # +![GitHub](https://img.shields.io/badge/Technology-Bluetooth_BLE-green) +![GitHub](https://img.shields.io/badge/CircuitPython-8.1.0--beta.0-green) +![GitHub](https://img.shields.io/badge/GSDK-v4.2.1-green) +![GitHub](https://img.shields.io/badge/SLC-5.6.3.0-green) +![GitHub](https://img.shields.io/badge/License-MIT-green) +![GitHub](https://img.shields.io/badge/GCC_build-passing-green) + +This port brings the Silicon Labs EFR32 series of MCUs to Circuitpython. + +Refer to **mpconfigport.mk** for a full list of enabled modules sorted by family. + +## How this port is organized: ## + +- **boards/** contains the configuration files for each development board and breakout available on the port, as well as system files and both shared and SoC-specific linker files. Board configuration includes a pin mapping of the board, oscillator information, board-specific build flags, and setup for some other peripheral where applicable. +- **common-hal/** contains the port-specific module implementations, used by shared-module and shared-bindings. +- **peripherals/** contains peripheral setup files and peripheral mapping information, sorted by family and sub-variant. Most files in this directory can be generated with the python scripts in **tools/**. +- **supervisor/** contains port-specific implementations of internal flash and serial, as well as the **port.c** file, which initializes the port at startup. +- **tools/** contains Silicon Labs configurator (SLC) tool, python scripts for generating peripheral and pin mapping files in **peripherals/** and **board/**. + +At the root level, refer to **mpconfigboard.h** and **mpconfigport.mk** for port specific settings and a list of enabled modules. + +## Prerequisites ## +Please ensure you set up your build environment appropriately, as per the guide. You will need: + +- Linux: https://learn.adafruit.com/building-circuitpython/linux +- Windows Subsystem for Linux (WSL): https://learn.adafruit.com/building-circuitpython/windows-subsystem-for-linux +- MacOS: Not supported yet + +Install necessary packages + + $ sudo apt install default-jre gcc-arm-none-eabi wget python3 python3-pip git git-lfs gettext uncrustify + $ sudo python -m pip install --upgrade pip + +## Board supported ## + +| Board | Code | Build CMD | +| --------------------------- | ------------ | ------------------------------------------ | +| xG24 Dev Kit | brd2601b | devkit_xg24_brd2601b | +| xG24 Explorer Kit | brd2703a | explorerkit_xg24_brd2703a | +| Sparkfun Thing Plus MGM240P | brd2704a | sparkfun_thingplus_matter_mgm240p_brd2704a | + +## Build instructions ## + +Ensure your clone of Circuitpython is ready to build by following the [guide on the Adafruit Website](https://learn.adafruit.com/building-circuitpython/build-circuitpython). This includes installing the toolchain, synchronizing submodules, and running `mpy-cross`. + +Clone the source code of CircuitPython from Github: + + $ git clone https://github.com/SiliconLabs/circuitpython.git + $ cd circuitpython + $ make fetch-submodules + +Checkout the branch or tag you want to build. For example: + + $ git checkout main + +Following the guideline below to install required packages for SLC tool: + https://www.silabs.com/documents/public/user-guides/ug520-software-project-generation-configuration-with-slc-cli.pdf + +Once the one-time build tasks are complete, you can build at any time by navigating to the port directory: + + $ make BOARD=explorerkit_xg24_brd2703a + +You may also build with certain flags available in the makefile, depending on your board and development goals: + + $ make BOARD=explorerkit_xg24_brd2703a DEBUG=1 + +Clean project by using: + + $ make BOARD=explorerkit_xg24_brd2703a clean + +## Bring-up on the board ## + +### Getting a REPL prompt ### + +Connect the devkit to the PC via the USB cable. The board uses serial for REPL access and debugging because the EFR32 chips has no USB support. + +#### Windows #### + +On Windows, we need to install a serial console e.g., PuTTY, MobaXterm. The JLink CDC UART Port can be found in the Device Manager. + +#### Linux #### + +Open a terminal and issue the following command:  + + $ ls /dev/ttyACM* + +Then note down the correct name and substitute com-port-name in the following command with it:  + + $ screen /dev/'com-port-name' + +### Using the REPL prompt ### + +After flashing the firmware to the board, at your first connecting to the board, you might see a blank screen. Press enter and you should be presented with a Circuitpython prompt, >>>. If not, try to reset the board (see instructions below). + +You can now type in simple commands such as:  + +```sh +>>> print("Hello world!")  + +Hello world +``` + +If something goes wrong with the board, you can reset it. Pressing CTRL+D when the prompt is open performs a soft reset. + +### Recommended editors ### + +**Thonny** is a simple code editor that works with the Adafruit CircuitPython boards.  + +Config serial: Tools > Options > Interpreter > Select MicroPython > Select Port Jlink CDC UART Port + +### Running CircuitPython scripts ### + +At the boot stage, two scripts will be run (if not booting in safe mode). First, the file  boot.py  will be executed. The file **boot.py** can be used to perform the initial setup. Then, after boot.py has been completed, the file **code.py** will be executed.   + +After code.py has finished executing, a REPL prompt will be presented on the serial port. Other files can also be executed by using the **Thonny** editors or using **Ampy** tool. + +![Thony](./res/Thony.png) + +With the boards which support USB mass storage, we can drag the files to the board file system. However, because the EFR32 boards don’t support USB mass storage, we need to use a tool like **Ampy** to copy the file to the board. You can use the latest version of **Ampy** and its  command to copy the module directories to the board. + +Refer to the guideline below for installing the **Ampy** tool:  + +https://learn.adafruit.com/micropython-basics-load-files-and-run-code/install-ampy   + +## Modules supported ## + +| Board | Modules Available| +| --------------------------- | ---------------- | +| xG24 Dev Kit | _asyncio, _bleio, _pixelmap, adafruit_ble, adafruit_bus_device, adafruit_pixelbuf, adafruit_register, aesio,analogio, array, atexit, binascii, bitmaptools, board, builtins, busio, collections, digitalio, displayio,errno, fontio, framebufferio, gc, getpass, gifio, json, math, microcontroller, micropython, msgpack, nvm, onewireio, os, pwmio, rainbowio, random, re, rtc, select, sharpdisplay, storage, struct, supervisor, sys, terminalio, time, traceback, ulab, uselect, vectorio, watchdog, zlib | +| xG24 Explorer Kit | _asyncio, _bleio, _pixelmap, adafruit_ble, adafruit_bus_device, adafruit_pixelbuf, adafruit_register, aesio,analogio, array, atexit, binascii, bitmaptools, board, builtins, busio, collections, digitalio, displayio,errno, fontio, framebufferio, gc, getpass, gifio, json, math, microcontroller, micropython, msgpack, nvm, onewireio, os, pwmio, rainbowio, random, re, rtc, sdcardio, select, sharpdisplay, storage, struct, supervisor, sys, terminalio, time, traceback, ulab, uselect, vectorio, watchdog, zlib | +| Sparkfun Thing Plus MGM240P | _asyncio, _bleio, _pixelmap, adafruit_ble, adafruit_bus_device, adafruit_pixelbuf, adafruit_register, aesio,analogio, array, atexit, binascii, bitmaptools, board, builtins, busio, collections, digitalio, displayio,errno, fontio, framebufferio, gc, getpass, gifio, json, math, microcontroller, micropython, msgpack, nvm, onewireio, os, pwmio, rainbowio, random, re, rtc, sdcardio, select, sharpdisplay, storage, struct, supervisor, sys, terminalio, time, traceback, ulab, uselect, vectorio, watchdog, zlib | diff --git a/ports/silabs/background.c b/ports/silabs/background.c new file mode 100644 index 000000000000..176918adda9b --- /dev/null +++ b/ports/silabs/background.c @@ -0,0 +1,50 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "supervisor/filesystem.h" +#include "supervisor/usb.h" +#include "supervisor/shared/stack.h" +#include "FreeRTOS.h" +#include "task.h" + +#if CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + +void port_background_tick(void) { + // Zero delay in case FreeRTOS wants to switch to something else + vTaskDelay(0); +} + +void port_background_task(void) { +} + +void port_start_background_tick(void) { +} + +void port_finish_background_tick(void) { +} diff --git a/ports/silabs/background.h b/ports/silabs/background.h new file mode 100644 index 000000000000..c68865fa5bdc --- /dev/null +++ b/ports/silabs/background.h @@ -0,0 +1,30 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_BACKGROUND_H +#define MICROPY_INCLUDED_EFR32_BACKGROUND_H + +#endif // MICROPY_INCLUDED_EFR32_BACKGROUND_H diff --git a/ports/silabs/boards/devkit_xg24_brd2601b/README.md b/ports/silabs/boards/devkit_xg24_brd2601b/README.md new file mode 100644 index 000000000000..438ec42bfc1e --- /dev/null +++ b/ports/silabs/boards/devkit_xg24_brd2601b/README.md @@ -0,0 +1,28 @@ +## Gen Pin instructions ## + +# Input File +pins.csv : contain pin name, port number ,pin number +pin_functions.csv : contain list of pin support for peripheral +make_pins.py : python script to gen pin + + +# Run make_pins.py +Copy above input file to folder boards/brd2601b/ +Run CMD: + $ cd boards/brd2601b/ + $ python make_pins.py -s pins.c -e pin_functions.h pins.csv pin_functions.csv + + -s: name/directory of output source file + -e: name/directory of output header file + +# Output +pins.c : register pin to board_module_globals_table + generate array contains supported function of pin +pin_functions.h : define index of functions + Example: pin_pa0_functions[FN_EUSART0_RX] == 1 // Can assign pin pa0 for EUSART0_RX + pin_pa0_functions[FN_EUSART0_RX] == 255 // Can't assign pin pa0 for EUSART0_RX + + +# Read pin define on REPL +import board +dir(board) diff --git a/ports/silabs/boards/devkit_xg24_brd2601b/board.c b/ports/silabs/boards/devkit_xg24_brd2601b/board.c new file mode 100644 index 000000000000..100ef47b151e --- /dev/null +++ b/ports/silabs/boards/devkit_xg24_brd2601b/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/silabs/boards/devkit_xg24_brd2601b/custom_brd2601b_cp_support.slcc b/ports/silabs/boards/devkit_xg24_brd2601b/custom_brd2601b_cp_support.slcc new file mode 100644 index 000000000000..b1731a306f41 --- /dev/null +++ b/ports/silabs/boards/devkit_xg24_brd2601b/custom_brd2601b_cp_support.slcc @@ -0,0 +1,27 @@ +id: custom_brd2601b_cp_support +label: CircuitPython BRD2601B support +description: > + CircuitPython Board support for BRD2601B. +package: custom +category: Custom +quality: production +root_path: ../boards/devkit_xg24_brd2601b +include: + - path: '' + file_list: + - path: mpconfigboard.h +source: + - path: board.c +provides: + - name: custom_brd2601b_cp_support +requires: + - name: efr32mg24b310f1536im48 + - name: sensor_pressure + - name: sensor_hall + - name: sensor_imu + - name: sensor_rht + - name: sensor_lux +recommends: + - id: sensor_rht + - id: sensor_lux + - id: bt_rail_compatibility_fix diff --git a/ports/silabs/boards/devkit_xg24_brd2601b/mpconfigboard.h b/ports/silabs/boards/devkit_xg24_brd2601b/mpconfigboard.h new file mode 100644 index 000000000000..5456e1ecd56b --- /dev/null +++ b/ports/silabs/boards/devkit_xg24_brd2601b/mpconfigboard.h @@ -0,0 +1,55 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "build-devkit_xg24_brd2601b/pin_functions.h" + +// Micropython setup +#define MICROPY_HW_BOARD_NAME "SiLabs xG24 Dev Kit" +#define MICROPY_HW_MCU_NAME EFR32_SERIES_LOWER + +#define HSE_VALUE ((uint32_t)8000000) +#define BOARD_HSE_SOURCE (RCC_HSE_BYPASS) +#define BOARD_HAS_LOW_SPEED_CRYSTAL (0) + +// On-board flash +#define SPI_FLASH_MOSI_PIN (&pin_PC3) +#define SPI_FLASH_MISO_PIN (&pin_PC2) +#define SPI_FLASH_SCK_PIN (&pin_PC1) +#define SPI_FLASH_CS_PIN (&pin_PC0) + +#define DEFAULT_I2C_BUS_SDA (&pin_PC5) +#define DEFAULT_I2C_BUS_SCL (&pin_PC4) +#define DEFAULT_I2C_PERIPHERAL I2C1 + +#define DEFAULT_SPI_BUS_SCK (&pin_PC1) +#define DEFAULT_SPI_BUS_MOSI (&pin_PC3) +#define DEFAULT_SPI_BUS_MISO (&pin_PC2) +#define DEFAULT_SPI_BUS_SS (&pin_PA7) + +#define NVM_BYTEARRAY_BUFFER_SIZE 512 +#define CIRCUITPY_INTERNAL_NVM_SIZE (512) +#undef MICROPY_USE_INTERNAL_PRINTF +#define MICROPY_USE_INTERNAL_PRINTF (0) diff --git a/ports/silabs/boards/devkit_xg24_brd2601b/mpconfigboard.mk b/ports/silabs/boards/devkit_xg24_brd2601b/mpconfigboard.mk new file mode 100644 index 000000000000..9c40c6fe7c86 --- /dev/null +++ b/ports/silabs/boards/devkit_xg24_brd2601b/mpconfigboard.mk @@ -0,0 +1,17 @@ + +BOARD_BRD = brd2601b +INTERNAL_FLASH_FILESYSTEM = 0 +QSPI_FLASH_FILESYSTEM = 0 +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = MX25R3235F + +MCU_SERIES = MG24 +MCU_VARIANT = EFR32MG24B310F1536IM48 + +CIRCUITPY_USB = 0 + +CIRCUITPY_CREATOR_ID = 0x19960000 +CIRCUITPY_CREATION_ID = 0x00242601 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BLE +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register diff --git a/ports/silabs/boards/devkit_xg24_brd2601b/pin_functions.csv b/ports/silabs/boards/devkit_xg24_brd2601b/pin_functions.csv new file mode 100644 index 000000000000..aad9f34198f0 --- /dev/null +++ b/ports/silabs/boards/devkit_xg24_brd2601b/pin_functions.csv @@ -0,0 +1,35 @@ +EUSART0_CS,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,,,,,,,,,,,,,, +EUSART0_RX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,,,,,,,,,,,,,, +EUSART0_SCLK,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,,,,,,,,,,,,,, +EUSART0_TX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,,,,,,,,,,,,,, +EUSART1_CS,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +EUSART1_RX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +EUSART1_SCLK,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +EUSART1_TX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +I2C0_SCL,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +I2C0_SDA,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +I2C1_SCL,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +I2C1_SDA,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +TIMER0_CC0,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +TIMER0_CC1,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +TIMER0_CC2,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +TIMER1_CC0,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +TIMER1_CC1,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +TIMER1_CC2,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +TIMER2_CC0,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,,,,,,,,,,,,,, +TIMER2_CC1,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,,,,,,,,,,,,,, +TIMER2_CC2,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,,,,,,,,,,,,,, +TIMER3_CC0,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +TIMER3_CC1,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +TIMER3_CC2,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +TIMER4_CC0,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,,,,,,,,,,,,,, +TIMER4_CC1,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,,,,,,,,,,,,,, +TIMER4_CC2,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,,,,,,,,,,,,,, +USART0_CLK,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +USART0_CS,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +USART0_RX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +USART0_TX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PC0,PC1,PC2,PC3,PC4,PC5,PC9,PD2,PD3,PD4,PD5,,, +VDAC0_CH0,,,,,,PB0,,,,,,,,,,,,,,,,, +VDAC0_CH1,,,,,,,PB1,,,,,,,,,,,,,,,, +VDAC1_CH0,,,,,,,,PB2,,,,,,,,,,,,,,, +VDAC1_CH1,,,,,,,,,PB3,,,,,,,,,,,,,, diff --git a/ports/silabs/boards/devkit_xg24_brd2601b/pins.csv b/ports/silabs/boards/devkit_xg24_brd2601b/pins.csv new file mode 100644 index 000000000000..c1d9a5a252f8 --- /dev/null +++ b/ports/silabs/boards/devkit_xg24_brd2601b/pins.csv @@ -0,0 +1,21 @@ +mcu_name, board_name,port ,pin +PA0,,0,0 +PA4,LEDG,0,4 +PA5,TX,0,5 +PA6,RX,0,6 +PA7,CS,0,7 +PB0,LEDB,1,0 +PB1,,1,1 +PB2,BTN0,1,2 +PB3,BTN1,1,3 +PC0,FLASH_CS,2,0 +PC1,SCLK,2,1 +PC2,CIPO,2,2 +PC3,COPI,2,3 +PC4,SCL,2,4 +PC5,SDA,2,5 +PC9,SENSOR_CS,2,9 +PD2,LEDR,3,2 +PD3,,3,3 +PD4,,3,4 +PD5,,3,5 diff --git a/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c b/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c new file mode 100644 index 000000000000..cdffa9f1e520 --- /dev/null +++ b/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c @@ -0,0 +1,214 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "common-hal/busio/I2C.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/translate/translate.h" +#include "em_i2c.h" +#include "sl_i2cspm.h" +#include "sl_i2cspm_sensor_config.h" +#include "sl_sensor_lux.h" +#include "sl_sensor_rht.h" +#include "sl_sensor_imu.h" +#include "sl_sensor_hall.h" +#include "sl_sensor_pressure.h" + +STATIC mp_obj_t sensor_init(busio_i2c_obj_t *i2c) { + sl_status_t sc; + + if (!common_hal_mcu_pin_is_free(&pin_PC9)) { + mp_raise_ValueError(translate("Pin PC9 is busy ")); + return mp_const_false; + } + + sc = sl_sensor_rht_init(); + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + + sc = sl_sensor_lux_init(); + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + + sc = sl_sensor_hall_init(); + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + + sc = sl_sensor_pressure_init(); + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + + sl_sensor_imu_init(); + sc = sl_sensor_imu_enable(true); + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + + common_hal_mcu_pin_claim(&pin_PC9); + return mp_const_true; +} + +STATIC mp_obj_t sensor_deinit() { + + sl_sensor_hall_deinit(); + sl_sensor_lux_deinit(); + sl_sensor_rht_deinit(); + sl_sensor_pressure_deinit(); + sl_sensor_imu_enable(false); + sl_sensor_imu_deinit(); + common_hal_reset_pin(&pin_PC9); + return mp_const_true; +} + +STATIC mp_obj_t sensor_get_temperature(void) { + sl_status_t sc; + uint32_t rh; + int32_t t; + sc = sl_sensor_rht_get(&rh, &t); + + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + + return mp_obj_new_float((float)t / 1000.0f); +} + +STATIC mp_obj_t sensor_get_humidity(void) { + sl_status_t sc; + uint32_t rh; + int32_t t; + sc = sl_sensor_rht_get(&rh, &t); + + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + return mp_obj_new_float((float)rh / 1000.0f); +} + +STATIC mp_obj_t sensor_get_lux(void) { + sl_status_t sc; + float lux; + sc = sl_sensor_lux_get(&lux); + + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + return mp_obj_new_float(lux); +} + +STATIC mp_obj_t sensor_get_hall(void) { + sl_status_t sc; + float field_strength; + bool alert; + bool tamper; + sc = sl_sensor_hall_get(&field_strength, &alert, &tamper); + + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + return mp_obj_new_float(field_strength); +} + +STATIC mp_obj_t sensor_get_pressure(void) { + sl_status_t sc; + float pressure; + sc = sl_sensor_pressure_get(&pressure); + + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + return mp_obj_new_float(pressure); +} + +STATIC mp_obj_t sensor_imu_get(void) { + sl_status_t sc; + int16_t ovec[3]; + int16_t avec[3]; + mp_obj_t ovec_obj[3]; + mp_obj_t avec_obj[3]; + mp_obj_t ret[2]; + + sc = sl_sensor_imu_get(ovec, avec); + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + + ovec_obj[0] = mp_obj_new_int(ovec[0]); + ovec_obj[1] = mp_obj_new_int(ovec[1]); + ovec_obj[2] = mp_obj_new_int(ovec[2]); + + avec_obj[0] = mp_obj_new_int(avec[0]); + avec_obj[1] = mp_obj_new_int(avec[1]); + avec_obj[2] = mp_obj_new_int(avec[2]); + ret[0] = mp_obj_new_list(3,ovec_obj); + ret[1] = mp_obj_new_list(3,avec_obj); + return mp_obj_new_tuple(2,ret); +} + +STATIC mp_obj_t sensor_imu_calibrate(void) { + sl_status_t sc; + sc = sl_sensor_imu_calibrate(); + if (sc != SL_STATUS_OK) { + return mp_const_false; + } + return mp_const_true; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(sensor_init_obj,sensor_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_deinit_obj,sensor_deinit); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_temperature_obj,sensor_get_temperature); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_humidity_obj,sensor_get_humidity); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_lux_obj,sensor_get_lux); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_hall_obj,sensor_get_hall); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_pressure_obj,sensor_get_pressure); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_imu_get_obj,sensor_imu_get); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_imu_calibrate_obj,sensor_imu_calibrate); + + +STATIC const mp_rom_map_elem_t sensor_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sensor) }, + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&sensor_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&sensor_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_temperature), MP_ROM_PTR(&sensor_get_temperature_obj) }, + { MP_ROM_QSTR(MP_QSTR_humidity), MP_ROM_PTR(&sensor_get_humidity_obj) }, + { MP_ROM_QSTR(MP_QSTR_lux), MP_ROM_PTR(&sensor_get_lux_obj) }, + { MP_ROM_QSTR(MP_QSTR_hall), MP_ROM_PTR(&sensor_get_hall_obj) }, + { MP_ROM_QSTR(MP_QSTR_pressure), MP_ROM_PTR(&sensor_get_pressure_obj) }, + { MP_ROM_QSTR(MP_QSTR_imu), MP_ROM_PTR(&sensor_imu_get_obj) }, + { MP_ROM_QSTR(MP_QSTR_imu_calibrate), MP_ROM_PTR(&sensor_imu_calibrate_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(sensor_module_globals, sensor_globals_table); + +const mp_obj_module_t sensor_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&sensor_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_sensor, sensor_module,1); diff --git a/ports/silabs/boards/explorerkit_xg24_brd2703a/README.md b/ports/silabs/boards/explorerkit_xg24_brd2703a/README.md new file mode 100644 index 000000000000..438ec42bfc1e --- /dev/null +++ b/ports/silabs/boards/explorerkit_xg24_brd2703a/README.md @@ -0,0 +1,28 @@ +## Gen Pin instructions ## + +# Input File +pins.csv : contain pin name, port number ,pin number +pin_functions.csv : contain list of pin support for peripheral +make_pins.py : python script to gen pin + + +# Run make_pins.py +Copy above input file to folder boards/brd2601b/ +Run CMD: + $ cd boards/brd2601b/ + $ python make_pins.py -s pins.c -e pin_functions.h pins.csv pin_functions.csv + + -s: name/directory of output source file + -e: name/directory of output header file + +# Output +pins.c : register pin to board_module_globals_table + generate array contains supported function of pin +pin_functions.h : define index of functions + Example: pin_pa0_functions[FN_EUSART0_RX] == 1 // Can assign pin pa0 for EUSART0_RX + pin_pa0_functions[FN_EUSART0_RX] == 255 // Can't assign pin pa0 for EUSART0_RX + + +# Read pin define on REPL +import board +dir(board) diff --git a/ports/silabs/boards/explorerkit_xg24_brd2703a/board.c b/ports/silabs/boards/explorerkit_xg24_brd2703a/board.c new file mode 100644 index 000000000000..f0fcc3d41fbb --- /dev/null +++ b/ports/silabs/boards/explorerkit_xg24_brd2703a/board.c @@ -0,0 +1,33 @@ +/***************************************************************************//** + * @file board.c + * @brief + ******************************************************************************* + * # License + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/silabs/boards/explorerkit_xg24_brd2703a/custom_brd2703a_cp_support.slcc b/ports/silabs/boards/explorerkit_xg24_brd2703a/custom_brd2703a_cp_support.slcc new file mode 100644 index 000000000000..b78d83ce517e --- /dev/null +++ b/ports/silabs/boards/explorerkit_xg24_brd2703a/custom_brd2703a_cp_support.slcc @@ -0,0 +1,20 @@ +id: custom_brd2703a_cp_support +label: CircuitPython BRD2703A support +description: > + CircuitPython Board support for BRD2703A. +package: custom +category: Custom +quality: production +root_path: ../boards/explorerkit_xg24_brd2703a +include: + - path: '' + file_list: + - path: mpconfigboard.h +source: + - path: board.c +provides: + - name: custom_brd2703a_cp_support +requires: + - name: efr32mg24b210f1536im48 +recommends: + - id: bt_rail_compatibility_fix diff --git a/ports/silabs/boards/explorerkit_xg24_brd2703a/mpconfigboard.h b/ports/silabs/boards/explorerkit_xg24_brd2703a/mpconfigboard.h new file mode 100644 index 000000000000..87da017fb7b8 --- /dev/null +++ b/ports/silabs/boards/explorerkit_xg24_brd2703a/mpconfigboard.h @@ -0,0 +1,52 @@ +/***************************************************************************//** + * @file mpconfigboard.h + * @brief + ******************************************************************************* + * # License + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ +#include "build-explorerkit_xg24_brd2703a/pin_functions.h" + +// Micropython setup +#define MICROPY_HW_BOARD_NAME "SiLabs xG24 Explorer Kit" +#define MICROPY_HW_MCU_NAME EFR32_SERIES_LOWER + +#define HSE_VALUE ((uint32_t)8000000) +#define BOARD_HSE_SOURCE (RCC_HSE_BYPASS) +#define BOARD_HAS_LOW_SPEED_CRYSTAL (0) + +#define DEFAULT_I2C_BUS_SDA (&pin_PB5) +#define DEFAULT_I2C_BUS_SCL (&pin_PB4) +#define DEFAULT_I2C_PERIPHERAL I2C0 + +#define DEFAULT_SPI_BUS_SCK (&pin_PC1) +#define DEFAULT_SPI_BUS_MOSI (&pin_PC3) +#define DEFAULT_SPI_BUS_MISO (&pin_PC2) +#define DEFAULT_SPI_BUS_SS (&pin_PC0) + +#define NVM_BYTEARRAY_BUFFER_SIZE (512) +#define CIRCUITPY_INTERNAL_NVM_SIZE (512) +#undef MICROPY_USE_INTERNAL_PRINTF +#define MICROPY_USE_INTERNAL_PRINTF (0) diff --git a/ports/silabs/boards/explorerkit_xg24_brd2703a/mpconfigboard.mk b/ports/silabs/boards/explorerkit_xg24_brd2703a/mpconfigboard.mk new file mode 100644 index 000000000000..dd63b4da175b --- /dev/null +++ b/ports/silabs/boards/explorerkit_xg24_brd2703a/mpconfigboard.mk @@ -0,0 +1,16 @@ +BOARD_BRD = brd2703a +INTERNAL_FLASH_FILESYSTEM = 1 +QSPI_FLASH_FILESYSTEM = 0 +SPI_FLASH_FILESYSTEM = 0 + +MCU_SERIES = MG24 +MCU_VARIANT = EFR32MG24B210F1536IM48 + +CIRCUITPY_USB = 0 + +CIRCUITPY_CREATOR_ID = 0x19960000 +CIRCUITPY_CREATION_ID = 0x00242703 + + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BLE +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register diff --git a/ports/silabs/boards/explorerkit_xg24_brd2703a/pin_functions.csv b/ports/silabs/boards/explorerkit_xg24_brd2703a/pin_functions.csv new file mode 100644 index 000000000000..8d623ce7081f --- /dev/null +++ b/ports/silabs/boards/explorerkit_xg24_brd2703a/pin_functions.csv @@ -0,0 +1,35 @@ +EUSART0_CS,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,,,,,,,,,,,, +EUSART0_RX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,,,,,,,,,,,, +EUSART0_SCLK,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,,,,,,,,,,,, +EUSART0_TX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,,,,,,,,,,,, +EUSART1_CS,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +EUSART1_RX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +EUSART1_SCLK,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +EUSART1_TX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +I2C0_SCL,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PB4,PC0,PC1,PC2,PC3,PC4,PC8,PC9,PD2,PD3,PD4,PD5 +I2C0_SDA,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PB4,PC0,PC1,PC2,PC3,PC4,PC8,PC9,PD2,PD3,PD4,PD5 +I2C1_SCL,,,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +I2C1_SDA,,,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +TIMER0_CC0,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +TIMER0_CC1,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +TIMER0_CC2,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +TIMER1_CC0,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +TIMER1_CC1,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +TIMER1_CC2,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +TIMER2_CC0,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,,,,,,,,,,,, +TIMER2_CC1,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,,,,,,,,,,,, +TIMER2_CC2,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,,,,,,,,,,,, +TIMER3_CC0,,,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +TIMER3_CC1,,,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +TIMER3_CC2,,,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +TIMER4_CC0,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,,,,,,,,,,,, +TIMER4_CC1,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,,,,,,,,,,,, +TIMER4_CC2,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,,,,,,,,,,,, +USART0_CLK,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +USART0_CS,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +USART0_RX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +USART0_TX,PA0,PA4,PA5,PA6,PA7,PB0,PB1,PB2,PB3,PB4,PB5,PC0,PC1,PC2,PC3,PC4,PC5,PC8,PC9,PD2,PD3,PD4,PD5 +VDAC0_CH0,,,,,,PB0,,,,,,,,,,,,,,,,, +VDAC0_CH1,,,,,,,PB1,,,,,,,,,,,,,,,, +VDAC1_CH0,,,,,,,,PB2,,,,,,,,,,,,,,, +VDAC1_CH1,,,,,,,,,PB3,,,,,,,,,,,,,, diff --git a/ports/silabs/boards/explorerkit_xg24_brd2703a/pins.csv b/ports/silabs/boards/explorerkit_xg24_brd2703a/pins.csv new file mode 100644 index 000000000000..c32105790615 --- /dev/null +++ b/ports/silabs/boards/explorerkit_xg24_brd2703a/pins.csv @@ -0,0 +1,24 @@ +mcu_name, board_name,port ,pin +PA0,MIKROE_PWM,0,0 +PA4,LED0,0,4 +PA5,TX,0,5 +PA6,RX,0,6 +PA7,LED1,0,7 +PB0,MIKROE_AN,1,0 +PB1,MIKROE_INT,1,1 +PB2,BTN0,1,2 +PB3,BNT1,1,3 +PB4,MIKROE_SCL,1,4 +PB5,MIKROE_SDA,1,5 +PC0,MIKROE_CS,2,0 +PC1,MIKROE_SCK,2,1 +PC2,MIKROE_MISO,2,2 +PC3,MIKROE_MOSI,2,3 +PC4,QWIIC_SCL,2,4 +PC5,QWIIC_SDA,2,5 +PC8,MIKROE_RST,2,8 +PC9,,2,9 +PD2,,3,2 +PD3,,3,3 +PD4,MIKROE_TX,3,4 +PD5,MIKROE_RX,3,5 diff --git a/ports/silabs/boards/mp_efr32xg24_gchelper.s b/ports/silabs/boards/mp_efr32xg24_gchelper.s new file mode 100644 index 000000000000..18fe4a4a3aad --- /dev/null +++ b/ports/silabs/boards/mp_efr32xg24_gchelper.s @@ -0,0 +1,28 @@ + .syntax unified + .cpu cortex-m33 + .thumb + .text + .align 2 + +@ uint cpu_get_regs_and_sp(r0=uint regs[10]) + .global cpu_get_regs_and_sp + .thumb + .thumb_func + .type cpu_get_regs_and_sp, %function +cpu_get_regs_and_sp: +@ store registers into given array + str r4, [r0], #4 + str r5, [r0], #4 + str r6, [r0], #4 + str r7, [r0], #4 + str r8, [r0], #4 + str r9, [r0], #4 + str r10, [r0], #4 + str r11, [r0], #4 + str r12, [r0], #4 + str r13, [r0], #4 +@ return the sp + @Move stack pointer to return register + mov r0, sp + @Branch to link register (return address) and change instruction set if needed + bx lr diff --git a/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/README.md b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/README.md new file mode 100644 index 000000000000..438ec42bfc1e --- /dev/null +++ b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/README.md @@ -0,0 +1,28 @@ +## Gen Pin instructions ## + +# Input File +pins.csv : contain pin name, port number ,pin number +pin_functions.csv : contain list of pin support for peripheral +make_pins.py : python script to gen pin + + +# Run make_pins.py +Copy above input file to folder boards/brd2601b/ +Run CMD: + $ cd boards/brd2601b/ + $ python make_pins.py -s pins.c -e pin_functions.h pins.csv pin_functions.csv + + -s: name/directory of output source file + -e: name/directory of output header file + +# Output +pins.c : register pin to board_module_globals_table + generate array contains supported function of pin +pin_functions.h : define index of functions + Example: pin_pa0_functions[FN_EUSART0_RX] == 1 // Can assign pin pa0 for EUSART0_RX + pin_pa0_functions[FN_EUSART0_RX] == 255 // Can't assign pin pa0 for EUSART0_RX + + +# Read pin define on REPL +import board +dir(board) diff --git a/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/board.c b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/board.c new file mode 100644 index 000000000000..100ef47b151e --- /dev/null +++ b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/custom_brd2704a_cp_support.slcc b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/custom_brd2704a_cp_support.slcc new file mode 100644 index 000000000000..669e19908fa4 --- /dev/null +++ b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/custom_brd2704a_cp_support.slcc @@ -0,0 +1,18 @@ +id: custom_brd2704a_cp_support +label: CircuitPython BRD2704A support +description: > + CircuitPython Board support for BRD2704A. +package: custom +category: Custom +quality: production +root_path: ../boards/sparkfun_thingplus_matter_mgm240p_brd2704a +include: + - path: '' + file_list: + - path: mpconfigboard.h +source: + - path: board.c +provides: + - name: custom_brd2704a_cp_support +requires: + - name: mgm240pb32vna diff --git a/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/mpconfigboard.h b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/mpconfigboard.h new file mode 100644 index 000000000000..ea43ef27cd97 --- /dev/null +++ b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/mpconfigboard.h @@ -0,0 +1,49 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "build-sparkfun_thingplus_matter_mgm240p_brd2704a/pin_functions.h" + +// Micropython setup +#define MICROPY_HW_BOARD_NAME "Sparkfun Thing Plus MGM240P" +#define MICROPY_HW_MCU_NAME EFR32_SERIES_LOWER + +#define HSE_VALUE ((uint32_t)8000000) +#define BOARD_HSE_SOURCE (RCC_HSE_BYPASS) +#define BOARD_HAS_LOW_SPEED_CRYSTAL (0) + +#define DEFAULT_I2C_BUS_SDA (&pin_PB4) +#define DEFAULT_I2C_BUS_SCL (&pin_PB3) +#define DEFAULT_I2C_PERIPHERAL I2C0 + +#define DEFAULT_SPI_BUS_SCK (&pin_PC2) +#define DEFAULT_SPI_BUS_MOSI (&pin_PC3) +#define DEFAULT_SPI_BUS_MISO (&pin_PC6) +#define DEFAULT_SPI_BUS_SS (&pin_PA7) + +#define NVM_BYTEARRAY_BUFFER_SIZE (512) +#define CIRCUITPY_INTERNAL_NVM_SIZE (512) +#undef MICROPY_USE_INTERNAL_PRINTF +#define MICROPY_USE_INTERNAL_PRINTF (0) diff --git a/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/mpconfigboard.mk b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/mpconfigboard.mk new file mode 100644 index 000000000000..dcfc337031c8 --- /dev/null +++ b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/mpconfigboard.mk @@ -0,0 +1,17 @@ + +BOARD_BRD = brd2704a +INTERNAL_FLASH_FILESYSTEM = 1 +QSPI_FLASH_FILESYSTEM = 0 +SPI_FLASH_FILESYSTEM = 0 + +MCU_SERIES = MG24 +MCU_VARIANT = MGM240PB32VNA + +CIRCUITPY_USB = 0 +CIRCUITPY_SDCARDIO = 1 + +CIRCUITPY_CREATOR_ID = 0x19960000 +CIRCUITPY_CREATION_ID = 0x00242704 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BLE +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register diff --git a/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/pin_functions.csv b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/pin_functions.csv new file mode 100644 index 000000000000..a1ff1c3820bc --- /dev/null +++ b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/pin_functions.csv @@ -0,0 +1,35 @@ +EUSART0_CS,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,,,,,,,,,,,,,, +EUSART0_RX,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,,,,,,,,,,,,,, +EUSART0_SCLK,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,,,,,,,,,,,,,, +EUSART0_TX,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,,,,,,,,,,,,,, +EUSART1_CS,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +EUSART1_RX,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +EUSART1_SCLK,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +EUSART1_TX,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +I2C0_SCL,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PD0,PD1,PD2,PD3,, +I2C0_SDA,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PD0,PD1,PD2,PD3,, +I2C1_SCL,,,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +I2C1_SDA,,,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +TIMER0_CC0,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +TIMER0_CC1,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +TIMER0_CC2,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +TIMER1_CC0,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +TIMER1_CC1,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +TIMER1_CC2,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +TIMER2_CC0,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,,,,,,,,,,,,,, +TIMER2_CC1,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,,,,,,,,,,,,,, +TIMER2_CC2,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,,,,,,,,,,,,,, +TIMER3_CC0,,,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +TIMER3_CC1,,,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +TIMER3_CC2,,,,,,,,,,,,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +TIMER4_CC0,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,,,,,,,,,,,,,, +TIMER4_CC1,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,,,,,,,,,,,,,, +TIMER4_CC2,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,,,,,,,,,,,,,, +USART0_CLK,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +USART0_CS,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +USART0_RX,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +USART0_TX,PA0,PA4,PA5,PA6,PA7,PA8,PB0,PB1,PB2,PB3,PB4,PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PD0,PD1,PD2,PD3,, +VDAC0_CH0,,,,,,,PB0,,,,,,,,,,,,,,,,,, +VDAC0_CH1,,,,,,,,PB1,,,,,,,,,,,,,,,,, +VDAC1_CH0,,,,,,,,,PB2,,,,,,,,,,,,,,,, +VDAC1_CH1,,,,,,,,,,PB3,,,,,,,,,,,,,,, diff --git a/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/pins.csv b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/pins.csv new file mode 100644 index 000000000000..7c60920065f2 --- /dev/null +++ b/ports/silabs/boards/sparkfun_thingplus_matter_mgm240p_brd2704a/pins.csv @@ -0,0 +1,24 @@ +mcu_name, board_name,port ,pin +PA0,,0,0 +PA4,,0,4 +PA5,TX,0,5 +PA6,RX,0,6 +PA7,SD_CS,0,7 +PA8,LED,0,8 +PB0,,1,0 +PB1,,1,1 +PB2,,1,2 +PB3,SCL,1,3 +PB4,SDA,1,4 +PC0,,2,0 +PC1,,2,1 +PC2,SCK,2,2 +PC3,MOSI,2,3 +PC4,,2,4 +PC5,,2,5 +PC6,MISO,2,6 +PC7,,2,7 +PD0,,3,0 +PD1,,3,1 +PD2,,3,2 +PD3,,3,3 diff --git a/ports/silabs/circuitpython_efr32.slcp b/ports/silabs/circuitpython_efr32.slcp new file mode 100644 index 000000000000..e7010b08cdd9 --- /dev/null +++ b/ports/silabs/circuitpython_efr32.slcp @@ -0,0 +1,74 @@ +# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file. +description: | + A project structure used as a configuration for CircuitPython + Custom Bluetooth + Standard DMP (Dynamic Multiprotocol) applications. It runs on top of FreeRTOS and multiprotocol RAIL utilizing IEEE 802.15.4 standard protocol. +filter: +- name: Capability + value: [Multiprotocol] +- name: Device Type + value: [SoC] +- name: Project Difficulty + value: [Advanced] +- name: Wireless Technology + value: [Bluetooth] +package: Bluetooth +quality: production +tag: ['hardware:rf:band:2400', 'hardware:device:ram:64'] +sdk: {id: gecko_sdk, version: 4.2.1} +toolchain_settings: [] +sdk_extension: +- id: cp_efr32 + version: 1.0.0 +component: +- {id: bluetooth_feature_nvm} +- {id: bluetooth_feature_gatt_server} +- {id: bluetooth_feature_sm} +- {id: mpu} +- {id: bluetooth_feature_legacy_advertiser} +- {id: bluetooth_feature_legacy_scanner} +- {id: gatt_configuration} +- {id: freertos} +- {id: bluetooth_stack} +- {id: bluetooth_feature_gatt} +- {id: uartdrv_core} +- {id: i2cspm_core} +- {id: spidrv_core} +- {id: pwm_core} +- {id: emlib_usart} +- {id: emlib_vdac} +- {id: emlib_iadc} +- {id: nvm3_lib} +- {id: nvm3_default} +- {id: tempdrv} +- {id: sleeptimer} +- {id: emlib_wdog} +- {id: bluetooth_feature_connection} +- {id: rail_lib_multiprotocol} +- {id: bluetooth_feature_dynamic_gattdb} +- {id: bluetooth_feature_system} +- {id: bluetooth_feature_scanner} +- {id: component_catalog} +- {id: app_assert} +requires: +- condition: [brd2601b] + name: custom_brd2601b_cp_support +- condition: [brd2704a] + name: custom_brd2704a_cp_support +- condition: [brd2703a] + name: custom_brd2703a_cp_support +configuration: +- {name: SL_SLEEPTIMER_WALLCLOCK_CONFIG, value: '1'} +- {name: NVM3_DEFAULT_MAX_OBJECT_SIZE, value: '512'} +- {name: SL_STACK_SIZE, value: '2752'} +- {name: SL_HEAP_SIZE, value: '11000'} +- name: SL_POWER_MANAGER_LOWEST_EM_ALLOWED + value: '1' +- {name: configTOTAL_HEAP_SIZE, value: '8192'} +- {name: configTIMER_TASK_PRIORITY, value: '55'} +- {name: configTIMER_TASK_STACK_DEPTH, value: '160'} +- condition: [psa_crypto] + name: SL_PSA_KEY_USER_SLOT_COUNT + value: '0' +- {name: APP_LOG_PREFIX_ENABLE, value: '0'} +ui_hints: + highlight: + - {path: config/btconf/gatt_configuration.btconf} diff --git a/ports/silabs/common-hal/_bleio/Adapter.c b/ports/silabs/common-hal/_bleio/Adapter.c new file mode 100644 index 000000000000..cbfdcbce55d2 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Adapter.c @@ -0,0 +1,650 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 +#include +#include "py/gc.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared/runtime/interrupt_char.h" +#include "shared-bindings/_bleio/Address.h" +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/ScanEntry.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/time/__init__.h" +#include "common-hal/_bleio/Connection.h" +#include "supervisor/shared/tick.h" + +#define PUBLIC_ADDRESS 0 +#define STATIC_ADDRESS 1 +#define BLE_EXT_ADV_MAX_SIZE 32 + +#define UNIT_0_625_MS (625) +#define UNIT_1_25_MS (1250) +#define UNIT_10_MS (10000) + +#define SCAN_TIMEOUT_MS_DEFAUT 3000 +#define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED 256 +#define BLE_GAP_SCAN_BUFFER_MAX 32 +#define DEVICE_NAME_LEN 15 + +EventGroupHandle_t xscan_event; +device_scan_info_t scan_info; +bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT]; + +// Set scan data form sl_bt_on_event +void set_scan_device_info_on_ble_evt(bd_addr address, + uint8_t address_type, + int8_t rssi, + uint8array *data) { + scan_info.address = address; + scan_info.address_type = address_type; + scan_info.rssi = rssi; + memcpy(scan_info.data, data->data, data->len); +} + +// Get state of the BLE adapter. +bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) { + return self->is_enable; +} + +// Set state of the BLE adapter +void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, + bool enabled) { + + const bool is_enabled = common_hal_bleio_adapter_get_enabled(self); + bd_addr get_address; + uint8_t address_type; + uint8_t conn_index; + bleio_connection_internal_t *connection; + sl_status_t sc = SL_STATUS_FAIL; + uint8_t device_name[DEVICE_NAME_LEN + 1]; + memset(device_name, 0, DEVICE_NAME_LEN); + + // Don't enable or disable twice + if (is_enabled == enabled) { + return; + } + + sc = sl_bt_system_get_identity_address(&get_address, &address_type); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Get address fail.")); + } + snprintf((char *)device_name, DEVICE_NAME_LEN + 1, + "CIRCUITPY-%X%X", get_address.addr[1], get_address.addr[0]); + + if (enabled) { + sl_bt_gatt_server_write_attribute_value(gattdb_device_name, + 0, + DEVICE_NAME_LEN, + device_name); + + // Clear all of the internal connection objects. + for (conn_index = 0; conn_index < BLEIO_TOTAL_CONNECTION_COUNT; conn_index++) { + connection = &bleio_connections[conn_index]; + // Reset connection. + connection->conn_handle = BLEIO_HANDLE_INVALID; + } + } else { + self->is_enable = false; + } +} + +// Get mac address of the BLE adapter +bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self) { + bd_addr get_address; + uint8_t address_type; + sl_status_t sc = SL_STATUS_FAIL; + bleio_address_obj_t *address; + + sc = sl_bt_system_get_identity_address(&get_address, &address_type); + if (SL_STATUS_OK != sc) { + return NULL; + } + + address = m_new_obj(bleio_address_obj_t); + address->base.type = &bleio_address_type; + common_hal_bleio_address_construct(address, get_address.addr, + BLEIO_ADDRESS_TYPE_RANDOM_STATIC); + return address; +} + +// Set identity address +bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, + bleio_address_obj_t *address) { + + sl_status_t sc = SL_STATUS_FAIL; + mp_buffer_info_t bufinfo; + bd_addr ble_addr; + + if (NULL == address) { + return false; + } + if (!mp_get_buffer(address->bytes, &bufinfo, MP_BUFFER_READ)) { + return false; + } + memcpy(ble_addr.addr, bufinfo.buf, 6); + sl_bt_system_set_identity_address(ble_addr, PUBLIC_ADDRESS); + return sc == SL_STATUS_OK; +} + +// Get name of the BLE adapter +mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) { + char name[DEVICE_NAME_LEN]; + size_t value_len = 0; + uint8_t sc; + memset(name, 0, DEVICE_NAME_LEN); + sc = sl_bt_gatt_server_read_attribute_value(gattdb_device_name, + 0, + DEVICE_NAME_LEN, + &value_len, + (uint8_t *)name); + if (SL_STATUS_OK != sc) { + return NULL; + } + return mp_obj_new_str(name, strlen(name)); +} + +// Set name of the BLE adapter +void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, + const char *name) { + sl_bt_gatt_server_write_attribute_value(gattdb_device_name, + 0, + DEVICE_NAME_LEN, + (const uint8_t *)name); +} + +// starts a BLE scan +mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, + uint8_t *prefixes, + size_t prefix_length, + bool extended, + mp_int_t buffer_size, + mp_float_t timeout, + mp_float_t interval, + mp_float_t window, + mp_int_t minimum_rssi, + bool active) { + + sl_status_t sc; + uint64_t start_ticks = supervisor_ticks_ms64(); + uint64_t current_ticks = start_ticks; + uint32_t timeout_ms = timeout * 1000; + + if (timeout_ms == 0) { + timeout_ms = SCAN_TIMEOUT_MS_DEFAUT; + } + + if (self->scan_results != NULL) { + if (!shared_module_bleio_scanresults_get_done(self->scan_results)) { + mp_raise_bleio_BluetoothError( + translate("Scan already in progress. Stop with stop_scan.")); + } + self->scan_results = NULL; + } + + sl_bt_scanner_stop(); + self->scan_results = shared_module_bleio_new_scanresults(buffer_size, + prefixes, + prefix_length, + minimum_rssi); + xscan_event = xEventGroupCreate(); + if (xscan_event != NULL) { + xEventGroupClearBits(xscan_event, 1 << 0); + } + + sc = sl_bt_scanner_start(sl_bt_scanner_scan_phy_1m, + sl_bt_scanner_discover_generic); + + if (SL_STATUS_OK != sc) { + self->scan_results = NULL; + } + + // Busy-wait until timeout or until we've read enough chars. + while (current_ticks - start_ticks <= timeout_ms) { + if (xscan_event != NULL) { + xEventGroupWaitBits(xscan_event, 1 << 0, pdTRUE, pdFALSE, + timeout_ms / portTICK_PERIOD_MS); + } + self->scan_results->prefix_length = 0; + scan_info.data_len = 28; + shared_module_bleio_scanresults_append( + self->scan_results, + supervisor_ticks_ms64(), + true, + true, + scan_info.rssi, + scan_info.address.addr, + scan_info.address_type, + scan_info.data, + scan_info.data_len); + current_ticks = supervisor_ticks_ms64(); + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + break; + } + } + + shared_module_bleio_scanresults_set_done(self->scan_results, true); + vEventGroupDelete(xscan_event); + return MP_OBJ_FROM_PTR(self->scan_results); +} + +void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self) { + if (self->scan_results == NULL) { + return; + } + sl_bt_scanner_stop(); + shared_module_bleio_scanresults_set_done(self->scan_results, true); + self->scan_results = NULL; +} + +// Start the advertising on an advertising set with specified +// discovery and connection modes +uint32_t _common_hal_bleio_adapter_start_advertising( + bleio_adapter_obj_t *self, + bool connectable, + bool anonymous, + uint32_t timeout, + float interval, + const uint8_t *advertising_data, + uint16_t advertising_data_len, + const uint8_t *scan_response_data, + uint16_t scan_response_data_len, + mp_int_t tx_power, + const bleio_address_obj_t *directed_to) { + + sl_status_t sc = SL_STATUS_FAIL; + int16_t set_power; + uint32_t interval_min = 160; + uint32_t interval_max = 160; + bd_addr address; + uint8_t address_type; + uint8_t system_id[8]; + uint8_t enable_connect; + + if (self->user_advertising) { + return SL_STATUS_BUSY; + } + + sc = sl_bt_advertiser_create_set(&self->advertising_handle); + + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Create_set fail.")); + return sc; + } + sc = sl_bt_advertiser_set_channel_map(self->advertising_handle, 7); + if (SL_STATUS_OK != sc) { + return sc; + } + + sc = sl_bt_system_get_identity_address(&address, &address_type); + + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Get address fail.")); + return sc; + } + // Pad and reverse unique ID to get System ID. + system_id[0] = address.addr[5]; + system_id[1] = address.addr[4]; + system_id[2] = address.addr[3]; + system_id[3] = 0xFF; + system_id[4] = 0xFE; + system_id[5] = address.addr[2]; + system_id[6] = address.addr[1]; + system_id[7] = address.addr[0]; + + sc = sl_bt_gatt_server_write_attribute_value(gattdb_system_id, + 0, + sizeof(system_id), + system_id); + if (SL_STATUS_OK != sc) { + return sc; + } + + sc = sl_bt_advertiser_set_tx_power(self->advertising_handle, + tx_power, + &set_power); + if (SL_STATUS_OK != sc) { + return sc; + } + + // Set advertising interval. + sc = sl_bt_advertiser_set_timing( + self->advertising_handle, + interval_min, // min. adv. interval (milliseconds * 1.6) + interval_max, // max. adv. interval (milliseconds * 1.6) + 0, // adv. duration + 0); // max. num. adv. events + + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Set_timing fail.")); + return sc; + } + + sc = sl_bt_legacy_advertiser_set_data( + self->advertising_handle, + sl_bt_advertiser_advertising_data_packet, + advertising_data_len, + advertising_data); + + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Set data fail.")); + return sc; + } + + // Start advertising and enable connections. + enable_connect = sl_bt_legacy_advertiser_scannable; + if (true == connectable) { + enable_connect = sl_bt_advertiser_connectable_scannable; + } + sc = sl_bt_legacy_advertiser_start(self->advertising_handle, + enable_connect); + + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Start advertise fail.")); + } else { + self->user_advertising = true; + } + + return sc; +} + +// Check size of packet advertising to send +STATIC void check_data_fit(size_t data_len, bool connectable) { + if (data_len > BLE_EXT_ADV_MAX_SIZE || + (connectable && data_len > BLE_EXT_ADV_MAX_SIZE)) { + mp_raise_ValueError( + translate("Data too large for advertisement packet")); + } +} + +// Start advertising +void common_hal_bleio_adapter_start_advertising( + bleio_adapter_obj_t *self, + bool connectable, + bool anonymous, + uint32_t timeout, + mp_float_t interval, + mp_buffer_info_t *advertising_data_bufinfo, + mp_buffer_info_t *scan_response_data_bufinfo, + mp_int_t tx_power, + const bleio_address_obj_t *directed_to) { + + if (self->user_advertising) { + common_hal_bleio_adapter_stop_advertising(self); + } + // Interval value has already been validated. + + check_data_fit(advertising_data_bufinfo->len, connectable); + check_data_fit(scan_response_data_bufinfo->len, connectable); + + if (advertising_data_bufinfo->len > 31 && scan_response_data_bufinfo->len > 0) { + mp_raise_bleio_BluetoothError( + translate("Extended advertisements not supported")); + } + + if (advertising_data_bufinfo->len > 0 && directed_to != NULL) { + mp_raise_bleio_BluetoothError( + translate("Data not supported with directed advertising")); + } + + if (anonymous) { + mp_raise_NotImplementedError(NULL); + } + + if (!timeout) { + timeout = INT32_MAX; + } else if (timeout > INT32_MAX) { + mp_raise_bleio_BluetoothError( + translate("Maximum timeout length is %d seconds"), INT32_MAX / 1000); + } + + _common_hal_bleio_adapter_start_advertising(self, connectable, anonymous, + timeout, interval, + advertising_data_bufinfo->buf, + advertising_data_bufinfo->len, + scan_response_data_bufinfo->buf, + scan_response_data_bufinfo->len, + tx_power, + directed_to); +} + +// Stop advertising +void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) { + if (!common_hal_bleio_adapter_get_advertising(self)) { + return; + } + sl_bt_advertiser_delete_set(self->advertising_handle); + sl_bt_advertiser_stop(0); + self->user_advertising = false; +} + +// Get status of advertising +bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self) { + return self->user_advertising; +} + +// Convert mac address of remote device to connect +STATIC void _convert_address(const bleio_address_obj_t *address, + bd_addr *sd_address, uint8_t *addr_type) { + mp_buffer_info_t address_buf_info; + *addr_type = address->type; + mp_get_buffer_raise(address->bytes, &address_buf_info, MP_BUFFER_READ); + memcpy(sd_address->addr, (uint8_t *)address_buf_info.buf, 6); +} + +// Add new connection into connection list +void _new_connection(uint16_t conn_handle) { + // Find an empty connection. One must always be available because the SD has the same + // total connection limit. + bleio_connection_internal_t *connection; + uint8_t conn_index; + for (conn_index = 0; conn_index < BLEIO_TOTAL_CONNECTION_COUNT; conn_index++) { + connection = &bleio_connections[conn_index]; + if (connection->conn_handle == BLEIO_HANDLE_INVALID) { + break; + } + } + connection->conn_handle = conn_handle; + connection->connection_obj = mp_const_none; + connection->pair_status = PAIR_NOT_PAIRED; + connection->mtu = 0; +} + +// Attempts a connection to the device with the given address. +mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, + bleio_address_obj_t *address, + mp_float_t timeout) { + + bd_addr addr; + uint8_t address_type; + sl_status_t error_code; + uint8_t conn_handle; + uint8_t conn_index; + bleio_connection_internal_t *connection; + + if (self->scan_results != NULL) { + common_hal_bleio_adapter_stop_scan(self); + } + conn_handle = common_hal_bleio_adapter_get_connected(self); + timeout = MSEC_TO_UNITS(timeout, UNIT_10_MS); + + _convert_address(address, &addr, &address_type); + + error_code = sl_bt_connection_open(addr, + address_type, + sl_bt_gap_phy_1m, + &conn_handle); + + // Negative values are error codes, connection handle otherwise. + if (SL_STATUS_OK != error_code) { + return mp_const_none; + } + + _new_connection(conn_handle); + + // TODO: If we have keys, then try and encrypt the connection. + + // TODO: Negotiate for better PHY and data lengths since we are the central. These are + // nice-to-haves so ignore any errors. + + // Make the connection object and return it. + for (conn_index = 0; conn_index < BLEIO_TOTAL_CONNECTION_COUNT; conn_index++) { + connection = &bleio_connections[conn_index]; + if (connection->conn_handle == conn_handle) { + connection->is_central = true; + connection->pair_status = PAIR_PAIRED; + return bleio_connection_new_from_internal(connection); + } + } + + mp_raise_bleio_BluetoothError( + translate("Failed to connect: internal error")); + return mp_const_none; +} + +// Get connected status +bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) { + uint8_t conn_index; + bleio_connection_internal_t *connection; + for (conn_index = 0; conn_index < BLEIO_TOTAL_CONNECTION_COUNT; conn_index++) { + connection = &bleio_connections[conn_index]; + if (connection->conn_handle != BLEIO_HANDLE_INVALID) { + return true; + } + } + return false; +} + +// Get connection object +mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) { + + size_t total_connected = 0; + mp_obj_t items[BLEIO_TOTAL_CONNECTION_COUNT]; + uint8_t conn_index; + bleio_connection_internal_t *connection; + + if (self->connection_objs != NULL) { + return self->connection_objs; + } + for (conn_index = 0; conn_index < BLEIO_TOTAL_CONNECTION_COUNT; conn_index++) { + connection = &bleio_connections[conn_index]; + if (connection->conn_handle != BLEIO_HANDLE_INVALID) { + if (connection->connection_obj == mp_const_none) { + connection->connection_obj = + bleio_connection_new_from_internal(connection); + } + items[total_connected] = connection->connection_obj; + total_connected++; + } + } + self->connection_objs = mp_obj_new_tuple(total_connected, items); + return self->connection_objs; +} + +void common_hal_bleio_adapter_remove_connection(uint8_t conn_handle) { + uint8_t conn_index; + bleio_connection_internal_t *connection; + osMutexAcquire(bluetooth_connection_mutex_id, osWaitForever); + for (conn_index = 0; conn_index < BLEIO_TOTAL_CONNECTION_COUNT; conn_index++) { + connection = &bleio_connections[conn_index]; + if (conn_handle == connection->conn_handle) { + connection->connection_obj = NULL; + connection->conn_handle = BLEIO_HANDLE_INVALID; + } + } + osMutexRelease(bluetooth_connection_mutex_id); +} + +// Delete all bonding +void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self) { + sl_status_t sc; + sc = sl_bt_sm_delete_bondings(); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("All bonding deleted fail.")); + } +} + +// Get status bonding to central +bool common_hal_bleio_adapter_is_bonded_to_central(bleio_adapter_obj_t *self) { + bleio_connection_internal_t *connection; + uint8_t conn_index; + for (conn_index = 0; conn_index < BLEIO_TOTAL_CONNECTION_COUNT; conn_index++) { + connection = &bleio_connections[conn_index]; + if (connection->conn_handle != BLEIO_HANDLE_INVALID) { + return true; + } + } + return false; +} + +void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter) { + // We divide by size_t so that we can scan each 32-bit aligned value to see + // if it is a pointer. This allows us to change the structs without worrying + // about collecting new pointers. + gc_collect_root((void **)adapter, + sizeof(bleio_adapter_obj_t) / (sizeof(size_t))); + gc_collect_root((void **)bleio_connections, + sizeof(bleio_connections) / (sizeof(size_t))); +} + +// Reset the BLE adapter +void bleio_adapter_reset(bleio_adapter_obj_t *adapter) { + + bool any_connected = false; + uint64_t start_ticks; + uint8_t conn_index; + bleio_connection_internal_t *connection; + + common_hal_bleio_adapter_stop_scan(adapter); + if (common_hal_bleio_adapter_get_advertising(adapter)) { + common_hal_bleio_adapter_stop_advertising(adapter); + } + + adapter->connection_objs = NULL; + for (conn_index = 0; conn_index < BLEIO_TOTAL_CONNECTION_COUNT; conn_index++) { + connection = &bleio_connections[conn_index]; + // Disconnect all connections cleanly. + if (connection->conn_handle != BLEIO_HANDLE_INVALID) { + common_hal_bleio_connection_disconnect(connection); + } + connection->connection_obj = mp_const_none; + } + + // Wait up to 125 ms (128 ticks) for disconnect to complete. This should be + // greater than most connection intervals. + start_ticks = supervisor_ticks_ms64(); + while (any_connected && supervisor_ticks_ms64() - start_ticks < 128) { + any_connected = false; + for (conn_index = 0; conn_index < BLEIO_TOTAL_CONNECTION_COUNT; conn_index++) { + connection = &bleio_connections[conn_index]; + any_connected |= connection->conn_handle != BLEIO_HANDLE_INVALID; + } + } +} diff --git a/ports/silabs/common-hal/_bleio/Adapter.h b/ports/silabs/common-hal/_bleio/Adapter.h new file mode 100644 index 000000000000..d7f252df3305 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Adapter.h @@ -0,0 +1,87 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR_COMMON_HAL_BLEIO_ADAPTER_H +#define MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_ADAPTER_H + +#include "py/obj.h" +#include "py/objtuple.h" +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/ScanResults.h" +#include "supervisor/background_callback.h" + +#ifndef BLEIO_TOTAL_CONNECTION_COUNT +#define BLEIO_TOTAL_CONNECTION_COUNT 5 +#endif + +#define BLEIO_HANDLE_INVALID 0xffff +#define BLE_GAP_ADDR_LEN 6 + +extern bleio_connection_internal_t + bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT]; + +extern EventGroupHandle_t xscan_event; + +typedef struct { + mp_obj_base_t base; + bleio_scanresults_obj_t *scan_results; + mp_obj_t name; + mp_obj_tuple_t *connection_objs; + background_callback_t background_callback; + bool user_advertising; + bool is_enable; + uint8_t advertising_handle; +} bleio_adapter_obj_t; + +typedef struct { + uint8_t addr_id_peer : 1; + uint8_t addr_type : 7; + uint8_t addr[BLE_GAP_ADDR_LEN]; +} ble_gap_addr_t; + +typedef struct { + // Pointer to the data buffer provided to/from the application. + uint8_t *p_data; + // Length of the data buffer, in bytes. + uint16_t len; +} ble_data_t; + +typedef struct { + uint8_t address_type; + uint8_t conn_handle; + uint8_t data_len; + int8_t rssi; + bd_addr address; + uint8_t data[255]; +} device_scan_info_t; + +void set_scan_device_info_on_ble_evt(bd_addr address, uint8_t address_type, + int8_t rssi, uint8array *data); +void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter); +void bleio_adapter_reset(bleio_adapter_obj_t *adapter); +void common_hal_bleio_adapter_remove_connection(uint8_t conn_handle); + +#endif // MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_ADAPTER_H diff --git a/ports/silabs/common-hal/_bleio/Attribute.c b/ports/silabs/common-hal/_bleio/Attribute.c new file mode 100644 index 000000000000..2e477a72baaa --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Attribute.c @@ -0,0 +1,27 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/_bleio/Attribute.h" diff --git a/ports/silabs/common-hal/_bleio/Attribute.h b/ports/silabs/common-hal/_bleio/Attribute.h new file mode 100644 index 000000000000..b2a635005b0f --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Attribute.h @@ -0,0 +1,32 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR_COMMON_HAL_BLEIO_ATTRIBUTE_H +#define MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_ATTRIBUTE_H + +#include "shared-module/_bleio/Attribute.h" + +#endif // MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_ATTRIBUTE_H diff --git a/ports/silabs/common-hal/_bleio/Characteristic.c b/ports/silabs/common-hal/_bleio/Characteristic.c new file mode 100644 index 000000000000..a39180b19b77 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Characteristic.c @@ -0,0 +1,407 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "py/runtime.h" +#include "common-hal/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared/runtime/interrupt_char.h" +#include "supervisor/shared/tick.h" +#include "supervisor/serial.h" + +EventGroupHandle_t xcharacteristic_event; + +// Set the characteristic data from sl_bt_on_event +bool set_characteristic_value_on_ble_evt(uint8_t conn_handle, + uint16_t char_handle, + uint8_t *data, + size_t data_len) { + + uint8_t serv_index; + uint8_t charc_index; + bleio_service_obj_t *service; + bleio_characteristic_obj_t *characteristic; + bleio_connection_internal_t *connection = + bleio_conn_handle_to_connection(conn_handle); + if (NULL == connection) { + mp_raise_bleio_BluetoothError(translate("Get connection fail.")); + return false; + } + for (serv_index = 0; serv_index < connection->remote_service_list->len; serv_index++) { + service = connection->remote_service_list->items[serv_index]; + + for (charc_index = 0; charc_index < service->characteristic_list->len; charc_index++) { + characteristic = service->characteristic_list->items[charc_index]; + + if (char_handle == characteristic->handle) { + characteristic->current_value = pvPortMalloc(data_len); + characteristic->current_value_len = data_len; + memcpy(characteristic->current_value, data, data_len); + + if (xcharacteristic_event != NULL) { + xEventGroupSetBits(xcharacteristic_event, 1 << 0); + } + return true; + } + } + } + return false; +} + +// Get the characteristic data object +STATIC bool get_characteristic_value(uint8_t conn_handle, + uint16_t char_handle, + uint8_t *data, + size_t *data_len) { + + uint8_t serv_index; + uint8_t charc_index; + bleio_service_obj_t *service; + bleio_characteristic_obj_t *characteristic; + bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(conn_handle); + + if (NULL == connection) { + mp_raise_bleio_BluetoothError(translate("Get connection fail.")); + return false; + } + for (serv_index = 0; serv_index < connection->remote_service_list->len; serv_index++) { + service = connection->remote_service_list->items[serv_index]; + + for (charc_index = 0; charc_index < service->characteristic_list->len; charc_index++) { + characteristic = service->characteristic_list->items[charc_index]; + + if (char_handle == characteristic->handle) { + *data_len = characteristic->current_value_len; + memcpy(data, characteristic->current_value, *data_len); + vPortFree(characteristic->current_value); + return true; + } + } + } + return false; +} + +// Create new bleio characteristic +void common_hal_bleio_characteristic_construct( + bleio_characteristic_obj_t *self, + bleio_service_obj_t *service, + uint16_t handle, bleio_uuid_obj_t *uuid, + bleio_characteristic_properties_t props, + bleio_attribute_security_mode_t read_perm, + bleio_attribute_security_mode_t write_perm, + mp_int_t max_length, + bool fixed_length, + mp_buffer_info_t *initial_value_bufinfo, + const char *user_description) { + + self->service = service; + self->uuid = uuid; + self->handle = BLEIO_HANDLE_INVALID; + self->cccd_handle = BLEIO_HANDLE_INVALID; + self->sccd_handle = BLEIO_HANDLE_INVALID; + self->props = props; + self->read_perm = read_perm; + self->write_perm = write_perm; + self->max_length = max_length > MAX_LENGTH_DATA ? MAX_LENGTH_DATA : max_length; + self->max_length = self->max_length ? self->max_length : MAX_LENGTH_DATA; + self->fixed_length = fixed_length; + + if (gc_alloc_possible()) { + self->descriptor_list = mp_obj_new_list(0, NULL); + } else { + self->descriptor_list = NULL; + } + + if (service->is_remote) { + self->handle = handle; + } else { + common_hal_bleio_service_add_characteristic(self->service, + self, + initial_value_bufinfo, + user_description); + + sl_bt_gatt_server_write_attribute_value( + self->handle, + 0, + initial_value_bufinfo->len, + (uint8_t *)initial_value_bufinfo->buf); + } +} + +// A tuple of Descriptor that describe this characteristic +mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors( + bleio_characteristic_obj_t *self) { + + if (self->descriptor_list == NULL) { + return mp_const_empty_tuple; + } + return mp_obj_new_tuple(self->descriptor_list->len, + self->descriptor_list->items); +} + +// The Service this Characteristic is a part of +bleio_service_obj_t *common_hal_bleio_characteristic_get_service( + bleio_characteristic_obj_t *self) { + + return self->service; +} + +// Get value of characteristic +size_t common_hal_bleio_characteristic_get_value( + bleio_characteristic_obj_t *self, + uint8_t *buf, + size_t len) { + + sl_status_t sc = SL_STATUS_FAIL; + EventBits_t ux_bits; + uint8_t retry = 10; + uint64_t start_ticks = supervisor_ticks_ms64(); + uint64_t current_ticks = start_ticks; + + if (self->handle == BLEIO_HANDLE_INVALID) { + return 0; + } + uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection); + + if (common_hal_bleio_service_get_is_remote(self->service)) { + // ble client gets characteristic value + if (BT_GATT_CHRC_READ & self->props) { + sc = sl_bt_gatt_read_characteristic_value(conn_handle,self->handle); + while (SL_STATUS_OK != sc && retry > 0) { + sc = sl_bt_gatt_read_characteristic_value(conn_handle,self->handle); + vTaskDelay(100 / portTICK_PERIOD_MS); + retry--; + } + } + + xcharacteristic_event = xEventGroupCreate(); + if (xcharacteristic_event != NULL) { + xEventGroupClearBits(xcharacteristic_event, 1 << 0); + } + + while (current_ticks - start_ticks <= GET_CHARACTERISTIC_TIMEOUT_MS) { + if (xcharacteristic_event != NULL) { + ux_bits = xEventGroupWaitBits( + xcharacteristic_event, 1 << 0, pdTRUE, pdFALSE, + GET_CHARACTERISTIC_TIMEOUT_MS / portTICK_PERIOD_MS); + + if ((ux_bits & (1 << 0)) == (1 << 0)) { + break; + } + } + current_ticks = supervisor_ticks_ms64(); + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + break; + } + } + get_characteristic_value(conn_handle, self->handle, buf, &len); + vEventGroupDelete(xcharacteristic_event); + return len; + + } else { + sc = sl_bt_gatt_server_read_attribute_value(self->handle, + 0, + self->max_length, + &len, + (uint8_t *)buf); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError( + translate("Read_attribute_value fail!")); + } + return len; + } + + return 0; +} + +// Get max length of charateristic +size_t common_hal_bleio_characteristic_get_max_length( + bleio_characteristic_obj_t *self) { + return self->max_length; +} + +// Set value of this characteristic +void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, + mp_buffer_info_t *bufinfo) { + + sl_status_t sc = SL_STATUS_FAIL; + uint16_t conn_handle; + uint16_t sent_len; + + if (common_hal_bleio_service_get_is_remote(self->service)) { + + conn_handle = bleio_connection_get_conn_handle(self->service->connection); + if ((self->props & CHAR_PROP_WRITE_NO_RESPONSE) != 0) { + sc = sl_bt_gatt_write_characteristic_value_without_response( + conn_handle, + self->handle, + bufinfo->len, + bufinfo->buf, + &sent_len); + } else { + sc = sl_bt_gatt_write_characteristic_value(conn_handle, + self->handle, + bufinfo->len, + bufinfo->buf); + } + } else { + if (self->props & BT_GATT_CHRC_READ) { + sc = sl_bt_gatt_server_write_attribute_value(self->handle, + 0, + bufinfo->len, + (uint8_t *)bufinfo->buf); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError( + translate("Write_attribute_value fail!")); + } + } + + if (self->props & BT_GATT_CHRC_NOTIFY) { + sc = sl_bt_gatt_server_send_notification( + 1, + self->handle, + bufinfo->len, + (uint8_t *)bufinfo->buf); + } + + if (self->props & BT_GATT_CHRC_INDICATE) { + sc = sl_bt_gatt_server_send_indication( + 1, + self->handle, + bufinfo->len, + (uint8_t *)bufinfo->buf); + } + } +} + +// Get UUID of this characteristic +bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid( + bleio_characteristic_obj_t *self) { + return self->uuid; +} + +// Get properties of this characteristic +bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties( + bleio_characteristic_obj_t *self) { + return self->props; +} + +// Add new descriptor to characteristic +void common_hal_bleio_characteristic_add_descriptor( + bleio_characteristic_obj_t *self, + bleio_descriptor_obj_t *descriptor) { + + sl_status_t sc = SL_STATUS_FAIL; + const uint8_t value; + uuid_128 bt_uuid_128; + sl_bt_uuid_16_t bt_uuid_16; + uint16_t gattdb_session; + + sc = sl_bt_gattdb_new_session(&gattdb_session); + + if (SL_STATUS_OK != sc && SL_STATUS_ALREADY_EXISTS != sc) { + mp_raise_bleio_BluetoothError(translate("Create new session fail.")); + return; + } + + if (BLE_UUID_TYPE_16 == descriptor->uuid->efr_ble_uuid.uuid.type) { + bt_uuid_16.data[0] = descriptor->uuid->efr_ble_uuid.uuid16.value & 0xff; + bt_uuid_16.data[1] = descriptor->uuid->efr_ble_uuid.uuid16.value >> 8; + + sl_bt_gattdb_add_uuid16_descriptor(self->session, + self->handle, + descriptor->handle, + 0, + bt_uuid_16, + sl_bt_gattdb_user_managed_value, + descriptor->max_length, + 2, + &value, + &descriptor->handle); + } else { + memcpy(bt_uuid_128.data, descriptor->uuid->efr_ble_uuid.uuid128.value, 16); + sl_bt_gattdb_add_uuid128_descriptor(self->session, + self->handle, + descriptor->handle, + 0, + bt_uuid_128, + sl_bt_gattdb_user_managed_value, + descriptor->max_length, + 2, + &value, + &descriptor->handle); + } + + sc = sl_bt_gattdb_commit(gattdb_session); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Commit descriptor fail.")); + return; + } + + mp_obj_list_append(MP_OBJ_FROM_PTR(self->descriptor_list), + MP_OBJ_FROM_PTR(descriptor)); +} + +// Set the remote characteristic’s CCCD to enable or disable notification and indication. +void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, + bool notify,bool indicate) { + + sl_status_t sc = SL_STATUS_FAIL; + + const uint16_t conn_handle = bleio_connection_get_conn_handle( + self->service->connection); + common_hal_bleio_check_connected(conn_handle); + notify = 1; + indicate = 0; + if (notify) { + sc = sl_bt_gatt_set_characteristic_notification(conn_handle, + self->handle,sl_bt_gatt_notification); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Notify fail")); + } + } + + if (indicate) { + sc = sl_bt_gatt_set_characteristic_notification(conn_handle, + self->handle,sl_bt_gatt_indication); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Indicate fail")); + } + } + + if (0 == notify && 0 == indicate) { + sc = sl_bt_gatt_set_characteristic_notification(conn_handle, + self->handle,sl_bt_gatt_disable); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Indicate fail")); + } + } +} diff --git a/ports/silabs/common-hal/_bleio/Characteristic.h b/ports/silabs/common-hal/_bleio/Characteristic.h new file mode 100644 index 000000000000..9605988b6883 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Characteristic.h @@ -0,0 +1,68 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR_COMMON_HAL_BLEIO_CHARACTERISTIC_H +#define MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_CHARACTERISTIC_H + +#include "shared-bindings/_bleio/Attribute.h" +#include "common-hal/_bleio/Descriptor.h" +#include "shared-module/_bleio/Characteristic.h" +#include "common-hal/_bleio/Service.h" +#include "common-hal/_bleio/UUID.h" + +#define MAX_LENGTH_DATA 512 +#define GET_CHARACTERISTIC_TIMEOUT_MS 1000 + +typedef struct _bleio_characteristic_obj { + mp_obj_base_t base; + // Will be MP_OBJ_NULL before being assigned to a Service. + bleio_service_obj_t *service; + bleio_uuid_obj_t *uuid; + uint8_t *current_value; + uint16_t current_value_len; + // Our internal allocation length. If > 0, then current_value is managed by + // this characteristic. + uint16_t current_value_alloc; + uint16_t max_length; + uint16_t def_handle; + uint16_t handle; + uint16_t session; + bleio_characteristic_properties_t props; + bleio_attribute_security_mode_t read_perm; + bleio_attribute_security_mode_t write_perm; + mp_obj_list_t *descriptor_list; + uint16_t user_desc_handle; + uint16_t cccd_handle; + uint16_t sccd_handle; + bool fixed_length; +} bleio_characteristic_obj_t; + +bool set_characteristic_value_on_ble_evt(uint8_t conn_handle, + uint16_t char_handle, + uint8_t *data, + size_t data_len); + +#endif // MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_CHARACTERISTIC_H diff --git a/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c b/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c new file mode 100644 index 000000000000..653de697cda3 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c @@ -0,0 +1,164 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "py/ringbuf.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/CharacteristicBuffer.h" +#include "common-hal/_bleio/CharacteristicBuffer.h" +#include "shared/runtime/interrupt_char.h" +#include "supervisor/shared/tick.h" + +// Characteristic buffer list of peripheral device +bleio_characteristic_buffer_obj_list_t bleio_characteristic_buffer_list; + +bool characteristic_buffer_on_ble_evt(uint16_t attribute, + uint8_t *data, + uint16_t len) { + + uint16_t cindex = 0; + for (cindex = 0; cindex < bleio_characteristic_buffer_list.len; cindex++) { + if (bleio_characteristic_buffer_list.data[cindex] != NULL && + bleio_characteristic_buffer_list.data[cindex]->characteristic->handle == attribute) { + taskENTER_CRITICAL(); + if (bleio_characteristic_buffer_list.data[cindex]->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(&bleio_characteristic_buffer_list.data[cindex]->ringbuf, data[i]); + } + } + } else { + ringbuf_put_n(&bleio_characteristic_buffer_list.data[cindex]->ringbuf,data, len); + } + taskEXIT_CRITICAL(); + + return true; + } + } + return false; +} + +void _common_hal_bleio_characteristic_buffer_construct( + bleio_characteristic_buffer_obj_t *self, + bleio_characteristic_obj_t *characteristic, + mp_float_t timeout, + uint8_t *buffer, size_t buffer_size, + 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; + ringbuf_init(&self->ringbuf, buffer, buffer_size); +} + +void common_hal_bleio_characteristic_buffer_construct( + bleio_characteristic_buffer_obj_t *self, + bleio_characteristic_obj_t *characteristic, + 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, + false); + + bleio_characteristic_buffer_list.data[bleio_characteristic_buffer_list.len] = self; + bleio_characteristic_buffer_list.len++; +} + +uint32_t common_hal_bleio_characteristic_buffer_read( + bleio_characteristic_buffer_obj_t *self, + uint8_t *data, + size_t len, + int *errcode) { + + uint64_t start_ticks = supervisor_ticks_ms64(); + // Wait for all bytes received or timeout + while ((ringbuf_num_filled(&self->ringbuf) < len) && + (supervisor_ticks_ms64() - start_ticks < self->timeout_ms)) { + RUN_BACKGROUND_TASKS; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + return 0; + } + } + taskENTER_CRITICAL(); + uint32_t num_bytes_read = ringbuf_get_n(&self->ringbuf, data, len); + taskEXIT_CRITICAL(); + + return num_bytes_read; +} + +uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available( + bleio_characteristic_buffer_obj_t *self) { + return ringbuf_num_filled(&self->ringbuf); +} + +void common_hal_bleio_characteristic_buffer_clear_rx_buffer( + bleio_characteristic_buffer_obj_t *self) { + taskENTER_CRITICAL(); + ringbuf_clear(&self->ringbuf); + taskEXIT_CRITICAL(); +} + +bool common_hal_bleio_characteristic_buffer_deinited( + bleio_characteristic_buffer_obj_t *self) { + return self->characteristic == NULL; +} + +void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) { + if (!common_hal_bleio_characteristic_buffer_deinited(self)) { + self->characteristic = NULL; + ringbuf_deinit(&self->ringbuf); + } +} + +bool common_hal_bleio_characteristic_buffer_connected( + bleio_characteristic_buffer_obj_t *self) { + return self->characteristic != NULL && + self->characteristic->service != NULL && + (!self->characteristic->service->is_remote || + (self->characteristic->service->connection != MP_OBJ_NULL && + common_hal_bleio_connection_get_connected(self->characteristic->service->connection))); +} + +void reset_characteristic_buffer_list() { + // Remove characteristic_buffer list + memset(bleio_characteristic_buffer_list.data, 0, + sizeof(bleio_characteristic_buffer_list.data)); + bleio_characteristic_buffer_list.len = 0; +} diff --git a/ports/silabs/common-hal/_bleio/CharacteristicBuffer.h b/ports/silabs/common-hal/_bleio/CharacteristicBuffer.h new file mode 100644 index 000000000000..6acb52e790a2 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/CharacteristicBuffer.h @@ -0,0 +1,55 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H +#define MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H + +#include "py/ringbuf.h" +#include "shared-bindings/_bleio/Characteristic.h" + +#define MAX_NUMBER_CHARACTERISTIC_BUFFER 64 +#define GET_CHARACTERISTIC_TIMEOUT_MS 1000 +typedef struct { + mp_obj_base_t base; + bleio_characteristic_obj_t *characteristic; + uint32_t timeout_ms; + // Ring buffer storing consecutive incoming values + ringbuf_t ringbuf; + bool watch_for_interrupt_char; +} bleio_characteristic_buffer_obj_t; + +typedef struct +{ + bleio_characteristic_buffer_obj_t *data[MAX_NUMBER_CHARACTERISTIC_BUFFER]; + uint8_t len; +} bleio_characteristic_buffer_obj_list_t; + +extern bleio_characteristic_buffer_obj_list_t bleio_characteristic_buffer_list; +extern bool characteristic_buffer_on_ble_evt(uint16_t attribute, + uint8_t *data, + uint16_t len); +extern void reset_characteristic_buffer_list(); +#endif // MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H diff --git a/ports/silabs/common-hal/_bleio/Connection.c b/ports/silabs/common-hal/_bleio/Connection.c new file mode 100644 index 000000000000..ad3f6db19837 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Connection.c @@ -0,0 +1,274 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "py/gc.h" +#include "py/objlist.h" +#include "py/objstr.h" +#include "py/qstr.h" +#include "py/runtime.h" + +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Attribute.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-module/_bleio/Characteristic.h" +#include "shared/runtime/interrupt_char.h" +#include "supervisor/shared/tick.h" +#include "supervisor/serial.h" + +// Give 10 seconds for discovery +#define DISCOVERY_TIMEOUT_MS 10000 +EventGroupHandle_t xdiscovery_event; + +// Get the remote peer status +bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self) { + if (self->connection == NULL) { + return false; + } + + return self->connection->pair_status == PAIR_PAIRED; +} + +// Get connected status +bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self) { + if (self->connection == NULL) { + return false; + } + return self->connection->conn_handle != BLEIO_HANDLE_INVALID; +} + +// Disconnects from the remote peripheral +void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self) { + sl_bt_connection_close(self->conn_handle); +} + +// Pair to the peer to improve security +void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, + bool bond) { + + while (self->pair_status == PAIR_WAITING && !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + } + if (self->pair_status == PAIR_PAIRED) { + return; + } + self->pair_status = PAIR_WAITING; + + while (self->pair_status == PAIR_WAITING && !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + } + if (mp_hal_is_interrupted()) { + return; + } +} + +// Get time between transmissions in milliseconds +mp_float_t common_hal_bleio_connection_get_connection_interval( + bleio_connection_internal_t *self) { + // TODO: Implement this. + return 0; +} + +// The maximum number of data bytes that can be sent in a single transmission +mp_int_t common_hal_bleio_connection_get_max_packet_length( + bleio_connection_internal_t *self) { + + sl_status_t sc = sl_bt_gatt_server_get_mtu(self->conn_handle,&self->mtu); + if (sc != SL_STATUS_OK) { + mp_raise_bleio_BluetoothError(translate("gatt_server_get_mtu fail.")); + } + + return self->mtu; +} + +// Set time between transmissions in milliseconds +void common_hal_bleio_connection_set_connection_interval( + bleio_connection_internal_t *self, + mp_float_t new_interval) { + self->conn_params_updating = true; + // TODO: Implement this. +} + +// Do BLE discovery for all services +mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services( + bleio_connection_obj_t *self, + mp_obj_t service_uuids_whitelist) { + + EventBits_t ux_bits; + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable; + mp_obj_t uuid_obj; + mp_obj_tuple_t *services_tuple; + sl_status_t sc = SL_STATUS_FAIL; + bleio_uuid_obj_t *uuid; + uint8_t uuid16_value[2]; + + uint64_t start_ticks = supervisor_ticks_ms64(); + uint64_t current_ticks = start_ticks; + + xdiscovery_event = xEventGroupCreate(); + if (xdiscovery_event != NULL) { + xEventGroupClearBits(xdiscovery_event,1 << 0); + } + self->connection->remote_service_list = mp_obj_new_list(0, NULL); + bleio_connection_ensure_connected(self); + if (NULL == self->connection->remote_service_list) { + mp_raise_bleio_BluetoothError( + translate("Create new remote service list fail.")); + return mp_const_none; + } + vTaskDelay(500 / portTICK_PERIOD_MS); + + if (service_uuids_whitelist == mp_const_none) { + + sc = sl_bt_gatt_discover_primary_services(self->connection->conn_handle); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Discover uuid fail.")); + return mp_const_none; + } + + while (current_ticks - start_ticks <= DISCOVERY_TIMEOUT_MS) { + + if (xdiscovery_event != NULL) { + ux_bits = xEventGroupWaitBits( + xdiscovery_event, + 1 << 0, + pdTRUE,pdFALSE, + DISCOVERY_TIMEOUT_MS / portTICK_PERIOD_MS); + + if ((ux_bits & (1 << 0)) == (1 << 0)) { + break; + } + } + current_ticks = supervisor_ticks_ms64(); + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + break; + } + } + + } else { + + iterable = mp_getiter(service_uuids_whitelist, &iter_buf); + while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + if (!mp_obj_is_type(uuid_obj, &bleio_uuid_type)) { + mp_raise_TypeError( + translate("non-UUID found in service_uuids_whitelist")); + } + uuid = MP_OBJ_TO_PTR(uuid_obj); + + if (BLE_UUID_TYPE_16 == uuid->efr_ble_uuid.uuid.type) { + uuid16_value[0] = uuid->efr_ble_uuid.uuid16.value & 0xff; + uuid16_value[1] = uuid->efr_ble_uuid.uuid16.value >> 8; + sc = sl_bt_gatt_discover_primary_services_by_uuid( + self->connection->conn_handle,2,uuid16_value); + + } else if (BLE_UUID_TYPE_128 == uuid->efr_ble_uuid.uuid.type) { + sc = sl_bt_gatt_discover_primary_services_by_uuid( + self->connection->conn_handle, + 16, + uuid->efr_ble_uuid.uuid128.value); + } + + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Discover fail.")); + return mp_const_none; + } + + while (current_ticks - start_ticks <= DISCOVERY_TIMEOUT_MS) { + + if (xdiscovery_event != NULL) { + ux_bits = xEventGroupWaitBits( + xdiscovery_event, + 1 << 0, + pdTRUE, + pdFALSE, + DISCOVERY_TIMEOUT_MS / portTICK_PERIOD_MS); + + if ((ux_bits & (1 << 0)) == (1 << 0)) { + break; + } + } + current_ticks = supervisor_ticks_ms64(); + if (mp_hal_is_interrupted()) { + break; + } + } + } + } + + vEventGroupDelete(xdiscovery_event); + services_tuple = mp_obj_new_tuple(self->connection->remote_service_list->len, + self->connection->remote_service_list->items); + + if (NULL == services_tuple) { + mp_raise_ValueError(translate("Create new service tuple fail.")); + return mp_const_none; + } + return services_tuple; +} + +// Get connection handle +uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self) { + if (self == NULL || self->connection == NULL) { + return BLEIO_HANDLE_INVALID; + } + return self->connection->conn_handle; +} + +mp_obj_t bleio_connection_new_from_internal( + bleio_connection_internal_t *internal) { + + bleio_connection_obj_t *connection; + if (internal->connection_obj != mp_const_none) { + return internal->connection_obj; + } + connection = m_new_obj(bleio_connection_obj_t); + connection->base.type = &bleio_connection_type; + connection->connection = internal; + internal->connection_obj = connection; + + return MP_OBJ_FROM_PTR(connection); +} + +// Get internal connection object by handle connection +bleio_connection_internal_t *bleio_conn_handle_to_connection( + uint16_t conn_handle) { + bleio_connection_internal_t *connection; + uint8_t conn_index; + for (conn_index = 0; conn_index < BLEIO_TOTAL_CONNECTION_COUNT; conn_index++) { + connection = &bleio_connections[conn_index]; + if (connection->conn_handle == conn_handle) { + return connection; + } + } + return NULL; +} diff --git a/ports/silabs/common-hal/_bleio/Connection.h b/ports/silabs/common-hal/_bleio/Connection.h new file mode 100644 index 000000000000..56872024c932 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Connection.h @@ -0,0 +1,96 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR_COMMON_HAL_BLEIO_CONNECTION_H +#define MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_CONNECTION_H + +#include + +#include "common-hal/_bleio/__init__.h" +#include "py/obj.h" +#include "py/objlist.h" +#include "common-hal/_bleio/Service.h" +#include "shared-module/_bleio/Address.h" +#include "FreeRTOS.h" +#include "event_groups.h" + +typedef enum { + PAIR_NOT_PAIRED, + PAIR_WAITING, + PAIR_PAIRED, +} pair_status_t; + +// We split the Connection object into two so that +// the internal mechanics can live outside of theVM. +// If it were one object, then we'd risk user code seeing +// a connection object of theirs be reused. +typedef struct +{ + uint16_t conn_handle; + bool is_central; + // Remote services discovered when this peripheral is acting as a client. + mp_obj_list_t *remote_service_list; + // The advertising data and scan response buffers are held by us, + // not by the SD, so we must maintain them and not change it. + // If we need to change the contents during advertising, + // there are tricks to get the SD to notice (see DevZone - TBS). + // bonding_keys_t bonding_keys; + // EDIV: Encrypted Diversifier: Identifies LTK during legacy pairing. + uint16_t ediv; + volatile pair_status_t pair_status; + uint8_t sec_status; // Internal security status. + mp_obj_t connection_obj; + volatile bool conn_params_updating; + uint16_t mtu; + // Request that CCCD values for this connection be saved, + // using sys_attr values. + volatile bool do_bond_cccds; + // Request that security key info for this connection be saved. + volatile bool do_bond_keys; + // Time of setting do_bond_ccds: we delay a bit to consolidate + // multiple CCCD changes into one write. Time is currently in ticks_ms. + uint64_t do_bond_cccds_request_time; +} bleio_connection_internal_t; + +typedef struct +{ + mp_obj_base_t base; + bleio_connection_internal_t *connection; + // The HCI disconnect reason. + uint8_t disconnect_reason; +} bleio_connection_obj_t; + +void bleio_connection_clear(bleio_connection_internal_t *self); + +uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self); + +mp_obj_t bleio_connection_new_from_internal( + bleio_connection_internal_t *connection); + +bleio_connection_internal_t *bleio_conn_handle_to_connection( + uint16_t conn_handle); +extern EventGroupHandle_t xdiscovery_event; +#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BLEIO_CONNECTION_H diff --git a/ports/silabs/common-hal/_bleio/Descriptor.c b/ports/silabs/common-hal/_bleio/Descriptor.c new file mode 100644 index 000000000000..6a40f1f859a9 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Descriptor.c @@ -0,0 +1,114 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/_bleio/__init__.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" + +void common_hal_bleio_descriptor_construct( + bleio_descriptor_obj_t *self, + bleio_characteristic_obj_t *characteristic, + bleio_uuid_obj_t *uuid, + bleio_attribute_security_mode_t read_perm, + bleio_attribute_security_mode_t write_perm, + mp_int_t max_length, bool fixed_length, + mp_buffer_info_t *initial_value_bufinfo) { + + const mp_int_t max_length_max = BLE_ATT_ATTR_MAX_LEN; + self->uuid = uuid; + self->handle = BLEIO_HANDLE_INVALID; + self->read_perm = read_perm; + self->write_perm = write_perm; + self->initial_value = mp_obj_new_bytes(initial_value_bufinfo->buf, + initial_value_bufinfo->len); + + if (max_length < 0 || max_length > max_length_max) { + mp_raise_ValueError_varg( + translate("max_length must be 0-%d when fixed_length is %s"), + max_length_max, fixed_length ? "True" : "False"); + } + self->max_length = max_length; + self->fixed_length = fixed_length; +} + +// Get descriptor uuid +bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid( + bleio_descriptor_obj_t *self) { + return self->uuid; +} + +bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic( + bleio_descriptor_obj_t *self) { + return self->characteristic; +} + +size_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self, + uint8_t *buf, size_t len) { + + uint16_t conn_handle; + if (self->handle != BLE_GATT_HANDLE_INVALID) { + conn_handle = bleio_connection_get_conn_handle( + self->characteristic->service->connection); + if (common_hal_bleio_service_get_is_remote( + self->characteristic->service)) { + + sl_bt_gatt_read_descriptor_value(conn_handle, self->handle); + } + } + + return 0; +} + +// Set value to descriptor +void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, + mp_buffer_info_t *bufinfo) { + + uint16_t conn_handle; + if (self->handle != BLE_GATT_HANDLE_INVALID) { + conn_handle = bleio_connection_get_conn_handle( + self->characteristic->service->connection); + if (common_hal_bleio_service_get_is_remote( + self->characteristic->service)) { + + // false means WRITE_REQ, not write-no-response + sl_bt_gatt_write_descriptor_value(conn_handle, + self->handle, + bufinfo->len, + bufinfo->buf); + } else { + // Validate data length for local descriptors only. + if (self->fixed_length && bufinfo->len != self->max_length) { + mp_raise_ValueError( + translate("Value length != required fixed length")); + } + if (bufinfo->len > self->max_length) { + mp_raise_ValueError(translate("Value length > max_length")); + } + } + } +} diff --git a/ports/silabs/common-hal/_bleio/Descriptor.h b/ports/silabs/common-hal/_bleio/Descriptor.h new file mode 100644 index 000000000000..b71cac2b68bb --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Descriptor.h @@ -0,0 +1,53 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR_COMMON_HAL_BLEIO_DESCRIPTOR_H +#define MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_DESCRIPTOR_H + +#include "py/obj.h" +#include "common-hal/_bleio/UUID.h" +#include "shared-module/_bleio/Attribute.h" + +#define BLE_ATT_ATTR_MAX_LEN 50 + +// Forward declare characteristic because it includes a Descriptor. +struct _bleio_characteristic_obj; + +typedef struct _bleio_descriptor_obj { + mp_obj_base_t base; + // Will be MP_OBJ_NULL before being assigned to a Characteristic. + struct _bleio_characteristic_obj *characteristic; + bleio_uuid_obj_t *uuid; + mp_obj_t initial_value; + uint16_t max_length; + bool fixed_length; + uint16_t handle; + // struct ble_gatt_dsc_def def; + bleio_attribute_security_mode_t read_perm; + bleio_attribute_security_mode_t write_perm; +} bleio_descriptor_obj_t; + +#endif // MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_DESCRIPTOR_H diff --git a/ports/silabs/common-hal/_bleio/PacketBuffer.c b/ports/silabs/common-hal/_bleio/PacketBuffer.c new file mode 100644 index 000000000000..dd74e1709925 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/PacketBuffer.c @@ -0,0 +1,399 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "py/runtime.h" +#include "py/stream.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/PacketBuffer.h" +#include "shared/runtime/interrupt_char.h" +#include "common-hal/_bleio/Connection.h" +#include "supervisor/shared/tick.h" +#include "supervisor/serial.h" + +// List packet buffer of peripheral device +bleio_packet_buffer_obj_list_t bleio_packet_buffer_list; + +// Write data to ringbuf of packet buffer +STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, + uint8_t *data, + uint16_t len) { + + uint16_t packet_length; + uint16_t packet_index; + 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; + } + + taskENTER_CRITICAL(); + // Push all the data onto the ring buffer. + // Make room for the new value by dropping the oldest packets first. + while (ringbuf_size(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) { + ringbuf_get_n(&self->ringbuf, + (uint8_t *)&packet_length, sizeof(uint16_t)); + + for (packet_index = 0; packet_index < packet_length; packet_index++) { + ringbuf_get(&self->ringbuf); + } + } + ringbuf_put_n(&self->ringbuf, (uint8_t *)&len, sizeof(uint16_t)); + ringbuf_put_n(&self->ringbuf, data, len); + taskEXIT_CRITICAL(); +} + +// Write characteristic or attribute value +STATIC int queue_next_write(bleio_packet_buffer_obj_t *self) { + self->packet_queued = false; + + uint32_t sc = SL_STATUS_OK; + if (self->pending_size > 0) { + if (self->client) { + if (self->write_type & BT_GATT_CHRC_WRITE_WITHOUT_RESP) { + uint16_t sent_len; + sc = sl_bt_gatt_write_characteristic_value_without_response( + self->conn_handle, self->characteristic->handle, + self->pending_size, + (uint8_t *)self->outgoing[self->pending_index], + &sent_len); + } else { + sc = sl_bt_gatt_write_characteristic_value( + self->conn_handle, self->characteristic->handle, + self->pending_size, + (uint8_t *)self->outgoing[self->pending_index]); + } + + } else { + if (self->write_type & BT_GATT_CHRC_READ) { + sc = sl_bt_gatt_server_write_attribute_value(self->characteristic->handle, + 0, + self->pending_size, + (uint8_t *)self->outgoing[self->pending_index]); + } + + if (self->write_type & BT_GATT_CHRC_NOTIFY) { + sc = sl_bt_gatt_server_send_notification( + self->conn_handle, + self->characteristic->handle, + self->pending_size, + (uint8_t *)self->outgoing[self->pending_index]); + } + + if (self->write_type & BT_GATT_CHRC_INDICATE) { + sl_bt_gatt_server_send_indication( + self->conn_handle, + self->characteristic->handle, + self->pending_size, + (uint8_t *)self->outgoing[self->pending_index]); + } + } + self->pending_size = 0; + self->pending_index = (self->pending_index + 1) % 2; + self->packet_queued = true; + } + return sc; +} + + +// This funttion is called in sl_bt_on_event to receive +bool packet_buffer_on_ble_evt(uint16_t attribute, uint8_t *data, uint16_t len) { + uint16_t cindex = 0; + for (cindex = 0; cindex < bleio_packet_buffer_list.len; cindex++) { + if (bleio_packet_buffer_list.data[cindex]->characteristic->handle == attribute) { + taskENTER_CRITICAL(); + write_to_ringbuf(bleio_packet_buffer_list.data[cindex], data, len); + taskEXIT_CRITICAL(); + + return true; + } + } + return false; +} + +void _common_hal_bleio_packet_buffer_construct( + bleio_packet_buffer_obj_t *self, + bleio_characteristic_obj_t *characteristic, + uint32_t *incoming_buffer, + size_t incoming_buffer_size, + uint32_t *outgoing_buffer1, + uint32_t *outgoing_buffer2, + size_t max_packet_size, + void *static_handler_entry) { + + bleio_characteristic_properties_t temp_prop; + self->characteristic = characteristic; + self->client = self->characteristic->service->is_remote; + self->max_packet_size = max_packet_size; + bleio_characteristic_properties_t incoming = self->characteristic->props & (BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_WRITE); + bleio_characteristic_properties_t outgoing = self->characteristic->props & (BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE); + + if (self->client) { + // Swap if we're the client. + temp_prop = incoming; + incoming = outgoing; + outgoing = temp_prop; + self->conn_handle = bleio_connection_get_conn_handle( + MP_OBJ_TO_PTR(self->characteristic->service->connection)); + } else { + self->conn_handle = BLE_CONN_HANDLE_INVALID; + } + + if (incoming) { + ringbuf_init(&self->ringbuf, + (uint8_t *)incoming_buffer, + incoming_buffer_size); + } + + self->packet_queued = false; + self->pending_index = 0; + self->pending_size = 0; + self->outgoing[0] = outgoing_buffer1; + self->outgoing[1] = outgoing_buffer2; + + if (self->client) { + if (incoming) { + if (incoming & BT_GATT_CHRC_NOTIFY) { + common_hal_bleio_characteristic_set_cccd(self->characteristic, + true, false); + } else { + common_hal_bleio_characteristic_set_cccd(self->characteristic, + false, true); + } + } + if (outgoing) { + self->write_type = BT_GATT_CHRC_WRITE; + if (outgoing & BT_GATT_CHRC_WRITE_WITHOUT_RESP) { + self->write_type = BT_GATT_CHRC_WRITE_WITHOUT_RESP; + } + } + } else { + self->write_type = outgoing; + } +} + +// Init packet buffer +void common_hal_bleio_packet_buffer_construct( + bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, + size_t buffer_size, size_t max_packet_size) { + + size_t incoming_buffer_size = 0; + uint32_t *incoming_buffer = NULL; + uint32_t *outgoing1 = NULL; + uint32_t *outgoing2 = NULL; + + bleio_characteristic_properties_t temp_properties; + // Cap the packet size to our implementation limits. + max_packet_size = MIN(max_packet_size, BLE_GATTS_VAR_ATTR_LEN_MAX - 3); + + bleio_characteristic_properties_t incoming = characteristic->props & (BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_WRITE); + bleio_characteristic_properties_t outgoing = characteristic->props & (BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE); + if (characteristic->service->is_remote) { + // Swap if we're the client. + temp_properties = incoming; + incoming = outgoing; + outgoing = temp_properties; + } + + if (incoming) { + incoming_buffer_size = buffer_size * (sizeof(uint16_t) + max_packet_size); + incoming_buffer = m_malloc(incoming_buffer_size, false); + } + + if (outgoing) { + outgoing1 = m_malloc(max_packet_size, false); + outgoing2 = m_malloc(max_packet_size, false); + } + _common_hal_bleio_packet_buffer_construct(self, characteristic, + incoming_buffer, incoming_buffer_size, + outgoing1, outgoing2, max_packet_size, + NULL); + + bleio_packet_buffer_list.data[bleio_packet_buffer_list.len] = self; + bleio_packet_buffer_list.len++; +} + +// Reads a single BLE packet into the buffer +mp_int_t common_hal_bleio_packet_buffer_readinto( + bleio_packet_buffer_obj_t *self, + uint8_t *data, + size_t len) { + + mp_int_t ret; + uint16_t packet_length; + + if (ringbuf_num_filled(&self->ringbuf) < 1) { + return 0; + } + taskENTER_CRITICAL(); + // Get packet length, which is in first two bytes of packet. + packet_length = 5; + ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t)); + + if (packet_length > len) { + // Packet is longer than requested. Return negative of overrun value. + ret = len - packet_length; + // Discard the packet if it's too large. Don't fill data. + while (packet_length--) { + (void)ringbuf_get(&self->ringbuf); + } + } else { + // Read as much as possible, but might be shorter than len. + ringbuf_get_n(&self->ringbuf, data, packet_length); + ret = packet_length; + } + taskEXIT_CRITICAL(); + return ret; +} + +// Writes all bytes from data into the same outgoing packet +mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, + const uint8_t *data, + size_t len, + uint8_t *header, + size_t header_len) { + + mp_int_t outgoing_packet_length; + mp_int_t total_len; + size_t num_bytes_written; + uint32_t *pending; + + if (!self->client) { + self->conn_handle = bleio_connections[0].conn_handle; + } + if (self->outgoing[0] == NULL) { + mp_raise_bleio_BluetoothError( + translate("Writes not supported on Characteristic")); + } + if (self->conn_handle == BLE_CONN_HANDLE_INVALID) { + return -1; + } + outgoing_packet_length = + common_hal_bleio_packet_buffer_get_outgoing_packet_length(self); + + if (outgoing_packet_length < 0) { + return -1; + } + + total_len = len + header_len; + if (total_len > outgoing_packet_length) { + // Supplied data will not fit in a single BLE packet. + mp_raise_ValueError_varg( + translate("Total data to write is larger than %q"), + MP_QSTR_outgoing_packet_length); + } + if (total_len > self->max_packet_size) { + // Supplied data will not fit in a single BLE packet. + mp_raise_ValueError_varg( + translate("Total data to write is larger than %q"), + MP_QSTR_max_packet_size); + } + outgoing_packet_length = MIN(outgoing_packet_length, self->max_packet_size); + + if (len + self->pending_size > (size_t)outgoing_packet_length) { + // No room to append len bytes to packet. Wait until we get a free buffer + // and keep checking that we haven't been disconnected. + while (self->pending_size != 0 && + self->conn_handle != BLE_CONN_HANDLE_INVALID && + !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + } + if (mp_hal_is_interrupted()) { + return -1; + } + } + if (self->conn_handle == BLE_CONN_HANDLE_INVALID) { + return -1; + } + + num_bytes_written = 0; + pending = self->outgoing[self->pending_index]; + + if (self->pending_size == 0) { + memcpy(pending, header, header_len); + self->pending_size += header_len; + num_bytes_written += header_len; + } + memcpy(((uint8_t *)pending) + self->pending_size, data, len); + self->pending_size += len; + num_bytes_written += len; + + queue_next_write(self); + return num_bytes_written; +} + +// Get length of receiving packet +mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length( + bleio_packet_buffer_obj_t *self) { + + if (self->characteristic == NULL) { + return -1; + } + return self->characteristic->max_length; +} + +// Get length of outgoing packet +mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length( + bleio_packet_buffer_obj_t *self) { + + if (self->characteristic == NULL) { + return -1; + } + return MIN(self->max_packet_size, self->characteristic->max_length); +} + +// Flush ring buffer og packer buffer +void common_hal_bleio_packet_buffer_flush(bleio_packet_buffer_obj_t *self) { + while ((self->pending_size != 0 || + self->packet_queued) && + self->conn_handle != BLEIO_HANDLE_INVALID && + !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + } +} + +// Check status of packet buffer obj +bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) { + return self->characteristic == NULL; +} + +// Deinit packet buffer +void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) { + if (!common_hal_bleio_packet_buffer_deinited(self)) { + ringbuf_deinit(&self->ringbuf); + } +} + +// Remove packet_buffer list when reload +void reset_packet_buffer_list() { + // Remove packet_buffer list + memset(bleio_packet_buffer_list.data, 0, + sizeof(bleio_packet_buffer_list.data)); + bleio_packet_buffer_list.len = 0; +} diff --git a/ports/silabs/common-hal/_bleio/PacketBuffer.h b/ports/silabs/common-hal/_bleio/PacketBuffer.h new file mode 100644 index 000000000000..f79eda6cf3a6 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/PacketBuffer.h @@ -0,0 +1,64 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR_COMMON_HAL_BLEIO_PACKETBUFFER_H +#define MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_PACKETBUFFER_H + +#include "py/ringbuf.h" +#include "shared-bindings/_bleio/Characteristic.h" + +#define MAX_NUMBER_PACKET_BUFFER 64 +typedef struct { + mp_obj_base_t base; + bleio_characteristic_obj_t *characteristic; + // Ring buffer storing consecutive incoming values. + ringbuf_t ringbuf; + // Two outgoing buffers to alternate between. + // One will be queued for transmission by the SD and + // the other is waiting to be queued and can be extended. + uint32_t *outgoing[2]; + volatile uint16_t pending_size; + // We remember the conn_handle so we can do a NOTIFY/INDICATE to a client. + // We can find out the conn_handle on a Characteristic write + // or a CCCD write (but not a read). + volatile uint16_t conn_handle; + uint16_t max_packet_size; + uint8_t pending_index; + uint8_t write_type; + bool client; + bool packet_queued; +} bleio_packet_buffer_obj_t; + +typedef struct { + bleio_packet_buffer_obj_t *data[MAX_NUMBER_PACKET_BUFFER]; + uint8_t len; +} bleio_packet_buffer_obj_list_t; + +extern bool packet_buffer_on_ble_evt(uint16_t attribute, + uint8_t *data, + uint16_t len); +extern void reset_packet_buffer_list(); +#endif // MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_PACKETBUFFER_H diff --git a/ports/silabs/common-hal/_bleio/Service.c b/ports/silabs/common-hal/_bleio/Service.c new file mode 100644 index 000000000000..5fd06a2111d0 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Service.c @@ -0,0 +1,242 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/runtime.h" +#include "common-hal/_bleio/__init__.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Service.h" + +// List ble service of central device +bleio_service_obj_list bleio_service_list; + +uint32_t _common_hal_bleio_service_construct( + bleio_service_obj_t *self, + bleio_uuid_obj_t *uuid, + bool is_secondary, + mp_obj_list_t *characteristic_list) { + + uint8_t service_type; + sl_status_t sc = SL_STATUS_FAIL; + uint16_t gattdb_session; + sl_bt_uuid_16_t bt_uuid; + + self->handle = 0xFFFF; + self->uuid = uuid; + self->characteristic_list = characteristic_list; + self->is_remote = false; + self->connection = NULL; + self->is_secondary = is_secondary; + + if (self->is_secondary) { + service_type = sl_bt_gattdb_secondary_service; + } else { + service_type = sl_bt_gattdb_primary_service; + } + + sc = sl_bt_gattdb_new_session(&gattdb_session); + if (SL_STATUS_OK != sc && SL_STATUS_ALREADY_EXISTS != sc) { + mp_raise_bleio_BluetoothError(translate("Create new session fail.")); + return sc; + } + if (BLE_UUID_TYPE_16 == self->uuid->efr_ble_uuid.uuid.type) { + + bt_uuid.data[0] = self->uuid->efr_ble_uuid.uuid16.value & 0xff; + bt_uuid.data[1] = self->uuid->efr_ble_uuid.uuid16.value >> 8; + sc = sl_bt_gattdb_add_service(gattdb_session, + service_type, + 0, 2, bt_uuid.data, + (uint16_t *)&self->handle); + } else if (BLE_UUID_TYPE_128 == self->uuid->efr_ble_uuid.uuid.type) { + sc = sl_bt_gattdb_add_service(gattdb_session, + service_type, 0, 16, + self->uuid->efr_ble_uuid.uuid128.value, + (uint16_t *)&self->handle); + } + + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Create new session fail.")); + return sc; + } + + sc = sl_bt_gattdb_start_service(gattdb_session, self->handle); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Start service fail.")); + } + + sc = sl_bt_gattdb_commit(gattdb_session); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Commit service fail.")); + } + + bleio_service_list.data[bleio_service_list.len] = self; + bleio_service_list.len++; + return sc; +} + +// Create a new Service identified by the specified UUID +void common_hal_bleio_service_construct(bleio_service_obj_t *self, + bleio_uuid_obj_t *uuid, + bool is_secondary) { + _common_hal_bleio_service_construct(self, uuid, + is_secondary, + mp_obj_new_list(0, NULL)); +} + +// Get service from connection +void bleio_service_from_connection(bleio_service_obj_t *self, + mp_obj_t connection) { + self->handle = BLEIO_HANDLE_INVALID; + self->uuid = NULL; + self->characteristic_list = mp_obj_new_list(0, NULL); + self->is_remote = true; + self->is_secondary = false; + self->connection = connection; +} + +// Get service uuid +bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) { + return self->uuid; +} + +// Get tuple charateristic of service +mp_obj_tuple_t *common_hal_bleio_service_get_characteristics( + bleio_service_obj_t *self) { + return mp_obj_new_tuple(self->characteristic_list->len, + self->characteristic_list->items); +} + +// This is a service provided by a remote device or not +bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self) { + return self->is_remote; +} + +// If the service is a secondary one +bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) { + return self->is_secondary; +} + +// Add new dynamic characteristic to service +void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, + bleio_characteristic_obj_t *characteristic, + mp_buffer_info_t *initial_value_bufinfo, + const char *user_description) { + + bool broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0; + bool read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0; + bool write_wo_resp = + (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) ? 1 : 0; + bool write = + write_wo_resp ? 1 : (characteristic->props & CHAR_PROP_WRITE) ? 1 + : 0; + bool notify = (characteristic->props & CHAR_PROP_NOTIFY) ? 1 : 0; + bool indicate = (characteristic->props & CHAR_PROP_INDICATE) ? 1 : 0; + + sl_status_t sc = SL_STATUS_FAIL; + sl_bt_uuid_16_t bt_uuid; + uint16_t gattdb_session; + + sc = sl_bt_gattdb_new_session(&gattdb_session); + + if (SL_STATUS_OK != sc && SL_STATUS_ALREADY_EXISTS != sc) { + mp_raise_bleio_BluetoothError(translate("Create new session fail.")); + return; + } + characteristic->props = (broadcast << 0) | (read << 1) | + (write_wo_resp << 2) | (write << 3) | (notify << 4) | (indicate << 5); + + if (BLE_UUID_TYPE_16 == characteristic->uuid->efr_ble_uuid.uuid.type) { + bt_uuid.data[0] = characteristic->uuid->efr_ble_uuid.uuid16.value & 0xff; + bt_uuid.data[1] = characteristic->uuid->efr_ble_uuid.uuid16.value >> 8; + + sc = sl_bt_gattdb_add_uuid16_characteristic( + gattdb_session, + self->handle, + characteristic->props, + 0, + 0, + bt_uuid, + sl_bt_gattdb_variable_length_value, + characteristic->max_length, + 0, + initial_value_bufinfo->buf, + &characteristic->handle); + + } else if (BLE_UUID_TYPE_128 == + characteristic->uuid->efr_ble_uuid.uuid.type) { + uuid_128 uuid; + memcpy(uuid.data, characteristic->uuid->efr_ble_uuid.uuid128.value, 16); + + sc = sl_bt_gattdb_add_uuid128_characteristic(gattdb_session, + self->handle, + characteristic->props, + 0, + 0, + uuid, + sl_bt_gattdb_variable_length_value, + characteristic->max_length, + 0, + initial_value_bufinfo->buf, + &characteristic->handle); + } + + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Add charateristic fail.")); + } + + sc = sl_bt_gattdb_start_characteristic(gattdb_session, + characteristic->handle); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Start charateristic fail.")); + return; + } + + sc = sl_bt_gattdb_commit(gattdb_session); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Commit charateristic fail.")); + return; + } + mp_obj_list_append(self->characteristic_list, + MP_OBJ_FROM_PTR(characteristic)); +} + +// Remove dynamic service when reload +void reset_dynamic_service() { + + uint16_t gattdb_session; + uint8_t svc_index; + // Remove dynamic service + for (svc_index = 0; svc_index < bleio_service_list.len; svc_index++) { + sl_bt_gattdb_new_session(&gattdb_session); + sl_bt_gattdb_remove_service(gattdb_session, + bleio_service_list.data[svc_index]->handle); + sl_bt_gattdb_commit(gattdb_session); + } + bleio_service_list.len = 0; +} diff --git a/ports/silabs/common-hal/_bleio/Service.h b/ports/silabs/common-hal/_bleio/Service.h new file mode 100644 index 000000000000..a389da21b7a6 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/Service.h @@ -0,0 +1,63 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR_COMMON_HAL_BLEIO_SERVICE_H +#define MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_SERVICE_H + +#include "py/objlist.h" +#include "common-hal/_bleio/UUID.h" + +#define MAX_NUMBER_SERVICE 64 + +typedef struct bleio_service_obj +{ + mp_obj_base_t base; + // Handle for the local service. + uint32_t handle; + // True if created during discovery. + bool is_remote; + bool is_secondary; + bleio_uuid_obj_t *uuid; + // The connection object is set only when this is a remote service. + // A local service doesn't know the connection. + mp_obj_t connection; + mp_obj_list_t *characteristic_list; + // Range of attribute handles of this remote service. + uint16_t start_handle; + uint16_t end_handle; +} bleio_service_obj_t; + +typedef struct +{ + bleio_service_obj_t *data[MAX_NUMBER_SERVICE]; + uint8_t len; +} bleio_service_obj_list; + +void bleio_service_from_connection(bleio_service_obj_t *self, + mp_obj_t connection); +uint16_t get_characteristic_handle(bleio_uuid_obj_t *uuid); +extern void reset_dynamic_service(); +#endif // MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_SERVICE_H diff --git a/ports/silabs/common-hal/_bleio/UUID.c b/ports/silabs/common-hal/_bleio/UUID.c new file mode 100644 index 000000000000..482a23d8f8bd --- /dev/null +++ b/ports/silabs/common-hal/_bleio/UUID.c @@ -0,0 +1,83 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/runtime.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/UUID.h" +#include "shared-bindings/_bleio/__init__.h" +#include "common-hal/_bleio/UUID.h" + +void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, + mp_int_t uuid16, + const uint8_t uuid128[16]) { + + if (uuid128 == NULL) { + self->efr_ble_uuid.uuid16.value = uuid16; + self->efr_ble_uuid.uuid.type = BLE_UUID_TYPE_16; + } else { + memcpy(self->efr_ble_uuid.uuid128.value, uuid128, 16); + self->efr_ble_uuid.uuid128.value[12] = uuid16 & 0xff; + self->efr_ble_uuid.uuid128.value[13] = (uuid16 >> 8) & 0xff; + self->efr_ble_uuid.uuid.type = BLE_UUID_TYPE_128; + } +} + +uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self) { + return self->efr_ble_uuid.uuid.type == BLE_UUID_TYPE_16 ? 16 : 128; +} + +uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) { + return self->efr_ble_uuid.uuid16.value; +} + +void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, + uint8_t uuid128[16]) { + memcpy(uuid128, self->efr_ble_uuid.uuid128.value, 16); +} + +void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t *buf) { + if (self->efr_ble_uuid.uuid.type == BLE_UUID_TYPE_16) { + buf[0] = self->efr_ble_uuid.uuid16.value & 0xff; + buf[1] = self->efr_ble_uuid.uuid16.value >> 8; + } else { + common_hal_bleio_uuid_get_uuid128(self, buf); + } +} + +void bleio_uuid_construct_from_efr_ble_uuid(bleio_uuid_obj_t *self, + ble_uuid_any_t *efr_ble_uuid) { + + if (self->efr_ble_uuid.uuid.type == BLE_UUID_TYPE_16) { + mp_raise_bleio_BluetoothError(translate("Unexpected efr uuid type")); + } + self->efr_ble_uuid.uuid16.value = efr_ble_uuid->uuid16.value; +} + +void bleio_uuid_convert_to_efr_ble_uuid(bleio_uuid_obj_t *self, + ble_uuid_any_t *efr_ble_uuid) { + efr_ble_uuid->uuid16.value = self->efr_ble_uuid.uuid16.value; +} diff --git a/ports/silabs/common-hal/_bleio/UUID.h b/ports/silabs/common-hal/_bleio/UUID.h new file mode 100644 index 000000000000..c1b99eb1ff91 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/UUID.h @@ -0,0 +1,90 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR_COMMON_HAL_BLEIO_UUID_H +#define MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_UUID_H + +#include "py/obj.h" + +#define UUID16_LEN 2 +#define UUID128_LEN 16 + +// Type of UUID +typedef enum { + // 16-bit UUID (BT SIG assigned) + BLE_UUID_TYPE_16 = 16, + // 32-bit UUID (BT SIG assigned) + BLE_UUID_TYPE_32 = 32, + // 128-bit UUID + BLE_UUID_TYPE_128 = 128, +} uuid_type_e; + +typedef struct { + // Type of the UUID + uint8_t type; +} ble_uuid_t; + +// 16-bit UUID +typedef struct { + uint8_t type; + uint16_t value; +} ble_uuid16_t; + +// 32-bit UUID +typedef struct { + uint8_t type; + uint32_t value; +} ble_uuid32_t; + +// 128-bit UUID +typedef struct { + uint8_t type; + uint8_t value[16]; +} ble_uuid128_t; + +typedef union { + ble_uuid_t uuid; + ble_uuid16_t uuid16; + ble_uuid32_t uuid32; + ble_uuid128_t uuid128; +} ble_uuid_any_t; + +typedef struct { + mp_obj_base_t base; + // Use the native way of storing UUID's: + // - ble_uuid_t.uuid is a 16-bit uuid. + // - ble_uuid_t.type is BLE_UUID_TYPE_BLE if it's a 16-bit Bluetooth SIG UUID. + // or is BLE_UUID_TYPE_VENDOR_BEGIN and higher, which indexes into a table of registered + // 128-bit UUIDs. + ble_uuid_any_t efr_ble_uuid; +} bleio_uuid_obj_t; + +void bleio_uuid_construct_from_efr_ble_uuid(bleio_uuid_obj_t *self, + ble_uuid_any_t *efr_ble_uuid); +void bleio_uuid_convert_to_efr_ble_uuid(bleio_uuid_obj_t *self, + ble_uuid_any_t *efr_ble_uuid); + +#endif // MICROPY_INCLUDED_EFR_COMMON_HAL_BLEIO_UUID_H diff --git a/ports/silabs/common-hal/_bleio/__init__.c b/ports/silabs/common-hal/_bleio/__init__.c new file mode 100644 index 000000000000..e7323c779379 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/__init__.c @@ -0,0 +1,402 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/runtime.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/CharacteristicBuffer.h" +#include "shared-bindings/_bleio/PacketBuffer.h" +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" +#include "supervisor/shared/bluetooth/bluetooth.h" +#include "common-hal/_bleio/__init__.h" + +STATIC conn_state_t conn_state; +osMutexId_t bluetooth_connection_mutex_id; +bleio_adapter_obj_t common_hal_bleio_adapter_obj; + +__ALIGNED(4) static uint8_t bluetooth_connection_mutex_cb[osMutexCbSize]; +const osMutexAttr_t bluetooth_connection_mutex_attr = { + .name = "Bluetooth Mutex", + .attr_bits = osMutexRecursive | osMutexPrioInherit, + .cb_mem = bluetooth_connection_mutex_cb, + .cb_size = osMutexCbSize +}; + +void bleio_user_reset() { + // Stop any user scanning or advertising. + common_hal_bleio_adapter_stop_scan(&common_hal_bleio_adapter_obj); + common_hal_bleio_adapter_stop_advertising(&common_hal_bleio_adapter_obj); + + // Maybe start advertising the BLE workflow. + supervisor_bluetooth_background(); +} + +void bleio_reset() { + reset_dynamic_service(); + reset_packet_buffer_list(); + reset_characteristic_buffer_list(); + bleio_adapter_reset(&common_hal_bleio_adapter_obj); + // Set this explicitly to save data. + common_hal_bleio_adapter_obj.base.type = &bleio_adapter_type; + if (!common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) { + return; + } + + supervisor_stop_bluetooth(); + common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false); + supervisor_start_bluetooth(); +} + +void bleio_background(void) { + +} + +void common_hal_bleio_gc_collect(void) { + bleio_adapter_gc_collect(&common_hal_bleio_adapter_obj); +} + +void check_ble_error(int error_code) { + if (error_code == SL_STATUS_OK) { + return; + } + switch (error_code) { + case SL_STATUS_TIMEOUT: + mp_raise_msg(&mp_type_TimeoutError, NULL); + return; + default: + mp_raise_bleio_BluetoothError( + translate("Unknown BLE error: %d"), error_code); + break; + } +} + +void common_hal_bleio_check_connected(uint16_t conn_handle) { + if (conn_handle == BLEIO_HANDLE_INVALID) { + mp_raise_ConnectionError(translate("Not connected")); + } +} + +// Bluetooth stack event handler. +void sl_bt_on_event(sl_bt_msg_t *evt) { + sl_status_t sc = SL_STATUS_OK; + bd_addr address; + uint8_t address_type = 0; + STATIC uint8_t serv_idx = 0; + STATIC uint8_t device_name[16]; + + bleio_connection_internal_t *connection; + bleio_service_obj_t *service; + bleio_characteristic_obj_t *characteristic; + bleio_uuid_obj_t *uuid; + bleio_characteristic_properties_t props; + + switch (SL_BT_MSG_ID(evt->header)) { + + case sl_bt_evt_system_boot_id: + + sc = sl_bt_system_get_identity_address(&address, &address_type); + + snprintf((char *)device_name, 14 + 1, + "CIRCUITPY-%X%X",address.addr[1], address.addr[0]); + sl_bt_gatt_server_write_attribute_value(gattdb_device_name, + 0,14,device_name); + + sc = sl_bt_sm_configure(0x00,sl_bt_sm_io_capability_noinputnooutput); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Sm configure fail")); + } + + sc = sl_bt_sm_set_bondable_mode(1); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError(translate("Set bondable mode fail")); + } + sl_bt_sm_delete_bondings(); + break; + + // This event indicates that a new connection was opened. + case sl_bt_evt_connection_opened_id: + serv_idx = 0; + osMutexAcquire(bluetooth_connection_mutex_id, osWaitForever); + // Device role is Peripheral + if (evt->data.evt_connection_opened.master == 0) { + bleio_connections[0].conn_handle = + evt->data.evt_connection_opened.connection; + bleio_connections[0].connection_obj = mp_const_none; + bleio_connections[0].pair_status = PAIR_PAIRED; + bleio_connections[0].is_central = false; + bleio_connections[0].mtu = 0; + } + + sc = sl_bt_sm_increase_security( + evt->data.evt_connection_opened.connection); + + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError( + translate("Increase security fail.")); + } + osMutexRelease(bluetooth_connection_mutex_id); + break; + + case sl_bt_evt_scanner_legacy_advertisement_report_id: + + set_scan_device_info_on_ble_evt( + evt->data.evt_scanner_legacy_advertisement_report.address, + evt->data.evt_scanner_legacy_advertisement_report.address_type, + evt->data.evt_scanner_legacy_advertisement_report.rssi, + &evt->data.evt_scanner_legacy_advertisement_report.data); + + if (xscan_event != NULL) { + xEventGroupSetBits(xscan_event,1 << 0); + } + break; + + case sl_bt_evt_connection_closed_id: + common_hal_bleio_adapter_remove_connection( + evt->data.evt_connection_closed.connection); + break; + + case sl_bt_evt_system_external_signal_id: + if (evt->data.evt_system_external_signal.extsignals & 1) { + sl_bt_external_signal(0); + } + break; + + case sl_bt_evt_gatt_service_id: + osMutexAcquire(bluetooth_connection_mutex_id, osWaitForever); + connection = bleio_conn_handle_to_connection( + evt->data.evt_gatt_service.connection); + service = m_new_obj(bleio_service_obj_t); + if (NULL == service) { + mp_raise_bleio_BluetoothError( + translate("Create new service obj fail")); + } + service->base.type = &bleio_service_type; + bleio_service_from_connection(service, + bleio_connection_new_from_internal(connection)); + service->is_remote = true; + service->handle = evt->data.evt_gatt_service.service; + uuid = m_new_obj(bleio_uuid_obj_t); + if (NULL == uuid) { + osMutexRelease(bluetooth_connection_mutex_id); + mp_raise_bleio_BluetoothError( + translate("Create new service uuid obj fail")); + break; + } + uuid->base.type = &bleio_uuid_type; + + if (UUID16_LEN == evt->data.evt_gatt_service.uuid.len) { + uuid->efr_ble_uuid.uuid16.value &= 0x0000; + uuid->efr_ble_uuid.uuid16.value + |= evt->data.evt_gatt_service.uuid.data[1]; + + uuid->efr_ble_uuid.uuid16.value = + (uuid->efr_ble_uuid.uuid16.value << 8) + | evt->data.evt_gatt_service.uuid.data[0]; + uuid->efr_ble_uuid.uuid.type = BLE_UUID_TYPE_16; + + } else if (UUID128_LEN == evt->data.evt_gatt_service.uuid.len) { + memcpy(uuid->efr_ble_uuid.uuid128.value, + evt->data.evt_gatt_service.uuid.data, UUID128_LEN); + uuid->efr_ble_uuid.uuid.type = BLE_UUID_TYPE_128; + } + service->uuid = uuid; + mp_obj_list_append(MP_OBJ_FROM_PTR(connection->remote_service_list), + MP_OBJ_FROM_PTR(service)); + conn_state = DISCOVER_SERVICES; + osMutexRelease(bluetooth_connection_mutex_id); + break; + + case sl_bt_evt_gatt_characteristic_id: + osMutexAcquire(bluetooth_connection_mutex_id, osWaitForever); + connection = bleio_conn_handle_to_connection( + evt->data.evt_gatt_characteristic.connection); + service = + MP_OBJ_TO_PTR(connection->remote_service_list->items[serv_idx - 1]); + + characteristic = m_new_obj(bleio_characteristic_obj_t); + if (characteristic == NULL) { + mp_raise_bleio_BluetoothError( + translate("Create new characteristic obj fail.")); + } + + characteristic->base.type = &bleio_characteristic_type; + uuid = m_new_obj(bleio_uuid_obj_t); + if (uuid == NULL) { + mp_raise_bleio_BluetoothError( + translate("Create new characteristic uuid obj fail.")); + break; + } + + uuid->base.type = &bleio_uuid_type; + if (UUID16_LEN == evt->data.evt_gatt_characteristic.uuid.len) { + uuid->efr_ble_uuid.uuid16.value &= 0x0000; + uuid->efr_ble_uuid.uuid16.value + |= evt->data.evt_gatt_characteristic.uuid.data[1]; + + uuid->efr_ble_uuid.uuid16.value = + (uuid->efr_ble_uuid.uuid16.value << 8) + | evt->data.evt_gatt_characteristic.uuid.data[0]; + + uuid->efr_ble_uuid.uuid.type = BLE_UUID_TYPE_16; + } else if ( + UUID128_LEN == evt->data.evt_gatt_characteristic.uuid.len) { + + memcpy(uuid->efr_ble_uuid.uuid128.value, + evt->data.evt_gatt_characteristic.uuid.data, + UUID128_LEN); + uuid->efr_ble_uuid.uuid.type = BLE_UUID_TYPE_128; + } + + props = evt->data.evt_gatt_characteristic.properties; + characteristic->handle = + evt->data.evt_gatt_characteristic.characteristic; + characteristic->props = props; + + common_hal_bleio_characteristic_construct( + characteristic, service, + evt->data.evt_gatt_characteristic.characteristic, uuid, + props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, + 0, false, + mp_const_empty_bytes, + NULL); + + mp_obj_list_append(MP_OBJ_FROM_PTR(service->characteristic_list), + MP_OBJ_FROM_PTR(characteristic)); + osMutexRelease(bluetooth_connection_mutex_id); + break; + + case sl_bt_evt_gatt_procedure_completed_id: + + if (conn_state == DISCOVER_SERVICES + || conn_state == DISCOVER_CHARACTERISTICS) { + + connection = MP_OBJ_TO_PTR( + bleio_conn_handle_to_connection( + evt->data.evt_gatt_procedure_completed.connection)); + + if (connection != NULL + && serv_idx < connection->remote_service_list->len) { + + service = connection->remote_service_list->items[serv_idx]; + sc = sl_bt_gatt_discover_characteristics( + evt->data.evt_gatt_procedure_completed.connection, + service->handle); + + conn_state = DISCOVER_CHARACTERISTICS; + serv_idx++; + + } else { + conn_state = RUNNING; + serv_idx = 0; + if (xdiscovery_event != NULL) { + xEventGroupSetBits(xdiscovery_event,1 << 0); + } + } + } + break; + + case sl_bt_evt_gatt_characteristic_value_id: + + if (characteristic_buffer_on_ble_evt( + evt->data.evt_gatt_characteristic_value.characteristic, + evt->data.evt_gatt_characteristic_value.value.data, + evt->data.evt_gatt_characteristic_value.value.len)) { + } else if (packet_buffer_on_ble_evt( + evt->data.evt_gatt_characteristic_value.characteristic, + evt->data.evt_gatt_characteristic_value.value.data, + evt->data.evt_gatt_characteristic_value.value.len)) { + } else { + + set_characteristic_value_on_ble_evt( + evt->data.evt_gatt_characteristic_value.connection, + evt->data.evt_gatt_characteristic_value.characteristic, + evt->data.evt_gatt_characteristic_value.value.data, + evt->data.evt_gatt_characteristic_value.value.len); + } + + sl_bt_gatt_send_characteristic_confirmation( + evt->data.evt_gatt_characteristic_value.connection); + break; + + case sl_bt_evt_gatt_server_attribute_value_id: + if (characteristic_buffer_on_ble_evt( + evt->data.evt_gatt_server_attribute_value.attribute, + evt->data.evt_gatt_server_attribute_value.value.data, + evt->data.evt_gatt_server_attribute_value.value.len)) { + } else { + packet_buffer_on_ble_evt( + evt->data.evt_gatt_server_attribute_value.attribute, + evt->data.evt_gatt_server_attribute_value.value.data, + evt->data.evt_gatt_server_attribute_value.value.len); + } + break; + + case sl_bt_evt_gatt_server_characteristic_status_id: + break; + + case sl_bt_evt_sm_passkey_display_id: + break; + + case sl_bt_evt_sm_confirm_bonding_id: + sc = sl_bt_sm_bonding_confirm( + evt->data.evt_sm_confirm_bonding.connection,1); + if (SL_STATUS_OK != sc) { + mp_raise_bleio_BluetoothError( + translate("Bonding confirm fail")); + } + break; + + case sl_bt_evt_sm_bonded_id: + break; + + case sl_bt_evt_sm_bonding_failed_id: + break; + + case sl_bt_evt_connection_parameters_id: + switch (evt->data.evt_connection_parameters.security_mode) + { + case connection_mode1_level1: + break; + case connection_mode1_level2: + break; + case connection_mode1_level3: + break; + case connection_mode1_level4: + break; + default: + break; + } + break; + + default: + break; + } +} diff --git a/ports/silabs/common-hal/_bleio/__init__.h b/ports/silabs/common-hal/_bleio/__init__.h new file mode 100644 index 000000000000..63eda59d84f1 --- /dev/null +++ b/ports/silabs/common-hal/_bleio/__init__.h @@ -0,0 +1,80 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_BLE_HCI_COMMON_HAL_INIT_H +#define MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H + +#include +#include +#include "shared-bindings/_bleio/UUID.h" + +#include "gatt_db.h" +#include "sl_status.h" +#include "sl_bt_api.h" +#include "sl_bgapi.h" +#include "sl_bluetooth.h" +#include "sl_bt_rtos_adaptation.h" +#include "sl_cmsis_os2_common.h" +#include + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) +#define SEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000000) / (RESOLUTION)) +#define UNITS_TO_SEC(TIME, RESOLUTION) (((TIME)*(RESOLUTION)) / 1000000) + +// We assume variable length data. 20 bytes max (23 - 3). +#define GATT_MAX_DATA_LENGTH (BT_ATT_DEFAULT_LE_MTU - 3) + +#define BLE_GATT_HANDLE_INVALID 0x0000 +#define BLE_CONN_HANDLE_INVALID 0xFFFF + +// Maximum length for fixed length Attribute Values. +#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) + +// Maximum length for variable length Attribute Values. +#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) + +// Track if the user code modified the BLE state +// to know if we need to undo it on reload. +extern bool vm_used_ble; + +// UUID shared by all CCCD's. +extern bleio_uuid_obj_t cccd_uuid; +extern void bleio_reset(); + +extern osMutexId_t bluetooth_connection_mutex_id; +extern const osMutexAttr_t bluetooth_connection_mutex_attr; +typedef enum { + DISCOVER_SERVICES, + DISCOVER_CHARACTERISTICS, + RUNNING +} conn_state_t; + +#endif // MICROPY_INCLUDED_BLE_HCI_COMMON_HAL_INIT_H diff --git a/ports/silabs/common-hal/analogio/AnalogIn.c b/ports/silabs/common-hal/analogio/AnalogIn.c new file mode 100644 index 000000000000..ecf61ca26860 --- /dev/null +++ b/ports/silabs/common-hal/analogio/AnalogIn.c @@ -0,0 +1,216 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "common-hal/analogio/AnalogIn.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared/runtime/interrupt_char.h" +#include "supervisor/shared/translate/translate.h" +#include "em_cmu.h" +#include "em_iadc.h" + +// Set CLK_ADC to 10MHz +#define CLK_SRC_ADC_FREQ 20000000 // CLK_SRC_ADC +#define CLK_ADC_FREQ 10000000 // CLK_ADC - 10 MHz max in normal mode + +// Number of scan channels +#define NUM_INPUTS 8 + +STATIC uint8_t num_current_input = 0; +STATIC volatile uint16_t scan_result[NUM_INPUTS]; +STATIC volatile uint8_t scan_flag = 0; +STATIC IADC_ScanTable_t init_scan_table = IADC_SCANTABLE_DEFAULT; // Scan Table + +// Construct analogin pin. This function is called when init AnalogIn +void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, + const mcu_pin_obj_t *pin) { + + uint8_t adc_index; + if (self->pin == NULL) { + self->id = NUM_INPUTS + 1; + for (adc_index = 0; adc_index < NUM_INPUTS; adc_index++) { + if (init_scan_table.entries[adc_index].includeInScan == false) { + self->id = adc_index; + self->pin = pin; + init_scan_table.entries[adc_index].includeInScan = true; + init_scan_table.entries[adc_index].negInput = iadcNegInputGnd; + init_scan_table.entries[adc_index].posInput + = IADC_portPinToPosInput(self->pin->port, self->pin->number); + num_current_input++; + break; + } + } + } + + if (self->id == NUM_INPUTS + 1) { + mp_raise_ValueError(translate("ADC busy pin")); + } + + // Declare init structs + IADC_Init_t init = IADC_INIT_DEFAULT; + IADC_AllConfigs_t initAllConfigs = IADC_ALLCONFIGS_DEFAULT; + IADC_InitScan_t initScan = IADC_INITSCAN_DEFAULT; + + CMU_ClockEnable(cmuClock_IADC0, true); + + // Select clock for IADC + CMU_ClockSelectSet(cmuClock_IADCCLK, cmuSelect_FSRCO); + + // Modify init structures and initialize + init.warmup = iadcWarmupKeepWarm; + + // Set the HFSCLK prescale value here + init.srcClkPrescale = IADC_calcSrcClkPrescale(IADC0, CLK_SRC_ADC_FREQ, 0); + + // Configuration 0 is used by both scan and single conversions by + // default. Use internal bandgap as the reference and specify the + // reference voltage in mV. + // Resolution is not configurable directly but is based on the + // selected oversampling ratio (osrHighSpeed), which defaults to + // 2x and generates 12-bit results. + initAllConfigs.configs[0].reference = iadcCfgReferenceInt1V2; + initAllConfigs.configs[0].vRef = 1210; + initAllConfigs.configs[0].osrHighSpeed = iadcCfgOsrHighSpeed2x; + initAllConfigs.configs[0].analogGain = iadcCfgAnalogGain0P5x; + + // Divide CLK_SRC_ADC to set the CLK_ADC frequency + initAllConfigs.configs[0].adcClkPrescale + = IADC_calcAdcClkPrescale(IADC0, + CLK_ADC_FREQ, + 0, + iadcCfgModeNormal, + init.srcClkPrescale); + + + // Set the SCANFIFODVL flag when there are 8 entries in the scan + // FIFO. Note that in this example, the interrupt associated with + // the SCANFIFODVL flag in the IADC_IF register is not used. + // Similarly, the fifoDmaWakeup member of the initScan structure + // is left at its default setting of false, so LDMA service is not + // requested when the FIFO holds the specified number of samples. + initScan.dataValidLevel = _IADC_SCANFIFOCFG_DVL_VALID8; + + // Tag FIFO entry with scan table entry id + initScan.showId = true; + + // Initialize IADC + IADC_init(IADC0, &init, &initAllConfigs); + + // Initialize scan + IADC_initScan(IADC0, &initScan, &init_scan_table); + + if (self->pin->port == gpioPortA) { + GPIO->ABUSALLOC |= GPIO_ABUSALLOC_AEVEN0_ADC0; + GPIO->ABUSALLOC |= GPIO_ABUSALLOC_AODD0_ADC0; + } else if (self->pin->port == gpioPortB) { + GPIO->BBUSALLOC |= GPIO_BBUSALLOC_BEVEN0_ADC0; + GPIO->BBUSALLOC |= GPIO_BBUSALLOC_BODD0_ADC0; + } else { + GPIO->CDBUSALLOC |= GPIO_CDBUSALLOC_CDEVEN0_ADC0; + GPIO->CDBUSALLOC |= GPIO_CDBUSALLOC_CDODD0_ADC0; + } + + // Clear any previous interrupt flags + IADC_clearInt(IADC0, _IADC_IF_MASK); + + // Enable Scan interrupts + IADC_enableInt(IADC0, IADC_IEN_SCANTABLEDONE); + + // Enable ADC interrupts + NVIC_ClearPendingIRQ(IADC_IRQn); + NVIC_EnableIRQ(IADC_IRQn); + + common_hal_mcu_pin_claim(pin); +} + +// Check obj is deinited or not +bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) { + return self->pin == NULL; +} + +// Deinit a analogin obj +void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { + if (num_current_input > 0) { + num_current_input--; + if (num_current_input == 0) { + IADC_reset(IADC0); + } + } + init_scan_table.entries[self->id].includeInScan = false; + init_scan_table.entries[self->id].posInput = iadcPosInputGnd; + scan_result[self->id] = 0; + common_hal_reset_pin(self->pin); + self->pin = NULL; +} + +// IADC Handler to read adc value +void IADC_IRQHandler(void) { + IADC_Result_t result = {0, 0}; + + // While the FIFO count is non-zero + while (IADC_getScanFifoCnt(IADC0)) { + // Pull a scan result from the FIFO + result = IADC_pullScanFifoResult(IADC0); + scan_result[result.id] = result.data; + scan_result[result.id] *= 16; + } + scan_flag = 1; + IADC_clearInt(IADC0, IADC_IF_SCANTABLEDONE); +} + +// Get adc value, use IADC_IRQHandler +// adc value 0 - 65535 +uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { + // Start scan + IADC_command(IADC0, iadcCmdStartScan); + + uint64_t start_ticks = supervisor_ticks_ms64(); + uint64_t current_ticks = start_ticks; + + // Busy-wait until timeout or until we've read enough chars. + while (current_ticks - start_ticks <= 1000) { + current_ticks = supervisor_ticks_ms64(); + if (scan_flag == 1) { + scan_flag = 0; + break; + } + RUN_BACKGROUND_TASKS; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + break; + } + } + + uint16_t ret = scan_result[self->id]; + scan_result[self->id] = 0; + return ret; +} + +// Get adc ref value +float common_hal_analogio_analogin_get_reference_voltage + (analogio_analogin_obj_t *self) { + return 2.42f; +} diff --git a/ports/silabs/common-hal/analogio/AnalogIn.h b/ports/silabs/common-hal/analogio/AnalogIn.h new file mode 100644 index 000000000000..ae6703613207 --- /dev/null +++ b/ports/silabs/common-hal/analogio/AnalogIn.h @@ -0,0 +1,39 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_COMMON_HAL_ANALOGIO_ANALOGIN_H +#define MICROPY_INCLUDED_EFR32_COMMON_HAL_ANALOGIO_ANALOGIN_H + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; + uint8_t id; +} analogio_analogin_obj_t; + +#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_ANALOGIO_ANALOGIN_H diff --git a/ports/silabs/common-hal/analogio/AnalogOut.c b/ports/silabs/common-hal/analogio/AnalogOut.c new file mode 100644 index 000000000000..88b2f53f9ed3 --- /dev/null +++ b/ports/silabs/common-hal/analogio/AnalogOut.c @@ -0,0 +1,167 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "shared-bindings/analogio/AnalogOut.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/translate/translate.h" +#include "common-hal/microcontroller/Pin.h" +#include "em_vdac.h" + +// Set the VDAC to max frequency of 1 MHz +#define CLK_VDAC_FREQ 1000000 + +// List DAC pin and channel supported +mcu_dac_pin_obj_t mcu_dac_list[DAC_BANK_ARRAY_LEN] = { + DAC(VDAC0, 0, FN_VDAC0_CH0, false, 0, &pin_PB0), + DAC(VDAC0, 1, FN_VDAC0_CH1, false, 0, &pin_PB1), + DAC(VDAC1, 0, FN_VDAC1_CH0, false, 0, &pin_PB2), + DAC(VDAC1, 1, FN_VDAC1_CH1, false, 0, &pin_PB3), +}; + +// Construct analogout pin. This function is called when init analogout +void common_hal_analogio_analogout_construct(analogio_analogout_obj_t *self, + const mcu_pin_obj_t *pin) { + uint8_t dac_num = DAC_BANK_ARRAY_LEN; + mcu_dac_pin_obj_t *p_dac; + uint8_t dac_index; + + if (self->dac == NULL) { + for (dac_index = 0; dac_index < dac_num; dac_index++) { + p_dac = &mcu_dac_list[dac_index]; + + if (p_dac->pin == pin) { + self->dac = p_dac; + self->dac->is_used = true; + self->dac->value = 0; + break; + } + } + } + + if (self->dac == NULL) { + mp_raise_ValueError(translate("DAC Device Init Error")); + } + + // Use default settings + VDAC_Init_TypeDef init = VDAC_INIT_DEFAULT; + VDAC_InitChannel_TypeDef initChannel = VDAC_INITCHANNEL_DEFAULT; + + // Use the HFRCOEM23 to clock the VDAC in order to operate in EM3 mode + CMU_ClockSelectSet(self->dac->vdac == VDAC0 ? + cmuClock_VDAC0:cmuClock_VDAC1, cmuSelect_HFRCOEM23); + + // Enable the HFRCOEM23 and VDAC clocks + CMU_ClockEnable(cmuClock_HFRCOEM23, true); + CMU_ClockEnable(self->dac->vdac == VDAC0 ? + cmuClock_VDAC0 : cmuClock_VDAC1, true); + + // Calculate the VDAC clock prescaler value resulting in a 1 MHz VDAC clock + init.prescaler = VDAC_PrescaleCalc(VDAC0, CLK_VDAC_FREQ); + + init.reference = vdacRef2V5; + // Clocking is requested on demand + init.onDemandClk = false; + + // Disable High Capacitance Load mode + initChannel.highCapLoadEnable = false; + + // Use Low Power mode + initChannel.powerMode = vdacPowerModeLowPower; + + // Initialize the VDAC and VDAC channel + VDAC_Init(self->dac->vdac, &init); + + VDAC_InitChannel(self->dac->vdac, &initChannel, self->dac->channel); + + // Enable the VDAC + VDAC_Enable(self->dac->vdac, self->dac->channel, true); + + for (dac_index = 0; dac_index < dac_num; dac_index++) { + p_dac = &mcu_dac_list[dac_index]; + + if (p_dac->vdac == self->dac->vdac && p_dac->pin != self->dac->pin + && p_dac->is_used == true) { + VDAC_InitChannel(p_dac->vdac, &initChannel, p_dac->channel); + VDAC_Enable(p_dac->vdac, p_dac->channel, true); + VDAC_ChannelOutputSet(p_dac->vdac, p_dac->channel, + p_dac->value >> 4); + break; + } + } + + VDAC_ChannelOutputSet(self->dac->vdac, self->dac->channel, 0); + + common_hal_mcu_pin_claim(pin); +} + +// Check obj is deinited or not +bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { + return self->dac == NULL; +} + +// Deinit analogout obj +void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { + uint8_t dac_num = DAC_BANK_ARRAY_LEN; + mcu_dac_pin_obj_t *p_dac; + uint8_t dac_index; + VDAC_Enable(self->dac->vdac, self->dac->channel, false); + + for (dac_index = 0; dac_index < dac_num; dac_index++) { + p_dac = &mcu_dac_list[dac_index]; + if (p_dac->vdac == self->dac->vdac && p_dac->pin != self->dac->pin + && p_dac->is_used == false) { + VDAC_Reset(self->dac->vdac); + } + } + common_hal_reset_pin(self->dac->pin); + + self->dac->value = 0; + self->dac->is_used = false; + self->dac = NULL; +} + +// Set value for dac pin +// dac value 0 - 65535 (0 - 2.5V) +void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, + uint16_t value) { + self->dac->value = value; + // Write the output value to VDAC DATA register + VDAC_ChannelOutputSet(self->dac->vdac, self->dac->channel, value >> 4); +} + +// Function reset dac peripheral +void analogout_reset(void) { + uint8_t dac_index; + mcu_dac_pin_obj_t *p_dac; + for (dac_index = 0; dac_index < DAC_BANK_ARRAY_LEN; dac_index++) { + p_dac = &mcu_dac_list[dac_index]; + if (p_dac->is_used == true) { + VDAC_Reset(p_dac->vdac); + } + } +} diff --git a/ports/silabs/common-hal/analogio/AnalogOut.h b/ports/silabs/common-hal/analogio/AnalogOut.h new file mode 100644 index 000000000000..a8a8e8f9ae3f --- /dev/null +++ b/ports/silabs/common-hal/analogio/AnalogOut.h @@ -0,0 +1,42 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_COMMON_HAL_ANALOGIO_ANALOGOUT_H +#define MICROPY_INCLUDED_EFR32_COMMON_HAL_ANALOGIO_ANALOGOUT_H + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" +#include "peripherals/periph.h" + +typedef struct +{ + mp_obj_base_t base; + mcu_dac_pin_obj_t *dac; +} analogio_analogout_obj_t; + +void analogout_reset(void); + +#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_ANALOGIO_ANALOGOUT_H diff --git a/ports/silabs/common-hal/analogio/__init__.c b/ports/silabs/common-hal/analogio/__init__.c new file mode 100644 index 000000000000..eea58c77d631 --- /dev/null +++ b/ports/silabs/common-hal/analogio/__init__.c @@ -0,0 +1 @@ +// No analogio module functions. diff --git a/ports/silabs/common-hal/board/__init__.c b/ports/silabs/common-hal/board/__init__.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ports/silabs/common-hal/busio/I2C.c b/ports/silabs/common-hal/busio/I2C.c new file mode 100644 index 000000000000..6d858be85e04 --- /dev/null +++ b/ports/silabs/common-hal/busio/I2C.c @@ -0,0 +1,212 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/busio/I2C.h" +#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" + +STATIC I2CSPM_Init_TypeDef i2cspm_init; +STATIC bool in_used = false; +STATIC bool never_reset = false; + +// Reser I2C peripheral +void i2c_reset(void) { + if ((!never_reset) && in_used) { + I2C_Reset(DEFAULT_I2C_PERIPHERAL); + in_used = false; + } +} + +// Construct I2C protocol, this function init i2c peripheral +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t *scl, + const mcu_pin_obj_t *sda, + uint32_t frequency, uint32_t timeout) { + + if ((scl != NULL) && (sda != NULL)) { + if (scl->function_list[ DEFAULT_I2C_PERIPHERAL == I2C1? + FN_I2C1_SCL : FN_I2C0_SCL] == 1 && + scl->function_list[DEFAULT_I2C_PERIPHERAL == I2C1? + FN_I2C1_SDA : FN_I2C0_SDA] == 1) { + self->scl = scl; + self->sda = sda; + self->has_lock = false; + i2cspm_init.sclPort = self->scl->port; + i2cspm_init.sclPin = self->scl->number; + i2cspm_init.sdaPort = self->sda->port; + i2cspm_init.sdaPin = self->sda->number; + i2cspm_init.port = DEFAULT_I2C_PERIPHERAL; + i2cspm_init.i2cRefFreq = 0; + i2cspm_init.i2cMaxFreq = I2C_FREQ_STANDARD_MAX; + i2cspm_init.i2cClhr = i2cClockHLRStandard; + + self->i2cspm = i2cspm_init.port; + I2CSPM_Init(&i2cspm_init); + common_hal_mcu_pin_claim(scl); + common_hal_mcu_pin_claim(sda); + in_used = true; + } else { + mp_raise_ValueError(translate("Hardware busy, try alternative pins")); + } + } else { + raise_ValueError_invalid_pins(); + } +} + +// Never reset I2C obj when reload +void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { + never_reset = true; + common_hal_never_reset_pin(self->sda); + common_hal_never_reset_pin(self->scl); +} + +// Check I2C status, deinited or not +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return self->sda == NULL; +} + +// Deinit i2c obj, reset I2C pin +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return; + } + I2C_Reset(self->i2cspm); + common_hal_reset_pin(self->sda); + common_hal_reset_pin(self->scl); + self->sda = NULL; + self->scl = NULL; + self->i2cspm = NULL; + in_used = false; +} + +// Probe device in I2C bus +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + I2C_TransferSeq_TypeDef seq; + I2C_TransferReturn_TypeDef ret; + uint8_t data = 0; + + seq.addr = addr << 1; + seq.flags = I2C_FLAG_READ; + + seq.buf[0].data = &data; + seq.buf[0].len = 1; + + ret = I2CSPM_Transfer(self->i2cspm, &seq); + if (ret != i2cTransferDone) { + return false; + } + return true; +} + +// Lock I2C bus +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + bool grabbed_lock = false; + + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + + return grabbed_lock; +} + +// Check I2C lock status +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return self->has_lock; +} + +// Unlock I2C bus +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + self->has_lock = false; +} + +// Write data to the device selected by address +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + + I2C_TransferSeq_TypeDef seq; + I2C_TransferReturn_TypeDef ret; + + seq.addr = addr << 1; + seq.flags = I2C_FLAG_WRITE; + + seq.buf[0].data = (uint8_t *)data; + seq.buf[0].len = len; + + ret = I2CSPM_Transfer(self->i2cspm, &seq); + if (ret != i2cTransferDone) { + return MP_EIO; + } + return 0; +} + +// Read into buffer from the device selected by address +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, + uint16_t addr, + uint8_t *data, size_t len) { + + I2C_TransferSeq_TypeDef seq; + I2C_TransferReturn_TypeDef ret; + + seq.addr = addr << 1; + seq.flags = I2C_FLAG_READ; + + seq.buf[0].data = data; + seq.buf[0].len = len; + + ret = I2CSPM_Transfer(self->i2cspm, &seq); + if (ret != i2cTransferDone) { + return MP_EIO; + } + return 0; +} + +// Write the bytes from out_data to the device selected by address, +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, + uint8_t *in_data, size_t in_len) { + + I2C_TransferSeq_TypeDef seq; + I2C_TransferReturn_TypeDef ret; + + seq.addr = addr << 1; + seq.flags = I2C_FLAG_WRITE_READ; + // Select command to issue + seq.buf[0].data = out_data; + seq.buf[0].len = out_len; + // Select location/length of data to be read + seq.buf[1].data = in_data; + seq.buf[1].len = in_len; + + ret = I2CSPM_Transfer(self->i2cspm, &seq); + if (ret != i2cTransferDone) { + return MP_EIO; + } + return 0; +} diff --git a/ports/silabs/common-hal/busio/I2C.h b/ports/silabs/common-hal/busio/I2C.h new file mode 100644 index 000000000000..14f879ee445a --- /dev/null +++ b/ports/silabs/common-hal/busio/I2C.h @@ -0,0 +1,46 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_COMMON_HAL_BUSIO_I2C_H +#define MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_I2C_H + +#include "common-hal/microcontroller/Pin.h" +#include "peripherals/periph.h" +#include "py/obj.h" +#include "em_i2c.h" +#include "sl_i2cspm.h" + +typedef struct { + mp_obj_base_t base; + I2C_TypeDef *i2cspm; + bool has_lock; + const mcu_pin_obj_t *scl; + const mcu_pin_obj_t *sda; +} busio_i2c_obj_t; + +void i2c_reset(void); + +#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_I2C_H diff --git a/ports/silabs/common-hal/busio/SPI.c b/ports/silabs/common-hal/busio/SPI.c new file mode 100644 index 000000000000..a6f3109a328a --- /dev/null +++ b/ports/silabs/common-hal/busio/SPI.c @@ -0,0 +1,252 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/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" + +// Note that any bugs introduced in this file can cause crashes +// at startupfor chips using external SPI flash. + +STATIC SPIDRV_HandleData_t spidrv_eusart_handle; +STATIC SPIDRV_Init_t spidrv_eusart_init = SPIDRV_MASTER_EUSART1; +STATIC bool in_used = false; +STATIC bool never_reset = false; + +// Reset SPI when reload +void spi_reset(void) { + if (!never_reset && in_used) { + SPIDRV_DeInit(&spidrv_eusart_handle); + in_used = false; + } + return; +} + +// Construct SPI protocol, this function init SPI peripheral +void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t *sck, + const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *miso, + bool half_duplex) { + Ecode_t sc = ECODE_OK; + + if (half_duplex) { + mp_raise_NotImplementedError( + translate("Half duplex SPI is not implemented")); + } + + if ((sck != NULL) && (mosi != NULL) && (miso != NULL)) { + if (sck->function_list[FN_EUSART1_SCLK] == 1 + && miso->function_list[FN_EUSART1_RX] == 1 + && mosi->function_list[FN_EUSART1_TX] == 1) { + + self->sck = sck; + self->mosi = mosi; + self->miso = miso; + self->handle = &spidrv_eusart_handle; + self->polarity = 0; + self->phase = 0; + self->bits = 8; + + spidrv_eusart_init.portTx = mosi->port; + spidrv_eusart_init.portRx = miso->port; + spidrv_eusart_init.portClk = sck->port; + spidrv_eusart_init.pinTx = mosi->number; + spidrv_eusart_init.pinRx = miso->number; + spidrv_eusart_init.pinClk = sck->number; + spidrv_eusart_init.bitRate = 1000000; + spidrv_eusart_init.frameLength = 8; + spidrv_eusart_init.dummyTxValue = 0; + spidrv_eusart_init.type = spidrvMaster; + spidrv_eusart_init.bitOrder = spidrvBitOrderMsbFirst; + spidrv_eusart_init.clockMode = spidrvClockMode0; + spidrv_eusart_init.csControl = spidrvCsControlApplication; + spidrv_eusart_init.slaveStartMode = spidrvSlaveStartImmediate; + + sc = SPIDRV_Init(self->handle, &spidrv_eusart_init); + if (sc != ECODE_EMDRV_SPIDRV_OK) { + mp_raise_ValueError(translate("SPI init error")); + } + } else { + mp_raise_ValueError(translate("Hardware busy, try alternative pins")); + } + } else { + raise_ValueError_invalid_pins(); + } + + in_used = true; + common_hal_mcu_pin_claim(sck); + common_hal_mcu_pin_claim(mosi); + common_hal_mcu_pin_claim(miso); +} + +// Never reset SPI when reload +void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { + never_reset = true; + common_hal_never_reset_pin(self->mosi); + common_hal_never_reset_pin(self->miso); + common_hal_never_reset_pin(self->sck); +} + +// Check SPI status, deinited or not +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + return self->sck == NULL; +} + +// Deinit SPI obj +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + + if (common_hal_busio_spi_deinited(self)) { + return; + } + + Ecode_t sc = SPIDRV_DeInit(self->handle); + if (sc != ECODE_EMDRV_SPIDRV_OK) { + mp_raise_RuntimeError(translate("SPI re-init")); + } + + in_used = false; + self->sck = NULL; + self->mosi = NULL; + self->miso = NULL; + self->handle = NULL; + common_hal_reset_pin(self->mosi); + common_hal_reset_pin(self->miso); + common_hal_reset_pin(self->sck); +} + +// Configures the SPI bus. The SPI object must be locked. +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, + uint32_t baudrate, + uint8_t polarity, + uint8_t phase, + uint8_t bits) { + Ecode_t sc; + // This resets the SPI, so check before updating it redundantly + if (baudrate == self->baudrate && polarity == self->polarity + && phase == self->phase && bits == self->bits) { + return true; + } + + sc = SPIDRV_DeInit(self->handle); + if (sc != ECODE_EMDRV_SPIDRV_OK) { + mp_raise_RuntimeError(translate("SPI re-init")); + } + in_used = false; + self->baudrate = baudrate; + self->phase = phase; + self->bits = bits; + self->polarity = polarity; + + spidrv_eusart_init.bitRate = baudrate; + spidrv_eusart_init.frameLength = 8; + if (polarity == 0 && phase == 0) { + spidrv_eusart_init.clockMode = spidrvClockMode0; + } else if (polarity == 0 && phase == 1) { + spidrv_eusart_init.clockMode = spidrvClockMode1; + } else if (polarity == 1 && phase == 0) { + spidrv_eusart_init.clockMode = spidrvClockMode2; + } else if (polarity == 1 && phase == 1) { + spidrv_eusart_init.clockMode = spidrvClockMode3; + } + + sc = SPIDRV_Init(self->handle, &spidrv_eusart_init); + if (sc != ECODE_EMDRV_SPIDRV_OK) { + mp_raise_RuntimeError(translate("SPI re-init")); + } + in_used = true; + return true; +} + +// Lock SPI bus +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + bool grabbed_lock = false; + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + + return grabbed_lock; +} + +// Check SPI lock status +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return self->has_lock; +} + +// Unlock SPI bus +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { + self->has_lock = false; +} + +// Write the data contained in buffer +bool common_hal_busio_spi_write(busio_spi_obj_t *self, + const uint8_t *data, + size_t len) { + + Ecode_t result = SPIDRV_MTransmitB(self->handle, data, len); + return result == ECODE_EMDRV_SPIDRV_OK; +} + +// Read data into buffer +bool common_hal_busio_spi_read(busio_spi_obj_t *self, + uint8_t *data, size_t len, + uint8_t write_value) { + + self->handle->initData.dummyTxValue = write_value; + Ecode_t result = SPIDRV_MReceiveB(self->handle, data, len); + return result == ECODE_EMDRV_SPIDRV_OK; +} + +// Write out the data in data_out +// while simultaneously reading data into data_in +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, + const uint8_t *data_out, + uint8_t *data_in, + size_t len) { + + Ecode_t result = SPIDRV_MTransferB(self->handle, data_out, data_in, len); + return result == ECODE_EMDRV_SPIDRV_OK; +} + +// Get SPI baudrate +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t *self) { + return self->baudrate; +} + +// Get SPI phase +uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t *self) { + return self->phase; +} + +// Get SPI polarity +uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t *self) { + return self->polarity; +} diff --git a/ports/silabs/common-hal/busio/SPI.h b/ports/silabs/common-hal/busio/SPI.h new file mode 100644 index 000000000000..f81316cda187 --- /dev/null +++ b/ports/silabs/common-hal/busio/SPI.h @@ -0,0 +1,52 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_COMMON_HAL_BUSIO_SPI_H +#define MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_SPI_H + +#include "common-hal/microcontroller/Pin.h" +#include "peripherals/periph.h" +#include "py/obj.h" +#include "spidrv.h" + +typedef struct { + mp_obj_base_t base; + SPIDRV_Handle_t handle; + bool has_lock; + const mcu_pin_obj_t *sck; + const mcu_pin_obj_t *mosi; + const mcu_pin_obj_t *miso; + const mcu_pin_obj_t *nss; + uint32_t baudrate; + uint16_t prescaler; + uint8_t polarity; + uint8_t phase; + uint8_t bits; +} busio_spi_obj_t; + +void spi_reset(void); + +#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_SPI_H diff --git a/ports/silabs/common-hal/busio/UART.c b/ports/silabs/common-hal/busio/UART.c new file mode 100644 index 000000000000..8b1883d90692 --- /dev/null +++ b/ports/silabs/common-hal/busio/UART.c @@ -0,0 +1,299 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/UART.h" + +#include "mpconfigport.h" +#include "shared/readline/readline.h" +#include "shared/runtime/interrupt_char.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate/translate.h" + +#define UARTDRV_USART_BUFFER_SIZE 6 + +// Define RX and TX buffer queues +DEFINE_BUF_QUEUE(UARTDRV_USART_BUFFER_SIZE, uartdrv_usart_rx_buffer); +DEFINE_BUF_QUEUE(UARTDRV_USART_BUFFER_SIZE, uartdrv_usart_tx_buffer); + +STATIC UARTDRV_HandleData_t uartdrv_usart_handle; +STATIC UARTDRV_InitUart_t uartdrv_usart_init; +STATIC bool in_used = false; +STATIC bool never_reset = false; +busio_uart_obj_t *context; +volatile Ecode_t errflag; // Used to restart read halts + +// Reset uart peripheral +void uart_reset(void) { + if ((!never_reset) && in_used) { + if (UARTDRV_DeInit(&uartdrv_usart_handle) != ECODE_EMDRV_UARTDRV_OK) { + mp_raise_ValueError(translate("UART Deinit fail")); + } + in_used = false; + } +} + +// Construct uart obj +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, + const mcu_pin_obj_t *rs485_dir, + bool rs485_invert, + uint32_t baudrate, + uint8_t bits, + busio_uart_parity_t parity, + uint8_t stop, + mp_float_t timeout, + uint16_t receiver_buffer_size, + byte *receiver_buffer, + bool sigint_enabled) { + + if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) + || (rs485_invert == true)) { + mp_raise_NotImplementedError(translate("RS485")); + } + + if ((tx != NULL) && (rx != NULL)) { + if (tx->function_list[FN_USART0_TX] == 1 + && tx->function_list[FN_USART0_RX] == 1) { + + self->handle = &uartdrv_usart_handle; + self->baudrate = baudrate; + self->tx = tx; + self->rx = rx; + self->sigint_enabled = sigint_enabled; + self->timeout_ms = timeout * 1000; + uartdrv_usart_init.port = USART0; + uartdrv_usart_init.baudRate = baudrate; + uartdrv_usart_init.txPort = tx->port; + uartdrv_usart_init.rxPort = rx->port; + uartdrv_usart_init.txPin = tx->number; + uartdrv_usart_init.rxPin = rx->number; + uartdrv_usart_init.uartNum = 0; + uartdrv_usart_init.stopBits = (stop >= 2) ? usartStopbits2 + :usartStopbits1; + uartdrv_usart_init.parity = (USART_Parity_TypeDef)parity; + uartdrv_usart_init.oversampling = usartOVS4; + uartdrv_usart_init.mvdis = false; + uartdrv_usart_init.fcType = uartdrvFlowControlNone; + + uartdrv_usart_init.rxQueue = (UARTDRV_Buffer_FifoQueue_t *) + &uartdrv_usart_rx_buffer; + uartdrv_usart_init.txQueue = (UARTDRV_Buffer_FifoQueue_t *) + &uartdrv_usart_tx_buffer; + + if (UARTDRV_InitUart(self->handle,&uartdrv_usart_init) + != ECODE_EMDRV_UARTDRV_OK) { + mp_raise_RuntimeError(translate("UART init")); + } + common_hal_mcu_pin_claim(tx); + common_hal_mcu_pin_claim(rx); + in_used = true; + + // Use the provided buffer when given. + if (receiver_buffer != NULL) { + ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); + } else { + if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { + m_malloc_fail(receiver_buffer_size); + } + } + errflag = ECODE_EMDRV_UARTDRV_OK; + context = self; + + } else { + mp_raise_ValueError(translate("Hardware busy, try alternative pins")); + } + + } else { + raise_ValueError_invalid_pins(); + } +} + +// Never reset UART obj when reload +void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) { + never_reset = true; + common_hal_never_reset_pin(self->tx); + common_hal_never_reset_pin(self->rx); + return; +} + +// Check Uart status, deinited or not +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + return self->handle == NULL; +} + +// Deinit uart obj +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + if (common_hal_busio_uart_deinited(self)) { + return; + } + + if (UARTDRV_DeInit(self->handle) != ECODE_EMDRV_UARTDRV_OK) { + mp_raise_RuntimeError(translate("UART de-init")); + } + + common_hal_reset_pin(self->rx); + common_hal_reset_pin(self->tx); + self->tx = NULL; + self->rx = NULL; + self->handle = NULL; + in_used = false; +} + +// Callback function for UARTDRV_Receive +void UARTDRV_Receive_Callback(UARTDRV_Handle_t *handle, + Ecode_t transferStatus, + uint8_t *data, + UARTDRV_Count_t transferCount) { + (void)handle; + (void)transferStatus; + (void)data; + (void)transferCount; + + taskENTER_CRITICAL(); + ringbuf_put_n(&context->ringbuf, &context->rx_char, 1); + taskEXIT_CRITICAL(); + errflag = UARTDRV_Receive(context->handle,&context->rx_char,1, + (UARTDRV_Callback_t)UARTDRV_Receive_Callback); + if (context->sigint_enabled) { + if (context->rx_char == CHAR_CTRL_C) { + common_hal_busio_uart_clear_rx_buffer(context); + mp_sched_keyboard_interrupt(); + } + } +} + +// 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. +// If no bytes are read, return None. +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, + size_t len, int *errcode) { + + uint64_t start_ticks = supervisor_ticks_ms64(); + if (len == 0) { + // Nothing to read. + return 0; + } + errflag = ECODE_EMDRV_UARTDRV_WAITING; + // Wait for all bytes received or timeout, same as nrf + while ((ringbuf_num_filled(&self->ringbuf) < len) && + (supervisor_ticks_ms64() - start_ticks < self->timeout_ms)) { + + RUN_BACKGROUND_TASKS; + // restart if it failed in the callback + if (errflag != ECODE_EMDRV_UARTDRV_OK) { + errflag = UARTDRV_Receive(self->handle,&self->rx_char,1, + (UARTDRV_Callback_t)UARTDRV_Receive_Callback); + } + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + return 0; + } + } + + taskENTER_CRITICAL(); + // Copy as much received data as available, up to len bytes. + size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len); + taskEXIT_CRITICAL(); + + if (rx_bytes == 0) { + *errcode = EAGAIN; + return MP_STREAM_ERROR; + } + return rx_bytes; +} + +// Write the buffer of bytes to the bus. +size_t common_hal_busio_uart_write(busio_uart_obj_t *self, + const uint8_t *data, + size_t len, + int *errcode) { + + Ecode_t ret = UARTDRV_TransmitB(self->handle, (uint8_t *)data, len); + if (ret != ECODE_EMDRV_UARTDRV_OK) { + mp_raise_RuntimeError(translate("UART write")); + } + return len; +} + +// Get uart baudrate value +uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { + return self->baudrate; +} + +// Set uart baudrate value +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, + uint32_t baudrate) { + + // Don't reset if it's the same value + if (baudrate == self->baudrate) { + return; + } + uartdrv_usart_init.baudRate = baudrate; + if (UARTDRV_InitUart(self->handle, &uartdrv_usart_init) + != ECODE_EMDRV_UARTDRV_OK) { + mp_raise_RuntimeError(translate("UART re-init")); + } +} + +// Get timeout for receive +mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) { + return (mp_float_t)(self->timeout_ms / 1000.0f); +} + +// Set timeout for receive +void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, + mp_float_t timeout) { + self->timeout_ms = timeout * 1000; +} + +// Query characters available to read +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { + return ringbuf_num_filled(&self->ringbuf); +} + +// Clear rx buffer +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { + taskENTER_CRITICAL(); + ringbuf_clear(&self->ringbuf); + taskEXIT_CRITICAL(); + self->handle->rxQueue->head = 0; + self->handle->rxQueue->tail = 0; + self->handle->rxQueue->used = 0; +} + +// Check uart bus ready to transmit or not +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { + return UARTDRV_GetTransmitDepth(self->handle) == 0; +} diff --git a/ports/silabs/common-hal/busio/UART.h b/ports/silabs/common-hal/busio/UART.h new file mode 100644 index 000000000000..50d43d5cd674 --- /dev/null +++ b/ports/silabs/common-hal/busio/UART.h @@ -0,0 +1,52 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_COMMON_HAL_BUSIO_UART_H +#define MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_UART_H + +#include "common-hal/microcontroller/Pin.h" +#include "peripherals/periph.h" +#include "py/obj.h" +#include "py/ringbuf.h" +#include "uartdrv.h" +#include "FreeRTOS.h" +#include "task.h" + +typedef struct { + mp_obj_base_t base; + UARTDRV_Handle_t handle; + const mcu_pin_obj_t *rx; + const mcu_pin_obj_t *tx; + ringbuf_t ringbuf; + uint8_t rx_char; + uint32_t baudrate; + uint32_t timeout_ms; + bool sigint_enabled; +} busio_uart_obj_t; + +void uart_reset(void); + +#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_UART_H diff --git a/ports/silabs/common-hal/busio/__init__.c b/ports/silabs/common-hal/busio/__init__.c new file mode 100644 index 000000000000..41761b6743ae --- /dev/null +++ b/ports/silabs/common-hal/busio/__init__.c @@ -0,0 +1 @@ +// No busio module functions. diff --git a/ports/silabs/common-hal/digitalio/DigitalInOut.c b/ports/silabs/common-hal/digitalio/DigitalInOut.c new file mode 100644 index 000000000000..0f266bb41e74 --- /dev/null +++ b/ports/silabs/common-hal/digitalio/DigitalInOut.c @@ -0,0 +1,159 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "py/runtime.h" +#include "supervisor/shared/translate/translate.h" + +// Never reset pin when reload +void common_hal_digitalio_digitalinout_never_reset( + digitalio_digitalinout_obj_t *self) { + common_hal_never_reset_pin(self->pin); +} + +// Construct Digitalio obj +digitalinout_result_t common_hal_digitalio_digitalinout_construct( + digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin) { + common_hal_mcu_pin_claim(pin); + self->pin = pin; + GPIO_PinModeSet(pin->port, pin->number, gpioModeInput, 1); + return DIGITALINOUT_OK; +} + +// Check Digitalio status, deinited or not +bool common_hal_digitalio_digitalinout_deinited( + digitalio_digitalinout_obj_t *self) { + return self->pin == NULL; +} + +// Deinit Digitalio obj +void common_hal_digitalio_digitalinout_deinit( + digitalio_digitalinout_obj_t *self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + return; + } + common_hal_reset_pin(self->pin); + self->pin = NULL; +} + +// Switch pin to input +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( + digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + if (pull == PULL_NONE) { + GPIO_PinModeSet(self->pin->port,self->pin->number,gpioModeInput,1); + } else if (pull == PULL_UP) { + GPIO_PinModeSet(self->pin->port,self->pin->number,gpioModeInputPull,1); + } else { + GPIO_PinModeSet(self->pin->port,self->pin->number,gpioModeInputPull,0); + } + return DIGITALINOUT_OK; +} + +// Switch pin to output +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( + digitalio_digitalinout_obj_t *self, bool value, + digitalio_drive_mode_t drive_mode) { + if (drive_mode == DRIVE_MODE_OPEN_DRAIN) { + GPIO_PinModeSet(self->pin->port,self->pin->number, + gpioModeWiredAnd,value); + } else { + GPIO_PinModeSet(self->pin->port,self->pin->number, + gpioModePushPull,value); + } + + if (value) { + GPIO_PinOutSet(self->pin->port, self->pin->number); + } else { + GPIO_PinOutClear(self->pin->port, self->pin->number); + } + + return DIGITALINOUT_OK; +} + +// Get direction of the pin +digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( + digitalio_digitalinout_obj_t *self) { + GPIO_Mode_TypeDef mode = GPIO_PinModeGet(self->pin->port,self->pin->number); + if (mode >= gpioModePushPull) { + return DIRECTION_OUTPUT; + } + return DIRECTION_INPUT; +} + +// Set digital logic level of the pin +void common_hal_digitalio_digitalinout_set_value( + digitalio_digitalinout_obj_t *self, bool value) { + if (value) { + GPIO_PinOutSet(self->pin->port, self->pin->number); + } else { + GPIO_PinOutClear(self->pin->port, self->pin->number); + } +} + +// The digital logic level of the pin +bool common_hal_digitalio_digitalinout_get_value( + digitalio_digitalinout_obj_t *self) { + if (common_hal_digitalio_digitalinout_get_direction(self) + == DIRECTION_OUTPUT) { + return GPIO_PinOutGet(self->pin->port, self->pin->number); + } + return GPIO_PinInGet(self->pin->port, self->pin->number); +} + +// Set drive mode +digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode( + digitalio_digitalinout_obj_t *self, + digitalio_drive_mode_t drive_mode) { + if (drive_mode == DRIVE_MODE_OPEN_DRAIN) { + GPIO_PinModeSet(self->pin->port,self->pin->number,gpioModeWiredAnd,1); + } else { + GPIO_PinModeSet(self->pin->port,self->pin->number,gpioModePushPull,1); + } + return DIGITALINOUT_OK; +} + +// Get drive mode +digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( + digitalio_digitalinout_obj_t *self) { + GPIO_Mode_TypeDef mode = GPIO_PinModeGet(self->pin->port,self->pin->number); + if (mode >= gpioModeWiredAnd) { + return DRIVE_MODE_OPEN_DRAIN; + } + return DRIVE_MODE_PUSH_PULL; +} + +// Set pull direction +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( + digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + return DIGITALINOUT_OK; +} + +// Get pull direction +digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( + digitalio_digitalinout_obj_t *self) { + return PULL_NONE; +} diff --git a/ports/silabs/common-hal/digitalio/DigitalInOut.h b/ports/silabs/common-hal/digitalio/DigitalInOut.h new file mode 100644 index 000000000000..23a5a235378f --- /dev/null +++ b/ports/silabs/common-hal/digitalio/DigitalInOut.h @@ -0,0 +1,39 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_COMMON_HAL_DIGITALIO_DIGITALINOUT_H +#define MICROPY_INCLUDED_EFR32_COMMON_HAL_DIGITALIO_DIGITALINOUT_H + +#include "common-hal/microcontroller/Pin.h" +#include "em_gpio.h" + +typedef struct +{ + mp_obj_base_t base; + const mcu_pin_obj_t *pin; +} digitalio_digitalinout_obj_t; + +#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_DIGITALIO_DIGITALINOUT_H diff --git a/ports/silabs/common-hal/digitalio/__init__.c b/ports/silabs/common-hal/digitalio/__init__.c new file mode 100644 index 000000000000..20fad459593a --- /dev/null +++ b/ports/silabs/common-hal/digitalio/__init__.c @@ -0,0 +1 @@ +// No digitalio module functions. diff --git a/ports/silabs/common-hal/microcontroller/Pin.c b/ports/silabs/common-hal/microcontroller/Pin.c new file mode 100644 index 000000000000..24141522df73 --- /dev/null +++ b/ports/silabs/common-hal/microcontroller/Pin.c @@ -0,0 +1,115 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/digitalio/DigitalInOut.h" +#include "py/mphal.h" +#include "em_gpio.h" + +#define GPIO_PORT_COUNT (MP_ARRAY_SIZE(ports)) + +GPIO_Port_TypeDef ports[] = {gpioPortA, gpioPortB, gpioPortC, gpioPortD}; +STATIC uint16_t claimed_pins[GPIO_PORT_COUNT]; +STATIC uint16_t __ALIGNED(4) never_reset_pins[GPIO_PORT_COUNT]; + +// Reset all pin except pin in never_reset_pins list +void reset_all_pins(void) { + + uint8_t pin_num; + uint8_t port_num; + // Reset claimed pins + for (pin_num = 0; pin_num < GPIO_PORT_COUNT; pin_num++) { + claimed_pins[pin_num] = never_reset_pins[pin_num]; + } + + for (port_num = 0; port_num < GPIO_PORT_COUNT; port_num++) { + for (pin_num = 0; pin_num < 16; pin_num++) { + if (GPIO_PORT_PIN_VALID(ports[port_num],pin_num) + && !(never_reset_pins[port_num] >> pin_num & 0x01)) { + GPIO_PinModeSet(ports[port_num], pin_num,gpioModeInput,1); + } + } + } +} + +// Mark pin as free and return it to a quiescent state. +void reset_pin_number(uint8_t pin_port, uint8_t pin_number) { + // Clear claimed bit & reset + claimed_pins[pin_port] &= ~(1 << pin_number); + never_reset_pins[pin_port] &= ~(1 << pin_number); + GPIO_PinModeSet(pin_port, pin_number, gpioModeInput, 1); +} + +// Mark pin as never reset +void never_reset_pin_number(uint8_t pin_port, uint8_t pin_number) { + never_reset_pins[pin_port] |= 1 << pin_number; + // Make sure never reset pins are also always claimed + claimed_pins[pin_port] |= 1 << pin_number; +} + +// Mark pin as never reset +void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) { + never_reset_pin_number(pin->port, pin->number); +} + +// Reset pin +void common_hal_reset_pin(const mcu_pin_obj_t *pin) { + if (pin == NULL) { + return; + } + reset_pin_number(pin->port, pin->number); +} + +// Mark pin as in used +void claim_pin(uint8_t pin_port, uint8_t pin_number) { + // Set bit in claimed_pins bitmask. + claimed_pins[pin_port] |= 1 << pin_number; +} + +// Check pin status free or in used +bool pin_number_is_free(uint8_t pin_port, uint8_t pin_number) { + return !(claimed_pins[pin_port] & (1 << pin_number)); +} + +// Check pin status free or in used +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { + return pin_number_is_free(pin->port, pin->number); +} + +// Calculate pin number for a pin obj +uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t *pin) { + return pin->port * 16 + pin->number; +} + +// Mark pin is in used +void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) { + claim_pin(pin->port, pin->number); +} + +// Reset pin by pin number +void common_hal_mcu_pin_reset_number(uint8_t pin_no) { + reset_pin_number(pin_no / 16, pin_no % 16); +} diff --git a/ports/silabs/common-hal/microcontroller/Pin.h b/ports/silabs/common-hal/microcontroller/Pin.h new file mode 100644 index 000000000000..20bf8a82f2b8 --- /dev/null +++ b/ports/silabs/common-hal/microcontroller/Pin.h @@ -0,0 +1,36 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_COMMON_HAL_MICROCONTROLLER_PIN_H +#define MICROPY_INCLUDED_EFR32_COMMON_HAL_MICROCONTROLLER_PIN_H + +#include "py/mphal.h" + +#include "peripherals/pins.h" + +void reset_all_pins(void); + +#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_MICROCONTROLLER_PIN_H diff --git a/ports/silabs/common-hal/microcontroller/Processor.c b/ports/silabs/common-hal/microcontroller/Processor.c new file mode 100644 index 000000000000..1414a28df63a --- /dev/null +++ b/ports/silabs/common-hal/microcontroller/Processor.c @@ -0,0 +1,67 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/runtime.h" + +#if CIRCUITPY_ALARM +#include "common-hal/alarm/__init__.h" +#endif +#include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" +#include "supervisor/shared/translate/translate.h" +#include "tempdrv.h" +#include "em_system.h" +#include "em_cmu.h" + +float common_hal_mcu_processor_get_temperature(void) { + TEMPDRV_Init(); + return (float)TEMPDRV_GetTemp(); +} + +float common_hal_mcu_processor_get_voltage(void) { + // xG24 does not have built-in direct reading of processor voltage + // Have Only 1 of IADC, already used for analogio module + return 3.3f; +} + +uint32_t common_hal_mcu_processor_get_frequency(void) { + return CMU_ClockFreqGet(cmuClock_HCLK); +} + +void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { + + size_t byte_index; + uint64_t serial = SYSTEM_GetUnique(); + for (byte_index = 0; byte_index < sizeof(uint64_t); byte_index++) { + raw_id[byte_index] = (serial >> (64 - ((byte_index + 1) * 8))) & 0xff; + } +} + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + return RESET_REASON_UNKNOWN; +} diff --git a/ports/silabs/common-hal/microcontroller/Processor.h b/ports/silabs/common-hal/microcontroller/Processor.h new file mode 100644 index 000000000000..7faea68da3b7 --- /dev/null +++ b/ports/silabs/common-hal/microcontroller/Processor.h @@ -0,0 +1,39 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#define MICROPY_INCLUDED_EFR32_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H + +#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 12 + +#include "py/obj.h" + +typedef struct +{ + mp_obj_base_t base; +} mcu_processor_obj_t; + +#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H diff --git a/ports/silabs/common-hal/microcontroller/__init__.c b/ports/silabs/common-hal/microcontroller/__init__.c new file mode 100644 index 000000000000..b1472fcf4372 --- /dev/null +++ b/ports/silabs/common-hal/microcontroller/__init__.c @@ -0,0 +1,223 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/microcontroller/Processor.h" + +#include "shared-bindings/nvm/ByteArray.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Processor.h" + +#include "supervisor/filesystem.h" +#include "supervisor/shared/safe_mode.h" +#include "em_chip.h" +#include "em_core.h" +#include "sl_udelay.h" + +void common_hal_mcu_delay_us(uint32_t delay) { + sl_udelay_wait(delay); +} + +void common_hal_mcu_disable_interrupts(void) { + CORE_CriticalDisableIrq(); +} + +void common_hal_mcu_enable_interrupts(void) { + CORE_CriticalEnableIrq(); +} + +void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { + if (runmode == RUNMODE_SAFE_MODE) { + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); + } +} + +void common_hal_mcu_reset(void) { + filesystem_flush(); // TODO: implement as part of flash improvements + CHIP_Reset(); +} + +// The singleton microcontroller.Processor object, bound to microcontroller.cpu +// It currently only has properties, and no state. +const mcu_processor_obj_t common_hal_mcu_processor_obj = { + .base = { + .type = &mcu_processor_type, + }, +}; + +#if CIRCUITPY_INTERNAL_NVM_SIZE > 0 +// The singleton nvm.ByteArray object. +const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = { + .base = { + .type = &nvm_bytearray_type, + }, + .len = NVM_BYTEARRAY_BUFFER_SIZE +}; + +#endif + +#if CIRCUITPY_WATCHDOG +// The singleton watchdog.WatchDogTimer object. +watchdog_watchdogtimer_obj_t common_hal_mcu_watchdogtimer_obj = { + .base = { + .type = &watchdog_watchdogtimer_type, + }, + .timeout = 0.0f, + .mode = WATCHDOGMODE_NONE, +}; +#endif + +// This maps MCU pin names to pin objects. +const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { + + #ifdef GPIO_PA0_EXISTS + { MP_ROM_QSTR(MP_QSTR_PA0), MP_ROM_PTR(&pin_PA0) }, + #endif + + #ifdef GPIO_PA1_EXISTS + { MP_ROM_QSTR(MP_QSTR_PA1), MP_ROM_PTR(&pin_PA1) }, + #endif + + #ifdef GPIO_PA2_EXISTS + { MP_ROM_QSTR(MP_QSTR_PA2), MP_ROM_PTR(&pin_PA2) }, + #endif + + #ifdef GPIO_PA3_EXISTS + { MP_ROM_QSTR(MP_QSTR_PA3), MP_ROM_PTR(&pin_PA3) }, + #endif + + #ifdef GPIO_PA4_EXISTS + { MP_ROM_QSTR(MP_QSTR_PA4), MP_ROM_PTR(&pin_PA4) }, + #endif + + #ifdef GPIO_PA5_EXISTS + { MP_ROM_QSTR(MP_QSTR_PA5), MP_ROM_PTR(&pin_PA5) }, + #endif + #ifdef GPIO_PA6_EXISTS + { MP_ROM_QSTR(MP_QSTR_PA6), MP_ROM_PTR(&pin_PA6) }, + #endif + + #ifdef GPIO_PA7_EXISTS + { MP_ROM_QSTR(MP_QSTR_PA7), MP_ROM_PTR(&pin_PA7) }, + #endif + + #ifdef GPIO_PA8_EXISTS + { MP_ROM_QSTR(MP_QSTR_PA8), MP_ROM_PTR(&pin_PA8) }, + #endif + + #ifdef GPIO_PB0_EXISTS + { MP_ROM_QSTR(MP_QSTR_PB0), MP_ROM_PTR(&pin_PB0) }, + #endif + + #ifdef GPIO_PB1_EXISTS + { MP_ROM_QSTR(MP_QSTR_PB1), MP_ROM_PTR(&pin_PB1) }, + #endif + + #ifdef GPIO_PB2_EXISTS + { MP_ROM_QSTR(MP_QSTR_PB2), MP_ROM_PTR(&pin_PB2) }, + #endif + + #ifdef GPIO_PB3_EXISTS + { MP_ROM_QSTR(MP_QSTR_PB3), MP_ROM_PTR(&pin_PB3) }, + #endif + + #ifdef GPIO_PB4_EXISTS + { MP_ROM_QSTR(MP_QSTR_PB4), MP_ROM_PTR(&pin_PB4) }, + #endif + + #ifdef GPIO_PB5_EXISTS + { MP_ROM_QSTR(MP_QSTR_PB5), MP_ROM_PTR(&pin_PB5) }, + #endif + + #ifdef GPIO_PC0_EXISTS + { MP_ROM_QSTR(MP_QSTR_PC0), MP_ROM_PTR(&pin_PC0) }, + #endif + + #ifdef GPIO_PC1_EXISTS + { MP_ROM_QSTR(MP_QSTR_PC1), MP_ROM_PTR(&pin_PC1) }, + #endif + + #ifdef GPIO_PC2_EXISTS + { MP_ROM_QSTR(MP_QSTR_PC2), MP_ROM_PTR(&pin_PC2) }, + #endif + + #ifdef GPIO_PC3_EXISTS + { MP_ROM_QSTR(MP_QSTR_PC3), MP_ROM_PTR(&pin_PC3) }, + #endif + + #ifdef GPIO_PC4_EXISTS + { MP_ROM_QSTR(MP_QSTR_PC4), MP_ROM_PTR(&pin_PC4) }, + #endif + + #ifdef GPIO_PC5_EXISTS + { MP_ROM_QSTR(MP_QSTR_PC5), MP_ROM_PTR(&pin_PC5) }, + #endif + + #ifdef GPIO_PC6_EXISTS + { MP_ROM_QSTR(MP_QSTR_PC6), MP_ROM_PTR(&pin_PC6) }, + #endif + + #ifdef GPIO_PC7_EXISTS + { MP_ROM_QSTR(MP_QSTR_PC7), MP_ROM_PTR(&pin_PC7) }, + #endif + #ifdef GPIO_PC8_EXISTS + { MP_ROM_QSTR(MP_QSTR_PC8), MP_ROM_PTR(&pin_PC8) }, + #endif + + #ifdef GPIO_PC9_EXISTS + { MP_ROM_QSTR(MP_QSTR_PC9), MP_ROM_PTR(&pin_PC9) }, + #endif + + #ifdef GPIO_PD0_EXISTS + { MP_ROM_QSTR(MP_QSTR_PD0), MP_ROM_PTR(&pin_PD0) }, + #endif + + #ifdef GPIO_PD1_EXISTS + { MP_ROM_QSTR(MP_QSTR_PD1), MP_ROM_PTR(&pin_PD1) }, + #endif + + #ifdef GPIO_PD2_EXISTS + { MP_ROM_QSTR(MP_QSTR_PD2), MP_ROM_PTR(&pin_PD2) }, + #endif + + #ifdef GPIO_PD3_EXISTS + { MP_ROM_QSTR(MP_QSTR_PD3), MP_ROM_PTR(&pin_PD3) }, + #endif + + #ifdef GPIO_PD4_EXISTS + { MP_ROM_QSTR(MP_QSTR_PD4), MP_ROM_PTR(&pin_PD4) }, + #endif + + #ifdef GPIO_PD5_EXISTS + { MP_ROM_QSTR(MP_QSTR_PD5), MP_ROM_PTR(&pin_PD5) } + #endif +}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table); diff --git a/ports/silabs/common-hal/nvm/ByteArray.c b/ports/silabs/common-hal/nvm/ByteArray.c new file mode 100644 index 000000000000..e94ed9198d63 --- /dev/null +++ b/ports/silabs/common-hal/nvm/ByteArray.c @@ -0,0 +1,98 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/nvm/ByteArray.h" +#include "supervisor/shared/stack.h" + +#include "py/runtime.h" +#include "supervisor/shared/translate/translate.h" + +#include "nvm3_default.h" +#include "nvm3_default_config.h" + +uint8_t nvm_array[NVM_BYTEARRAY_BUFFER_SIZE]; +STATIC bool isInitialized = false; +#define NVM_KEY 98 + +// Get length of nvm bytearray +uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) { + return self->len; +} + +uint32_t nvm3_read(nvm_bytearray_obj_t *self) { + uint32_t type; + Ecode_t err; + size_t len; + + if (isInitialized == false) { + nvm3_initDefault(); + isInitialized = true; + } + err = nvm3_getObjectInfo(nvm3_defaultHandle, NVM_KEY, &type, &len); + if (err != ECODE_NVM3_OK || type != NVM3_OBJECTTYPE_DATA + || len != NVM_BYTEARRAY_BUFFER_SIZE) { + + nvm3_deleteObject(nvm3_defaultHandle, NVM_KEY); + nvm3_writeData(nvm3_defaultHandle, NVM_KEY, nvm_array, + NVM_BYTEARRAY_BUFFER_SIZE); + } + + err = nvm3_readData(nvm3_defaultHandle, NVM_KEY, nvm_array, + NVM_BYTEARRAY_BUFFER_SIZE); + + return err; +} + +// Write n bytes to nvm bytearray +bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self, + uint32_t start_index, uint8_t *values, + uint32_t len) { + Ecode_t err; + err = nvm3_read(self); + + if (err != ECODE_NVM3_OK) { + mp_raise_RuntimeError(translate("NVM3 read false")); + } + // Set bytes in buffer + memmove(nvm_array + start_index, values, len); + + err = nvm3_writeData(nvm3_defaultHandle, NVM_KEY, nvm_array, + NVM_BYTEARRAY_BUFFER_SIZE); + + if (err != ECODE_NVM3_OK) { + mp_raise_RuntimeError(translate("NVM3 write false")); + } + + return true; +} + +// Read n bytes from nvm bytearray +void common_hal_nvm_bytearray_get_bytes(nvm_bytearray_obj_t *self, + uint32_t start_index, + uint32_t len, uint8_t *values) { + nvm3_read(self); + memcpy(values, nvm_array + start_index, len); +} diff --git a/ports/silabs/common-hal/nvm/ByteArray.h b/ports/silabs/common-hal/nvm/ByteArray.h new file mode 100644 index 000000000000..ac609e47eb9c --- /dev/null +++ b/ports/silabs/common-hal/nvm/ByteArray.h @@ -0,0 +1,37 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_COMMON_HAL_NVM_BYTEARRAY_H +#define MICROPY_INCLUDED_EFR32_COMMON_HAL_NVM_BYTEARRAY_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint32_t len; +} nvm_bytearray_obj_t; + +#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_NVM_BYTEARRAY_H diff --git a/ports/silabs/common-hal/nvm/__init__.c b/ports/silabs/common-hal/nvm/__init__.c new file mode 100644 index 000000000000..1b702a1584d2 --- /dev/null +++ b/ports/silabs/common-hal/nvm/__init__.c @@ -0,0 +1 @@ +// No nvm module functions. diff --git a/ports/silabs/common-hal/os/__init__.c b/ports/silabs/common-hal/os/__init__.c new file mode 100644 index 000000000000..d4841556defd --- /dev/null +++ b/ports/silabs/common-hal/os/__init__.c @@ -0,0 +1,66 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "genhdr/mpversion.h" +#include "py/mpconfig.h" +#include "py/objstr.h" +#include "py/objtuple.h" + +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "peripherals/periph.h" +#define RNG_TIMEOUT 5 + +STATIC const qstr os_uname_info_fields[] = { + MP_QSTR_sysname, MP_QSTR_nodename, + MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine +}; +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, EFR32_SERIES_LOWER); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, EFR32_SERIES_LOWER); + +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); + +STATIC MP_DEFINE_ATTRTUPLE( + os_uname_info_obj, + os_uname_info_fields, + 5, + (mp_obj_t)&os_uname_info_sysname_obj, + (mp_obj_t)&os_uname_info_nodename_obj, + (mp_obj_t)&os_uname_info_release_obj, + (mp_obj_t)&os_uname_info_version_obj, + (mp_obj_t)&os_uname_info_machine_obj); + +mp_obj_t common_hal_os_uname(void) { + return (mp_obj_t)&os_uname_info_obj; +} + +bool common_hal_os_urandom(uint8_t *buffer, uint32_t length) { + + return false; +} diff --git a/ports/silabs/common-hal/pwmio/PWMOut.c b/ports/silabs/common-hal/pwmio/PWMOut.c new file mode 100644 index 000000000000..b55c821462a2 --- /dev/null +++ b/ports/silabs/common-hal/pwmio/PWMOut.c @@ -0,0 +1,181 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "common-hal/pwmio/PWMOut.h" +#include "shared-bindings/pwmio/PWMOut.h" +#include "supervisor/shared/translate/translate.h" +#include "shared-bindings/microcontroller/Pin.h" + +STATIC sl_pwm_instance_t pwm_handle[TIM_BANK_ARRAY_LEN]; +STATIC bool never_reset_tim[TIM_BANK_ARRAY_LEN]; + +mcu_tim_pin_obj_t mcu_tim_list[TIM_BANK_ARRAY_LEN] = { + TIM(TIMER0, 0, FN_TIMER0_CC0, NULL), + TIM(TIMER1, 0, FN_TIMER1_CC0, NULL), + TIM(TIMER2, 0, FN_TIMER2_CC0, NULL), + TIM(TIMER3, 0, FN_TIMER3_CC0, NULL), + TIM(TIMER4, 0, FN_TIMER4_CC0, NULL), +}; + +// Reset all pwm channel +void pwmout_reset(void) { + uint8_t tim_index; + for (tim_index = 0; tim_index < TIM_BANK_ARRAY_LEN; tim_index++) { + mcu_tim_pin_obj_t *l_tim = &mcu_tim_list[tim_index]; + if (l_tim->pin != NULL) { + sl_pwm_deinit(&pwm_handle[tim_index]); + } + } + +} + +// Create a PWM object associated with the given pin +pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, + const mcu_pin_obj_t *pin, + uint16_t duty, + uint32_t frequency, + bool variable_frequency) { + uint8_t tim_num = TIM_BANK_ARRAY_LEN; + uint8_t percent = (duty * 100) / 65535; + sl_pwm_config_t pwm_config; + pwm_config.frequency = frequency; + pwm_config.polarity = PWM_ACTIVE_LOW; + + mcu_tim_pin_obj_t *l_tim; + uint8_t tim_index; + + if (self->tim == NULL) { + for (tim_index = 0; tim_index < tim_num; tim_index++) { + l_tim = &mcu_tim_list[tim_index]; + + if ((l_tim->pin == NULL && pin->function_list[l_tim->fn_index] == 1) + || l_tim->pin == pin) { + l_tim->pin = pin; + self->tim = l_tim; + self->handle = &pwm_handle[tim_index]; + break; + } + } + } + + if (self->tim == NULL) { + return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; + } + + self->duty_cycle = duty; + self->variable_frequency = variable_frequency; + self->frequency = frequency; + self->handle->port = pin->port; + self->handle->pin = pin->number; + self->handle->timer = self->tim->timer; + self->handle->channel = self->tim->channel; + self->tim->pin = pin; + + if (SL_STATUS_OK != sl_pwm_init(self->handle, &pwm_config)) { + return PWMOUT_INITIALIZATION_ERROR; + } + + sl_pwm_start(self->handle); + sl_pwm_set_duty_cycle(self->handle, percent); + + common_hal_mcu_pin_claim(pin); + return PWMOUT_OK; +} + +// Mark pwm obj to never reset after reload +void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { + + uint8_t tim_index; + for (tim_index = 0; tim_index < TIM_BANK_ARRAY_LEN; tim_index++) { + if (&mcu_tim_list[tim_index] == self->tim) { + never_reset_tim[tim_index] = true; + common_hal_never_reset_pin(self->tim->pin); + break; + } + } +} + +// Pwm will be reset after reloading. +void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) { + + uint8_t tim_index; + for (tim_index = 0; tim_index < TIM_BANK_ARRAY_LEN; tim_index++) { + if (&mcu_tim_list[tim_index] == self->tim) { + never_reset_tim[tim_index] = false; + break; + } + } +} + +// Check pwm obj status, deinited or not +bool common_hal_pwmio_pwmout_deinited(pwmio_pwmout_obj_t *self) { + return self->tim == NULL; +} + +// Deint pwm obj +void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { + sl_pwm_deinit(self->handle); + common_hal_reset_pin(self->tim->pin); + mcu_tim_pin_obj_t *l_tim = self->tim; + l_tim->pin = NULL; +} + +// Set pwm duty cycle +void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t *self, + uint16_t duty) { + uint8_t percent = (duty * 100) / 65535; + sl_pwm_set_duty_cycle(self->handle, percent); + self->duty_cycle = duty; +} + +// Get pwm duty cycle +uint16_t common_hal_pwmio_pwmout_get_duty_cycle(pwmio_pwmout_obj_t *self) { + return self->duty_cycle; +} + +// Set pwm frequency +void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t *self, + uint32_t frequency) { + sl_pwm_config_t pwm_config; + pwm_config.frequency = frequency; + pwm_config.polarity = PWM_ACTIVE_LOW; + sl_pwm_init(self->handle, &pwm_config); +} + +// Get pwm frequency +uint32_t common_hal_pwmio_pwmout_get_frequency(pwmio_pwmout_obj_t *self) { + return self->frequency; +} + +// Check variable frequency +bool common_hal_pwmio_pwmout_get_variable_frequency(pwmio_pwmout_obj_t *self) { + return self->variable_frequency; +} + +// Get pin value in pwmio obj +const mcu_pin_obj_t *common_hal_pwmio_pwmout_get_pin(pwmio_pwmout_obj_t *self) { + return self->tim->pin; +} diff --git a/ports/silabs/common-hal/pwmio/PWMOut.h b/ports/silabs/common-hal/pwmio/PWMOut.h new file mode 100644 index 000000000000..484b1d87b93e --- /dev/null +++ b/ports/silabs/common-hal/pwmio/PWMOut.h @@ -0,0 +1,47 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_STM32F4_COMMON_HAL_PWMIO_PWMOUT_H +#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_PWMIO_PWMOUT_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" +#include "peripherals/periph.h" +#include "sl_pwm.h" + +typedef struct { + mp_obj_base_t base; + sl_pwm_instance_t *handle; + mcu_tim_pin_obj_t *tim; + bool variable_frequency : 1; + uint16_t duty_cycle; + uint32_t frequency; +} pwmio_pwmout_obj_t; + +void pwmout_reset(void); + +#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_PWMIO_PWMOUT_H diff --git a/ports/silabs/common-hal/pwmio/__init__.c b/ports/silabs/common-hal/pwmio/__init__.c new file mode 100644 index 000000000000..9e551a1072b3 --- /dev/null +++ b/ports/silabs/common-hal/pwmio/__init__.c @@ -0,0 +1 @@ +// No pwmio module functions. diff --git a/ports/silabs/common-hal/rtc/RTC.c b/ports/silabs/common-hal/rtc/RTC.c new file mode 100644 index 000000000000..f3de48894c8d --- /dev/null +++ b/ports/silabs/common-hal/rtc/RTC.c @@ -0,0 +1,78 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/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" +#include "sl_sleeptimer.h" + +// Set rtc time +void common_hal_rtc_set_time(timeutils_struct_time_t *tm) { + + sl_sleeptimer_date_t date = { 0 }; + date.year = tm->tm_year - 1900; + // Month enum begins at + date.month = tm->tm_mon - 1; + date.month_day = tm->tm_mday; + date.day_of_week = tm->tm_wday == 6?0:tm->tm_wday + 1; + date.hour = tm->tm_hour; + date.min = tm->tm_min; + date.sec = tm->tm_sec; + date.day_of_year = tm->tm_yday; + sl_sleeptimer_set_datetime(&date); +} + +// Get rtc time +void common_hal_rtc_get_time(timeutils_struct_time_t *tm) { + sl_sleeptimer_date_t date; + sl_sleeptimer_get_datetime(&date); + + tm->tm_year = date.year + 1900; + tm->tm_mon = date.month + 1; + tm->tm_mday = date.month_day; + tm->tm_wday = date.day_of_week == 0?6:date.day_of_week - 1; + tm->tm_hour = date.hour; + tm->tm_min = date.min; + tm->tm_sec = date.sec; + tm->tm_yday = date.day_of_year; + +} + +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/silabs/common-hal/rtc/RTC.h b/ports/silabs/common-hal/rtc/RTC.h new file mode 100644 index 000000000000..12683a310a71 --- /dev/null +++ b/ports/silabs/common-hal/rtc/RTC.h @@ -0,0 +1,33 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_RTC_RTC_H +#define MICROPY_INCLUDED_STM_COMMON_HAL_RTC_RTC_H + +extern void rtc_init(void); +extern void rtc_reset(void); + +#endif // MICROPY_INCLUDED_STM_COMMON_HAL_RTC_RTC_H diff --git a/ports/silabs/common-hal/rtc/__init__.c b/ports/silabs/common-hal/rtc/__init__.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ports/silabs/common-hal/rtc/__init__.h b/ports/silabs/common-hal/rtc/__init__.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ports/silabs/common-hal/supervisor/Runtime.c b/ports/silabs/common-hal/supervisor/Runtime.c new file mode 100644 index 000000000000..f2ac082604cb --- /dev/null +++ b/ports/silabs/common-hal/supervisor/Runtime.c @@ -0,0 +1,37 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/supervisor/Runtime.h" +#include "supervisor/serial.h" + +bool common_hal_supervisor_runtime_get_serial_connected(void) { + return (bool)serial_connected(); +} + +bool common_hal_supervisor_runtime_get_serial_bytes_available(void) { + return (bool)serial_bytes_available(); +} diff --git a/ports/silabs/common-hal/supervisor/Runtime.h b/ports/silabs/common-hal/supervisor/Runtime.h new file mode 100644 index 000000000000..b71bd9b54580 --- /dev/null +++ b/ports/silabs/common-hal/supervisor/Runtime.h @@ -0,0 +1,37 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_COMMON_HAL_SUPERVISOR_RUNTIME_H +#define MICROPY_INCLUDED_STM32_COMMON_HAL_SUPERVISOR_RUNTIME_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} super_runtime_obj_t; + +#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_SUPERVISOR_RUNTIME_H diff --git a/ports/silabs/common-hal/supervisor/__init__.c b/ports/silabs/common-hal/supervisor/__init__.c new file mode 100644 index 000000000000..16dc414b06f8 --- /dev/null +++ b/ports/silabs/common-hal/supervisor/__init__.c @@ -0,0 +1,38 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "shared-bindings/supervisor/__init__.h" +#include "shared-bindings/supervisor/Runtime.h" + +// The singleton supervisor.Runtime object, bound to supervisor.runtime +// It currently only has properties, and no state. +const super_runtime_obj_t common_hal_supervisor_runtime_obj = { + .base = { + .type = &supervisor_runtime_type, + }, +}; diff --git a/ports/silabs/common-hal/watchdog/WatchDogMode.c b/ports/silabs/common-hal/watchdog/WatchDogMode.c new file mode 100644 index 000000000000..200db64eece9 --- /dev/null +++ b/ports/silabs/common-hal/watchdog/WatchDogMode.c @@ -0,0 +1,25 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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. + */ diff --git a/ports/silabs/common-hal/watchdog/WatchDogTimer.c b/ports/silabs/common-hal/watchdog/WatchDogTimer.c new file mode 100644 index 000000000000..b6158e1cc679 --- /dev/null +++ b/ports/silabs/common-hal/watchdog/WatchDogTimer.c @@ -0,0 +1,133 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "common-hal/watchdog/WatchDogTimer.h" + +#include "shared-bindings/watchdog/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" + +#include "em_wdog.h" +#include "em_cmu.h" + +void common_hal_watchdog_feed(watchdog_watchdogtimer_obj_t *self) { + WDOGn_Feed(DEFAULT_WDOG); +} + +void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { + WDOG_Enable(false); +} + +void watchdog_reset(void) { + common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); +} + +mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { + return self->timeout; +} + +void common_hal_watchdog_set_timeout(watchdog_watchdogtimer_obj_t *self, + mp_float_t new_timeout) { + + // Max timeout is 256000 ms + uint64_t timeout = new_timeout * 1000; + mp_arg_validate_int_max(timeout, 256000, MP_QSTR_WatchDogTimeout); + + if ((uint32_t)self->timeout != (uint32_t)new_timeout) { + + // Watchdog Initialize settings + WDOG_Init_TypeDef wdogInit = WDOG_INIT_DEFAULT; + + switch ((uint32_t)new_timeout) + { + case 1: + wdogInit.perSel = wdogPeriod_1k; + break; + case 2: + wdogInit.perSel = wdogPeriod_2k; + break; + case 4: + wdogInit.perSel = wdogPeriod_4k; + break; + case 8: + wdogInit.perSel = wdogPeriod_8k; + break; + case 16: + wdogInit.perSel = wdogPeriod_16k; + break; + case 32: + wdogInit.perSel = wdogPeriod_32k; + break; + case 64: + wdogInit.perSel = wdogPeriod_64k; + break; + case 128: + wdogInit.perSel = wdogPeriod_128k; + break; + case 256: + wdogInit.perSel = wdogPeriod_256k; + break; + default: + mp_raise_ValueError( + translate("Timeout value supported: 1,2,4,8,16,32,64,128,256")); + + } + + self->timeout = new_timeout; + // Enable clock for the WDOG module; has no effect on xG21 + CMU_ClockEnable(cmuClock_WDOG0, true); + + // ULFRCO as clock source + CMU_ClockSelectSet(cmuClock_WDOG0, cmuSelect_ULFRCO); + + wdogInit.em1Run = true; + wdogInit.em2Run = true; + wdogInit.em3Run = true; + + // Initializing watchdog with chosen settings + WDOGn_Init(DEFAULT_WDOG, &wdogInit); + } +} + +watchdog_watchdogmode_t common_hal_watchdog_get_mode + (watchdog_watchdogtimer_obj_t *self) { + return self->mode; +} + +void common_hal_watchdog_set_mode(watchdog_watchdogtimer_obj_t *self, + watchdog_watchdogmode_t new_mode) { + if (self->mode != new_mode) { + if (new_mode == WATCHDOGMODE_RAISE) { + mp_raise_NotImplementedError( + translate("RAISE mode is not implemented")); + } else if (new_mode == WATCHDOGMODE_NONE) { + self->mode = WATCHDOGMODE_NONE; + common_hal_watchdog_deinit(self); + } + self->mode = new_mode; + common_hal_watchdog_set_timeout(self, self->timeout); + } +} diff --git a/ports/silabs/common-hal/watchdog/WatchDogTimer.h b/ports/silabs/common-hal/watchdog/WatchDogTimer.h new file mode 100644 index 000000000000..d1538bd491f8 --- /dev/null +++ b/ports/silabs/common-hal/watchdog/WatchDogTimer.h @@ -0,0 +1,43 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_WATCHDOG_WATCHDOGTIMER_H +#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H + +#include "py/obj.h" +#include "shared-bindings/watchdog/WatchDogMode.h" +#include "shared-bindings/watchdog/WatchDogTimer.h" + +struct _watchdog_watchdogtimer_obj_t { + mp_obj_base_t base; + mp_float_t timeout; + watchdog_watchdogmode_t mode; +}; + +// This needs to be called in order to disable the watchdog +void watchdog_reset(void); + +#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H diff --git a/ports/silabs/common-hal/watchdog/__init__.c b/ports/silabs/common-hal/watchdog/__init__.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ports/silabs/cp_efr32_extension/cp_efr32.slce b/ports/silabs/cp_efr32_extension/cp_efr32.slce new file mode 100644 index 000000000000..90052a887d11 --- /dev/null +++ b/ports/silabs/cp_efr32_extension/cp_efr32.slce @@ -0,0 +1,10 @@ +id: cp_efr32 +label: CircuitPython support +version: 1.0.0 +sdk: + id: "gecko_sdk" + version: 4.2.1 +component_path: + - path: ../boards/devkit_xg24_brd2601b/ + - path: ../boards/explorerkit_xg24_brd2703a/ + - path: ../boards/sparkfun_thingplus_matter_mgm240p_brd2704a/ diff --git a/ports/silabs/gecko_sdk b/ports/silabs/gecko_sdk new file mode 160000 index 000000000000..3fbadf9fb4e9 --- /dev/null +++ b/ports/silabs/gecko_sdk @@ -0,0 +1 @@ +Subproject commit 3fbadf9fb4e904fd8ed087642a41762b833ae0fe diff --git a/ports/silabs/license.md b/ports/silabs/license.md new file mode 100644 index 000000000000..5b8797814f43 --- /dev/null +++ b/ports/silabs/license.md @@ -0,0 +1,21 @@ +MIT License + +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 +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. diff --git a/ports/silabs/mpconfigport.h b/ports/silabs/mpconfigport.h new file mode 100644 index 000000000000..ba498dd7631a --- /dev/null +++ b/ports/silabs/mpconfigport.h @@ -0,0 +1,73 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 EFR32_MPCONFIGPORT_H__ +#define EFR32_MPCONFIGPORT_H__ + +#include + +#define MICROPY_PY_FUNCTION_ATTRS (1) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) + +// 24kiB stack +#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000 + +// Board flags: +#ifndef BOARD_OVERWRITE_SWD +#define BOARD_OVERWRITE_SWD (0) +#endif +#ifndef BOARD_VTOR_DEFER +#define BOARD_VTOR_DEFER (0) +#endif +#ifndef BOARD_NO_VBUS_SENSE +#define BOARD_NO_VBUS_SENSE (0) +#endif +#ifndef BOARD_NO_USB_OTG_ID_SENSE +#define BOARD_NO_USB_OTG_ID_SENSE (0) +#endif + +#if INTERNAL_FLASH_FILESYSTEM +#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR (0x080E0000UL) +#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (512 * 1024) +#else +#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (0) +#endif + +// Peripheral implementation counts +#define MAX_UART 1 +#define MAX_I2C 1 +#define MAX_SPI 1 + +#define asm(str) __asm(str) + +#include "py/circuitpy_mpconfig.h" + +#define MICROPY_PORT_ROOT_POINTERS \ + void *cpy_uart_obj_all[MAX_UART]; \ + void *cpy_i2c_obj_all[MAX_I2C]; \ + CIRCUITPY_COMMON_ROOT_POINTERS + +#endif // EFR32_MPCONFIGPORT_H__ diff --git a/ports/silabs/mpconfigport.mk b/ports/silabs/mpconfigport.mk new file mode 100644 index 000000000000..b3a2d637245b --- /dev/null +++ b/ports/silabs/mpconfigport.mk @@ -0,0 +1,37 @@ +LONGINT_IMPL ?= MPZ +INTERNAL_LIBM ?= 1 +USB_NUM_ENDPOINT_PAIRS ?= 0 + +CIRCUITPY_ANALOGIO ?= 1 +CIRCUITPY_BLEIO ?= 1 +CIRCUITPY_BUSDEVICE ?= 1 +CIRCUITPY_BUSIO ?= 1 +CIRCUITPY_DIGITALIO ?= 1 +CIRCUITPY_DISPLAYIO ?= 1 +CIRCUITPY_FRAMEBUFFERIO ?= 1 +CIRCUITPY_NVM ?= 1 +CIRCUITPY_PWMIO ?= 1 +CIRCUITPY_RTC ?= 1 +CIRCUITPY_WATCHDOG ?=1 + +ifeq ($(MCU_SERIES),MG24) + # Not yet implemented common-hal modules: + CIRCUITPY_AUDIOIO ?= 0 + CIRCUITPY_AUDIOCORE ?= 0 + CIRCUITPY_AUDIOPWMIO ?= 0 + CIRCUITPY_AUDIOBUSIO ?= 0 + CIRCUITPY_BITBANGIO ?= 0 + CIRCUITPY_BLEIO_HCI ?= 0 + CIRCUITPY_COUNTIO ?= 0 + CIRCUITPY_FREQUENCYIO ?= 0 + CIRCUITPY_I2CTARGET ?= 0 + CIRCUITPY_KEYPAD ?= 0 + CIRCUITPY_NEOPIXEL_WRITE ?= 0 + CIRCUITPY_PARALLELDISPLAY ?= 0 + CIRCUITPY_PULSEIO ?= 0 + CIRCUITPY_ROTARYIO ?= 0 + CIRCUITPY_TOUCHIO ?= 0 + CIRCUITPY_USB ?= 0 +endif + +CIRCUITPY_BUILD_EXTENSIONS ?= bin diff --git a/ports/silabs/mphalport.c b/ports/silabs/mphalport.c new file mode 100644 index 000000000000..715541b96849 --- /dev/null +++ b/ports/silabs/mphalport.c @@ -0,0 +1,46 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/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); +} + +void mp_hal_disable_all_interrupts(void) { + common_hal_mcu_disable_interrupts(); +} + +void mp_hal_enable_all_interrupts(void) { + common_hal_mcu_enable_interrupts(); +} diff --git a/ports/silabs/mphalport.h b/ports/silabs/mphalport.h new file mode 100644 index 000000000000..39c817868a8c --- /dev/null +++ b/ports/silabs/mphalport.h @@ -0,0 +1,51 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_MPHALPORT_H +#define MICROPY_INCLUDED_EFR32_MPHALPORT_H + +#include "py/obj.h" + +#include "lib/oofatfs/ff.h" + +#include "supervisor/shared/tick.h" + +// Global millisecond tick count (driven by SysTick interrupt). +static inline mp_uint_t mp_hal_ticks_ms(void) { + return supervisor_ticks_ms32(); +} +// Number of bytes in receive buffer +extern volatile uint8_t usb_rx_count; +extern volatile bool mp_cdc_enabled; + +int receive_usb(void); + +void mp_hal_set_interrupt_char(int c); + +void mp_hal_disable_all_interrupts(void); +void mp_hal_enable_all_interrupts(void); + +#endif // MICROPY_INCLUDED_EFR32_MPHALPORT_H diff --git a/ports/silabs/peripherals/periph.h b/ports/silabs/peripherals/periph.h new file mode 100644 index 000000000000..e70119a6b52b --- /dev/null +++ b/ports/silabs/peripherals/periph.h @@ -0,0 +1,81 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_PERIPHERALS_PERIPH_H__ +#define __MICROPY_INCLUDED_EFR32_PERIPHERALS_PERIPH_H__ + +#include +#include + +#include "pins.h" +#include "uartdrv.h" +#include "sl_pwm.h" +#include "em_vdac.h" +#define TIM_BANK_ARRAY_LEN 5 + + +// Timer Peripheral +typedef struct { + TIMER_TypeDef *timer; + uint8_t channel; + uint8_t fn_index; + const mcu_pin_obj_t *pin; +} mcu_tim_pin_obj_t; + +#define TIM(timer_index, channel_index, pin_fun, pin_num) \ + { \ + .timer = timer_index, \ + .channel = channel_index, \ + .fn_index = pin_fun, \ + .pin = pin_num \ + } + +extern mcu_tim_pin_obj_t mcu_tim_list[TIM_BANK_ARRAY_LEN]; + +#define DAC_BANK_ARRAY_LEN 4 + +typedef struct { + VDAC_TypeDef *vdac; + uint8_t channel; + uint8_t fn_index; + bool is_used; + uint16_t value; + const mcu_pin_obj_t *pin; +} mcu_dac_pin_obj_t; + +#define DAC(vdac_index, channel_index, pin_fun, used, dac_value, pin_num) \ + { \ + .vdac = vdac_index, \ + .channel = channel_index, \ + .fn_index = pin_fun, \ + .is_used = used, \ + .value = dac_value, \ + .pin = pin_num \ + } + +extern mcu_dac_pin_obj_t mcu_dac_list[DAC_BANK_ARRAY_LEN]; + +#endif // __MICROPY_INCLUDED_EFR32_PERIPHERALS_PERIPH_H__ diff --git a/ports/silabs/peripherals/pins.h b/ports/silabs/peripherals/pins.h new file mode 100644 index 000000000000..ca02bf4af696 --- /dev/null +++ b/ports/silabs/peripherals/pins.h @@ -0,0 +1,171 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_PERIPHERALS_PINS_H__ +#define __MICROPY_INCLUDED_EFR32_PERIPHERALS_PINS_H__ + +typedef struct { + mp_obj_base_t base; + const uint8_t port : 4; + const uint8_t number : 4; + const uint8_t *const function_list; +} mcu_pin_obj_t; + +extern const mp_obj_type_t mcu_pin_type; + +#define PIN(p_port, p_number, p_funtion_list) \ + { \ + {&mcu_pin_type}, \ + .port = p_port, \ + .number = p_number, \ + .function_list = p_funtion_list \ + } + +#ifdef GPIO_PA0_EXISTS +extern const mcu_pin_obj_t pin_PA0; +#endif + +#ifdef GPIO_PA1_EXISTS +extern const mcu_pin_obj_t pin_PA1; +#endif + +#ifdef GPIO_PA2_EXISTS +extern const mcu_pin_obj_t pin_PA2; +#endif + +#ifdef GPIO_PA3_EXISTS +extern const mcu_pin_obj_t pin_PA3; +#endif + +#ifdef GPIO_PA4_EXISTS +extern const mcu_pin_obj_t pin_PA4; +#endif + +#ifdef GPIO_PA5_EXISTS +extern const mcu_pin_obj_t pin_PA5; +#endif + +#ifdef GPIO_PA6_EXISTS +extern const mcu_pin_obj_t pin_PA6; +#endif + +#ifdef GPIO_PA7_EXISTS +extern const mcu_pin_obj_t pin_PA7; +#endif + +#ifdef GPIO_PA8_EXISTS +extern const mcu_pin_obj_t pin_PA8; +#endif + +#ifdef GPIO_PB0_EXISTS +extern const mcu_pin_obj_t pin_PB0; +#endif + +#ifdef GPIO_PB1_EXISTS +extern const mcu_pin_obj_t pin_PB1; +#endif + +#ifdef GPIO_PB2_EXISTS +extern const mcu_pin_obj_t pin_PB2; +#endif + +#ifdef GPIO_PB3_EXISTS +extern const mcu_pin_obj_t pin_PB3; +#endif + +#ifdef GPIO_PB4_EXISTS +extern const mcu_pin_obj_t pin_PB4; +#endif + +#ifdef GPIO_PB5_EXISTS +extern const mcu_pin_obj_t pin_PB5; +#endif + +#ifdef GPIO_PC0_EXISTS +extern const mcu_pin_obj_t pin_PC0; +#endif + +#ifdef GPIO_PC1_EXISTS +extern const mcu_pin_obj_t pin_PC1; +#endif + +#ifdef GPIO_PC2_EXISTS +extern const mcu_pin_obj_t pin_PC2; +#endif + +#ifdef GPIO_PC3_EXISTS +extern const mcu_pin_obj_t pin_PC3; +#endif + +#ifdef GPIO_PC4_EXISTS +extern const mcu_pin_obj_t pin_PC4; +#endif + +#ifdef GPIO_PC5_EXISTS +extern const mcu_pin_obj_t pin_PC5; +#endif + +#ifdef GPIO_PC6_EXISTS +extern const mcu_pin_obj_t pin_PC6; +#endif + +#ifdef GPIO_PC7_EXISTS +extern const mcu_pin_obj_t pin_PC7; +#endif + +#ifdef GPIO_PC8_EXISTS +extern const mcu_pin_obj_t pin_PC8; +#endif + +#ifdef GPIO_PC9_EXISTS +extern const mcu_pin_obj_t pin_PC9; +#endif + +#ifdef GPIO_PD0_EXISTS +extern const mcu_pin_obj_t pin_PD0; +#endif + +#ifdef GPIO_PD1_EXISTS +extern const mcu_pin_obj_t pin_PD1; +#endif + +#ifdef GPIO_PD2_EXISTS +extern const mcu_pin_obj_t pin_PD2; +#endif + +#ifdef GPIO_PD3_EXISTS +extern const mcu_pin_obj_t pin_PD3; +#endif + +#ifdef GPIO_PD4_EXISTS +extern const mcu_pin_obj_t pin_PD4; +#endif + +#ifdef GPIO_PD5_EXISTS +extern const mcu_pin_obj_t pin_PD5; +#endif + +#endif // __MICROPY_INCLUDED_EFR32_PERIPHERALS_PINS_H__ diff --git a/ports/silabs/peripherals/rtc.h b/ports/silabs/peripherals/rtc.h new file mode 100644 index 000000000000..74e32017677c --- /dev/null +++ b/ports/silabs/peripherals/rtc.h @@ -0,0 +1,33 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_PERIPHERALS_RTC_H__ +#define __MICROPY_INCLUDED_EFR32_PERIPHERALS_RTC_H__ + +#include +#include + +#endif // __MICROPY_INCLUDED_EFR32_PERIPHERALS_RTC_H__ diff --git a/ports/silabs/peripherals/timers.h b/ports/silabs/peripherals/timers.h new file mode 100644 index 000000000000..6fb7bb2a0309 --- /dev/null +++ b/ports/silabs/peripherals/timers.h @@ -0,0 +1,29 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 "peripherals/periph.h" diff --git a/ports/silabs/qstrdefsport.h b/ports/silabs/qstrdefsport.h new file mode 100644 index 000000000000..3ba897069bf7 --- /dev/null +++ b/ports/silabs/qstrdefsport.h @@ -0,0 +1 @@ +// qstrs specific to this port diff --git a/ports/silabs/res/Thony.png b/ports/silabs/res/Thony.png new file mode 100755 index 000000000000..93b3f5dd4b25 Binary files /dev/null and b/ports/silabs/res/Thony.png differ diff --git a/ports/silabs/silabs.pintool b/ports/silabs/silabs.pintool new file mode 100644 index 000000000000..1121cb391da3 --- /dev/null +++ b/ports/silabs/silabs.pintool @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ports/silabs/supervisor/internal_flash.c b/ports/silabs/supervisor/internal_flash.c new file mode 100644 index 000000000000..c260649c6318 --- /dev/null +++ b/ports/silabs/supervisor/internal_flash.c @@ -0,0 +1,138 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/internal_flash.h" + +#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" + +#include "FreeRTOS.h" +#include "task.h" + +#include "em_core.h" +#include "em_device.h" +#include "em_cmu.h" +#include "em_msc.h" +#include "sl_status.h" + +#define NO_CACHE 0xffffffff +uint8_t _flash_cache[FLASH_PAGE_SIZE] __attribute__((aligned(4))); +uint32_t _flash_page_addr = NO_CACHE; + +STATIC inline uint32_t lba2addr(uint32_t block) { + return CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR + block * FILESYSTEM_BLOCK_SIZE; +} + +void supervisor_flash_init(void) { + // Enable MSC clock if supported + CMU_ClockEnable(cmuClock_MSC, true); +} + +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +uint32_t supervisor_flash_get_block_count(void) { + return CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE / FILESYSTEM_BLOCK_SIZE; +} + +void port_internal_flash_flush(void) { + if (_flash_page_addr == NO_CACHE) { + return; + } + + msc_Return_TypeDef ret = mscReturnOk; + + // Skip if data is the same + if (memcmp(_flash_cache, (void *)_flash_page_addr, FLASH_PAGE_SIZE) != 0) { + + MSC_Init(); + taskENTER_CRITICAL(); + ret = MSC_ErasePage((uint32_t *)_flash_page_addr); + taskEXIT_CRITICAL(); + if (mscReturnOk != ret) { + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); + } + taskENTER_CRITICAL(); + ret = MSC_WriteWord((uint32_t *)_flash_page_addr,_flash_cache,FLASH_PAGE_SIZE); + taskEXIT_CRITICAL(); + if (mscReturnOk != ret) { + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); + } + MSC_Deinit(); + } +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { + // Must write out anything in cache before trying to read. + supervisor_flash_flush(); + + uint32_t src = lba2addr(block); + memcpy(dest, (uint8_t *)src, FILESYSTEM_BLOCK_SIZE * num_blocks); + return 0; // success +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) { + while (num_blocks) { + uint32_t const addr = lba2addr(lba); + uint32_t const page_addr = addr & ~(FLASH_PAGE_SIZE - 1); + + // Up to page boundary + uint32_t count = 8 - (lba % 8); + count = MIN(num_blocks, count); + + if (page_addr != _flash_page_addr) { + // Write out anything in cache before overwriting it.*/ + supervisor_flash_flush(); + + _flash_page_addr = page_addr; + + // Copy the current contents of the entire page into the cache. + memcpy(_flash_cache, (void *)page_addr, FLASH_PAGE_SIZE); + } + + // Overwrite part or all of the page cache with the src data. + memcpy(_flash_cache + (addr & (FLASH_PAGE_SIZE - 1)), src, count * FILESYSTEM_BLOCK_SIZE); + + // adjust for next run + lba += count; + src += count * FILESYSTEM_BLOCK_SIZE; + num_blocks -= count; + } + return 0; // success +} + +void supervisor_flash_release_cache(void) { +} diff --git a/ports/silabs/supervisor/internal_flash.h b/ports/silabs/supervisor/internal_flash.h new file mode 100644 index 000000000000..898376e9d626 --- /dev/null +++ b/ports/silabs/supervisor/internal_flash.h @@ -0,0 +1,38 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_INTERNAL_FLASH_H +#define MICROPY_INCLUDED_EFR32_INTERNAL_FLASH_H + +#include +#include + +#include "py/mpconfig.h" + +#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms +#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) + +#endif // MICROPY_INCLUDED_EFR32_INTERNAL_FLASH_H diff --git a/ports/silabs/supervisor/internal_flash_root_pointers.h b/ports/silabs/supervisor/internal_flash_root_pointers.h new file mode 100644 index 000000000000..16694d5dacd1 --- /dev/null +++ b/ports/silabs/supervisor/internal_flash_root_pointers.h @@ -0,0 +1,32 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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_EFR32_INTERNAL_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_EFR32_INTERNAL_FLASH_ROOT_POINTERS_H + +#define FLASH_ROOT_POINTERS + +#endif // MICROPY_INCLUDED_EFR32_INTERNAL_FLASH_ROOT_POINTERS_H diff --git a/ports/silabs/supervisor/port.c b/ports/silabs/supervisor/port.c new file mode 100644 index 000000000000..b5deebf9799f --- /dev/null +++ b/ports/silabs/supervisor/port.c @@ -0,0 +1,336 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/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" + +#if CIRCUITPY_AUDIOPWMIO +#include "common-hal/audiopwmio/PWMAudioOut.h" +#endif +#if CIRCUITPY_BUSIO +#include "common-hal/busio/I2C.h" +#include "common-hal/busio/SPI.h" +#include "common-hal/busio/UART.h" +#endif +#if CIRCUITPY_PULSEIO +#include "common-hal/pulseio/PulseOut.h" +#include "common-hal/pulseio/PulseIn.h" +#endif +#if CIRCUITPY_PWMIO +#include "common-hal/pwmio/PWMOut.h" +#endif +#if CIRCUITPY_PULSEIO || CIRCUITPY_PWMIO +#include "peripherals/timers.h" +#endif +#if CIRCUITPY_SDIOIO +#include "common-hal/sdioio/SDCard.h" +#endif +#if CIRCUITPY_PULSEIO || CIRCUITPY_ALARM +#include "peripherals/exti.h" +#endif +#if CIRCUITPY_ALARM +#include "common-hal/alarm/__init__.h" +#endif +#if CIRCUITPY_RTC +#include "shared-bindings/rtc/__init__.h" +#endif +#if CIRCUITPY_ANALOGIO +#include "common-hal/analogio/AnalogOut.h" +#endif + +#if CIRCUITPY_BLEIO +#include "common-hal/_bleio/__init__.h" +#endif + +// Include headers of EFR32 +#include +#include "em_chip.h" +#include "sl_cmsis_os2_common.h" +#include "sl_component_catalog.h" +#include "sl_sleeptimer.h" +#include "sl_system_init.h" +#include "sl_system_kernel.h" + +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) +#include "sl_power_manager.h" +#endif // SL_CATALOG_POWER_MANAGER_PRESENT + +#if !defined(SL_CATALOG_KERNEL_PRESENT) +#error "Error: Requires SL_CATALOG_KERNEL_PRESENT definition" +#endif + +#define SL_CIRCUITPYTHON_TASK_STACK_EXTRA_SIZE (32) +#define SL_CIRCUITPYTHON_TASK_PRIORITY (40) +#define HEAP_SIZE (88 * 1024) + +extern uint32_t __bss_start__; +extern uint32_t __bss_end__; + +uint32_t _sbss; +uint32_t _ebss; + +uint32_t *heap; +uint32_t heap_size; + +STATIC sl_sleeptimer_timer_handle_t _tick_timer; +STATIC sl_sleeptimer_timer_handle_t _sleep_timer; + +// CircuitPython stack thread +STATIC void circuitpython_thread(void *p_arg); +STATIC osThreadId_t tid_thread_circuitpython; +__ALIGNED(8) +STATIC uint8_t thread_circuitpython_stk[(CIRCUITPY_DEFAULT_STACK_SIZE + + SL_CIRCUITPYTHON_TASK_STACK_EXTRA_SIZE) & + 0xFFFFFFF8u]; +__ALIGNED(4) +STATIC uint8_t thread_circuitpython_cb[osThreadCbSize]; + +STATIC const osThreadAttr_t thread_circuitpython_attr = { + .name = "CircuitPython stack", + .stack_mem = thread_circuitpython_stk, + .stack_size = sizeof(thread_circuitpython_stk), + .cb_mem = thread_circuitpython_cb, + .cb_size = osThreadCbSize, + .priority = (osPriority_t)SL_CIRCUITPYTHON_TASK_PRIORITY +}; + +STATIC bool isSchedulerStarted = false; + +safe_mode_t port_init(void) { + #if defined(SL_CATALOG_KERNEL_PRESENT) + + if (!isSchedulerStarted) { + _sbss = __bss_start__; + _ebss = __bss_end__; + + isSchedulerStarted = true; + // Initialize Silicon Labs device, system, service(s) and protocol stack(s). + // Note that if the kernel is present, processing task(s) will be created by + // this call. + sl_system_init(); + // Create thread for Bluetooth stack + if (tid_thread_circuitpython == NULL) { + tid_thread_circuitpython = osThreadNew(circuitpython_thread, + NULL, + &thread_circuitpython_attr); + } + + // Create mutex for Bluetooth handle + if (bluetooth_connection_mutex_id == NULL) { + bluetooth_connection_mutex_id = osMutexNew(&bluetooth_connection_mutex_attr); + } + + if (tid_thread_circuitpython == NULL) { + for (;;) { + } + } + // Start the kernel. Task(s) created in app_init() will start running. + sl_system_kernel_start(); + } + + #endif // SL_CATALOG_KERNEL_PRESENT + + if (heap == NULL) { + heap = malloc(HEAP_SIZE); + heap_size = HEAP_SIZE / sizeof(uint32_t); + } + if (heap == NULL) { + return SAFE_MODE_NO_HEAP; + } + return SAFE_MODE_NONE; +} + +void reset_port(void) { + reset_all_pins(); + + #if CIRCUITPY_BUSIO + i2c_reset(); + spi_reset(); + uart_reset(); + #endif + + #if CIRCUITPY_PWMIO + pwmout_reset(); + #endif + + #if CIRCUITPY_ANALOGIO + analogout_reset(); + #endif + + #if CIRCUITPY_BLEIO + bleio_reset(); + #endif +} + +void reset_to_bootloader(void) { + CHIP_Reset(); + for (;;) { + } +} + +void reset_cpu(void) { + CHIP_Reset(); + for (;;) { + } +} + +uint32_t *port_heap_get_bottom(void) { + return heap; +} + +uint32_t *port_heap_get_top(void) { + return heap + heap_size; +} + +bool port_has_fixed_stack(void) { + return true; +} + +uint32_t *port_stack_get_limit(void) { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + return (uint32_t *)thread_circuitpython_stk; + #pragma GCC diagnostic pop +} + +uint32_t *port_stack_get_top(void) { + return port_stack_get_limit() + CIRCUITPY_DEFAULT_STACK_SIZE / sizeof(uint32_t); +} + +uint64_t port_get_raw_ticks(uint8_t *subticks) { + uint32_t timer_freq = sl_sleeptimer_get_timer_frequency(); + uint64_t all_subticks = (uint64_t)(sl_sleeptimer_get_tick_count()) * 1024; + if (subticks != NULL) { + *subticks = all_subticks % timer_freq; + } + return all_subticks / timer_freq; +} + +// Periodic tick timer callback +STATIC void on_tick_timer_timeout(sl_sleeptimer_timer_handle_t *handle, + void *data) { + (void)&handle; + (void)&data; + supervisor_tick(); + + // CircuitPython's VM is run in a separate FreeRTOS task from timer callbacks. + // So, we have to notify the main task every time in case it's waiting for us. + osThreadFlagsSet(tid_thread_circuitpython, 0x0001); +} + +// Enable 1/1024 second tick. +void port_enable_tick(void) { + uint32_t timer_freq = sl_sleeptimer_get_timer_frequency(); + + // Create timer for waking up the system periodically. + sl_sleeptimer_start_periodic_timer(&_tick_timer, + timer_freq / 1024, + on_tick_timer_timeout, NULL, + 0, + SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG); +} + +// Disable 1/1024 second tick. +void port_disable_tick(void) { + sl_sleeptimer_stop_timer(&_tick_timer); +} + +void port_wake_main_task(void) { + osThreadFlagsSet(tid_thread_circuitpython, 0x0001); +} + +STATIC void on_sleep_timer_timeout(sl_sleeptimer_timer_handle_t *handle, + void *data) { + port_wake_main_task(); +} + +void port_interrupt_after_ticks(uint32_t ticks) { + uint32_t timer_freq = sl_sleeptimer_get_timer_frequency(); + + uint32_t timer_tick = (uint32_t)((((uint64_t)ticks * timer_freq) + 1023) / 1024u); + + // Create one-shot timer for waking up the system. + sl_sleeptimer_start_timer(&_sleep_timer, + timer_tick, + on_sleep_timer_timeout, NULL, + 0, + SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG); +} + +void port_idle_until_interrupt(void) { + if (!background_callback_pending()) { + osThreadFlagsWait(0x0001, osFlagsWaitAny, osWaitForever); + } + +} + +// Place the word to save just after our BSS section that gets blanked. +void port_set_saved_word(uint32_t value) { + __bss_end__ = value; +} + +uint32_t port_get_saved_word(void) { + return __bss_end__; +} + +#if CIRCUITPY_ALARM +// Board deinit in case boards/xxx/board.c does not provide board_deinit() +MP_WEAK void board_deinit(void) { +} +#endif + +extern void main(void); + +void circuitpython_thread(void *p_arg) { + (void)p_arg; + main(); +} + +__attribute__((used)) void BusFault_Handler(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); + while (true) { + asm ("nop;"); + } +} + +__attribute__((used)) void UsageFault_Handler(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); + while (true) { + asm ("nop;"); + } +} + +__attribute__((used)) void HardFault_Handler(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); + while (true) { + asm ("nop;"); + } +} diff --git a/ports/silabs/supervisor/serial.c b/ports/silabs/supervisor/serial.c new file mode 100644 index 000000000000..01aaa4983568 --- /dev/null +++ b/ports/silabs/supervisor/serial.c @@ -0,0 +1,156 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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/mphal.h" +#include "py/ringbuf.h" +#include "supervisor/port.h" +#include "supervisor/serial.h" +#include "shared/readline/readline.h" +#include "shared/runtime/interrupt_char.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "py/runtime.h" + +#include "em_cmu.h" +#include "em_core.h" +#include "em_gpio.h" +#include "em_eusart.h" +#include "em_gpio.h" +#include "em_cmu.h" + +#define CONSOLE_RCV_BUFFER_SIZE 4096 + +#define EUSART_VCOM_TX_PORT gpioPortA +#define EUSART_VCOM_TX_PIN 5 + +#define EUSART_VCOM_RX_PORT gpioPortA +#define EUSART_VCOM_RX_PIN 6 + +STATIC ringbuf_t con_uart_rx_ringbuf; +STATIC byte con_uart_rx_buf[CONSOLE_RCV_BUFFER_SIZE]; +STATIC volatile uint8_t received_data; + +// USART0 RX interrupt handler , put characters to ring buffer one by one +void EUSART0_RX_IRQHandler(void) { + CORE_DECLARE_IRQ_STATE; + CORE_ENTER_ATOMIC(); + + received_data = EUSART0->RXDATA; + if (1 != ringbuf_put_n(&con_uart_rx_ringbuf, (uint8_t *)&received_data, 1)) { + mp_raise_OverflowError_varg(translate("Console UART RX buffer overflow")); + } + + CORE_EXIT_ATOMIC(); + port_wake_main_task(); + + if (received_data == CHAR_CTRL_C && + mp_interrupt_char == CHAR_CTRL_C) { + ringbuf_clear(&con_uart_rx_ringbuf); + mp_sched_keyboard_interrupt(); + } + EUSART_IntClear(EUSART0, EUSART_IF_RXFL); +} + +// Configure EUSART0 for REPL +void port_serial_early_init(void) { + + // Enable clock to GPIO and EUSART1 + CMU_ClockEnable(cmuClock_GPIO, true); + CMU_ClockEnable(cmuClock_EUSART0, true); + + // Configure the EUSART TX pin to the board controller as an output + GPIO_PinModeSet(EUSART_VCOM_TX_PORT, EUSART_VCOM_TX_PIN, gpioModePushPull, 0); + + // Configure the EUSART RX pin to the board controller as an input + GPIO_PinModeSet(EUSART_VCOM_RX_PORT, EUSART_VCOM_RX_PIN, gpioModeInput, 0); + + // Route EUSART0 TX and RX to the board controller TX and RX pins + GPIO->EUSARTROUTE[0].TXROUTE = (EUSART_VCOM_TX_PORT << _GPIO_EUSART_TXROUTE_PORT_SHIFT) + | (EUSART_VCOM_TX_PIN << _GPIO_EUSART_TXROUTE_PIN_SHIFT); + GPIO->EUSARTROUTE[0].RXROUTE = (EUSART_VCOM_RX_PORT << _GPIO_EUSART_RXROUTE_PORT_SHIFT) + | (EUSART_VCOM_RX_PIN << _GPIO_EUSART_RXROUTE_PIN_SHIFT); + + // Enable RX and TX signals now that they have been routed + GPIO->EUSARTROUTE[0].ROUTEEN = GPIO_EUSART_ROUTEEN_RXPEN | GPIO_EUSART_ROUTEEN_TXPEN; + + // Default asynchronous initializer (115.2 Kbps, 8N1, no flow control) + EUSART_UartInit_TypeDef init = EUSART_UART_INIT_DEFAULT_HF; + + // Configure and enable EUSART0 for high-frequency (EM0/1) operation + EUSART_UartInitHf(EUSART0, &init); + + + // Claim and never reset UART console pin + common_hal_mcu_pin_claim(&pin_PA5); + common_hal_mcu_pin_claim(&pin_PA6); + common_hal_never_reset_pin(&pin_PA5); + common_hal_never_reset_pin(&pin_PA6); +} + +// Enable EUSART0 interrupt, init ring buffer +void port_serial_init(void) { + ringbuf_init(&con_uart_rx_ringbuf, + con_uart_rx_buf, + CONSOLE_RCV_BUFFER_SIZE); + + received_data = 0; + // Enable NVIC USART sources + NVIC_ClearPendingIRQ(EUSART0_RX_IRQn); + NVIC_EnableIRQ(EUSART0_RX_IRQn); + NVIC_SetPriority(EUSART0_RX_IRQn, 3); + EUSART_IntEnable(EUSART0, EUSART_IEN_RXFL); +} + +bool port_serial_connected(void) { + return true; +} + +// Get a characters from ring buffer +char port_serial_read(void) { + int data; + + CORE_DECLARE_IRQ_STATE; + CORE_ENTER_ATOMIC(); + + data = ringbuf_get(&con_uart_rx_ringbuf); + + CORE_EXIT_ATOMIC(); + + return (char)data; +} + +// Checking ring buffer haves bytes available or not +bool port_serial_bytes_available(void) { + return ringbuf_num_filled(&con_uart_rx_ringbuf) > 0 ? true : false; +} + +// Send n bytes data to serial by EUSART0 +void port_serial_write_substring(const char *text, uint32_t len) { + char *p_text = (char *)text; + while (len--) { + EUSART_Tx(EUSART0, *p_text); + p_text++; + } +} diff --git a/ports/silabs/tools/make_pins.py b/ports/silabs/tools/make_pins.py new file mode 100644 index 000000000000..bd4973d3e098 --- /dev/null +++ b/ports/silabs/tools/make_pins.py @@ -0,0 +1,216 @@ +import csv +import argparse +import string + + +def parse_pins(filename): + """Parse CSV file given in filename. + The CSV file should have the following columns: + mcu_name, board_name, port (integer), pin (integer) + The CSV file should also have a header row""" + pins = {} + with open(filename, newline="") as csv_file: + reader = csv.reader(csv_file) + reader.__next__() + for row in reader: + entry = (row[0].strip(), row[1].strip(), int(row[2].strip()), int(row[3].strip())) + pins[row[0].lower()] = entry + return pins + + +def parse_pin_functions(filename): + """Parse a CSV file with peripheral pin mappings. + The CSV file should have the following columns + func_name, LOC0,LOC1,...,LOC31 + There should not be any header row""" + functions = {} + with open(filename, newline="") as csv_file: + reader = csv.reader(csv_file) + for row in reader: + entry = row[1:] + functions[row[0].strip()] = entry + return functions + + +def make_pin_name(pin): + """Create pin name""" + return "pin_" + pin[0] + + +def make_mcu_dict_entry(pin): + """Create a pin mcu dictionary entry""" + entry = "{ MP_ROM_QSTR(MP_QSTR_" + pin[0] + "), MP_ROM_PTR(&" + make_pin_name(pin) + ") }," + return entry + + +def make_mcu_dict_entry2(pin): + """Create a pin mcu dictionary entry""" + entry = ( + "{ MP_ROM_QSTR(MP_QSTR_" + pin[1] + "), \t\t\tMP_ROM_PTR(&" + make_pin_name(pin) + ") }," + ) + return entry + + +def make_mcu_dict(pins): + """Create the mcu dictionary""" + decl = "\n\nSTATIC const mp_rom_map_elem_t board_module_globals_table[] = {\n" + decl += "\tCIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS\n" + for pin in pins.values(): + decl += "\t" + make_mcu_dict_entry(pin) + "\n" + + decl += "\n" + for pin in pins.values(): + if pin[1] != "": + decl += "\t" + make_mcu_dict_entry2(pin) + "\n" + + decl += "\t{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },\n" + decl += "\t{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },\n" + decl += "};\n" + decl += "MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);\n" + return decl + + +def make_board_dict_entry(pin): + """Create a pin board dictionary entry""" + entry = "{ MP_OBJ_NEW_QSTR(MP_QSTR_" + pin[1] + "), (mp_obj_t)&" + make_pin_name(pin) + " }," + return entry + + +def make_pin_function_list_decl(pin, fcns): + """Create a pin function list declaration""" + decl = "\nconst uint8_t pin_" + pin + "_functions[] = { \n" + if len(fcns) > 0: + decl += str(fcns[0]) + for i in fcns[1:]: + decl += ", " + str(i) + decl += "\n};\n" + return decl + + +def make_pin_declaration(pin): + """Create a pin declaration""" + decl = ( + "\nconst mcu_pin_obj_t " + + make_pin_name(pin) + + " = PIN(" + + str(pin[2]) + + "," + + str(pin[3]) + + "," + + make_pin_name(pin).lower() + + "_functions" + ");" + ) + return decl + + +def define_pin_exists(pin): + ret = "\n#define GPIO_" + pin[0] + "_EXISTS\t1" + return ret + + +def make_pin_function_lists(functions, pins): + """Create lists of pin functions from the parsed CSV data""" + fcn_list = {} + decl = "" + i = 0 + for fcn, fcn_pins in sorted(functions.items()): + for j in range(0, len(fcn_pins)): + pin = fcn_pins[j].lower() + if pin == "": + continue + if pin not in fcn_list: + fcn_list[pin] = [255] * len(functions) + fcn_list[pin][i] = 1 + i += 1 + for pin in pins.keys(): + if not pin in fcn_list: + fcn_list[pin] = [] + + decl += make_pin_function_list_decl(pin, fcn_list[pin]) + + return decl + + +def make_source_file(src_file, pins, fcn): + """Make pins.c""" + with open(src_file, "w") as f: + f.write('#include "shared-bindings/board/__init__.h"\n') + f.write('#include "pin_functions.h"\n') + + f.write(make_pin_function_lists(fcn, pins)) + + for pin in pins.values(): + f.write(make_pin_declaration(pin)) + f.write(make_mcu_dict(pins)) + f.close() + return + + +def make_header_file(hdr_file, pins, fcns): + """Make pins.h""" + hdr_file_name = hdr_file.split("/")[-1] + guard_name = "__" + hdr_file_name.replace(".", "_").upper() + "__" + with open(hdr_file, "w") as f: + f.write("#ifndef " + guard_name + "\n") + f.write("#define " + guard_name + "\n\n") + + fcn_names = sorted(fcns.keys()) + for i in range(len(fcn_names)): + f.write("#define " + "FN_" + fcn_names[i] + "\t\t\t(" + str(i) + ")\n") + + for pin in pins.values(): + f.write(define_pin_exists(pin)) + + f.write("\n\n") + f.write("\n\n#endif /*" + guard_name + "*/\n") + f.close() + + return + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + prog="make_pins", + usage="%(prog)s [options]", + description="Parse a CSV file with pin data and store as corresponding C source and header files.", + ) + parser.add_argument( + "-s", + "--source_file", + dest="source_file", + action="store", + help="Name of the output source file", + default="pins.c", + ) + parser.add_argument( + "-e", + "--header_file", + dest="header_file", + action="store", + help="Name of the output header file", + default="pin_functions.h", + ) + + parser.add_argument( + "csv_file", + action="store", + help="Name of the input csv file", + ) + parser.add_argument( + "fcn_csv", + action="store", + help="Name of the csv file with pin functions", + ) + args = parser.parse_args() + + src_file = args.source_file + hdr_file = args.header_file + + csv_file = args.csv_file + fcn_csv = args.fcn_csv + + pins = parse_pins(csv_file) + fcns = parse_pin_functions(fcn_csv) + make_source_file(src_file, pins, fcns) + make_header_file(hdr_file, pins, fcns) diff --git a/ports/silabs/tools/slc_cli_linux b/ports/silabs/tools/slc_cli_linux new file mode 160000 index 000000000000..a2cef4434600 --- /dev/null +++ b/ports/silabs/tools/slc_cli_linux @@ -0,0 +1 @@ +Subproject commit a2cef4434600379695bef23bfbdcc8e604f7f305 diff --git a/ports/stm/Makefile b/ports/stm/Makefile index 094bee7aef1f..d6afeb5f29fa 100755 --- a/ports/stm/Makefile +++ b/ports/stm/Makefile @@ -215,7 +215,7 @@ ifneq ($(CIRCUITPY_AUDIOBUSIO_PDMIN),0) endif ifneq ($(CIRCUITPY_USB),0) -SRC_C += lib/tinyusb/src/portable/st/synopsys/dcd_synopsys.c +SRC_C += lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c endif SRC_S = \ @@ -268,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 dbf5ccee2b2e..7dc617f49fd4 100644 --- a/ports/stm/background.c +++ b/ports/stm/background.c @@ -35,7 +35,9 @@ void port_background_task(void) { } -void port_start_background_task(void) { +void port_background_tick(void) { } -void port_finish_background_task(void) { +void port_start_background_tick(void) { +} +void port_finish_background_tick(void) { } diff --git a/ports/stm/boards/common_default.ld b/ports/stm/boards/common_default.ld index 0c7efd01d4cd..7c96a42bc565 100644 --- a/ports/stm/boards/common_default.ld +++ b/ports/stm/boards/common_default.ld @@ -24,7 +24,7 @@ SECTIONS . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ - /* This first flash block is 16K annd the isr vectors only take up + /* This first flash block is 16K and the isr vectors only take up about 400 bytes. Micropython pads this with files, but this didn't work with the size of Circuitpython's ff object. */ diff --git a/ports/stm/boards/common_nvm.ld b/ports/stm/boards/common_nvm.ld index 91e453bfd91b..1d10db8a314f 100644 --- a/ports/stm/boards/common_nvm.ld +++ b/ports/stm/boards/common_nvm.ld @@ -26,7 +26,7 @@ SECTIONS . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ - /* This first flash block is 16K annd the isr vectors only take up + /* This first flash block is 16K and the isr vectors only take up about 400 bytes. Micropython pads this with files, but this didn't work with the size of Circuitpython's ff object. */ diff --git a/ports/stm/boards/common_tcm.ld b/ports/stm/boards/common_tcm.ld index 9e677862d31e..d7be64d6679b 100644 --- a/ports/stm/boards/common_tcm.ld +++ b/ports/stm/boards/common_tcm.ld @@ -26,7 +26,7 @@ SECTIONS . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ - /* This first flash block is 16K annd the isr vectors only take up + /* This first flash block is 16K and the isr vectors only take up about 400 bytes. Micropython pads this with files, but this didn't work with the size of Circuitpython's ff object. */ diff --git a/ports/stm/boards/espruino_pico/mpconfigboard.mk b/ports/stm/boards/espruino_pico/mpconfigboard.mk index 6e4da86dd7ad..0ed5b161a187 100644 --- a/ports/stm/boards/espruino_pico/mpconfigboard.mk +++ b/ports/stm/boards/espruino_pico/mpconfigboard.mk @@ -14,7 +14,7 @@ LD_COMMON = boards/common_default.ld LD_FILE = boards/STM32F401xd_fs.ld # Disable ulab as we're nearly out of space on this board due to -# INTERNAL_FLASH_FILESYSTEM. It can probably be reenabled if we enable +# INTERNAL_FLASH_FILESYSTEM. It can probably be re-enabled if we enable # lto for this port, and if other stuff hasn't been added in the # meantime CIRCUITPY_AESIO = 0 diff --git a/ports/stm/boards/meowbit_v121/board.c b/ports/stm/boards/meowbit_v121/board.c index e4d362bbfabf..0edf3d40e4b7 100644 --- a/ports/stm/boards/meowbit_v121/board.c +++ b/ports/stm/boards/meowbit_v121/board.c @@ -54,7 +54,7 @@ uint8_t display_init_sequence[] = { 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V 0x20, 0, // _INVOFF //MISMATCh 0x2a vs 0x20 0x36, 1, 0x60, // _MADCTL bottom to top refresh - // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 cycle osc equalie, // fix on VTL 0x3a, 1, 0x05, // COLMOD - 16bit color 0xe0, 0x10, 0x02, 0x1c, 0x07, 0x12, diff --git a/ports/stm/boards/swan_r5/mpconfigboard.h b/ports/stm/boards/swan_r5/mpconfigboard.h index 94cc58ff9d15..8c6949201ea7 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/tests/board_voltage.py b/ports/stm/boards/swan_r5/tests/board_voltage.py index 6191067fde65..2cb0ad4cc0f8 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 @@ 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/swan_r5/tests/enable_3v3.py b/ports/stm/boards/swan_r5/tests/enable_3v3.py index ba955c4f588f..c32bbc58b80e 100644 --- a/ports/stm/boards/swan_r5/tests/enable_3v3.py +++ b/ports/stm/boards/swan_r5/tests/enable_3v3.py @@ -5,7 +5,7 @@ import supervisor import time -# Scenario: Enable 3V3 pin defintiion +# Scenario: Enable 3V3 pin definition # Then the symbol "board.ENABLE_3V3" is defined assert board.ENABLE_3V3 is not None diff --git a/ports/stm/common-hal/audiobusio/MEMS_Audio.h b/ports/stm/common-hal/audiobusio/MEMS_Audio.h index 2f670c850529..77f11dc82f9c 100644 --- a/ports/stm/common-hal/audiobusio/MEMS_Audio.h +++ b/ports/stm/common-hal/audiobusio/MEMS_Audio.h @@ -35,7 +35,7 @@ extern "C" { /** * @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. + * Interrupts for received data fire at half this duration / twice the frequency. */ #ifndef MEMS_AUDIO_MS_BUFFER #define MEMS_AUDIO_MS_BUFFER (1) diff --git a/ports/stm/common-hal/audiobusio/MEMS_Audio_ll_stm32l4.h b/ports/stm/common-hal/audiobusio/MEMS_Audio_ll_stm32l4.h index ce2c397d47a4..31a8133b63d3 100644 --- a/ports/stm/common-hal/audiobusio/MEMS_Audio_ll_stm32l4.h +++ b/ports/stm/common-hal/audiobusio/MEMS_Audio_ll_stm32l4.h @@ -148,7 +148,7 @@ typedef struct MemsAudio_STM32L4SAIPDM_t { pdm_data_available_t pdm_data_available; /** - * @brief A cound of the number of PDM clients in use. + * @brief A count of the number of PDM clients in use. */ uint32_t SAI1_client; diff --git a/ports/stm/common-hal/busio/UART.c b/ports/stm/common-hal/busio/UART.c index 48894db5f947..cdace316392d 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 diff --git a/ports/stm/common-hal/canio/Listener.c b/ports/stm/common-hal/canio/Listener.c index 69c196b78d0e..0def8192f943 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/microcontroller/__init__.c b/ports/stm/common-hal/microcontroller/__init__.c index c399951f54fd..dc2e125a68ec 100644 --- a/ports/stm/common-hal/microcontroller/__init__.c +++ b/ports/stm/common-hal/microcontroller/__init__.c @@ -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) { @@ -77,7 +76,7 @@ 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; diff --git a/ports/stm/common-hal/neopixel_write/__init__.c b/ports/stm/common-hal/neopixel_write/__init__.c index 99529793fab3..9eb30a45097c 100644 --- a/ports/stm/common-hal/neopixel_write/__init__.c +++ b/ports/stm/common-hal/neopixel_write/__init__.c @@ -67,7 +67,7 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, uint32_t p_mask = pin_mask(digitalinout->pin->number); __disable_irq(); - // Enable DWT in debug core. Useable when interrupts disabled, as opposed to Systick->VAL + // Enable DWT in debug core. Usable when interrupts disabled, as opposed to Systick->VAL CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; DWT->CYCCNT = 0; diff --git a/ports/stm/common-hal/pwmio/PWMOut.c b/ports/stm/common-hal/pwmio/PWMOut.c index cc712497d2c9..a983718ff297 100644 --- a/ports/stm/common-hal/pwmio/PWMOut.c +++ b/ports/stm/common-hal/pwmio/PWMOut.c @@ -40,7 +40,8 @@ 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) @@ -64,10 +65,25 @@ STATIC bool timer_get_optimal_divisors(uint32_t *period, uint32_t *prescaler, void pwmout_reset(void) { for (int i = 0; i < TIM_BANK_ARRAY_LEN; i++) { - if (!never_reset_tim[i]) { - tim_channels_taken[i] = 0x00; - tim_frequencies[i] = 0; + 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; } } @@ -176,6 +192,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, if (HAL_TIM_PWM_Init(&self->handle) != HAL_OK) { return PWMOUT_INITIALIZATION_ERROR; } + active_handles[tim_index] = &self->handle; } // Channel/PWM init @@ -208,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; } @@ -234,9 +242,13 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t *self) { } 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 (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/peripherals/stm32l4/clocks.c b/ports/stm/peripherals/stm32l4/clocks.c index 4419f751d4ba..5724a74ae2da 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/supervisor/internal_flash.c b/ports/stm/supervisor/internal_flash.c index e0f4153cb12c..f3f971975300 100644 --- a/ports/stm/supervisor/internal_flash.c +++ b/ports/stm/supervisor/internal_flash.c @@ -215,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 @@ -228,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; @@ -240,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; @@ -253,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; @@ -267,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; @@ -335,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/port.c b/ports/stm/supervisor/port.c index 97bd1c4982dc..1fb3f363774f 100644 --- a/ports/stm/supervisor/port.c +++ b/ports/stm/supervisor/port.c @@ -211,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) { @@ -357,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/tools/parse_af_csv.py b/ports/stm/tools/parse_af_csv.py index 3e48d4145dcf..e3188e2e24b5 100644 --- a/ports/stm/tools/parse_af_csv.py +++ b/ports/stm/tools/parse_af_csv.py @@ -31,6 +31,7 @@ # # 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/coverage.c b/ports/unix/coverage.c index 0e4c6dbd481b..b04bc2158ce6 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -456,7 +456,7 @@ STATIC mp_obj_t extra_coverage(void) { { mp_printf(&mp_plat_print, "# VM\n"); - // call mp_execute_bytecode with invalide bytecode (should raise NotImplementedError) + // call mp_execute_bytecode with invalid bytecode (should raise NotImplementedError) mp_obj_fun_bc_t fun_bc; fun_bc.bytecode = (const byte *)"\x01"; // just needed for n_state mp_code_state_t *code_state = m_new_obj_var(mp_code_state_t, mp_obj_t, 1); diff --git a/ports/unix/modos.c b/ports/unix/modos.c index a6365aa6a38e..8373c07a5c89 100644 --- a/ports/unix/modos.c +++ b/ports/unix/modos.c @@ -147,7 +147,7 @@ STATIC mp_obj_t mod_os_remove(mp_obj_t path_in) { const char *path = mp_obj_str_get_str(path_in); // Note that POSIX requires remove() to be able to delete a directory - // too (act as rmdir()). This is POSIX extenstion to ANSI C semantics + // too (act as rmdir()). This is POSIX extension to ANSI C semantics // of that function. But Python remove() follows ANSI C, and explicitly // required to raise exception on attempt to remove a directory. Thus, // call POSIX unlink() here. diff --git a/ports/unix/modtermios.c b/ports/unix/modtermios.c index 7a578becb9cc..4adef8a380bf 100644 --- a/ports/unix/modtermios.c +++ b/ports/unix/modtermios.c @@ -73,7 +73,7 @@ STATIC mp_obj_t mod_termios_tcsetattr(mp_obj_t fd_in, mp_obj_t when_in, mp_obj_t // We don't export TCSANOW and friends to save on code space. Then // common lazy sense says that passing 0 should be godo enough, and // it is e.g. for glibc. But for other libc's it's not, so set just - // treat 0 as defauling to TCSANOW. + // treat 0 as defaulting to TCSANOW. when = TCSANOW; } diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index c54fede81344..237b99bfe861 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). @@ -191,6 +194,8 @@ extern const struct _mp_print_t mp_stderr_print; +#define RUN_BACKGROUND_TASKS + #if !(defined(MICROPY_GCREGS_SETJMP) || defined(__x86_64__) || defined(__i386__) || defined(__thumb2__) || defined(__thumb__) || defined(__arm__)) // Fall back to setjmp() implementation for discovery of GC pointers in registers. #define MICROPY_GCREGS_SETJMP (1) diff --git a/ports/unix/variants/coverage/mpconfigvariant.h b/ports/unix/variants/coverage/mpconfigvariant.h index ba9e941c28db..0c6e10aeae00 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.h +++ b/ports/unix/variants/coverage/mpconfigvariant.h @@ -62,6 +62,7 @@ #define MICROPY_PY_FRAMEBUF (1) #define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (1) #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) +#define MICROPY_PY_STRUCT (0) // uses shared-bindings struct #define MICROPY_PY_UCRYPTOLIB (1) #define MICROPY_PY_UCRYPTOLIB_CTR (1) #define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (1) diff --git a/ports/unix/variants/coverage/mpconfigvariant.mk b/ports/unix/variants/coverage/mpconfigvariant.mk index e351fc0836a4..854d052c6c24 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.mk +++ b/ports/unix/variants/coverage/mpconfigvariant.mk @@ -26,19 +26,34 @@ 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 \ shared-bindings/aesio/__init__.c \ + shared-bindings/audiocore/__init__.c \ + shared-bindings/audiocore/RawSample.c \ + shared-bindings/audiocore/WaveFile.c \ + shared-bindings/audiomixer/__init__.c \ + shared-bindings/audiomixer/Mixer.c \ + shared-bindings/audiomixer/MixerVoice.c \ shared-bindings/bitmaptools/__init__.c \ shared-bindings/displayio/Bitmap.c \ shared-bindings/rainbowio/__init__.c \ + shared-bindings/struct/__init__.c \ + shared-bindings/synthio/__init__.c \ + shared-bindings/synthio/MidiTrack.c \ + shared-bindings/synthio/Synthesizer.c \ shared-bindings/traceback/__init__.c \ shared-bindings/util.c \ shared-bindings/zlib/__init__.c \ shared-module/aesio/aes.c \ shared-module/aesio/__init__.c \ + shared-module/audiocore/__init__.c \ + shared-module/audiocore/RawSample.c \ + shared-module/audiocore/WaveFile.c \ + shared-module/audiomixer/__init__.c \ + shared-module/audiomixer/Mixer.c \ + shared-module/audiomixer/MixerVoice.c \ shared-module/bitmaptools/__init__.c \ shared-module/displayio/area.c \ shared-module/displayio/Bitmap.c \ @@ -46,6 +61,10 @@ SRC_BITMAP := \ shared-module/displayio/ColorConverter.c \ shared-module/os/getenv.c \ shared-module/rainbowio/__init__.c \ + shared-module/struct/__init__.c \ + shared-module/synthio/__init__.c \ + shared-module/synthio/MidiTrack.c \ + shared-module/synthio/Synthesizer.c \ shared-module/traceback/__init__.c \ shared-module/zlib/__init__.c \ @@ -53,11 +72,17 @@ SRC_C += $(SRC_BITMAP) CFLAGS += \ -DCIRCUITPY_AESIO=1 \ + -DCIRCUITPY_AUDIOCORE=1 \ + -DCIRCUITPY_AUDIOMIXER=1 \ + -DCIRCUITPY_AUDIOCORE_DEBUG=1 \ -DCIRCUITPY_BITMAPTOOLS=1 \ -DCIRCUITPY_DISPLAYIO_UNIX=1 \ - -DCIRCUITPY_OS_GETENV=1 \ -DCIRCUITPY_GIFIO=1 \ + -DCIRCUITPY_OS_GETENV=1 \ -DCIRCUITPY_RAINBOWIO=1 \ + -DCIRCUITPY_STRUCT=1 \ + -DCIRCUITPY_SYNTHIO=1 \ + -DCIRCUITPY_SYNTHIO_MAX_CHANNELS=14 \ -DCIRCUITPY_TRACEBACK=1 \ -DCIRCUITPY_ZLIB=1 diff --git a/py/argcheck.c b/py/argcheck.c index 01c712ac36be..465a82c97e2b 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -31,7 +31,7 @@ #include "supervisor/shared/translate/translate.h" -void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) { +void PLACE_IN_ITCM(mp_arg_check_num_sig)(size_t n_args, size_t n_kw, uint32_t sig) { // TODO maybe take the function name as an argument so we can print nicer error messages // The reverse of MP_OBJ_FUN_MAKE_SIG @@ -234,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 of type %q"), arg_name, MP_QSTR_str); + 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; } @@ -249,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 of type %q"), arg_name, MP_QSTR_int); + 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/asmthumb.c b/py/asmthumb.c index 547e5bedc1f6..1b1923370b14 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -281,7 +281,7 @@ bool asm_thumb_b_n_label(asm_thumb_t *as, uint label) { #define OP_BCC_N(cond, byte_offset) (0xd000 | ((cond) << 8) | (((byte_offset) >> 1) & 0x00ff)) -// all these bit arithmetics need coverage testing! +// all these bit arithmetic need coverage testing! #define OP_BCC_W_HI(cond, byte_offset) (0xf000 | ((cond) << 6) | (((byte_offset) >> 10) & 0x0400) | (((byte_offset) >> 14) & 0x003f)) #define OP_BCC_W_LO(byte_offset) (0x8000 | ((byte_offset) & 0x2000) | (((byte_offset) >> 1) & 0x0fff)) diff --git a/py/bc.c b/py/bc.c index e1645dbff0e5..e7ad43389a17 100644 --- a/py/bc.c +++ b/py/bc.c @@ -111,7 +111,7 @@ STATIC void dump_args(const mp_obj_t *a, size_t sz) { // - code_state->fun_bc should contain a pointer to the function object // - code_state->ip should contain the offset in bytes from the pointer // code_state->fun_bc->bytecode to the entry n_state (0 for bytecode, non-zero for native) -void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args) { +void PLACE_IN_ITCM(mp_setup_code_state)(mp_code_state_t * code_state, size_t n_args, size_t n_kw, const mp_obj_t *args) { // This function is pretty complicated. It's main aim is to be efficient in speed and RAM // usage for the common case of positional only args. diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index be33d80a9991..fb5d745ebb99 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -182,6 +182,18 @@ endif ifeq ($(CIRCUITPY__EVE),1) SRC_PATTERNS += _eve/% endif +ifeq ($(CIRCUITPY_ESPCAMERA),1) +SRC_PATTERNS += espcamera/% +endif +ifeq ($(CIRCUITPY_ESPIDF),1) +SRC_PATTERNS += espidf/% +endif +ifeq ($(CIRCUITPY_ESPNOW),1) +SRC_PATTERNS += espnow/% +endif +ifeq ($(CIRCUITPY_ESPULP),1) +SRC_PATTERNS += espulp/% +endif ifeq ($(CIRCUITPY_FLOPPYIO),1) SRC_PATTERNS += floppyio/% endif @@ -530,6 +542,11 @@ $(filter $(SRC_PATTERNS), \ wifi/Packet.c \ ) +ifeq ($(CIRCUITPY_SAFEMODE_PY),1) +SRC_BINDINGS_ENUMS += \ + supervisor/SafeModeReason.c +endif + SRC_BINDINGS_ENUMS += \ util.c @@ -592,6 +609,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 \ @@ -630,6 +648,7 @@ SRC_SHARED_MODULE_ALL = \ supervisor/__init__.c \ supervisor/StatusBar.c \ synthio/MidiTrack.c \ + synthio/Synthesizer.c \ synthio/__init__.c \ terminalio/Terminal.c \ terminalio/__init__.c \ @@ -697,6 +716,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 \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 8bfb69297af1..cc7886cb3765 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -145,6 +145,7 @@ extern void common_hal_mcu_enable_interrupts(void); #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 @@ -254,6 +255,10 @@ typedef long mp_off_t; #define MICROPY_FATFS_EXFAT (CIRCUITPY_FULL_BUILD) #endif +#ifndef MICROPY_FF_MKFS_FAT32 +#define MICROPY_FF_MKFS_FAT32 (CIRCUITPY_FULL_BUILD) +#endif + // LONGINT_IMPL_xxx are defined in the Makefile. // #ifdef LONGINT_IMPL_NONE @@ -388,7 +393,7 @@ extern const struct _mp_obj_module_t nvm_module; // Native modules that are weak links can be accessed directly // by prepending their name with an underscore. This list should correspond to // MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS, assuming you want the native modules -// to be accessible when overriden. +// to be accessible when overridden. #define MICROPY_PORT_BUILTIN_MODULE_ALT_NAMES @@ -434,8 +439,8 @@ struct _supervisor_allocation_node; const char *readline_hist[8]; \ struct _supervisor_allocation_node *first_embedded_allocation; \ -void supervisor_run_background_tasks_if_tick(void); -#define RUN_BACKGROUND_TASKS (supervisor_run_background_tasks_if_tick()) +void background_callback_run_all(void); +#define RUN_BACKGROUND_TASKS (background_callback_run_all()) #define MICROPY_VM_HOOK_LOOP RUN_BACKGROUND_TASKS; #define MICROPY_VM_HOOK_RETURN RUN_BACKGROUND_TASKS; @@ -582,6 +587,18 @@ void supervisor_run_background_tasks_if_tick(void); #define MICROPY_WRAP_MP_EXECUTE_BYTECODE PLACE_IN_ITCM #endif +#ifndef MICROPY_WRAP_MP_LOAD_GLOBAL +#define MICROPY_WRAP_MP_LOAD_GLOBAL PLACE_IN_ITCM +#endif + +#ifndef MICROPY_WRAP_MP_LOAD_NAME +#define MICROPY_WRAP_MP_LOAD_NAME PLACE_IN_ITCM +#endif + +#ifndef MICROPY_WRAP_MP_OBJ_GET_TYPE +#define MICROPY_WRAP_MP_OBJ_GET_TYPE PLACE_IN_ITCM +#endif + #ifndef CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY #define CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY (0) #endif @@ -594,6 +611,8 @@ void supervisor_run_background_tasks_if_tick(void); #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) diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 3c1c173a5155..0aec2ebe74f5 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -107,6 +107,11 @@ CFLAGS += -DCIRCUITPY_AUDIOCORE=$(CIRCUITPY_AUDIOCORE) CIRCUITPY_AUDIOMIXER ?= $(CIRCUITPY_AUDIOIO) CFLAGS += -DCIRCUITPY_AUDIOMIXER=$(CIRCUITPY_AUDIOMIXER) +ifndef CIRCUITPY_AUDIOCORE_DEBUG +CIRCUITPY_AUDIOCORE_DEBUG ?= 0 +endif +CFLAGS += -DCIRCUITPY_AUDIOCORE_DEBUG=$(CIRCUITPY_AUDIOCORE_DEBUG) + ifndef CIRCUITPY_AUDIOMP3 ifeq ($(CIRCUITPY_FULL_BUILD),1) CIRCUITPY_AUDIOMP3 = $(CIRCUITPY_AUDIOCORE) @@ -221,17 +226,19 @@ CFLAGS += -DCIRCUITPY_OS_GETENV=$(CIRCUITPY_OS_GETENV) CIRCUITPY_ERRNO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_ERRNO=$(CIRCUITPY_ERRNO) -# CIRCUITPY_ESPIDF and CIRCUITPY_ESPULP 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_ESPNOW ?= 0 +CFLAGS += -DCIRCUITPY_ESPNOW=$(CIRCUITPY_ESPNOW) + CIRCUITPY_ESPULP ?= 0 CFLAGS += -DCIRCUITPY_ESPULP=$(CIRCUITPY_ESPULP) -CIRCUITPY_ESP32_CAMERA ?= 0 -CFLAGS += -DCIRCUITPY_ESP32_CAMERA=$(CIRCUITPY_ESP32_CAMERA) +CIRCUITPY_ESPCAMERA ?= 0 +CFLAGS += -DCIRCUITPY_ESPCAMERA=$(CIRCUITPY_ESPCAMERA) CIRCUITPY__EVE ?= 0 CFLAGS += -DCIRCUITPY__EVE=$(CIRCUITPY__EVE) @@ -249,7 +256,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 @@ -283,6 +291,15 @@ CFLAGS += -DCIRCUITPY_JSON=$(CIRCUITPY_JSON) CIRCUITPY_KEYPAD ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_KEYPAD=$(CIRCUITPY_KEYPAD) +CIRCUITPY_KEYPAD_KEYS ?= $(CIRCUITPY_KEYPAD) +CFLAGS += -DCIRCUITPY_KEYPAD_KEYS=$(CIRCUITPY_KEYPAD_KEYS) + +CIRCUITPY_KEYPAD_KEYMATRIX ?= $(CIRCUITPY_KEYPAD) +CFLAGS += -DCIRCUITPY_KEYPAD_KEYMATRIX=$(CIRCUITPY_KEYPAD_KEYMATRIX) + +CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS ?= $(CIRCUITPY_KEYPAD) +CFLAGS += -DCIRCUITPY_KEYPAD_SHIFTREGISTERKEYS=$(CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS) + CIRCUITPY_MATH ?= 1 CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH) @@ -373,6 +390,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. @@ -394,6 +415,11 @@ 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) @@ -425,6 +451,10 @@ CFLAGS += -DCIRCUITPY_SUPERVISOR=$(CIRCUITPY_SUPERVISOR) CIRCUITPY_SYNTHIO ?= $(CIRCUITPY_AUDIOCORE) CFLAGS += -DCIRCUITPY_SYNTHIO=$(CIRCUITPY_SYNTHIO) +CIRCUITPY_SYNTHIO_MAX_CHANNELS ?= 2 +CFLAGS += -DCIRCUITPY_SYNTHIO_MAX_CHANNELS=$(CIRCUITPY_SYNTHIO_MAX_CHANNELS) + + CIRCUITPY_SYS ?= 1 CFLAGS += -DCIRCUITPY_SYS=$(CIRCUITPY_SYS) @@ -514,7 +544,7 @@ CFLAGS += -DUSB_NUM_ENDPOINT_PAIRS=$(USB_NUM_ENDPOINT_PAIRS) CIRCUITPY_USTACK ?= 0 CFLAGS += -DCIRCUITPY_USTACK=$(CIRCUITPY_USTACK) -# for decompressing utlities +# for decompressing utilities CIRCUITPY_ZLIB ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_ZLIB=$(CIRCUITPY_ZLIB) @@ -548,6 +578,10 @@ CFLAGS += -DCIRCUITPY_TUSB_MEM_ALIGN=$(CIRCUITPY_TUSB_MEM_ALIGN) CIRCUITPY_TUSB_ATTR_USBRAM ?= ".bss.usbram" CFLAGS += -DCIRCUITPY_TUSB_ATTR_USBRAM=$(CIRCUITPY_TUSB_ATTR_USBRAM) +# Output function trace information from the ARM ITM. +CIRCUITPY_SWO_TRACE ?= 0 +CFLAGS += -DCIRCUITPY_SWO_TRACE=$(CIRCUITPY_SWO_TRACE) + # Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk # $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers. # This should correspond to the MICROPY_LONGINT_IMPL definition in mpconfigport.h. diff --git a/py/compile.c b/py/compile.c index 432aeca56157..3668bee320ca 100644 --- a/py/compile.c +++ b/py/compile.c @@ -3477,7 +3477,7 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f } } - // update maximim number of labels needed + // update maximum number of labels needed if (comp->next_label > max_num_labels) { max_num_labels = comp->next_label; } diff --git a/py/emitbc.c b/py/emitbc.c index 8f7b1d5b726c..80d0bf489bfb 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -253,7 +253,7 @@ STATIC void emit_write_bytecode_byte_obj(emit_t *emit, int stack_adj, byte b, mp emit_write_bytecode_byte(emit, stack_adj, b); emit->bytecode_offset = (size_t)MP_ALIGN(emit->bytecode_offset, sizeof(mp_obj_t)); mp_obj_t *c = (mp_obj_t *)emit_get_cur_to_write_bytecode(emit, sizeof(mp_obj_t)); - // Verify thar c is already uint-aligned + // Verify that c is already uint-aligned assert(c == MP_ALIGN(c, sizeof(mp_obj_t))); *c = obj; #endif @@ -269,7 +269,7 @@ STATIC void emit_write_bytecode_byte_raw_code(emit_t *emit, int stack_adj, byte emit_write_bytecode_byte(emit, stack_adj, b); emit->bytecode_offset = (size_t)MP_ALIGN(emit->bytecode_offset, sizeof(void *)); void **c = (void **)emit_get_cur_to_write_bytecode(emit, sizeof(void *)); - // Verify thar c is already uint-aligned + // Verify that c is already uint-aligned assert(c == MP_ALIGN(c, sizeof(void *))); *c = rc; #endif diff --git a/py/emitnative.c b/py/emitnative.c index 5946fcd341f1..7d615d58161f 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -944,7 +944,7 @@ STATIC void emit_access_stack(emit_t *emit, int pos, vtype_kind_t *vtype, int re } // does an efficient X=pop(); discard(); push(X) -// needs a (non-temp) register in case the poped element was stored in the stack +// needs a (non-temp) register in case the popped element was stored in the stack STATIC void emit_fold_stack_top(emit_t *emit, int reg_dest) { stack_info_t *si = &emit->stack_info[emit->stack_size - 2]; si[0] = si[1]; diff --git a/py/enum.c b/py/enum.c index 681c3b3103e5..22b909019663 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 d0b8529a4dff..63191047e032 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 d75cfc665812..4671f3348bcf 100644 --- a/py/formatfloat.c +++ b/py/formatfloat.c @@ -39,7 +39,7 @@ Routine for converting a arbitrary floating point number into a string. - The code in this funcion was inspired from Fred Bayer's pdouble.c. + The code in this function was inspired from Fred Bayer's pdouble.c. Since pdouble.c was released as Public Domain, I'm releasing this code as public domain as well. @@ -390,7 +390,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch --dec; --num_digits_left; if (digit_index <= 0) { - // Once we get below 1.0, we scale up f instead of calculting + // Once we get below 1.0, we scale up f instead of calculating // negative powers of 10 in u_base. This provides better // renditions of exact decimals like 1/16 etc. f *= FPCONST(10.0); diff --git a/py/gc.c b/py/gc.c index fc6bc90b67d4..1812507c6166 100644 --- a/py/gc.c +++ b/py/gc.c @@ -231,7 +231,9 @@ bool gc_is_locked(void) { // children: mark the unmarked child blocks and put those newly marked // blocks on the stack. When all children have been checked, pop off the // topmost block on the stack and repeat with that one. -STATIC void gc_mark_subtree(size_t block) { +// We don't instrument these functions because they occur a lot during GC and +// fill up the output buffer quickly. +STATIC void MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_mark_subtree)(size_t block) { // Start with the block passed in the argument. size_t sp = 0; for (;;) { @@ -350,7 +352,7 @@ STATIC void gc_sweep(void) { } // Mark can handle NULL pointers because it verifies the pointer is within the heap bounds. -STATIC void gc_mark(void *ptr) { +STATIC void MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_mark)(void *ptr) { if (VERIFY_PTR(ptr)) { size_t block = BLOCK_FROM_PTR(ptr); if (ATB_GET_KIND(block) == AT_HEAD) { @@ -397,7 +399,7 @@ void gc_collect_ptr(void *ptr) { #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) __attribute__((no_sanitize_address)) #endif -static void *gc_get_ptr(void **ptrs, int i) { +static void *MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_get_ptr)(void **ptrs, int i) { #if MICROPY_DEBUG_VALGRIND if (!VALGRIND_CHECK_MEM_IS_ADDRESSABLE(&ptrs[i], sizeof(*ptrs))) { return NULL; @@ -518,7 +520,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(); @@ -712,7 +714,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 460271af8132..1c5089fdfc81 100644 --- a/py/genlast.py +++ b/py/genlast.py @@ -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/makecompresseddata.py b/py/makecompresseddata.py index 9603de871311..1bce3e8e8374 100644 --- a/py/makecompresseddata.py +++ b/py/makecompresseddata.py @@ -24,7 +24,7 @@ def check_non_ascii(msg): # Replace with . -# Trival scheme to demo/test. +# Trivial scheme to demo/test. def space_compression(error_strings): for line in error_strings: check_non_ascii(line) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 2abbdedefdb0..d16bb0d09aa1 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -249,6 +249,7 @@ "zip", ] + # this must match the equivalent function in qstr.c def compute_hash(qstr, bytes_hash): hash = 5381 diff --git a/py/maketranslationdata.py b/py/maketranslationdata.py index fbf396c73f02..a07f70265c06 100644 --- a/py/maketranslationdata.py +++ b/py/maketranslationdata.py @@ -84,6 +84,7 @@ '"': '\\"', } + # this must match the equivalent function in qstr.c def compute_hash(qstr, bytes_hash): hash = 5381 @@ -277,7 +278,7 @@ def est_net_savings(s, occ): 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 diff --git a/py/mkrules.mk b/py/mkrules.mk index ef0f66117d21..09ed82ac5b7e 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -13,7 +13,7 @@ OBJ_EXTRA_ORDER_DEPS = # tree. # # So for example, py/map.c would have an object file name py/map.o -# The object files will go into the build directory and mantain the same +# The object files will go into the build directory and maintain the same # directory structure as the source tree. So the final dependency will look # like this: # @@ -142,7 +142,7 @@ endif ifneq ($(PROG),) # Build a standalone executable (unix does this) -# The executable should have an .exe extension for builds targetting 'pure' +# The executable should have an .exe extension for builds targeting 'pure' # Windows, i.e. msvc or mingw builds, but not when using msys or cygwin's gcc. COMPILER_TARGET := $(shell $(CC) -dumpmachine) ifneq (,$(findstring mingw,$(COMPILER_TARGET))) diff --git a/py/mpconfig.h b/py/mpconfig.h index 9d68f4ce9d1c..d3842afbe729 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1827,6 +1827,17 @@ typedef double mp_float_t; #define MP_WEAK __attribute__((weak)) #endif +// Modifier for functions which should not be instrumented when tracing with +// -finstrument-functions +#ifndef MP_NO_INSTRUMENT +#define MP_NO_INSTRUMENT __attribute__((no_instrument_function)) +#endif + +// Modifier for functions which should ideally inlined +#ifndef MP_INLINE +#define MP_INLINE inline MP_NO_INSTRUMENT +#endif + // Modifier for functions which should be never inlined #ifndef MP_NOINLINE #define MP_NOINLINE __attribute__((noinline)) @@ -1847,6 +1858,12 @@ typedef double mp_float_t; #define MP_UNLIKELY(x) __builtin_expect((x), 0) #endif +// Modifier for functions which aren't often used. Calls will also be considered +// unlikely. Section names are `.text.unlikely` for use in linker scripts. +#ifndef MP_COLD +#define MP_COLD __attribute__((cold)) +#endif + // To annotate that code is unreachable #ifndef MP_UNREACHABLE #if defined(__GNUC__) diff --git a/py/obj.c b/py/obj.c index 72a06471766c..c394656016b8 100644 --- a/py/obj.c +++ b/py/obj.c @@ -521,7 +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)) { - mp_raise_TypeError_varg(translate("%q must be of type %q"), MP_QSTR_index, MP_QSTR_int); + 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) { diff --git a/py/obj.h b/py/obj.h index b7e76a110628..92732b31dd89 100644 --- a/py/obj.h +++ b/py/obj.h @@ -86,19 +86,19 @@ typedef struct _mp_obj_base_t mp_obj_base_t; #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A -static inline bool mp_obj_is_small_int(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_small_int(mp_const_obj_t o) { return (((mp_int_t)(o)) & 1) != 0; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 1) #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_uint_t)(small_int)) << 1) | 1)) -static inline bool mp_obj_is_qstr(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_qstr(mp_const_obj_t o) { return (((mp_int_t)(o)) & 7) == 2; } #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 3) #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 2)) -static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 7) == 6; } #define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) (((mp_uint_t)(o)) >> 3) @@ -115,25 +115,25 @@ mp_float_t mp_obj_float_get(mp_obj_t self_in); mp_obj_t mp_obj_new_float(mp_float_t value); #endif -static inline bool mp_obj_is_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 0; } #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B -static inline bool mp_obj_is_small_int(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_small_int(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 1; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 2) #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_uint_t)(small_int)) << 2) | 1)) -static inline bool mp_obj_is_qstr(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_qstr(mp_const_obj_t o) { return (((mp_int_t)(o)) & 7) == 3; } #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 3) #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 3)) -static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 7) == 7; } #define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) (((mp_uint_t)(o)) >> 3) @@ -150,13 +150,13 @@ mp_float_t mp_obj_float_get(mp_obj_t self_in); mp_obj_t mp_obj_new_float(mp_float_t value); #endif -static inline bool mp_obj_is_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 1) == 0; } #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C -static inline bool mp_obj_is_small_int(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_small_int(mp_const_obj_t o) { return (((mp_int_t)(o)) & 1) != 0; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 1) @@ -166,17 +166,17 @@ static inline bool mp_obj_is_small_int(mp_const_obj_t o) { #define mp_const_float_e MP_ROM_PTR((mp_obj_t)(((0x402df854 & ~3) | 2) + 0x80800000)) #define mp_const_float_pi MP_ROM_PTR((mp_obj_t)(((0x40490fdb & ~3) | 2) + 0x80800000)) -static inline bool mp_obj_is_float(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_float(mp_const_obj_t o) { return (((mp_uint_t)(o)) & 3) == 2 && (((mp_uint_t)(o)) & 0xff800007) != 0x00000006; } -static inline mp_float_t mp_obj_float_get(mp_const_obj_t o) { +static MP_INLINE mp_float_t mp_obj_float_get(mp_const_obj_t o) { union { mp_float_t f; mp_uint_t u; } num = {.u = ((mp_uint_t)o - 0x80800000) & ~3}; return num.f; } -static inline mp_obj_t mp_obj_new_float(mp_float_t f) { +static MP_INLINE mp_obj_t mp_obj_new_float(mp_float_t f) { union { mp_float_t f; mp_uint_t u; @@ -185,37 +185,37 @@ static inline mp_obj_t mp_obj_new_float(mp_float_t f) { } #endif -static inline bool mp_obj_is_qstr(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_qstr(mp_const_obj_t o) { return (((mp_uint_t)(o)) & 0xff80000f) == 0x00000006; } #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 4) #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 4) | 0x00000006)) -static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { return (((mp_uint_t)(o)) & 0xff80000f) == 0x0000000e; } #define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) (((mp_uint_t)(o)) >> 4) #define MP_OBJ_NEW_IMMEDIATE_OBJ(val) ((mp_obj_t)(((val) << 4) | 0xe)) -static inline bool mp_obj_is_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 0; } #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D -static inline bool mp_obj_is_small_int(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_small_int(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0001000000000000; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)((o) << 16)) >> 17) #define MP_OBJ_NEW_SMALL_INT(small_int) (((((uint64_t)(small_int)) & 0x7fffffffffff) << 1) | 0x0001000000000001) -static inline bool mp_obj_is_qstr(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_qstr(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0002000000000000; } #define MP_OBJ_QSTR_VALUE(o) ((((uint32_t)(o)) >> 1) & 0xffffffff) #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)(((uint64_t)(((uint32_t)(qst)) << 1)) | 0x0002000000000001)) -static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0003000000000000; } #define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) ((((uint32_t)(o)) >> 46) & 3) @@ -230,17 +230,17 @@ static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { #define mp_const_float_e {((mp_obj_t)((uint64_t)0x4005bf0a8b145769 + 0x8004000000000000))} #define mp_const_float_pi {((mp_obj_t)((uint64_t)0x400921fb54442d18 + 0x8004000000000000))} -static inline bool mp_obj_is_float(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_float(mp_const_obj_t o) { return ((uint64_t)(o) & 0xfffc000000000000) != 0; } -static inline mp_float_t mp_obj_float_get(mp_const_obj_t o) { +static MP_INLINE mp_float_t mp_obj_float_get(mp_const_obj_t o) { union { mp_float_t f; uint64_t r; } num = {.r = o - 0x8004000000000000}; return num.f; } -static inline mp_obj_t mp_obj_new_float(mp_float_t f) { +static MP_INLINE mp_obj_t mp_obj_new_float(mp_float_t f) { union { mp_float_t f; uint64_t r; @@ -249,7 +249,7 @@ static inline mp_obj_t mp_obj_new_float(mp_float_t f) { } #endif -static inline bool mp_obj_is_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_obj(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0000000000000000; } #define MP_OBJ_TO_PTR(o) ((void *)(uintptr_t)(o)) @@ -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) @@ -454,7 +454,7 @@ typedef enum _mp_map_lookup_kind_t { MP_MAP_LOOKUP_ADD_IF_NOT_FOUND_OR_REMOVE_IF_FOUND = 3, // only valid for mp_set_lookup } mp_map_lookup_kind_t; -static inline bool mp_map_slot_is_filled(const mp_map_t *map, size_t pos) { +static MP_INLINE bool mp_map_slot_is_filled(const mp_map_t *map, size_t pos) { assert(pos < map->alloc); return (map)->table[pos].key != MP_OBJ_NULL && (map)->table[pos].key != MP_OBJ_SENTINEL; } @@ -476,7 +476,7 @@ typedef struct _mp_set_t { mp_obj_t *table; } mp_set_t; -static inline bool mp_set_slot_is_filled(const mp_set_t *set, size_t pos) { +static MP_INLINE bool mp_set_slot_is_filled(const mp_set_t *set, size_t pos) { return (set)->table[pos] != MP_OBJ_NULL && (set)->table[pos] != MP_OBJ_SENTINEL; } @@ -821,7 +821,7 @@ extern const struct _mp_obj_exception_t mp_static_GeneratorExit_obj; #define mp_obj_is_tuple_compatible(o) (mp_type_get_getiter_slot(mp_obj_get_type(o)) == mp_obj_tuple_getiter) mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict); -static inline mp_obj_t mp_obj_new_bool(mp_int_t x) { +static MP_INLINE mp_obj_t mp_obj_new_bool(mp_int_t x) { return x ? mp_const_true : mp_const_false; } mp_obj_t mp_obj_new_cell(mp_obj_t obj); @@ -893,7 +893,7 @@ mp_obj_t mp_obj_equal_not_equal(mp_binary_op_t op, mp_obj_t o1, mp_obj_t o2); bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2); // returns true if o is bool, small int or long int -static inline bool mp_obj_is_integer(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_integer(mp_const_obj_t o) { return mp_obj_is_int(o) || mp_obj_is_bool(o); } @@ -940,7 +940,7 @@ mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in); mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in); void mp_init_emergency_exception_buf(void); -static inline mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) { +static MP_INLINE mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) { assert(exc_type->make_new == mp_obj_exception_make_new); return mp_obj_exception_make_new(exc_type, 1, 0, &arg); } @@ -957,42 +957,42 @@ void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, size_t s #if MICROPY_PY_BUILTINS_FLOAT // float #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT -static inline float mp_obj_get_float_to_f(mp_obj_t o) { +static MP_INLINE float mp_obj_get_float_to_f(mp_obj_t o) { return mp_obj_get_float(o); } -static inline double mp_obj_get_float_to_d(mp_obj_t o) { +static MP_INLINE double mp_obj_get_float_to_d(mp_obj_t o) { return (double)mp_obj_get_float(o); } -static inline mp_obj_t mp_obj_new_float_from_f(float o) { +static MP_INLINE mp_obj_t mp_obj_new_float_from_f(float o) { return mp_obj_new_float(o); } -static inline mp_obj_t mp_obj_new_float_from_d(double o) { +static MP_INLINE mp_obj_t mp_obj_new_float_from_d(double o) { return mp_obj_new_float((mp_float_t)o); } #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE -static inline float mp_obj_get_float_to_f(mp_obj_t o) { +static MP_INLINE float mp_obj_get_float_to_f(mp_obj_t o) { return (float)mp_obj_get_float(o); } -static inline double mp_obj_get_float_to_d(mp_obj_t o) { +static MP_INLINE double mp_obj_get_float_to_d(mp_obj_t o) { return mp_obj_get_float(o); } -static inline mp_obj_t mp_obj_new_float_from_f(float o) { +static MP_INLINE mp_obj_t mp_obj_new_float_from_f(float o) { return mp_obj_new_float((mp_float_t)o); } -static inline mp_obj_t mp_obj_new_float_from_d(double o) { +static MP_INLINE mp_obj_t mp_obj_new_float_from_d(double o) { return mp_obj_new_float(o); } #endif #if MICROPY_FLOAT_HIGH_QUALITY_HASH mp_int_t mp_float_hash(mp_float_t val); #else -static inline mp_int_t mp_float_hash(mp_float_t val) { +static MP_INLINE mp_int_t mp_float_hash(mp_float_t val) { return (mp_int_t)val; } #endif @@ -1031,7 +1031,7 @@ mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index); mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value); mp_obj_t mp_obj_dict_delete(mp_obj_t self_in, mp_obj_t key); mp_obj_t mp_obj_dict_copy(mp_obj_t self_in); -static inline mp_map_t *mp_obj_dict_get_map(mp_obj_t dict) { +static MP_INLINE mp_map_t *mp_obj_dict_get_map(mp_obj_t dict) { return &((mp_obj_dict_t *)MP_OBJ_TO_PTR(dict))->map; } diff --git a/py/objarray.c b/py/objarray.c index a66a73a5ac5f..763ec15cdb99 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/objdict.c b/py/objdict.c index 306205d12f8a..02aedacdd661 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -229,7 +229,7 @@ STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { /******************************************************************************/ /* dict methods */ -STATIC void mp_ensure_not_fixed(const mp_obj_dict_t *dict) { +STATIC void PLACE_IN_ITCM(mp_ensure_not_fixed)(const mp_obj_dict_t * dict) { if (dict->map.is_fixed) { mp_raise_TypeError(NULL); } @@ -643,7 +643,7 @@ size_t mp_obj_dict_len(mp_obj_t self_in) { return self->map.used; } -mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value) { +mp_obj_t PLACE_IN_ITCM(mp_obj_dict_store)(mp_obj_t self_in, mp_obj_t key, mp_obj_t value) { mp_check_self(mp_obj_is_dict_or_ordereddict(self_in)); mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); mp_ensure_not_fixed(self); diff --git a/py/objexcept.c b/py/objexcept.c index 80da4870761d..e05c3ca8d739 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); @@ -170,7 +176,7 @@ mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_obj_tuple_t *o_tuple; if (n_args == 0) { - // No args, can use the empty tuple straightaway + // No args, can use the empty tuple straight away o_tuple = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj; } else { // Try to allocate memory for the tuple containing the args @@ -228,7 +234,7 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { 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_varg(MP_ERROR_TEXT("%q must be of type %q or None"), MP_QSTR___context__, MP_QSTR_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]); } @@ -240,7 +246,7 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } 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 None"), attr, MP_QSTR_BaseException); + 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 @@ -250,7 +256,7 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } 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 None"), attr, MP_QSTR_BaseException); + 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__) { @@ -583,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 77b338e9518b..1230fdf18a53 100644 --- a/py/objexcept.h +++ b/py/objexcept.h @@ -43,6 +43,7 @@ typedef struct _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/objfun.c b/py/objfun.c index 55c3fbbb06df..5a02869fcf21 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -50,7 +50,7 @@ /******************************************************************************/ /* builtin functions */ -STATIC mp_obj_t fun_builtin_0_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_builtin_0_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { (void)args; assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_0)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); @@ -68,7 +68,7 @@ const mp_obj_type_t mp_type_fun_builtin_0 = { ), }; -STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_builtin_1_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_1)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); mp_arg_check_num(n_args, n_kw, 1, 1, false); @@ -85,7 +85,7 @@ const mp_obj_type_t mp_type_fun_builtin_1 = { ), }; -STATIC mp_obj_t fun_builtin_2_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_builtin_2_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_2)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); mp_arg_check_num(n_args, n_kw, 2, 2, false); @@ -102,7 +102,7 @@ const mp_obj_type_t mp_type_fun_builtin_2 = { ), }; -STATIC mp_obj_t fun_builtin_3_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_builtin_3_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_3)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); mp_arg_check_num(n_args, n_kw, 3, 3, false); @@ -119,7 +119,7 @@ const mp_obj_type_t mp_type_fun_builtin_3 = { ), }; -STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_builtin_var_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_var)); mp_obj_fun_builtin_var_t *self = MP_OBJ_TO_PTR(self_in); @@ -418,7 +418,7 @@ mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args_in, mp_obj_t def_kw_args, const byt #if MICROPY_EMIT_NATIVE -STATIC mp_obj_t fun_native_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_native_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { MP_STACK_CHECK(); mp_obj_fun_bc_t *self = self_in; mp_call_fun_t fun = MICROPY_MAKE_POINTER_CALLABLE((void *)self->bytecode); @@ -505,7 +505,7 @@ STATIC mp_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { } } -STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_asm_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_obj_fun_asm_t *self = self_in; mp_arg_check_num(n_args, n_kw, self->n_args, self->n_args, false); diff --git a/py/objgenerator.c b/py/objgenerator.c index 2256911e23d0..7c3ec99307bc 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -40,10 +40,11 @@ // Instance of GeneratorExit exception - needed by generator.close() #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 -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}; /******************************************************************************/ /* generator wrapper */ @@ -370,9 +371,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gen_instance_throw_obj, 2, 4, gen_ins static mp_obj_t generatorexit(void) { #if MICROPY_CPYTHON_EXCEPTION_CHAIN MP_STATIC_ASSERT(!MICROPY_CONST_GENERATOREXIT_OBJ); - mp_static_GeneratorExit_obj.context = NULL; - mp_static_GeneratorExit_obj.cause = NULL; - mp_static_GeneratorExit_obj.suppress_context = false; + mp_obj_exception_initialize0(&mp_static_GeneratorExit_obj, &mp_type_GeneratorExit); #endif return MP_OBJ_FROM_PTR(&mp_static_GeneratorExit_obj); } diff --git a/py/objmodule.c b/py/objmodule.c index a9d20c7ee537..8f04a445977b 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/objproperty.c b/py/objproperty.c index e8ae5094fa28..f55efc8bdbb6 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -99,7 +99,7 @@ const mp_obj_type_t mp_type_property = { extern const mp_obj_property_t __property_getter_start, __property_getter_end, __property_getset_start, __property_getset_end; #endif -const mp_obj_t *mp_obj_property_get(mp_obj_t self_in, size_t *n_proxy) { +const mp_obj_t *PLACE_IN_ITCM(mp_obj_property_get)(mp_obj_t self_in, size_t *n_proxy) { mp_check_self(mp_obj_is_type(self_in, &mp_type_property)); mp_obj_property_t *self = MP_OBJ_TO_PTR(self_in); #if MICROPY_PY_OPTIMIZE_PROPERTY_FLASH_SIZE diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 863bbd42d702..b3b23d0f01af 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(translate("%q must be of type %q"), MP_QSTR_index, MP_QSTR_int); + 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/objtuple.h b/py/objtuple.h index 7bfb447fa4c5..ded265b47e01 100644 --- a/py/objtuple.h +++ b/py/objtuple.h @@ -50,6 +50,9 @@ mp_obj_t mp_obj_tuple_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf); extern const mp_obj_type_t mp_type_attrtuple; +// Relies on gcc Variadic Macros and Statement Expressions +#define MP_OBJ_NEW_TUPLE(...) ({mp_obj_t _z[] = {__VA_ARGS__}; mp_obj_new_tuple(MP_ARRAY_SIZE(_z), _z);}) + #define MP_DEFINE_ATTRTUPLE(tuple_obj_name, fields, nitems, ...) \ const mp_rom_obj_tuple_t tuple_obj_name = { \ .base = {&mp_type_attrtuple}, \ diff --git a/py/objtype.c b/py/objtype.c index 76b9551be8de..5b04c361e18b 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -649,7 +649,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des mp_obj_t member = dest[0]; if (member != MP_OBJ_NULL) { if (!(self->base.type->flags & MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS)) { - // Class doesn't have any special accessors to check so return straightaway + // Class doesn't have any special accessors to check so return straight away return; } diff --git a/py/py.mk b/py/py.mk index 0cbfd252f2df..c598f44cbd25 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 $@" diff --git a/py/pystack.c b/py/pystack.c index 43dfd4ed6cbb..696b033377c0 100644 --- a/py/pystack.c +++ b/py/pystack.c @@ -36,7 +36,7 @@ void mp_pystack_init(void *start, void *end) { MP_STATE_THREAD(pystack_cur) = start; } -void *mp_pystack_alloc(size_t n_bytes) { +void *PLACE_IN_ITCM(mp_pystack_alloc)(size_t n_bytes) { n_bytes = (n_bytes + (MICROPY_PYSTACK_ALIGN - 1)) & ~(MICROPY_PYSTACK_ALIGN - 1); #if MP_PYSTACK_DEBUG n_bytes += MICROPY_PYSTACK_ALIGN; diff --git a/py/pystack.h b/py/pystack.h index ed51e0c7e36c..169d58b6f778 100644 --- a/py/pystack.h +++ b/py/pystack.h @@ -41,7 +41,7 @@ void *mp_pystack_alloc(size_t n_bytes); // This function can free multiple continuous blocks at once: just pass the // pointer to the block that was allocated first and it and all subsequently // allocated blocks will be freed. -static inline void mp_pystack_free(void *ptr) { +static MP_INLINE void mp_pystack_free(void *ptr) { assert((uint8_t *)ptr >= MP_STATE_THREAD(pystack_start)); assert((uint8_t *)ptr <= MP_STATE_THREAD(pystack_cur)); #if MP_PYSTACK_DEBUG @@ -59,16 +59,16 @@ static inline void mp_pystack_free(void *ptr) { MP_STATE_THREAD(pystack_cur) = (uint8_t *)ptr; } -static inline void mp_pystack_realloc(void *ptr, size_t n_bytes) { +static MP_INLINE void mp_pystack_realloc(void *ptr, size_t n_bytes) { mp_pystack_free(ptr); mp_pystack_alloc(n_bytes); } -static inline size_t mp_pystack_usage(void) { +static MP_INLINE size_t mp_pystack_usage(void) { return MP_STATE_THREAD(pystack_cur) - MP_STATE_THREAD(pystack_start); } -static inline size_t mp_pystack_limit(void) { +static MP_INLINE size_t mp_pystack_limit(void) { return MP_STATE_THREAD(pystack_end) - MP_STATE_THREAD(pystack_start); } @@ -78,43 +78,43 @@ static inline size_t mp_pystack_limit(void) { #define mp_local_alloc(n_bytes) alloca(n_bytes) -static inline void mp_local_free(void *ptr) { +static MP_INLINE void mp_local_free(void *ptr) { (void)ptr; } -static inline void *mp_nonlocal_alloc(size_t n_bytes) { +static MP_INLINE void *mp_nonlocal_alloc(size_t n_bytes) { return m_new(uint8_t, n_bytes); } -static inline void *mp_nonlocal_realloc(void *ptr, size_t old_n_bytes, size_t new_n_bytes) { +static MP_INLINE void *mp_nonlocal_realloc(void *ptr, size_t old_n_bytes, size_t new_n_bytes) { return m_renew(uint8_t, ptr, old_n_bytes, new_n_bytes); } -static inline void mp_nonlocal_free(void *ptr, size_t n_bytes) { +static MP_INLINE void mp_nonlocal_free(void *ptr, size_t n_bytes) { m_del(uint8_t, ptr, n_bytes); } #else -static inline void *mp_local_alloc(size_t n_bytes) { +static MP_INLINE void *mp_local_alloc(size_t n_bytes) { return mp_pystack_alloc(n_bytes); } -static inline void mp_local_free(void *ptr) { +static MP_INLINE void mp_local_free(void *ptr) { mp_pystack_free(ptr); } -static inline void *mp_nonlocal_alloc(size_t n_bytes) { +static MP_INLINE void *mp_nonlocal_alloc(size_t n_bytes) { return mp_pystack_alloc(n_bytes); } -static inline void *mp_nonlocal_realloc(void *ptr, size_t old_n_bytes, size_t new_n_bytes) { +static MP_INLINE void *mp_nonlocal_realloc(void *ptr, size_t old_n_bytes, size_t new_n_bytes) { (void)old_n_bytes; mp_pystack_realloc(ptr, new_n_bytes); return ptr; } -static inline void mp_nonlocal_free(void *ptr, size_t n_bytes) { +static MP_INLINE void mp_nonlocal_free(void *ptr, size_t n_bytes) { (void)n_bytes; mp_pystack_free(ptr); } diff --git a/py/qstr.c b/py/qstr.c index 083e12d6f01e..96e2a79192fe 100644 --- a/py/qstr.c +++ b/py/qstr.c @@ -137,7 +137,7 @@ void qstr_init(void) { #endif } -STATIC const char *find_qstr(qstr q, qstr_attr_t *attr) { +STATIC const char *PLACE_IN_ITCM(find_qstr)(qstr q, qstr_attr_t *attr) { // search pool for this qstr // total_prev_len==0 in the final pool, so the loop will always terminate const qstr_pool_t *pool = MP_STATE_VM(last_pool); diff --git a/py/ringbuf.c b/py/ringbuf.c index 8a4cb33cbc89..5936b6423062 100644 --- a/py/ringbuf.c +++ b/py/ringbuf.c @@ -72,7 +72,6 @@ int ringbuf_get16(ringbuf_t *r) { if (r->used < 2) { return -1; } - int high_byte = ringbuf_get(r); int low_byte = ringbuf_get(r); return (high_byte << 8) | low_byte; @@ -92,6 +91,15 @@ int ringbuf_put(ringbuf_t *r, uint8_t v) { return 0; } +int ringbuf_put16(ringbuf_t *r, uint16_t v) { + if (r->size - r->used < 2) { + return -1; + } + ringbuf_put(r, (v >> 8) & 0xff); + ringbuf_put(r, v & 0xff); + return 0; +} + void ringbuf_clear(ringbuf_t *r) { r->next_write = 0; r->next_read = 0; @@ -132,13 +140,3 @@ size_t ringbuf_get_n(ringbuf_t *r, uint8_t *buf, size_t bufsize) { } return bufsize; } - -int ringbuf_put16(ringbuf_t *r, uint16_t v) { - if (r->size - r->used < 2) { - return -1; - } - - ringbuf_put(r, (v >> 8) & 0xff); - ringbuf_put(r, v & 0xff); - return 0; -} diff --git a/py/runtime.c b/py/runtime.c index 9779456d0ca3..804b955e0745 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 @@ -418,7 +414,7 @@ mp_obj_t MICROPY_WRAP_MP_BINARY_OP(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs } else { // standard precision is enough for right-shift if (rhs_val >= (mp_int_t)(sizeof(lhs_val) * MP_BITS_PER_BYTE)) { - // Shifting to big amounts is underfined behavior + // Shifting to big amounts is undefined behavior // in C and is CPU-dependent; propagate sign bit. rhs_val = sizeof(lhs_val) * MP_BITS_PER_BYTE - 1; } @@ -1592,7 +1588,7 @@ mp_obj_t mp_parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t parse_i #endif // MICROPY_ENABLE_COMPILER -NORETURN void m_malloc_fail(size_t num_bytes) { +NORETURN MP_COLD void m_malloc_fail(size_t num_bytes) { DEBUG_printf("memory allocation failed, allocating %u bytes\n", (uint)num_bytes); #if MICROPY_ENABLE_GC if (gc_is_locked()) { @@ -1605,25 +1601,25 @@ NORETURN void m_malloc_fail(size_t num_bytes) { #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE -NORETURN void mp_raise_type(const mp_obj_type_t *exc_type) { +NORETURN MP_COLD void mp_raise_type(const mp_obj_type_t *exc_type) { nlr_raise(mp_obj_new_exception(exc_type)); } -NORETURN void mp_raise_ValueError_no_msg(void) { +NORETURN MP_COLD void mp_raise_ValueError_no_msg(void) { mp_raise_type(&mp_type_ValueError); } -NORETURN void mp_raise_TypeError_no_msg(void) { +NORETURN MP_COLD void mp_raise_TypeError_no_msg(void) { mp_raise_type(&mp_type_TypeError); } -NORETURN void mp_raise_NotImplementedError_no_msg(void) { +NORETURN MP_COLD void mp_raise_NotImplementedError_no_msg(void) { mp_raise_type(&mp_type_NotImplementedError); } #else -NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg) { if (msg == NULL) { nlr_raise(mp_obj_new_exception(exc_type)); } else { @@ -1631,19 +1627,19 @@ NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_strin } } -NORETURN void mp_raise_msg_vlist(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, va_list argptr) { +NORETURN MP_COLD void mp_raise_msg_vlist(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, va_list argptr) { mp_obj_t exception = mp_obj_new_exception_msg_vlist(exc_type, fmt, argptr); nlr_raise(exception); } -NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(exc_type, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char *msg) { +NORETURN MP_COLD void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char *msg) { if (msg == NULL) { nlr_raise(mp_obj_new_exception(exc_type)); } else { @@ -1651,56 +1647,56 @@ NORETURN void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char *msg) { } } -NORETURN void mp_raise_AttributeError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_AttributeError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_AttributeError, msg); } -NORETURN void mp_raise_RuntimeError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_RuntimeError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_RuntimeError, msg); } -NORETURN void mp_raise_ImportError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_ImportError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_ImportError, msg); } -NORETURN void mp_raise_IndexError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_IndexError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_IndexError, msg); } -NORETURN void mp_raise_IndexError_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_IndexError_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_IndexError, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_ValueError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_ValueError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_ValueError, msg); } -NORETURN void mp_raise_ValueError_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_ValueError_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_ValueError, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_TypeError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_TypeError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_TypeError, msg); } -NORETURN void mp_raise_TypeError_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_TypeError_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_TypeError, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_OSError_msg(const compressed_string_t *msg) { mp_raise_msg(&mp_type_OSError, msg); } -NORETURN void mp_raise_OSError_errno_str(int errno_, mp_obj_t str) { +NORETURN MP_COLD void mp_raise_OSError_errno_str(int errno_, mp_obj_t str) { mp_obj_t args[2] = { MP_OBJ_NEW_SMALL_INT(errno_), str, @@ -1708,26 +1704,26 @@ NORETURN void mp_raise_OSError_errno_str(int errno_, mp_obj_t str) { nlr_raise(mp_obj_new_exception_args(&mp_type_OSError, 2, args)); } -NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_OSError, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_ConnectionError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_ConnectionError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_ConnectionError, msg); } -NORETURN void mp_raise_BrokenPipeError(void) { +NORETURN MP_COLD void mp_raise_BrokenPipeError(void) { mp_raise_type_arg(&mp_type_BrokenPipeError, MP_OBJ_NEW_SMALL_INT(MP_EPIPE)); } -NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_NotImplementedError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_NotImplementedError, msg); } -NORETURN void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_NotImplementedError, fmt, argptr); @@ -1735,17 +1731,18 @@ NORETURN void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, } -NORETURN void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_OverflowError, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_type_arg(const mp_obj_type_t *exc_type, mp_obj_t arg) { +NORETURN MP_COLD 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)); } +// Leave this as not COLD because it is used by iterators in normal execution. NORETURN void mp_raise_StopIteration(mp_obj_t arg) { if (arg == MP_OBJ_NULL) { mp_raise_type(&mp_type_StopIteration); @@ -1754,18 +1751,18 @@ NORETURN void mp_raise_StopIteration(mp_obj_t arg) { } } -NORETURN void mp_raise_OSError(int errno_) { +NORETURN MP_COLD void mp_raise_OSError(int errno_) { mp_raise_type_arg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_)); } #endif #if MICROPY_STACK_CHECK || MICROPY_ENABLE_PYSTACK -NORETURN void mp_raise_recursion_depth(void) { +NORETURN MP_COLD void mp_raise_recursion_depth(void) { mp_raise_RuntimeError(MP_ERROR_TEXT("maximum recursion depth exceeded")); } #endif -NORETURN void mp_raise_ZeroDivisionError(void) { +NORETURN MP_COLD 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 a5f66b150726..d154772508b5 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -86,7 +86,7 @@ bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg); int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char, int flags, char fill, int width, int prec); void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig); -static inline void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) { +static MP_INLINE void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) { mp_arg_check_num_sig(n_args, n_kw, MP_OBJ_FUN_MAKE_SIG(n_args_min, n_args_max, takes_kw)); } 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); @@ -110,19 +110,21 @@ 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); -static inline mp_obj_dict_t *PLACE_IN_ITCM(mp_locals_get)(void) { +static MP_INLINE mp_obj_dict_t *mp_locals_get(void) { return MP_STATE_THREAD(dict_locals); } -static inline void PLACE_IN_ITCM(mp_locals_set)(mp_obj_dict_t * d) { +static MP_INLINE void mp_locals_set(mp_obj_dict_t *d) { MP_STATE_THREAD(dict_locals) = d; } -static inline mp_obj_dict_t *PLACE_IN_ITCM(mp_globals_get)(void) { +static MP_INLINE mp_obj_dict_t *mp_globals_get(void) { return MP_STATE_THREAD(dict_globals); } -static inline void PLACE_IN_ITCM(mp_globals_set)(mp_obj_dict_t * d) { +static MP_INLINE void mp_globals_set(mp_obj_dict_t *d) { MP_STATE_THREAD(dict_globals) = d; } @@ -179,7 +181,7 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o); // may return MP_OBJ_STOP_ITERATIO mp_obj_t mp_iternext(mp_obj_t o); // will always return MP_OBJ_STOP_ITERATION instead of raising StopIteration(...) mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val); -static inline mp_obj_t mp_make_stop_iteration(mp_obj_t o) { +static MP_INLINE mp_obj_t mp_make_stop_iteration(mp_obj_t o) { MP_STATE_THREAD(stop_iteration_arg) = o; return MP_OBJ_STOP_ITERATION; } diff --git a/py/scope.h b/py/scope.h index 8b0542107229..b189260a37a6 100644 --- a/py/scope.h +++ b/py/scope.h @@ -49,7 +49,7 @@ typedef struct _id_info_t { uint8_t kind; uint8_t flags; // when it's an ID_INFO_KIND_LOCAL this is the unique number of the local - // whet it's an ID_INFO_KIND_CELL/FREE this is the unique number of the closed over variable + // when it's an ID_INFO_KIND_CELL/FREE this is the unique number of the closed over variable uint16_t local_num; qstr qst; } id_info_t; diff --git a/py/sequence.c b/py/sequence.c index 7befc857637a..42a9a4a0ae18 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -171,7 +171,7 @@ bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, size_t len1, const mp continue; } - // Othewise, if they are not equal, we can have final decision based on them + // Otherwise, if they are not equal, we can have final decision based on them if (op == MP_BINARY_OP_EQUAL) { // In particular, if we are checking for equality, here're the answer return false; diff --git a/py/stackctrl.c b/py/stackctrl.c index d699d6da6141..546987f04d33 100644 --- a/py/stackctrl.c +++ b/py/stackctrl.c @@ -38,7 +38,7 @@ void mp_stack_set_top(void *top) { MP_STATE_THREAD(stack_top) = top; } -mp_uint_t mp_stack_usage(void) { +mp_uint_t PLACE_IN_ITCM(mp_stack_usage)(void) { // Assumes descending stack // Force routine to not be inlined. Better guarantee than MP_NOINLINE for -flto. __asm volatile (""); @@ -52,7 +52,7 @@ void mp_stack_set_limit(mp_uint_t limit) { MP_STATE_THREAD(stack_limit) = limit; } -void mp_stack_check(void) { +void PLACE_IN_ITCM(mp_stack_check)(void) { if (mp_stack_usage() >= MP_STATE_THREAD(stack_limit)) { mp_raise_recursion_depth(); } diff --git a/requirements-ci.txt b/requirements-ci.txt index 81deb34beb04..2f6e042fb81d 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 0dcfad39567b..5efa084652bf 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,6 +6,7 @@ typer sh click cpp-coveralls + requests requests-cache @@ -13,8 +14,8 @@ requests-cache polib # For pre-commit -pyyaml black +pyyaml pre-commit # for combining the Nordic SoftDevice with CircuitPython @@ -23,12 +24,13 @@ intelhex # for building & testing natmods pyelftools -# for stubs and annotations -adafruit-circuitpython-typing - # for mbedtls certificate store cryptography # for web workflow minify minify_html jsmin + +# for Silicon Labs Configurator (SLC) +websockets +colorama diff --git a/requirements-doc.txt b/requirements-doc.txt index 43e99fa32fa1..0489dc0b9f29 100644 --- a/requirements-doc.txt +++ b/requirements-doc.txt @@ -13,6 +13,7 @@ sphinx!=5.2.0.post0 sphinx-autoapi sphinx-rtd-theme sphinxcontrib-svg2pdfconverter +sphinxcontrib-jquery readthedocs-sphinx-search myst-parser diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c index e1c5fc3ad541..823250c36510 100644 --- a/shared-bindings/_bleio/Characteristic.c +++ b/shared-bindings/_bleio/Characteristic.c @@ -256,7 +256,8 @@ 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]); diff --git a/shared-bindings/_bleio/CharacteristicBuffer.c b/shared-bindings/_bleio/CharacteristicBuffer.c index 12853b3ac3da..1efb992c723d 100644 --- a/shared-bindings/_bleio/CharacteristicBuffer.c +++ b/shared-bindings/_bleio/CharacteristicBuffer.c @@ -47,7 +47,6 @@ STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self //| 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. //| @@ -160,7 +159,12 @@ STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r 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); diff --git a/shared-bindings/_bleio/CharacteristicBuffer.h b/shared-bindings/_bleio/CharacteristicBuffer.h index de85f019bcbe..9dc3252d5a46 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/ScanResults.c b/shared-bindings/_bleio/ScanResults.c index b0f37d9fe50c..ec4e0c72e85b 100644 --- a/shared-bindings/_bleio/ScanResults.c +++ b/shared-bindings/_bleio/ScanResults.c @@ -54,7 +54,8 @@ STATIC mp_obj_t scanresults_iternext(mp_obj_t self_in) { //| ... //| 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/__init__.c b/shared-bindings/_bleio/__init__.c index 1ec2a2758af8..f34d3af5c52f 100644 --- a/shared-bindings/_bleio/__init__.c +++ b/shared-bindings/_bleio/__init__.c @@ -58,6 +58,7 @@ //| adapter: Adapter //| """BLE Adapter used to manage device discovery and connections. //| This object is the sole instance of `_bleio.Adapter`.""" +//| //| class BluetoothError(Exception): //| """Catchall exception for Bluetooth related errors.""" @@ -121,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 @@ -132,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 bd0cf9b4ead8..5975ee1ca177 100644 --- a/shared-bindings/_eve/__init__.c +++ b/shared-bindings/_eve/__init__.c @@ -93,7 +93,8 @@ 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) { @@ -109,7 +110,8 @@ 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) { @@ -137,7 +139,8 @@ 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) { @@ -218,7 +221,8 @@ 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) { @@ -255,7 +259,8 @@ 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) { @@ -274,7 +279,8 @@ 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) { @@ -290,7 +296,8 @@ 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) { @@ -308,7 +315,8 @@ 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) { @@ -327,7 +335,8 @@ 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) { @@ -343,7 +352,8 @@ 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) { @@ -359,7 +369,8 @@ 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) { @@ -388,7 +399,8 @@ 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) { @@ -403,7 +415,8 @@ 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) { @@ -420,7 +433,8 @@ 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) { @@ -454,7 +468,8 @@ 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) { @@ -469,7 +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); @@ -483,7 +499,8 @@ 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) { @@ -501,7 +518,8 @@ 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) { @@ -521,7 +539,8 @@ 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) { @@ -547,7 +566,8 @@ 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) { @@ -599,7 +619,8 @@ 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) { @@ -648,7 +669,8 @@ 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) { @@ -665,7 +687,8 @@ 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) { @@ -683,7 +706,8 @@ 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) { @@ -700,7 +724,8 @@ 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) { @@ -716,7 +741,8 @@ 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) { @@ -732,7 +758,8 @@ 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) { @@ -747,7 +774,8 @@ 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) { @@ -857,7 +885,8 @@ 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) { @@ -872,7 +901,8 @@ 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) { @@ -887,7 +917,8 @@ 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) { @@ -902,7 +933,8 @@ 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`. +//| """ //| ... @@ -918,7 +950,8 @@ 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`. +//| """ //| ... // } diff --git a/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c b/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c index d2b7f0c6cea4..a77179c88663 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. //| diff --git a/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c b/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c index 6626d27f773b..6108247aa116 100644 --- a/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +++ b/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c @@ -51,7 +51,6 @@ //| phase: int = 0, //| extra_clocks: int = 0 //| ) -> None: -//| //| """ //| Represents a single SPI device and manages locking the bus and the device address. //| diff --git a/shared-bindings/adafruit_pixelbuf/PixelBuf.c b/shared-bindings/adafruit_pixelbuf/PixelBuf.c index cf18804ec9a2..2848a02c6246 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 @@ -78,7 +78,8 @@ 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 }; diff --git a/shared-bindings/aesio/aes.c b/shared-bindings/aesio/aes.c index 9170b6379923..c5c50515eaa2 100644 --- a/shared-bindings/aesio/aes.c +++ b/shared-bindings/aesio/aes.c @@ -20,7 +20,7 @@ //| self, //| key: ReadableBuffer, //| mode: int = 0, -//| iv: Optional[ReadableBuffer] = None, +//| IV: Optional[ReadableBuffer] = None, //| segment_size: int = 8, //| ) -> None: //| """Create a new AES state with the given key. @@ -28,7 +28,7 @@ //| :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 IV: Initialization vector to use for CBC or CTR mode //| //| Additional arguments are supported for legacy reasons. //| @@ -47,7 +47,9 @@ 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} }, @@ -61,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; @@ -82,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; } @@ -101,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) { @@ -142,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: @@ -164,28 +172,21 @@ STATIC void validate_length(aesio_aes_obj_t *self, size_t src_length, //| 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``. @@ -194,43 +195,31 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(aesio_aes_encrypt_into_obj, //| 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) { @@ -239,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/__init__.c b/shared-bindings/alarm/__init__.c index 48dccff8dfe1..94879e14d417 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -71,8 +71,9 @@ //| wake_alarm: Optional[circuitpython_typing.Alarm] //| """The most recently triggered alarm. If CircuitPython was sleeping, the alarm that woke it from sleep. -//| If no alarm occured since the last hard reset or soft restart, value is ``None``. +//| If no alarm occurred since the last hard reset or soft restart, value is ``None``. //| """ +//| // wake_alarm is implemented as a dictionary entry, so there's no code here. @@ -86,7 +87,7 @@ STATIC void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { mp_obj_is_type(objs[i], &alarm_touch_touchalarm_type)) { continue; } - mp_raise_TypeError_varg(translate("Expected an %q"), MP_QSTR_Alarm); + mp_raise_TypeError_varg(translate("Expected a kind of %q"), MP_QSTR_Alarm); } } @@ -207,10 +208,7 @@ STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_o 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); - if (!mp_obj_is_type(dio, &digitalio_digitalinout_type)) { - mp_raise_TypeError_varg(translate("Expected a %q"), MP_QSTR_DigitalInOut); - } - dios_array[i] = MP_OBJ_TO_PTR(dio); + 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); diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 82bfae4286dd..c47f482e7467 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -33,7 +33,7 @@ #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 +// the same alarm object that was originally passed in, unlike deep sleep, which // must create an identical copy due to the VM reset extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index 6e8bc5341eb4..c75061b77a68 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -74,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, diff --git a/shared-bindings/alarm/time/TimeAlarm.c b/shared-bindings/alarm/time/TimeAlarm.c index abbb050c646d..86c96de1d45d 100644 --- a/shared-bindings/alarm/time/TimeAlarm.c +++ b/shared-bindings/alarm/time/TimeAlarm.c @@ -45,7 +45,7 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) { //| """Trigger an alarm when the specified time is reached.""" //| //| def __init__( -//| self, monotonic_time: Optional[float] = None, epoch_time: Optional[int] = None +//| 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``. diff --git a/shared-bindings/alarm/touch/TouchAlarm.c b/shared-bindings/alarm/touch/TouchAlarm.c index cce31e6ffe22..20612cb106d8 100644 --- a/shared-bindings/alarm/touch/TouchAlarm.c +++ b/shared-bindings/alarm/touch/TouchAlarm.c @@ -56,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 index 193552c31367..4641df6891f5 100644 --- a/shared-bindings/analogbufio/BufferedIn.c +++ b/shared-bindings/analogbufio/BufferedIn.c @@ -76,7 +76,7 @@ STATIC mp_obj_t analogbufio_bufferedin_make_new(const mp_obj_type_t *type, size_ 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); + 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); diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c index 800c0bfa21b9..3b71f688c809 100644 --- a/shared-bindings/analogio/AnalogIn.c +++ b/shared-bindings/analogio/AnalogIn.c @@ -37,7 +37,7 @@ #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); + return validate_obj_is_free_pin(obj, MP_QSTR_pin); } //| class AnalogIn: diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c index de6811b5a311..6b10d3757193 100644 --- a/shared-bindings/analogio/AnalogOut.c +++ b/shared-bindings/analogio/AnalogOut.c @@ -61,7 +61,7 @@ STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t // 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; diff --git a/shared-bindings/atexit/__init__.c b/shared-bindings/atexit/__init__.c index 914cac582b41..9a91e0bc8020 100644 --- a/shared-bindings/atexit/__init__.c +++ b/shared-bindings/atexit/__init__.c @@ -37,11 +37,11 @@ //| |see_cpython_module| :mod:`cpython:atexit`. //| """ //| ... +//| //| 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()`. @@ -65,7 +65,6 @@ 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, diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c index b570191da9fb..8c6f1a3a7a72 100644 --- a/shared-bindings/audiobusio/I2SOut.c +++ b/shared-bindings/audiobusio/I2SOut.c @@ -97,7 +97,7 @@ //| ... 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")); + mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_I2SOut); return NULL; // Not reachable. #else enum { ARG_bit_clock, ARG_word_select, ARG_data, ARG_left_justified }; @@ -110,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; diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index db19ab6eddf7..1f0e50029203 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -94,7 +94,7 @@ //| ... 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")); + mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_PDMIn); #else enum { ARG_clock_pin, ARG_data_pin, ARG_sample_rate, ARG_bit_depth, ARG_mono, ARG_oversample, ARG_startup_delay }; static const mp_arg_t allowed_args[] = { @@ -112,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); diff --git a/shared-bindings/audiocore/RawSample.c b/shared-bindings/audiocore/RawSample.c index d185476f0366..39992f87c179 100644 --- a/shared-bindings/audiocore/RawSample.c +++ b/shared-bindings/audiocore/RawSample.c @@ -40,7 +40,7 @@ //| 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 +//| """Create a RawSample based on the given buffer of 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 //| channel 1 and so on. diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c index 36204fa2b2e7..3a13db72a02e 100644 --- a/shared-bindings/audiocore/WaveFile.c +++ b/shared-bindings/audiocore/WaveFile.c @@ -32,6 +32,7 @@ #include "shared-bindings/audiocore/WaveFile.h" #include "shared-bindings/util.h" #include "supervisor/shared/translate/translate.h" +#include "extmod/vfs_posix.h" //| class WaveFile: //| """Load a wave file for audio playback diff --git a/shared-bindings/audiocore/__init__.c b/shared-bindings/audiocore/__init__.c index 2e3b479cf6b2..6f32979099db 100644 --- a/shared-bindings/audiocore/__init__.c +++ b/shared-bindings/audiocore/__init__.c @@ -29,7 +29,6 @@ #include "py/obj.h" #include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/audiocore/__init__.h" #include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/audiocore/WaveFile.h" @@ -37,10 +36,57 @@ //| """Support for audio samples""" +#if CIRCUITPY_AUDIOCORE_DEBUG +// (no docstrings so that the debug functions are not shown on docs.circuitpython.org) +STATIC mp_obj_t audiocore_get_buffer(mp_obj_t sample_in) { + uint8_t *buffer = NULL; + uint32_t buffer_length = 0; + audioio_get_buffer_result_t gbr = audiosample_get_buffer(sample_in, false, 0, &buffer, &buffer_length); + + mp_obj_t result[2] = {mp_obj_new_int_from_uint(gbr), mp_const_none}; + + if (gbr != GET_BUFFER_ERROR) { + // copies the data because the gc semantics of get_buffer are unclear + result[1] = mp_obj_new_bytes(buffer, buffer_length); + } + + return mp_obj_new_tuple(2, result); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiocore_get_buffer_obj, audiocore_get_buffer); + +STATIC mp_obj_t audiocore_get_structure(mp_obj_t sample_in) { + bool single_buffer, samples_signed; + uint32_t max_buffer_length; + uint8_t spacing; + + audiosample_get_buffer_structure(sample_in, false, &single_buffer, &samples_signed, &max_buffer_length, &spacing); + mp_obj_t result[4] = { + mp_obj_new_int_from_uint(single_buffer), + mp_obj_new_int_from_uint(samples_signed), + mp_obj_new_int_from_uint(max_buffer_length), + mp_obj_new_int_from_uint(spacing), + }; + return mp_obj_new_tuple(4, result); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiocore_get_structure_obj, audiocore_get_structure); + +STATIC mp_obj_t audiocore_reset_buffer(mp_obj_t sample_in) { + audiosample_reset_buffer(sample_in, false, 0); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiocore_reset_buffer_obj, audiocore_reset_buffer); + +#endif + STATIC const mp_rom_map_elem_t audiocore_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiocore) }, { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) }, { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) }, + #if CIRCUITPY_AUDIOCORE_DEBUG + { MP_ROM_QSTR(MP_QSTR_get_buffer), MP_ROM_PTR(&audiocore_get_buffer_obj) }, + { MP_ROM_QSTR(MP_QSTR_reset_buffer), MP_ROM_PTR(&audiocore_reset_buffer_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_structure), MP_ROM_PTR(&audiocore_get_structure_obj) }, + #endif }; STATIC MP_DEFINE_CONST_DICT(audiocore_module_globals, audiocore_module_globals_table); diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index a569097480ac..7909176114c9 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -105,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); diff --git a/shared-bindings/audiomixer/Mixer.c b/shared-bindings/audiomixer/Mixer.c index 58c618fc11e7..83fcc0671238 100644 --- a/shared-bindings/audiomixer/Mixer.c +++ b/shared-bindings/audiomixer/Mixer.c @@ -33,8 +33,6 @@ #include "py/binary.h" #include "py/objproperty.h" #include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/util.h" #include "supervisor/shared/translate/translate.h" diff --git a/shared-bindings/audiomixer/Mixer.h b/shared-bindings/audiomixer/Mixer.h index 88592a1cb3cd..d04f793ddec7 100644 --- a/shared-bindings/audiomixer/Mixer.h +++ b/shared-bindings/audiomixer/Mixer.h @@ -27,9 +27,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H #define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H -#include "common-hal/microcontroller/Pin.h" #include "shared-module/audiomixer/Mixer.h" -#include "shared-bindings/audiocore/RawSample.h" extern const mp_obj_type_t audiomixer_mixer_type; extern const mp_obj_type_t audiomixer_mixervoice_type; diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c index 0bdef1f4cdac..1d6cd7f39a56 100644 --- a/shared-bindings/audiomixer/MixerVoice.c +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -32,8 +32,6 @@ #include "py/binary.h" #include "py/objproperty.h" #include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/util.h" #include "supervisor/shared/translate/translate.h" @@ -62,7 +60,8 @@ 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 }; @@ -114,7 +113,7 @@ STATIC mp_obj_t audiomixer_mixervoice_obj_set_level(size_t n_args, const mp_obj_ 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); - float level = mp_obj_get_float(args[ARG_level].u_obj); + mp_float_t level = mp_obj_get_float(args[ARG_level].u_obj); if (level > 1 || level < 0) { mp_raise_ValueError(translate("level must be between 0 and 1")); diff --git a/shared-bindings/audiomixer/MixerVoice.h b/shared-bindings/audiomixer/MixerVoice.h index bce463276019..0ff8accee442 100644 --- a/shared-bindings/audiomixer/MixerVoice.h +++ b/shared-bindings/audiomixer/MixerVoice.h @@ -26,9 +26,6 @@ #ifndef SHARED_BINDINGS_AUDIOMIXER_MIXERVOICE_H_ #define SHARED_BINDINGS_AUDIOMIXER_MIXERVOICE_H_ -#include "common-hal/microcontroller/Pin.h" -#include "shared-bindings/audiocore/RawSample.h" - #include "shared-module/audiomixer/MixerVoice.h" #include "shared-module/audiomixer/Mixer.h" @@ -39,8 +36,8 @@ void common_hal_audiomixer_mixervoice_construct(audiomixer_mixervoice_obj_t *sel void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t *self, audiomixer_mixer_obj_t *parent); void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t *self, mp_obj_t sample, bool loop); void common_hal_audiomixer_mixervoice_stop(audiomixer_mixervoice_obj_t *self); -float common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self); -void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, float gain); +mp_float_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self); +void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_float_t gain); bool common_hal_audiomixer_mixervoice_get_playing(audiomixer_mixervoice_obj_t *self); diff --git a/shared-bindings/audiomixer/__init__.c b/shared-bindings/audiomixer/__init__.c index 8292be9e95e3..4c8068172bbe 100644 --- a/shared-bindings/audiomixer/__init__.c +++ b/shared-bindings/audiomixer/__init__.c @@ -29,7 +29,6 @@ #include "py/obj.h" #include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/audiomixer/Mixer.h" //| """Support for audio mixing""" diff --git a/shared-bindings/audiomp3/MP3Decoder.c b/shared-bindings/audiomp3/MP3Decoder.c index 4a8805b294cf..68e78cb0d595 100644 --- a/shared-bindings/audiomp3/MP3Decoder.c +++ b/shared-bindings/audiomp3/MP3Decoder.c @@ -45,7 +45,6 @@ //| """ //| //| def __init__(self, file: Union[str, typing.BinaryIO], buffer: WriteableBuffer) -> None: -//| //| """Load a .mp3 file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`. //| //| :param Union[str, typing.BinaryIO] file: The name of a mp3 file (preferred) or an already opened mp3 file diff --git a/shared-bindings/audiomp3/__init__.c b/shared-bindings/audiomp3/__init__.c index 948910c45e58..9fe525dfe23c 100644 --- a/shared-bindings/audiomp3/__init__.c +++ b/shared-bindings/audiomp3/__init__.c @@ -33,7 +33,7 @@ //| """Support for MP3-compressed audio files //| -//| For more infomration about working with MP3 files in CircuitPython, +//| For more information about working with MP3 files in CircuitPython, //| see `this CircuitPython Essentials Learn guide page //| `_. //| """ diff --git a/shared-bindings/audiopwmio/PWMAudioOut.c b/shared-bindings/audiopwmio/PWMAudioOut.c index 2e17bbda8cd8..f05fbfdfe92c 100644 --- a/shared-bindings/audiopwmio/PWMAudioOut.c +++ b/shared-bindings/audiopwmio/PWMAudioOut.c @@ -56,6 +56,10 @@ //| :param int quiescent_value: The output value when no signal is present. Samples should start //| and end with this value to prevent audible popping. //| +//| **Limitations:** On mimxrt10xx, low sample rates may have an audible +//| "carrier" frequency. The manufacturer datasheet states that the "MQS" peripheral +//| is intended for 44 kHz or 48kHz input signals. +//| //| Simple 8ksps 440 Hz sin wave:: //| //| import audiocore @@ -108,11 +112,18 @@ 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); + // The object is made long-lived because many implementations keep + // a pointer to the object (e.g., for the interrupt handler), which + // will not work properly if the object is moved. It is created + // with a finaliser as some ports use these (rather than 'reset' functions) + // to ensure resources are collected at interpreter shutdown. + audiopwmio_pwmaudioout_obj_t *self = m_new_ll_obj_with_finaliser(audiopwmio_pwmaudioout_obj_t); self->base.type = &audiopwmio_pwmaudioout_type; common_hal_audiopwmio_pwmaudioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int); @@ -247,6 +258,7 @@ MP_PROPERTY_GETTER(audiopwmio_pwmaudioout_paused_obj, STATIC const mp_rom_map_elem_t audiopwmio_pwmaudioout_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiopwmio_pwmaudioout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&audiopwmio_pwmaudioout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiopwmio_pwmaudioout___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiopwmio_pwmaudioout_play_obj) }, diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index 19c27740e306..9684b87df2ed 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" @@ -76,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; @@ -187,10 +188,15 @@ STATIC void readfrom(bitbangio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffe 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); @@ -244,10 +250,15 @@ STATIC void writeto(bitbangio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer 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); diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 1b7c877bdac4..cf4f34f0e48c 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" @@ -84,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; @@ -192,9 +193,19 @@ 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 }; @@ -211,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; } @@ -267,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; } @@ -337,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/bitmaptools/__init__.c b/shared-bindings/bitmaptools/__init__.c index dd62b515fe21..d0aea33ef95b 100644 --- a/shared-bindings/bitmaptools/__init__.c +++ b/shared-bindings/bitmaptools/__init__.c @@ -50,6 +50,7 @@ //| `_ //| for information about using the :py:mod:`displayio` module. //| """ +//| STATIC int16_t validate_point(mp_obj_t point, int16_t default_value) { // Checks if point is None and returns default_value, otherwise decodes integer value @@ -319,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 @@ -514,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; @@ -529,6 +523,101 @@ 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 draw_polygon( +//| dest_bitmap: displayio.Bitmap, +//| xs: ReadableBuffer, +//| ys: ReadableBuffer, +//| value: int, +//| close: Optional[bool] = True, +//| ) -> None: +//| """Draw a polygon connecting 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) Whether 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, @@ -541,7 +630,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_line_obj, 0, bitmaptools_obj_draw_li //| """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 -//| avalable in the destination bitmap. +//| available in the destination bitmap. //| //| If x1 or y1 are not specified, they are taken as 0. If x2 or y2 //| are not specified, or are given as -1, they are taken as the width @@ -633,7 +722,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_arrayblit_obj, 0, bitmaptools_arrayblit); //| :param typing.BinaryIO file: A file opened in binary mode //| :param int bits_per_pixel: Number of bits per pixel. Values 1, 2, 4, 8, 16, 24, and 32 are supported; //| :param int element_size: Number of bytes per element. Values of 1, 2, and 4 are supported, except that 24 ``bits_per_pixel`` requires 1 byte per element. -//| :param bool reverse_pixels_in_element: If set, the first pixel in a word is taken from the Most Signficant Bits; otherwise, it is taken from the Least Significant Bits. +//| :param bool reverse_pixels_in_element: If set, the first pixel in a word is taken from the Most Significant Bits; otherwise, it is taken from the Least Significant Bits. //| :param bool swap_bytes_in_element: If the ``element_size`` is not 1, then reverse the byte order of each element read. //| :param bool reverse_rows: Reverse the direction of the row loading (required for some bitmap images). //| """ @@ -693,7 +782,7 @@ STATIC mp_obj_t bitmaptools_readinto(size_t n_args, const mp_obj_t *pos_args, mp MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_readinto_obj, 0, bitmaptools_readinto); //| class DitherAlgorithm: -//| """Identifies the algorith for dither to use""" +//| """Identifies the algorithm for dither to use""" //| //| Atkinson: "DitherAlgorithm" //| """The classic Atkinson dither, often associated with the Hypercard esthetic""" @@ -741,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")); @@ -779,7 +868,86 @@ STATIC mp_obj_t bitmaptools_dither(size_t n_args, const mp_obj_t *pos_args, mp_m return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_dither_obj, 0, bitmaptools_dither); +// requires all 5 arguments + +//| def draw_circle( +//| dest_bitmap: displayio.Bitmap, x: int, y: int, radius: int, value: int +//| ) -> None: +//| """Draws a circle into a bitmap specified using a center (x0,y0) and radius r. +//| +//| :param bitmap dest_bitmap: Destination bitmap that will be written into +//| :param int x: x-pixel position of the circle's center +//| :param int y: y-pixel position of the circle's center +//| :param int radius: circle's radius +//| :param int value: Bitmap palette index that will be written into the +//| circle in the destination bitmap +//| +//| .. code-block:: Python +//| +//| import board +//| import displayio +//| import bitmaptools +//| +//| display = board.DISPLAY +//| main_group = displayio.Group() +//| display.root_group = main_group +//| +//| palette = displayio.Palette(2) +//| palette[0] = 0xffffff +//| palette[1] = 0x440044 +//| +//| bmp = displayio.Bitmap(128,128, 2) +//| bmp.fill(0) +//| +//| bitmaptools.circle(64,64, 32, 1) +//| +//| tilegrid = displayio.TileGrid(bitmap=bmp, pixel_shader=palette) +//| main_group.append(tilegrid) +//| +//| while True: +//| pass +//| +//| """ +//| +//| ... +//| +STATIC mp_obj_t bitmaptools_obj_draw_circle(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_dest_bitmap, ARG_x, ARG_y, ARG_radius, ARG_value}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_radius, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT}, + }; + 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 + + 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")); + } + + + int16_t x = args[ARG_x].u_int; + int16_t y = args[ARG_y].u_int; + int16_t radius = args[ARG_radius].u_int; + + mp_arg_validate_int_range(x, 0, destination->width, MP_QSTR_x); + mp_arg_validate_int_range(y, 0, destination->height, MP_QSTR_y); + mp_arg_validate_int_min(radius, 0, MP_QSTR_radius); + + common_hal_bitmaptools_draw_circle(destination, x, y, radius, value); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_circle_obj, 0, bitmaptools_obj_draw_circle); STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bitmaptools) }, @@ -790,6 +958,8 @@ 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_draw_circle), MP_ROM_PTR(&bitmaptools_draw_circle_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 fb5c78911f64..21fb1b50ab51 100644 --- a/shared-bindings/bitmaptools/__init__.h +++ b/shared-bindings/bitmaptools/__init__.h @@ -64,6 +64,12 @@ void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination, int16_t x1, int16_t y1, uint32_t value); +void common_hal_bitmaptools_draw_circle(displayio_bitmap_t *destination, + int16_t x, int16_t y, + int16_t radius, + 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 ea4e70ae3aaf..3107b310dbd7 100644 --- a/shared-bindings/bitops/__init__.c +++ b/shared-bindings/bitops/__init__.c @@ -30,6 +30,7 @@ #include "shared-bindings/bitops/__init__.h" //| """Routines for low-level manipulation of binary data""" +//| //| def bit_transpose( //| input: ReadableBuffer, output: WriteableBuffer, width: int = 8 diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c index e4003d4f6bf1..99b99b37ea89 100644 --- a/shared-bindings/board/__init__.c +++ b/shared-bindings/board/__init__.c @@ -43,7 +43,7 @@ //| Common container for board base pin names. These will vary from board to //| board so don't expect portability when using this module. //| -//| Another common use of this module is to use serial communciation buses with +//| Another common use of this module is to use serial communication buses with //| the default pins and settings. For more information about serial communcication //| in CircuitPython, see the :mod:`busio`. //| @@ -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 e589dea08bf5..5cf52eaa1a1a 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/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/runtime.h" #include "supervisor/shared/translate/translate.h" @@ -47,7 +48,6 @@ //| 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. @@ -80,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; @@ -207,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) { @@ -260,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); @@ -331,23 +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); 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 badf80bf935c..ccdceb57607a 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" @@ -60,7 +61,6 @@ //| 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, @@ -103,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")); @@ -264,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; } @@ -323,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; } @@ -392,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")); } @@ -463,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 76166580a0fd..3b8f831219e9 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 59e46cafc420..a10dc8efad80 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -48,9 +48,13 @@ //| //| def __init__( //| self, -//| tx: microcontroller.Pin, -//| rx: microcontroller.Pin, +//| 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, @@ -74,11 +78,13 @@ //| :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. //| //| **Limitations:** RS485 is not supported on SAMD, nRF, Broadcom, Spresense, or STM. -//| On i.MX and Raspberry Pi RP2040 support is implemented in software: +//| 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. //| """ @@ -116,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; @@ -137,15 +153,11 @@ 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. // This is needed to avoid crashes with certain UART implementations which - // cannot accomodate being moved after creation. (See + // cannot accommodate being moved after creation. (See // https://github.com/adafruit/circuitpython/issues/1056) busio_uart_obj_t *self = m_new_ll_obj_with_finaliser(busio_uart_obj_t); self->base.type = &busio_uart_type; diff --git a/shared-bindings/canio/CAN.c b/shared-bindings/canio/CAN.c index b2e85c02442e..bce581f50128 100644 --- a/shared-bindings/canio/CAN.c +++ b/shared-bindings/canio/CAN.c @@ -77,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")); } @@ -233,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; @@ -272,7 +268,7 @@ STATIC mp_obj_t canio_can_send(mp_obj_t self_in, mp_obj_t message_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; diff --git a/shared-bindings/canio/__init__.c b/shared-bindings/canio/__init__.c index 0416e5cb39b5..ecef7ebde6db 100644 --- a/shared-bindings/canio/__init__.c +++ b/shared-bindings/canio/__init__.c @@ -58,6 +58,7 @@ //| For more information on working with this module, refer to //| `this Learn Guide on using it `_. //| """ +//| #include "py/obj.h" #include "py/enum.h" diff --git a/shared-bindings/countio/Counter.c b/shared-bindings/countio/Counter.c index eed676a17ef3..fc60994f5c4b 100644 --- a/shared-bindings/countio/Counter.c +++ b/shared-bindings/countio/Counter.c @@ -53,11 +53,11 @@ 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. - countio_counter_obj_t *self = m_new_ll_obj(countio_counter_obj_t); + countio_counter_obj_t *self = m_new_ll_obj_with_finaliser(countio_counter_obj_t); self->base.type = &countio_counter_type; common_hal_countio_counter_construct(self, pin, edge, pull); @@ -134,6 +134,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(countio_counter_reset_obj, countio_counter_reset); STATIC const mp_rom_map_elem_t countio_counter_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&countio_counter_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&countio_counter_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&countio_counter___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&countio_counter_count_obj) }, diff --git a/shared-bindings/countio/Edge.c b/shared-bindings/countio/Edge.c index ec96163b3e4a..9b8e74304b5e 100644 --- a/shared-bindings/countio/Edge.c +++ b/shared-bindings/countio/Edge.c @@ -65,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/__init__.c b/shared-bindings/countio/__init__.c index 25e9c7d630a8..0d412cc17f72 100644 --- a/shared-bindings/countio/__init__.c +++ b/shared-bindings/countio/__init__.c @@ -11,7 +11,7 @@ //| """Support for edge counting //| -//| The `countio` module contains logic to read and count edge transistions +//| The `countio` module contains logic to read and count edge transitions //| //| For more information on the applications of counting edges, see //| `this Learn Guide on sequential circuits diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index e6fe592a65d7..c0195115fa66 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -69,7 +69,7 @@ STATIC void check_result(digitalinout_result_t result) { } MP_WEAK const mcu_pin_obj_t *common_hal_digitalio_validate_pin(mp_obj_t obj) { - return validate_obj_is_free_pin(obj); + return validate_obj_is_free_pin(obj, MP_QSTR_pin); } //| class DigitalInOut: @@ -125,7 +125,7 @@ STATIC mp_obj_t digitalio_digitalinout_obj___exit__(size_t n_args, const mp_obj_ } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(digitalio_digitalinout_obj___exit___obj, 4, 4, digitalio_digitalinout_obj___exit__); -STATIC void check_for_deinit(digitalio_digitalinout_obj_t *self) { +STATIC inline void check_for_deinit(digitalio_digitalinout_obj_t *self) { if (common_hal_digitalio_digitalinout_deinited(self)) { raise_deinited_error(); } diff --git a/shared-bindings/digitalio/Pull.c b/shared-bindings/digitalio/Pull.c index 5934ddb9c2bb..3c7a036d1e07 100644 --- a/shared-bindings/digitalio/Pull.c +++ b/shared-bindings/digitalio/Pull.c @@ -83,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 65551f4e0d17..12aee30b1971 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -62,14 +62,11 @@ //| ... 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]); - uint32_t height = mp_obj_get_int(all_args[1]); - uint32_t value_count = mp_obj_get_int(all_args[2]); + uint32_t width = mp_arg_validate_int_range(mp_obj_get_int(all_args[0]), 1, 32767, MP_QSTR_width); + uint32_t height = mp_arg_validate_int_range(mp_obj_get_int(all_args[1]), 1, 32767, MP_QSTR_height); + uint32_t value_count = mp_arg_validate_int_range(mp_obj_get_int(all_args[2]), 1, 65535, MP_QSTR_value_count); uint32_t bits = 1; - if (value_count == 0) { - mp_raise_ValueError(translate("value_count must be > 0")); - } while ((value_count - 1) >> bits) { if (bits < 8) { bits <<= 1; @@ -84,11 +81,19 @@ STATIC mp_obj_t displayio_bitmap_make_new(const mp_obj_type_t *type, size_t n_ar return MP_OBJ_FROM_PTR(self); } + +STATIC void check_for_deinit(displayio_bitmap_t *self) { + if (common_hal_displayio_bitmap_deinited(self)) { + raise_deinited_error(); + } +} + //| 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); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_bitmap_get_width(self)); } @@ -102,6 +107,7 @@ MP_PROPERTY_GETTER(displayio_bitmap_width_obj, STATIC mp_obj_t displayio_bitmap_obj_get_height(mp_obj_t self_in) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_bitmap_get_height(self)); } @@ -134,6 +140,7 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val } displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); if (mp_obj_is_type(index_obj, &mp_type_slice)) { // TODO(tannewt): Implement subscr after slices support start, stop and step tuples. @@ -144,28 +151,24 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val uint16_t x = 0; uint16_t y = 0; if (mp_obj_is_small_int(index_obj)) { - mp_int_t i = MP_OBJ_SMALL_INT_VALUE(index_obj); + mp_int_t i = mp_arg_validate_int_min(MP_OBJ_SMALL_INT_VALUE(index_obj), 0, MP_QSTR_index); uint16_t width = common_hal_displayio_bitmap_get_width(self); x = i % width; y = i / width; } else { mp_obj_t *items; mp_obj_get_array_fixed_n(index_obj, 2, &items); - x = mp_obj_get_int(items[0]); - y = mp_obj_get_int(items[1]); - if (x >= common_hal_displayio_bitmap_get_width(self) || y >= common_hal_displayio_bitmap_get_height(self)) { - mp_raise_IndexError(translate("pixel coordinates out of bounds")); - } + x = mp_arg_validate_int_range(mp_obj_get_int(items[0]), 0, self->width - 1, MP_QSTR_x); + y = mp_arg_validate_int_range(mp_obj_get_int(items[1]), 0, self->height - 1, MP_QSTR_y); } if (value_obj == MP_OBJ_SENTINEL) { // load return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_bitmap_get_pixel(self, x, y)); } else { - mp_uint_t value = (mp_uint_t)mp_obj_get_int(value_obj); - if ((value >> common_hal_displayio_bitmap_get_bits_per_value(self)) != 0) { - mp_raise_ValueError(translate("pixel value requires too many bits")); - } + mp_uint_t value = (mp_uint_t)mp_arg_validate_int_range( + mp_obj_get_int(value_obj), 0, + (UINT32_MAX >> (32 - common_hal_displayio_bitmap_get_bits_per_value(self))), MP_QSTR_value); common_hal_displayio_bitmap_set_pixel(self, x, y, value); } return mp_const_none; @@ -214,9 +217,11 @@ STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_arg mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); displayio_bitmap_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); - int16_t x = args[ARG_x].u_int; - int16_t y = args[ARG_y].u_int; + // Check x,y are within self (target) bitmap boundary + int16_t x = mp_arg_validate_int_range(args[ARG_x].u_int, 0, self->width - 1, MP_QSTR_x); + int16_t y = mp_arg_validate_int_range(args[ARG_y].u_int, 0, self->height - 1, MP_QSTR_y); displayio_bitmap_t *source = mp_arg_validate_type(args[ARG_source].u_obj, &displayio_bitmap_type, MP_QSTR_source_bitmap); @@ -226,32 +231,21 @@ STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_arg mp_raise_ValueError(translate("source palette too large")); } - int16_t x1 = args[ARG_x1].u_int; - int16_t y1 = args[ARG_y1].u_int; + // Check x1,y1,x2,y2 are within source bitmap boundary + int16_t x1 = mp_arg_validate_int_range(args[ARG_x1].u_int, 0, source->width - 1, MP_QSTR_x1); + int16_t y1 = mp_arg_validate_int_range(args[ARG_y1].u_int, 0, source->height - 1, MP_QSTR_y1); int16_t x2, y2; // if x2 or y2 is None, then set as the maximum size of the source bitmap if (args[ARG_x2].u_obj == mp_const_none) { x2 = source->width; } else { - x2 = mp_obj_get_int(args[ARG_x2].u_obj); + x2 = mp_arg_validate_int_range(mp_obj_get_int(args[ARG_x2].u_obj), 0, source->width, MP_QSTR_x2); } // int16_t y2; if (args[ARG_y2].u_obj == mp_const_none) { y2 = source->height; } else { - y2 = mp_obj_get_int(args[ARG_y2].u_obj); - } - - // Check x,y are within self (target) bitmap boundary - if ((x < 0) || (y < 0) || (x > self->width) || (y > self->height)) { - mp_raise_ValueError(translate("out of range of target")); - } - // Check x1,y1,x2,y2 are within source bitmap boundary - if ((x1 < 0) || (x1 > source->width) || - (y1 < 0) || (y1 > source->height) || - (x2 < 0) || (x2 > source->width) || - (y2 < 0) || (y2 > source->height)) { - mp_raise_ValueError(translate("out of range of source")); + y2 = mp_arg_validate_int_range(mp_obj_get_int(args[ARG_y2].u_obj), 0, source->height, MP_QSTR_y2); } // Ensure x1 < x2 and y1 < y2 @@ -288,11 +282,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(displayio_bitmap_blit_obj, 1, displayio_bitmap_obj_bl //| ... 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); + check_for_deinit(self); - mp_uint_t value = (mp_uint_t)mp_obj_get_int(value_obj); - if ((value >> common_hal_displayio_bitmap_get_bits_per_value(self)) != 0) { - mp_raise_ValueError(translate("pixel value requires too many bits")); - } + mp_uint_t value = (mp_uint_t)mp_arg_validate_int_range(mp_obj_get_int(value_obj), 0,(1u << common_hal_displayio_bitmap_get_bits_per_value(self)) - 1,MP_QSTR_value); common_hal_displayio_bitmap_fill(self, value); return mp_const_none; @@ -318,9 +310,10 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_bitmap_fill_obj, displayio_bitmap_obj_fill); //| notified of the "dirty rectangle" that encloses all modified //| pixels.""" //| ... -//| STATIC mp_obj_t displayio_bitmap_obj_dirty(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + enum { ARG_x1, ARG_y1, ARG_x2, ARG_y2 }; static const mp_arg_t allowed_args[] = { { MP_QSTR_x1, MP_ARG_INT, {.u_int = 0} }, @@ -344,13 +337,24 @@ STATIC mp_obj_t displayio_bitmap_obj_dirty(size_t n_args, const mp_obj_t *pos_ar } MP_DEFINE_CONST_FUN_OBJ_KW(displayio_bitmap_dirty_obj, 0, displayio_bitmap_obj_dirty); +//| def deinit(self) -> None: +//| """Release resources allocated by Bitmap.""" +//| ... +//| +STATIC mp_obj_t displayio_bitmap_obj_deinit(mp_obj_t self_in) { + displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_displayio_bitmap_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_bitmap_deinit_obj, displayio_bitmap_obj_deinit); + STATIC const mp_rom_map_elem_t displayio_bitmap_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_bitmap_height_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_bitmap_width_obj) }, { MP_ROM_QSTR(MP_QSTR_blit), MP_ROM_PTR(&displayio_bitmap_blit_obj) }, { MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&displayio_bitmap_fill_obj) }, { MP_ROM_QSTR(MP_QSTR_dirty), MP_ROM_PTR(&displayio_bitmap_dirty_obj) }, - + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&displayio_bitmap_deinit_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_bitmap_locals_dict, displayio_bitmap_locals_dict_table); diff --git a/shared-bindings/displayio/Bitmap.h b/shared-bindings/displayio/Bitmap.h index 074f7dfa5ceb..b35f4eadbcfc 100644 --- a/shared-bindings/displayio/Bitmap.h +++ b/shared-bindings/displayio/Bitmap.h @@ -48,5 +48,7 @@ void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16 uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y); void common_hal_displayio_bitmap_fill(displayio_bitmap_t *bitmap, uint32_t value); int common_hal_displayio_bitmap_get_buffer(displayio_bitmap_t *self, mp_buffer_info_t *bufinfo, mp_uint_t flags); +void common_hal_displayio_bitmap_deinit(displayio_bitmap_t *self); +bool common_hal_displayio_bitmap_deinited(displayio_bitmap_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_BITMAP_H diff --git a/shared-bindings/displayio/ColorConverter.c b/shared-bindings/displayio/ColorConverter.c index 997174f28b7d..06de5a4b0961 100644 --- a/shared-bindings/displayio/ColorConverter.c +++ b/shared-bindings/displayio/ColorConverter.c @@ -61,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); } @@ -73,10 +73,8 @@ STATIC mp_obj_t displayio_colorconverter_obj_convert(mp_obj_t self_in, mp_obj_t displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); mp_int_t color = mp_arg_validate_type_int(color_obj, MP_QSTR_color); - _displayio_colorspace_t colorspace; - colorspace.depth = 16; 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); diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index e5a2836d1a0d..49194ebd1ec0 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -41,6 +41,7 @@ //| _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 @@ -185,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); @@ -238,10 +240,16 @@ 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); @@ -281,7 +289,8 @@ 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 }; @@ -416,7 +425,9 @@ 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); @@ -444,7 +455,8 @@ MP_PROPERTY_GETSET(displayio_display_root_group_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 displayio_display_obj_fill_row(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/displayio/EPaperDisplay.c b/shared-bindings/displayio/EPaperDisplay.c index f3831b5084a3..93d91110a2b7 100644 --- a/shared-bindings/displayio/EPaperDisplay.c +++ b/shared-bindings/displayio/EPaperDisplay.c @@ -71,14 +71,16 @@ //| write_color_ram_command: Optional[int] = None, //| color_bits_inverted: bool = False, //| highlight_color: int = 0x000000, -//| refresh_display_command: int, +//| 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, -//| two_byte_sequence_length: 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`). //| @@ -92,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 @@ -110,14 +112,17 @@ //| :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, @@ -126,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 }, @@ -147,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); @@ -167,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) { @@ -176,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; @@ -187,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; @@ -213,7 +242,11 @@ 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.""" @@ -350,7 +383,9 @@ 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.""" +//| """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); diff --git a/shared-bindings/displayio/EPaperDisplay.h b/shared-bindings/displayio/EPaperDisplay.h index 13fd51d13254..1ef2ed4b4b4a 100644 --- a/shared-bindings/displayio/EPaperDisplay.h +++ b/shared-bindings/displayio/EPaperDisplay.h @@ -37,12 +37,12 @@ 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); diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index edcf2ade0ec8..1f099f50610b 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -89,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); diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index 3e4569b271a8..24064a74c127 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -56,7 +56,7 @@ STATIC mp_obj_t displayio_group_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); - mp_int_t scale = mp_arg_validate_int_min(args[ARG_scale].u_int, 1, MP_QSTR_scale); + mp_int_t scale = mp_arg_validate_int_range(args[ARG_scale].u_int, 1, 32767,MP_QSTR_scale); displayio_group_t *self = m_new_obj(displayio_group_t); self->base.type = &displayio_group_type; diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c index 2374e58e4a77..f2647b0b166f 100644 --- a/shared-bindings/displayio/I2CDisplay.c +++ b/shared-bindings/displayio/I2CDisplay.c @@ -59,7 +59,8 @@ //| //| :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 }; @@ -71,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; diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index aa24dc262f8b..0c44ed0f6094 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -40,29 +40,54 @@ //| """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, mp_arg_validate_int_range(args[ARG_color_count].u_int, 1, 32767, MP_QSTR_color_count), args[ARG_dither].u_bool); return MP_OBJ_FROM_PTR(self); } +//| 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""" @@ -185,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 d9a798016cdc..2cc7417fe3ca 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/__init__.c b/shared-bindings/displayio/__init__.c index 3fcd1d082b2f..77dc8aecee2d 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -61,7 +61,7 @@ //| //| def release_displays() -> None: -//| """Releases any actively used displays so their busses and pins can be used again. This will also +//| """Releases any actively used displays so their buses and pins can be used again. This will also //| release the builtin display on boards that have one. You will need to reinitialize it yourself //| afterwards. This may take seconds to complete if an active EPaperDisplay is refreshing. //| diff --git a/shared-bindings/dualbank/__init__.c b/shared-bindings/dualbank/__init__.c index d3f75a4153ac..b77fb6d76b5e 100644 --- a/shared-bindings/dualbank/__init__.c +++ b/shared-bindings/dualbank/__init__.c @@ -30,25 +30,32 @@ #include "supervisor/flash.h" #endif -//| """DUALBANK Module +//| """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 //| @@ -58,6 +65,7 @@ //| dualbank.switch() //| """ //| ... +//| #if CIRCUITPY_STORAGE_EXTEND STATIC void raise_error_if_storage_extended(void) { @@ -68,10 +76,12 @@ STATIC void raise_error_if_storage_extended(void) { #endif //| def flash(buffer: ReadableBuffer, offset: int = 0) -> None: -//| """Writes one of two app partitions at the given offset. +//| """Writes one of the two app partitions at the given offset. +//| +//| This can be called multiple times when flashing the firmware in smaller chunks. //| -//| This can be called multiple times when flashing the firmware -//| in small chunks. +//| :param ReadableBuffer buffer: The entire firmware or a partial chunk. +//| :param int offset: Start writing at this offset in the app partition. //| """ //| ... //| @@ -102,10 +112,9 @@ 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. //| """ //| ... //| diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c index 51124984bf26..030b924c1e5d 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.c +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -58,7 +58,8 @@ //| //| :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 }; @@ -134,7 +135,8 @@ 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 }; @@ -263,7 +265,8 @@ 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 }; diff --git a/shared-bindings/frequencyio/FrequencyIn.c b/shared-bindings/frequencyio/FrequencyIn.c index 3138f543e710..bf09196e3d51 100644 --- a/shared-bindings/frequencyio/FrequencyIn.c +++ b/shared-bindings/frequencyio/FrequencyIn.c @@ -83,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; diff --git a/shared-bindings/getpass/__init__.c b/shared-bindings/getpass/__init__.c index 340b8fd7c64f..811d78e03dc8 100644 --- a/shared-bindings/getpass/__init__.c +++ b/shared-bindings/getpass/__init__.c @@ -33,9 +33,9 @@ //| //| """ //| ... +//| //| 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 57c38b554e3f..a0de52e2cc75 100644 --- a/shared-bindings/gifio/GifWriter.c +++ b/shared-bindings/gifio/GifWriter.c @@ -80,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); diff --git a/shared-bindings/gifio/OnDiskGif.c b/shared-bindings/gifio/OnDiskGif.c new file mode 100644 index 000000000000..f6acccfabfec --- /dev/null +++ b/shared-bindings/gifio/OnDiskGif.c @@ -0,0 +1,302 @@ +/* + * 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 "shared/runtime/context_manager_helpers.h" +#include "shared-bindings/util.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() +//| next_delay = 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, odg.bitmap) +//| +//| # The following optional code will free the OnDiskGif and allocated resources +//| # after use. This may be required before loading a new GIF in situations +//| # where RAM is limited and the first GIF took most of the RAM. +//| odg.deinit() +//| odg = None +//| gc.collect() +//| +//| """ +//| +//| 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); +} + +STATIC void check_for_deinit(gifio_ondiskgif_t *self) { + if (common_hal_gifio_ondiskgif_deinited(self)) { + raise_deinited_error(); + } +} + +//| def __enter__(self) -> OnDiskGif: +//| """No-op used by Context Managers.""" +//| ... +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the GIF when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +STATIC mp_obj_t gifio_ondiskgif_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_gifio_ondiskgif_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gifio_ondiskgif___exit___obj, 4, 4, gifio_ondiskgif_obj___exit__); + +//| 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); + + check_for_deinit(self); + 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); + + check_for_deinit(self); + 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); + + check_for_deinit(self); + 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); + + check_for_deinit(self); + 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); + + check_for_deinit(self); + 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); + + check_for_deinit(self); + 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); + + check_for_deinit(self); + 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); + + check_for_deinit(self); + 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); + +//| def deinit(self) -> None: +//| """Release resources allocated by OnDiskGif.""" +//| ... +//| +STATIC mp_obj_t gifio_ondiskgif_obj_deinit(mp_obj_t self_in) { + gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_gifio_ondiskgif_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(gifio_ondiskgif_deinit_obj, gifio_ondiskgif_obj_deinit); + +STATIC const mp_rom_map_elem_t gifio_ondiskgif_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gifio_ondiskgif_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&gifio_ondiskgif___exit___obj) }, + { 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 000000000000..6776466e8d7c --- /dev/null +++ b/shared-bindings/gifio/OnDiskGif.h @@ -0,0 +1,50 @@ +/* + * 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); +void common_hal_gifio_ondiskgif_deinit(gifio_ondiskgif_t *self); +bool common_hal_gifio_ondiskgif_deinited(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 6bd576596631..bfc87f0d9951 100644 --- a/shared-bindings/gifio/__init__.c +++ b/shared-bindings/gifio/__init__.c @@ -27,6 +27,7 @@ #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 @@ -34,6 +35,7 @@ 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/hashlib/Hash.c b/shared-bindings/hashlib/Hash.c index f385885b4d96..e3cbbc39d392 100644 --- a/shared-bindings/hashlib/Hash.c +++ b/shared-bindings/hashlib/Hash.c @@ -49,7 +49,8 @@ MP_PROPERTY_GETTER(hashlib_hash_digest_size_obj, (mp_obj_t)&hashlib_hash_digest_ //| 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)); diff --git a/shared-bindings/i2ctarget/I2CTarget.c b/shared-bindings/i2ctarget/I2CTarget.c index 17da952118b0..a07d038c6f26 100644 --- a/shared-bindings/i2ctarget/I2CTarget.c +++ b/shared-bindings/i2ctarget/I2CTarget.c @@ -81,8 +81,8 @@ STATIC mp_obj_t i2ctarget_i2c_target_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 *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); mp_obj_iter_buf_t iter_buf; mp_obj_t iterable = mp_getiter(args[ARG_addresses].u_obj, &iter_buf); diff --git a/shared-bindings/imagecapture/ParallelImageCapture.c b/shared-bindings/imagecapture/ParallelImageCapture.c index b6352514bf61..d568da158f3e 100644 --- a/shared-bindings/imagecapture/ParallelImageCapture.c +++ b/shared-bindings/imagecapture/ParallelImageCapture.c @@ -72,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; diff --git a/shared-bindings/imagecapture/__init__.c b/shared-bindings/imagecapture/__init__.c index fdd442411409..71d0b9125be5 100644 --- a/shared-bindings/imagecapture/__init__.c +++ b/shared-bindings/imagecapture/__init__.c @@ -35,7 +35,7 @@ //| //| .. seealso:: //| -//| Espressif microcontrollers use the `esp32_camera` module together. +//| Espressif microcontrollers use the `espcamera` module together. //| //| """ STATIC const mp_rom_map_elem_t imagecapture_module_globals_table[] = { diff --git a/shared-bindings/ipaddress/__init__.c b/shared-bindings/ipaddress/__init__.c index fb4c8bf38d6c..6da5a5229977 100644 --- a/shared-bindings/ipaddress/__init__.c +++ b/shared-bindings/ipaddress/__init__.c @@ -35,6 +35,7 @@ //| The `ipaddress` module provides types for IP addresses. It is a subset of CPython's ipaddress //| module. //| """ +//| bool ipaddress_parse_ipv4address(const char *str_data, size_t str_len, uint32_t *ip_out) { diff --git a/shared-bindings/is31fl3741/IS31FL3741.c b/shared-bindings/is31fl3741/IS31FL3741.c index 706e3deb2bfe..17b12da67abd 100644 --- a/shared-bindings/is31fl3741/IS31FL3741.c +++ b/shared-bindings/is31fl3741/IS31FL3741.c @@ -141,7 +141,8 @@ 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) { diff --git a/shared-bindings/keypad/Event.c b/shared-bindings/keypad/Event.c index 56a5815636a9..52c574e692ce 100644 --- a/shared-bindings/keypad/Event.c +++ b/shared-bindings/keypad/Event.c @@ -64,7 +64,7 @@ STATIC mp_obj_t keypad_event_make_new(const mp_obj_type_t *type, size_t n_args, timestamp = supervisor_ticks_ms(); } - (void)mp_obj_get_int_truncated(timestamp); // ensure that timesamp is an integer + (void)mp_obj_get_int_truncated(timestamp); // ensure that timestamp is an integer common_hal_keypad_event_construct(self, key_number, args[ARG_pressed].u_bool, timestamp); return MP_OBJ_FROM_PTR(self); } @@ -148,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) { @@ -166,9 +167,9 @@ STATIC mp_obj_t keypad_event_unary_op(mp_unary_op_t op, mp_obj_t self_in) { STATIC void keypad_event_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { keypad_event_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "", + mp_printf(print, "", common_hal_keypad_event_get_key_number(self), - common_hal_keypad_event_get_pressed(self) ? "pressed" : "released"); + common_hal_keypad_event_get_pressed(self) ? MP_QSTR_pressed : MP_QSTR_released); } STATIC const mp_rom_map_elem_t keypad_event_locals_dict_table[] = { diff --git a/shared-bindings/keypad/KeyMatrix.c b/shared-bindings/keypad/KeyMatrix.c index 28a68602ab91..2209f3f68fd7 100644 --- a/shared-bindings/keypad/KeyMatrix.c +++ b/shared-bindings/keypad/KeyMatrix.c @@ -56,7 +56,7 @@ //| An `EventQueue` is created when this object is created and is available in the `events` attribute. //| //| :param Sequence[microcontroller.Pin] row_pins: The pins attached to the rows. -//| :param Sequence[microcontroller.Pin] column_pins: The pins attached to the colums. +//| :param Sequence[microcontroller.Pin] column_pins: The pins attached to the columns. //| :param bool columns_to_anodes: Default ``True``. //| If the matrix uses diodes, the diode anodes are typically connected to the column pins, //| and the cathodes should be connected to the row pins. If your diodes are reversed, @@ -71,6 +71,7 @@ //| ... STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + #if CIRCUITPY_KEYPAD_KEYMATRIX keypad_keymatrix_obj_t *self = m_new_obj(keypad_keymatrix_obj_t); self->base.type = &keypad_keymatrix_type; enum { ARG_row_pins, ARG_column_pins, ARG_columns_to_anodes, ARG_interval, ARG_max_events }; @@ -102,20 +103,25 @@ 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; } common_hal_keypad_keymatrix_construct(self, num_row_pins, row_pins_array, num_column_pins, column_pins_array, args[ARG_columns_to_anodes].u_bool, interval, max_events); return MP_OBJ_FROM_PTR(self); + #else + mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_KeyMatrix); + + #endif } +#if CIRCUITPY_KEYPAD_KEYMATRIX //| def deinit(self) -> None: //| """Stop scanning and release the pins.""" //| ... @@ -228,9 +234,13 @@ STATIC const mp_rom_map_elem_t keypad_keymatrix_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(keypad_keymatrix_locals_dict, keypad_keymatrix_locals_dict_table); +#endif + const mp_obj_type_t keypad_keymatrix_type = { { &mp_type_type }, .name = MP_QSTR_KeyMatrix, .make_new = keypad_keymatrix_make_new, + #if CIRCUITPY_KEYPAD_KEYMATRIX .locals_dict = (mp_obj_t)&keypad_keymatrix_locals_dict, + #endif }; diff --git a/shared-bindings/keypad/Keys.c b/shared-bindings/keypad/Keys.c index 3a9eb84cf3b8..2481fedc6b55 100644 --- a/shared-bindings/keypad/Keys.c +++ b/shared-bindings/keypad/Keys.c @@ -73,6 +73,7 @@ //| ... STATIC mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + #if CIRCUITPY_KEYPAD_KEYS keypad_keys_obj_t *self = m_new_obj(keypad_keys_obj_t); self->base.type = &keypad_keys_type; enum { ARG_pins, ARG_value_when_pressed, ARG_pull, ARG_interval, ARG_max_events }; @@ -100,14 +101,19 @@ 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); return MP_OBJ_FROM_PTR(self); + #else + mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_Keys); + + #endif } +#if CIRCUITPY_KEYPAD_KEYS //| def deinit(self) -> None: //| """Stop scanning and release the pins.""" //| ... @@ -162,10 +168,13 @@ STATIC const mp_rom_map_elem_t keypad_keys_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(keypad_keys_locals_dict, keypad_keys_locals_dict_table); +#endif const mp_obj_type_t keypad_keys_type = { { &mp_type_type }, .name = MP_QSTR_Keys, .make_new = keypad_keys_make_new, + #if CIRCUITPY_KEYPAD_KEYS .locals_dict = (mp_obj_t)&keypad_keys_locals_dict, + #endif }; diff --git a/shared-bindings/keypad/ShiftRegisterKeys.c b/shared-bindings/keypad/ShiftRegisterKeys.c index 0703a78b6698..1fcf517ac37d 100644 --- a/shared-bindings/keypad/ShiftRegisterKeys.c +++ b/shared-bindings/keypad/ShiftRegisterKeys.c @@ -82,6 +82,7 @@ //| ... STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + #if CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS keypad_shiftregisterkeys_obj_t *self = m_new_obj(keypad_shiftregisterkeys_obj_t); self->base.type = &keypad_shiftregisterkeys_type; enum { ARG_clock, ARG_data, ARG_latch, ARG_value_to_latch, ARG_key_count, ARG_value_when_pressed, ARG_interval, ARG_max_events }; @@ -98,9 +99,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); @@ -113,8 +114,12 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz self, clock, data, latch, value_to_latch, key_count, value_when_pressed, interval, max_events); return MP_OBJ_FROM_PTR(self); + #else + mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_ShiftRegisterKeys); + #endif } +#if CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS //| def deinit(self) -> None: //| """Stop scanning and release the pins.""" //| ... @@ -169,10 +174,13 @@ STATIC const mp_rom_map_elem_t keypad_shiftregisterkeys_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(keypad_shiftregisterkeys_locals_dict, keypad_shiftregisterkeys_locals_dict_table); +#endif const mp_obj_type_t keypad_shiftregisterkeys_type = { { &mp_type_type }, .name = MP_QSTR_ShiftRegisterKeys, .make_new = keypad_shiftregisterkeys_make_new, + #if CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS .locals_dict = (mp_obj_t)&keypad_shiftregisterkeys_locals_dict, + #endif }; diff --git a/shared-bindings/math/__init__.c b/shared-bindings/math/__init__.c index 42a32749da30..8aee44ffb861 100644 --- a/shared-bindings/math/__init__.c +++ b/shared-bindings/math/__init__.c @@ -86,6 +86,7 @@ STATIC NORETURN void math_error(void) { //| //| pi: float //| """the ratio of a circle's circumference to its diameter""" +//| //| def acos(x: float) -> float: //| """Return the inverse cosine of ``x``.""" diff --git a/shared-bindings/mdns/Server.c b/shared-bindings/mdns/Server.c index aab7f7e350ce..0d06d67f0d9f 100644 --- a/shared-bindings/mdns/Server.c +++ b/shared-bindings/mdns/Server.c @@ -33,6 +33,10 @@ #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.""" @@ -53,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); @@ -194,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/memorymonitor/__init__.c b/shared-bindings/memorymonitor/__init__.c index 12c91cd1501f..7b05acd09552 100644 --- a/shared-bindings/memorymonitor/__init__.c +++ b/shared-bindings/memorymonitor/__init__.c @@ -34,6 +34,7 @@ #include "shared-bindings/memorymonitor/AllocationSize.h" //| """Memory monitoring helpers""" +//| //| class AllocationError(Exception): //| """Catchall exception for allocation related errors.""" diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c index f1b9a90d45cf..ea27df9812a2 100644 --- a/shared-bindings/microcontroller/Pin.c +++ b/shared-bindings/microcontroller/Pin.c @@ -93,23 +93,24 @@ const mp_obj_type_t mcu_pin_type = { ) }; -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; } @@ -120,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); } @@ -141,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); } @@ -159,16 +160,18 @@ void validate_list_is_free_pins(qstr what, const mcu_pin_obj_t **pins_out, mp_in 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 b41b3c308aa0..28d094904278 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); diff --git a/shared-bindings/microcontroller/ResetReason.c b/shared-bindings/microcontroller/ResetReason.c index 905c19f83f34..6f8ac8f42b20 100644 --- a/shared-bindings/microcontroller/ResetReason.c +++ b/shared-bindings/microcontroller/ResetReason.c @@ -39,31 +39,31 @@ MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, UNKNOWN, RESET_REASON_UNKNO MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESCUE_DEBUG, RESET_REASON_RESCUE_DEBUG); //| class ResetReason: -//| """The reason the microntroller was last reset""" +//| """The reason the microcontroller 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.""" +//| """The microcontroller was reset due to too low a voltage.""" //| //| SOFTWARE: object -//| """The microntroller was reset from software.""" +//| """The microcontroller was reset from software.""" //| //| DEEP_SLEEP_ALARM: object -//| """The microntroller was reset for deep sleep and restarted by an alarm.""" +//| """The microcontroller was reset for deep sleep and restarted by an alarm.""" //| //| RESET_PIN: object -//| """The microntroller was reset by a signal on its reset pin. The pin might be connected to a reset button.""" +//| """The microcontroller was reset by a signal on its reset pin. The pin might be connected to a reset button.""" //| //| WATCHDOG: object //| """The microcontroller was reset by its watchdog timer.""" //| //| UNKNOWN: object -//| """The microntroller restarted for an unknown reason.""" +//| """The microcontroller restarted for an unknown reason.""" //| //| RESCUE_DEBUG: object -//| """The microntroller was reset by the rescue debug port.""" +//| """The microcontroller was reset by the rescue debug port.""" //| MAKE_ENUM_MAP(mcu_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_ON), diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index 5716f7270e1d..2c1fdd5b5823 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -60,6 +60,7 @@ //| """CPU information and control, such as ``cpus[0].temperature`` and ``cpus[1].frequency`` //| (clock frequency) on chips with more than 1 cpu. The index selects which cpu. //| This object is an instance of `microcontroller.Processor`.""" +//| //| def delay_us(delay: int) -> None: //| """Dedicated delay method used for very short delays. **Do not** do long delays diff --git a/shared-bindings/msgpack/__init__.c b/shared-bindings/msgpack/__init__.c index d505e3a6d8be..7773d6d190fc 100644 --- a/shared-bindings/msgpack/__init__.c +++ b/shared-bindings/msgpack/__init__.c @@ -84,6 +84,7 @@ //| print(f"{data} -> {buffer.getvalue()} -> {decoded}") //| //| """ +//| //| def pack( //| obj: object, diff --git a/shared-bindings/neopixel_write/__init__.c b/shared-bindings/neopixel_write/__init__.c index 3a35fa824309..cc0e2a041ae5 100644 --- a/shared-bindings/neopixel_write/__init__.c +++ b/shared-bindings/neopixel_write/__init__.c @@ -109,16 +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/onewireio/OneWire.c b/shared-bindings/onewireio/OneWire.c index 4a0140ac5d02..3f0dc8772271 100644 --- a/shared-bindings/onewireio/OneWire.c +++ b/shared-bindings/onewireio/OneWire.c @@ -60,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; diff --git a/shared-bindings/onewireio/__init__.c b/shared-bindings/onewireio/__init__.c index 81b2d605d7e6..282192179b26 100644 --- a/shared-bindings/onewireio/__init__.c +++ b/shared-bindings/onewireio/__init__.c @@ -37,7 +37,7 @@ //| """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""" +//| Protocol definition is here: https://www.analog.com/en/technical-articles/1wire-communication-through-software.html""" 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 b2fb8ff09509..e9e5f0885ff5 100644 --- a/shared-bindings/os/__init__.c +++ b/shared-bindings/os/__init__.c @@ -241,7 +241,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync); //| """Returns a string of *size* random bytes based on a hardware True Random //| 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. +//| **Limitations:** Not available on SAMD21 due to lack of hardware. //| """ //| ... //| diff --git a/shared-bindings/paralleldisplay/ParallelBus.c b/shared-bindings/paralleldisplay/ParallelBus.c index 2f18624f1a82..ad9a1efdce99 100644 --- a/shared-bindings/paralleldisplay/ParallelBus.c +++ b/shared-bindings/paralleldisplay/ParallelBus.c @@ -39,7 +39,7 @@ //| class ParallelBus: //| """Manage updating a display over 8-bit parallel bus in the background while Python code runs. This -//| protocol may be refered to as 8080-I Series Parallel Interface in datasheets. It doesn't handle +//| protocol may be referred to as 8080-I Series Parallel Interface in datasheets. It doesn't handle //| display initialization.""" //| //| def __init__( @@ -85,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; @@ -102,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; diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c index 5aeb3af51ea9..67cffc9f7b6b 100644 --- a/shared-bindings/ps2io/Ps2.c +++ b/shared-bindings/ps2io/Ps2.c @@ -75,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; diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 6d1830c4f2a8..3510f112899b 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -86,10 +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); // Make object long-lived to avoid moving between imports - pulseio_pulsein_obj_t *self = m_new_ll_obj(pulseio_pulsein_obj_t); + pulseio_pulsein_obj_t *self = m_new_ll_obj_with_finaliser(pulseio_pulsein_obj_t); self->base.type = &pulseio_pulsein_type; common_hal_pulseio_pulsein_construct(self, pin, args[ARG_maxlen].u_int, @@ -277,6 +277,7 @@ STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t va STATIC const mp_rom_map_elem_t pulseio_pulsein_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pulseio_pulsein_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&pulseio_pulsein_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pulseio_pulsein___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&pulseio_pulsein_pause_obj) }, diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c index 758d3c2e77d8..2af07a46d831 100644 --- a/shared-bindings/pulseio/PulseOut.c +++ b/shared-bindings/pulseio/PulseOut.c @@ -77,10 +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; - 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); diff --git a/shared-bindings/pwmio/PWMOut.c b/shared-bindings/pwmio/PWMOut.c index 92eea1d1e06f..784f87a02597 100644 --- a/shared-bindings/pwmio/PWMOut.c +++ b/shared-bindings/pwmio/PWMOut.c @@ -69,7 +69,27 @@ 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. +//| +//| .. 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, @@ -134,7 +154,9 @@ 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 }; @@ -147,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; @@ -234,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); @@ -248,8 +271,7 @@ STATIC mp_obj_t pwmio_pwmout_obj_set_frequency(mp_obj_t self_in, mp_obj_t freque check_for_deinit(self); if (!common_hal_pwmio_pwmout_get_variable_frequency(self)) { mp_raise_AttributeError(translate( - "PWM frequency not writable when variable_frequency is False on " - "construction.")); + "PWM frequency not writable when variable_frequency is False on construction.")); } mp_int_t freq = mp_obj_get_int(frequency); if (freq == 0) { diff --git a/shared-bindings/qrio/QRDecoder.c b/shared-bindings/qrio/QRDecoder.c index 5ff65578e4ff..b37a14fd8f3e 100644 --- a/shared-bindings/qrio/QRDecoder.c +++ b/shared-bindings/qrio/QRDecoder.c @@ -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; } diff --git a/shared-bindings/rainbowio/__init__.c b/shared-bindings/rainbowio/__init__.c index 0dfdcd3a4525..324f43198e8b 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 fcf432931e42..33cd9e90d04f 100644 --- a/shared-bindings/random/__init__.c +++ b/shared-bindings/random/__init__.c @@ -47,6 +47,7 @@ //| from typing import TypeVar //| //| _T = TypeVar("_T") +//| //| def seed(seed: int) -> None: //| """Sets the starting seed of the random number generation. Further calls to diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c index 456f0cfbb180..f2877531bb81 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); } @@ -210,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); diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c index e05ffb9e433d..6b671194f630 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.c +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -42,7 +42,7 @@ //| ) -> 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. +//| relative to the position when the object is constructed. //| //| :param ~microcontroller.Pin pin_a: First pin to read pulses from. //| :param ~microcontroller.Pin pin_b: Second pin to read pulses from. @@ -72,11 +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); // 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); + rotaryio_incrementalencoder_obj_t *self = m_new_ll_obj_with_finaliser(rotaryio_incrementalencoder_obj_t); self->base.type = &rotaryio_incrementalencoder_type; common_hal_rotaryio_incrementalencoder_construct(self, pin_a, pin_b); @@ -171,6 +171,7 @@ MP_PROPERTY_GETSET(rotaryio_incrementalencoder_position_obj, STATIC const mp_rom_map_elem_t rotaryio_incrementalencoder_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rotaryio_incrementalencoder_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&rotaryio_incrementalencoder_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&rotaryio_incrementalencoder___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_position), MP_ROM_PTR(&rotaryio_incrementalencoder_position_obj) }, diff --git a/shared-bindings/rtc/__init__.c b/shared-bindings/rtc/__init__.c index 64adfe7d9e66..0220745c0f9d 100644 --- a/shared-bindings/rtc/__init__.c +++ b/shared-bindings/rtc/__init__.c @@ -36,6 +36,7 @@ //| The `rtc` module provides support for a Real Time Clock. You can access and manage the //| RTC using :class:`rtc.RTC`. It also backs the :func:`time.time` and :func:`time.localtime` //| functions using the onboard RTC if present.""" +//| void rtc_reset(void) { MP_STATE_VM(rtc_time_source) = (mp_obj_t)&rtc_rtc_obj; diff --git a/shared-bindings/sdcardio/SDCard.c b/shared-bindings/sdcardio/SDCard.c index a71541c54869..ce6783477401 100644 --- a/shared-bindings/sdcardio/SDCard.c +++ b/shared-bindings/sdcardio/SDCard.c @@ -89,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; @@ -126,7 +126,6 @@ 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 @@ -166,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 7e57330fc4fd..776b20fafeb0 100644 --- a/shared-bindings/sdioio/SDCard.c +++ b/shared-bindings/sdioio/SDCard.c @@ -98,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); @@ -160,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 @@ -182,7 +181,6 @@ 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 diff --git a/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c index 35e06b78387e..d9643495bab5 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 30f1b867b100..b2c15ac49934 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/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index fbf78a4cdca4..9d439b5bd418 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -379,7 +379,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, //| 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) { diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c index f056c741f352..302372137813 100644 --- a/shared-bindings/socketpool/SocketPool.c +++ b/shared-bindings/socketpool/SocketPool.c @@ -52,6 +52,7 @@ //| 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); diff --git a/shared-bindings/ssl/SSLSocket.c b/shared-bindings/ssl/SSLSocket.c index d6f4ad051c79..e0e79117159f 100644 --- a/shared-bindings/ssl/SSLSocket.c +++ b/shared-bindings/ssl/SSLSocket.c @@ -240,7 +240,8 @@ 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); diff --git a/shared-bindings/ssl/__init__.c b/shared-bindings/ssl/__init__.c index 9204c92790d1..696786005410 100644 --- a/shared-bindings/ssl/__init__.c +++ b/shared-bindings/ssl/__init__.c @@ -36,6 +36,7 @@ //| //| |see_cpython_module| :mod:`cpython:ssl`. //| """ +//| //| def create_default_context() -> ssl.SSLContext: //| """Return the default SSLContext.""" diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c index ad8b847fd5fc..c4bd728f67d8 100644 --- a/shared-bindings/storage/__init__.c +++ b/shared-bindings/storage/__init__.c @@ -166,8 +166,11 @@ MP_DEFINE_CONST_FUN_OBJ_1(storage_getmount_obj, storage_getmount); //| 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.""" //| ... //| @@ -249,7 +252,7 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_enable_usb_drive), MP_ROM_PTR(&storage_enable_usb_drive_obj) }, //| class VfsFat: -//| def __init__(self, block_device: str) -> None: +//| def __init__(self, block_device: BlockDevice) -> None: //| """Create a new VfsFat filesystem around the given block device. //| //| :param block_device: Block device the the filesystem lives on""" @@ -263,8 +266,15 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = { //| 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""" +//| @staticmethod +//| def mkfs(block_device: BlockDevice) -> None: +//| """Format the block device, deleting any data that may have been there. +//| +//| **Limitations**: On SAMD21 builds, `mkfs()` will raise ``OSError(22)`` when +//| attempting to format filesystems larger than 4GB. The extra code to format larger +//| filesystems will not fit on these builds. You can still access +//| larger filesystems, but you will need to format the filesystem on another device. +//| """ //| ... //| def open(self, path: str, mode: str) -> None: //| """Like builtin ``open()``""" diff --git a/shared-bindings/struct/__init__.c b/shared-bindings/struct/__init__.c index 59bc78005d55..5b63a15f1599 100644 --- a/shared-bindings/struct/__init__.c +++ b/shared-bindings/struct/__init__.c @@ -46,6 +46,7 @@ //| //| Supported format codes: *b*, *B*, *x*, *h*, *H*, *i*, *I*, *l*, *L*, *q*, *Q*, //| *s*, *P*, *f*, *d* (the latter 2 depending on the floating-point support).""" +//| //| def calcsize(fmt: str) -> int: diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 4d8ddbacc7b6..ecdd914a8f3a 100644 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -32,6 +32,7 @@ #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" @@ -106,7 +107,7 @@ void supervisor_set_run_reason(supervisor_run_reason_t run_reason) { } //| run_reason: RunReason -//| """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,6 +116,23 @@ 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.""" //| @@ -179,7 +197,11 @@ MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_next_stack_limit_obj, superviso 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); + if (!set_next_stack_size(size)) { + mp_raise_msg_varg(&mp_type_AttributeError, + MP_ERROR_TEXT("can't set attribute '%q'"), + MP_QSTR_next_stack_limit); + } return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(supervisor_runtime_set_next_stack_limit_obj, supervisor_runtime_set_next_stack_limit); @@ -218,6 +240,7 @@ STATIC const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { { 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) }, diff --git a/shared-bindings/supervisor/Runtime.h b/shared-bindings/supervisor/Runtime.h index debc5ec79cdd..3c3e2611f675 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 000000000000..2da03bdceda7 --- /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 000000000000..d061d7515460 --- /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/__init__.c b/shared-bindings/supervisor/__init__.c index 37f35e2e18f4..491cac2f17e2 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -59,6 +59,7 @@ //| 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`.""" +//| //| def reload() -> None: //| """Reload the main Python code and run it (equivalent to hitting Ctrl-D at the REPL).""" @@ -335,6 +336,11 @@ STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = { { 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) }, + #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) }, diff --git a/shared-bindings/synthio/MidiTrack.c b/shared-bindings/synthio/MidiTrack.c index b987337eaaf7..20a203ce9c07 100644 --- a/shared-bindings/synthio/MidiTrack.c +++ b/shared-bindings/synthio/MidiTrack.c @@ -32,13 +32,19 @@ #include "py/runtime.h" #include "shared-bindings/util.h" #include "shared-bindings/synthio/MidiTrack.h" +#include "shared-bindings/synthio/__init__.h" #include "supervisor/shared/translate/translate.h" //| class MidiTrack: -//| """Simple square-wave MIDI synth""" +//| """Simple MIDI synth""" //| //| def __init__( -//| self, buffer: ReadableBuffer, tempo: int, *, sample_rate: int = 11025 +//| self, +//| buffer: ReadableBuffer, +//| tempo: int, +//| *, +//| sample_rate: int = 11025, +//| waveform: ReadableBuffer = None //| ) -> 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 @@ -47,6 +53,7 @@ //| :param ~circuitpython_typing.ReadableBuffer buffer: Stream of MIDI events, as stored in a MIDI file track chunk //| :param int tempo: Tempo of the streamed events, in MIDI ticks per second //| :param int sample_rate: The desired playback sample rate; higher sample rate requires more memory +//| :param ReadableBuffer waveform: A single-cycle waveform. Default is a 50% duty cycle square wave. If specified, must be a ReadableBuffer of type 'h' (signed 16 bit) //| //| Simple melody:: //| @@ -65,11 +72,12 @@ //| 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 }; + enum { ARG_buffer, ARG_tempo, ARG_sample_rate, ARG_waveform }; static const mp_arg_t allowed_args[] = { { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_tempo, MP_ARG_INT | MP_ARG_REQUIRED }, { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 11025} }, + { MP_QSTR_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.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); @@ -77,13 +85,18 @@ STATIC mp_obj_t synthio_miditrack_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + mp_buffer_info_t bufinfo_waveform; + synthio_synth_parse_waveform(&bufinfo_waveform, args[ARG_waveform].u_obj); + synthio_miditrack_obj_t *self = m_new_obj(synthio_miditrack_obj_t); self->base.type = &synthio_miditrack_type; common_hal_synthio_miditrack_construct(self, (uint8_t *)bufinfo.buf, bufinfo.len, args[ARG_tempo].u_int, - args[ARG_sample_rate].u_int); + args[ARG_sample_rate].u_int, + bufinfo_waveform.buf, + bufinfo_waveform.len / 2); return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/synthio/MidiTrack.h b/shared-bindings/synthio/MidiTrack.h index d44d4c3bb7bd..90ddab8728cc 100644 --- a/shared-bindings/synthio/MidiTrack.h +++ b/shared-bindings/synthio/MidiTrack.h @@ -32,7 +32,7 @@ extern const mp_obj_type_t synthio_miditrack_type; void common_hal_synthio_miditrack_construct(synthio_miditrack_obj_t *self, - const uint8_t *buffer, uint32_t len, uint32_t tempo, uint32_t sample_rate); + const uint8_t *buffer, uint32_t len, uint32_t tempo, uint32_t sample_rate, const int16_t *waveform, uint16_t waveform_len); void common_hal_synthio_miditrack_deinit(synthio_miditrack_obj_t *self); bool common_hal_synthio_miditrack_deinited(synthio_miditrack_obj_t *self); diff --git a/shared-bindings/synthio/Synthesizer.c b/shared-bindings/synthio/Synthesizer.c new file mode 100644 index 000000000000..56ad0d76cde3 --- /dev/null +++ b/shared-bindings/synthio/Synthesizer.c @@ -0,0 +1,246 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * Copyright (c) 2023 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 "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-bindings/synthio/Synthesizer.h" +#include "shared-bindings/synthio/__init__.h" +#include "supervisor/shared/translate/translate.h" + +//| class Synthesizer: +//| def __init__(self, *, sample_rate: int = 11025, waveform: ReadableBuffer = None) -> None: +//| """Create a synthesizer object. +//| +//| This API is experimental. +//| +//| At least 2 simultaneous notes are supported. mimxrt10xx and rp2040 platforms support up to +//| 12 notes. +//| +//| Notes use MIDI note numbering, with 60 being C4 or Middle C, approximately 262Hz. +//| +//| :param int sample_rate: The desired playback sample rate; higher sample rate requires more memory +//| :param ReadableBuffer waveform: A single-cycle waveform. Default is a 50% duty cycle square wave. If specified, must be a ReadableBuffer of type 'h' (signed 16 bit). It is permitted to modify this buffer during synthesis. This can be used, for instance, to control the overall volume or timbre of the notes. +//| """ +STATIC mp_obj_t synthio_synthesizer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_sample_rate, ARG_waveform }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 11025} }, + { MP_QSTR_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.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); + + mp_buffer_info_t bufinfo_waveform; + synthio_synth_parse_waveform(&bufinfo_waveform, args[ARG_waveform].u_obj); + + synthio_synthesizer_obj_t *self = m_new_obj(synthio_synthesizer_obj_t); + self->base.type = &synthio_synthesizer_type; + + common_hal_synthio_synthesizer_construct(self, + args[ARG_sample_rate].u_int, + bufinfo_waveform.buf, + bufinfo_waveform.len / 2); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void check_for_deinit(synthio_synthesizer_obj_t *self) { + if (common_hal_synthio_synthesizer_deinited(self)) { + raise_deinited_error(); + } +} + +//| def press(self, /, press: Sequence[int] = ()) -> None: +//| """Turn some notes on. Notes use MIDI numbering, with 60 being middle C, approximately 262Hz. +//| +//| Pressing a note that was already pressed has no effect. +//| +//| :param Sequence[int] press: Any sequence of integer notes.""" +STATIC mp_obj_t synthio_synthesizer_press(mp_obj_t self_in, mp_obj_t press) { + synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_synthio_synthesizer_press(self, press); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(synthio_synthesizer_press_obj, synthio_synthesizer_press); +// +//| def release_then_press( +//| self, release: Sequence[int] = (), press: Sequence[int] = () +//| ) -> None: +//| """Turn some notes on and/or off. Notes use MIDI numbering, with 60 being middle C. +//| +//| It is OK to release note that was not actually turned on. +//| +//| Pressing a note that was already pressed has no effect. +//| +//| Releasing and pressing the note again has little effect, but does reset the phase +//| of the note, which may be perceptible as a small glitch. +//| +//| :param Sequence[int] release: Any sequence of integer notes. +//| :param Sequence[int] press: Any sequence of integer notes.""" +STATIC mp_obj_t synthio_synthesizer_release_then_press(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_release, ARG_press }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_release, MP_ARG_OBJ, {.u_obj = mp_const_empty_tuple } }, + { MP_QSTR_press, 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); + + synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + common_hal_synthio_synthesizer_release(self, args[ARG_release].u_obj); + common_hal_synthio_synthesizer_press(self, args[ARG_press].u_obj); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(synthio_synthesizer_release_then_press_obj, 1, synthio_synthesizer_release_then_press); + +// +//| def release_all_then_press(self, /, press: Sequence[int]) -> None: +//| """Turn any currently-playing notes off, then turn on the given notes +//| +//| Releasing and pressing the note again has little effect, but does reset the phase +//| of the note, which may be perceptible as a small glitch. +//| +//| :param Sequence[int] press: Any sequence of integer notes.""" +STATIC mp_obj_t synthio_synthesizer_release_all_then_press(mp_obj_t self_in, mp_obj_t press) { + synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_synthio_synthesizer_release_all(self); + common_hal_synthio_synthesizer_press(self, press); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(synthio_synthesizer_release_all_then_press_obj, synthio_synthesizer_release_all_then_press); + +// +//| def release_all(self) -> None: +//| """Turn any currently-playing notes off""" +STATIC mp_obj_t synthio_synthesizer_release_all(mp_obj_t self_in) { + synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_synthio_synthesizer_release_all(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(synthio_synthesizer_release_all_obj, synthio_synthesizer_release_all); + +//| def deinit(self) -> None: +//| """Deinitialises the object and releases any memory resources for reuse.""" +//| ... +STATIC mp_obj_t synthio_synthesizer_deinit(mp_obj_t self_in) { + synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_synthio_synthesizer_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(synthio_synthesizer_deinit_obj, synthio_synthesizer_deinit); + +//| 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_synthesizer_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_synthio_synthesizer_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(synthio_synthesizer___exit___obj, 4, 4, synthio_synthesizer_obj___exit__); +//| sample_rate: int +//| """32 bit value that tells how quickly samples are played in Hertz (cycles per second).""" +STATIC mp_obj_t synthio_synthesizer_obj_get_sample_rate(mp_obj_t self_in) { + synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_synthio_synthesizer_get_sample_rate(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(synthio_synthesizer_get_sample_rate_obj, synthio_synthesizer_obj_get_sample_rate); + +MP_PROPERTY_GETTER(synthio_synthesizer_sample_rate_obj, + (mp_obj_t)&synthio_synthesizer_get_sample_rate_obj); + +//| pressed: Tuple[int] +//| """A sequence of the currently pressed notes (read-only property)""" +//| +STATIC mp_obj_t synthio_synthesizer_obj_get_pressed(mp_obj_t self_in) { + synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return common_hal_synthio_synthesizer_get_pressed_notes(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(synthio_synthesizer_get_pressed_obj, synthio_synthesizer_obj_get_pressed); + +MP_PROPERTY_GETTER(synthio_synthesizer_pressed_obj, + (mp_obj_t)&synthio_synthesizer_get_pressed_obj); + +//| max_polyphony: int +//| """Maximum polyphony of the synthesizer (read-only class property)""" +//| + +STATIC const mp_rom_map_elem_t synthio_synthesizer_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_press), MP_ROM_PTR(&synthio_synthesizer_press_obj) }, + { MP_ROM_QSTR(MP_QSTR_release_all), MP_ROM_PTR(&synthio_synthesizer_release_all_obj) }, + { MP_ROM_QSTR(MP_QSTR_release_then_press), MP_ROM_PTR(&synthio_synthesizer_release_then_press_obj) }, + { MP_ROM_QSTR(MP_QSTR_release_all_then_press), MP_ROM_PTR(&synthio_synthesizer_release_all_then_press_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&synthio_synthesizer_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&synthio_synthesizer___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&synthio_synthesizer_sample_rate_obj) }, + { MP_ROM_QSTR(MP_QSTR_max_polyphony), MP_ROM_INT(CIRCUITPY_SYNTHIO_MAX_CHANNELS) }, + { MP_ROM_QSTR(MP_QSTR_pressed), MP_ROM_PTR(&synthio_synthesizer_pressed_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(synthio_synthesizer_locals_dict, synthio_synthesizer_locals_dict_table); + +STATIC const audiosample_p_t synthio_synthesizer_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .sample_rate = (audiosample_sample_rate_fun)common_hal_synthio_synthesizer_get_sample_rate, + .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_synthio_synthesizer_get_bits_per_sample, + .channel_count = (audiosample_channel_count_fun)common_hal_synthio_synthesizer_get_channel_count, + .reset_buffer = (audiosample_reset_buffer_fun)synthio_synthesizer_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)synthio_synthesizer_get_buffer, + .get_buffer_structure = (audiosample_get_buffer_structure_fun)synthio_synthesizer_get_buffer_structure, +}; + +const mp_obj_type_t synthio_synthesizer_type = { + { &mp_type_type }, + .name = MP_QSTR_Synthesizer, + .flags = MP_TYPE_FLAG_EXTENDED, + .make_new = synthio_synthesizer_make_new, + .locals_dict = (mp_obj_dict_t *)&synthio_synthesizer_locals_dict, + MP_TYPE_EXTENDED_FIELDS( + .protocol = &synthio_synthesizer_proto, + ), +}; diff --git a/shared-bindings/synthio/Synthesizer.h b/shared-bindings/synthio/Synthesizer.h new file mode 100644 index 000000000000..92e75a1c23a5 --- /dev/null +++ b/shared-bindings/synthio/Synthesizer.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * Copyright (c) 2023 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/synthio/Synthesizer.h" + +extern const mp_obj_type_t synthio_synthesizer_type; + +void common_hal_synthio_synthesizer_construct(synthio_synthesizer_obj_t *self, + uint32_t sample_rate, const int16_t *waveform, uint16_t waveform_len); + +void common_hal_synthio_synthesizer_deinit(synthio_synthesizer_obj_t *self); +bool common_hal_synthio_synthesizer_deinited(synthio_synthesizer_obj_t *self); +uint32_t common_hal_synthio_synthesizer_get_sample_rate(synthio_synthesizer_obj_t *self); +uint8_t common_hal_synthio_synthesizer_get_bits_per_sample(synthio_synthesizer_obj_t *self); +uint8_t common_hal_synthio_synthesizer_get_channel_count(synthio_synthesizer_obj_t *self); +void common_hal_synthio_synthesizer_release(synthio_synthesizer_obj_t *self, mp_obj_t to_release); +void common_hal_synthio_synthesizer_press(synthio_synthesizer_obj_t *self, mp_obj_t to_press); +void common_hal_synthio_synthesizer_release_all(synthio_synthesizer_obj_t *self); +mp_obj_t common_hal_synthio_synthesizer_get_pressed_notes(synthio_synthesizer_obj_t *self); diff --git a/shared-bindings/synthio/__init__.c b/shared-bindings/synthio/__init__.c index 106a073535fd..3c50377ff8c0 100644 --- a/shared-bindings/synthio/__init__.c +++ b/shared-bindings/synthio/__init__.c @@ -30,9 +30,11 @@ #include "py/obj.h" #include "py/runtime.h" #include "extmod/vfs_fat.h" +#include "extmod/vfs_posix.h" #include "shared-bindings/synthio/__init__.h" #include "shared-bindings/synthio/MidiTrack.h" +#include "shared-bindings/synthio/Synthesizer.h" //| """Support for MIDI synthesis""" //| @@ -42,6 +44,7 @@ //| //| :param typing.BinaryIO file: Already opened MIDI file //| :param int sample_rate: The desired playback sample rate; higher sample rate requires more memory +//| :param ReadableBuffer waveform: A single-cycle waveform. Default is a 50% duty cycle square wave. If specified, must be a ReadableBuffer of type 'h' (signed 16 bit) //| //| //| Playing a MIDI file from flash:: @@ -62,10 +65,11 @@ //| ... //| STATIC mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_file, ARG_sample_rate }; + enum { ARG_file, ARG_sample_rate, ARG_waveform }; static const mp_arg_t allowed_args[] = { { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 11025} }, + { MP_QSTR_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.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); @@ -74,6 +78,10 @@ STATIC mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_ma } pyb_file_obj_t *file = MP_OBJ_TO_PTR(args[ARG_file].u_obj); + + mp_buffer_info_t bufinfo_waveform; + synthio_synth_parse_waveform(&bufinfo_waveform, args[ARG_waveform].u_obj); + uint8_t chunk_header[14]; f_rewind(&file->fp); UINT bytes_read; @@ -113,9 +121,13 @@ STATIC mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_ma result->base.type = &synthio_miditrack_type; common_hal_synthio_miditrack_construct(result, buffer, track_size, - tempo, args[ARG_sample_rate].u_int); + tempo, args[ARG_sample_rate].u_int, bufinfo_waveform.buf, bufinfo_waveform.len / 2); + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(buffer, track_size); + #else m_free(buffer); + #endif return MP_OBJ_FROM_PTR(result); } @@ -125,6 +137,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(synthio_from_file_obj, 1, synthio_from_file); STATIC const mp_rom_map_elem_t synthio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_synthio) }, { MP_ROM_QSTR(MP_QSTR_MidiTrack), MP_ROM_PTR(&synthio_miditrack_type) }, + { MP_ROM_QSTR(MP_QSTR_Synthesizer), MP_ROM_PTR(&synthio_synthesizer_type) }, { MP_ROM_QSTR(MP_QSTR_from_file), MP_ROM_PTR(&synthio_from_file_obj) }, }; diff --git a/shared-bindings/synthio/__init__.h b/shared-bindings/synthio/__init__.h index 14af1a5805eb..3b7d47db285b 100644 --- a/shared-bindings/synthio/__init__.h +++ b/shared-bindings/synthio/__init__.h @@ -24,11 +24,6 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SYNTHIO___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_SYNTHIO___INIT___H +#pragma once -#include "py/obj.h" - -// Nothing now. - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SYNTHIO___INIT___H +extern int16_t shared_bindings_synthio_square_wave[]; diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index 226fa445dabf..7f26149b0092 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -63,7 +63,7 @@ STATIC mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, 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; diff --git a/shared-bindings/traceback/__init__.c b/shared-bindings/traceback/__init__.c index 153587e919c8..3ad601eb3945 100644 --- a/shared-bindings/traceback/__init__.c +++ b/shared-bindings/traceback/__init__.c @@ -37,6 +37,7 @@ //| |see_cpython_module| :mod:`cpython:traceback`. //| """ //| ... +//| 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 }; diff --git a/shared-bindings/uheap/__init__.c b/shared-bindings/uheap/__init__.c index 376be78ef1a3..40aa869225db 100644 --- a/shared-bindings/uheap/__init__.c +++ b/shared-bindings/uheap/__init__.c @@ -32,6 +32,7 @@ #include "shared-bindings/uheap/__init__.h" //| """Heap size analysis""" +//| //| def info(object: object) -> int: //| """Prints memory debugging info for the given object and returns the diff --git a/shared-bindings/usb/core/__init__.c b/shared-bindings/usb/core/__init__.c index 84d202945ae6..faeef23a8835 100644 --- a/shared-bindings/usb/core/__init__.c +++ b/shared-bindings/usb/core/__init__.c @@ -40,6 +40,7 @@ //| //| This is a subset of the PyUSB core module. //| """ +//| //| class USBError(OSError): //| """Catchall exception for USB related errors.""" diff --git a/shared-bindings/usb_cdc/__init__.c b/shared-bindings/usb_cdc/__init__.c index e23e289309c7..b4e712e854ca 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/__init__.c b/shared-bindings/usb_hid/__init__.c index 9cb9303143bf..5c61cc52dedd 100644 --- a/shared-bindings/usb_hid/__init__.c +++ b/shared-bindings/usb_hid/__init__.c @@ -47,6 +47,7 @@ //| containing a `Device` that describes the boot device chosen (keyboard or mouse). //| The request for a boot device overrides any other HID devices. //| """ +//| //| def disable() -> None: //| """Do not present any USB HID devices to the host computer. diff --git a/shared-bindings/usb_host/Port.c b/shared-bindings/usb_host/Port.c index 7fb79e75a55e..53b1fec54f1e 100644 --- a/shared-bindings/usb_host/Port.c +++ b/shared-bindings/usb_host/Port.c @@ -47,8 +47,8 @@ STATIC mp_obj_t usb_host_port_make_new(const mp_obj_type_t *type, // 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; diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c index 982cd144da36..d3d5cf2626fa 100644 --- a/shared-bindings/usb_midi/__init__.c +++ b/shared-bindings/usb_midi/__init__.c @@ -42,6 +42,7 @@ //| //| ports: Tuple[Union[PortIn, PortOut], ...] //| """Tuple of all MIDI ports. Each item is ether `PortIn` or `PortOut`.""" +//| //| def disable() -> None: //| """Disable presenting a USB MIDI device to the host. diff --git a/shared-bindings/ustack/__init__.c b/shared-bindings/ustack/__init__.c index b42fb2a6145f..17bdcbb1c0a9 100644 --- a/shared-bindings/ustack/__init__.c +++ b/shared-bindings/ustack/__init__.c @@ -35,6 +35,7 @@ //| """Stack information and analysis""" +//| #if MICROPY_MAX_STACK_USAGE //| def max_stack_usage() -> int: diff --git a/shared-bindings/vectorio/Circle.c b/shared-bindings/vectorio/Circle.c index 87cd46ad9ab4..9896876a8a2b 100644 --- a/shared-bindings/vectorio/Circle.c +++ b/shared-bindings/vectorio/Circle.c @@ -24,7 +24,8 @@ //| :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 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[] = { diff --git a/shared-bindings/vectorio/Polygon.c b/shared-bindings/vectorio/Polygon.c index 6ad102e6e6b1..b188fc49554a 100644 --- a/shared-bindings/vectorio/Polygon.c +++ b/shared-bindings/vectorio/Polygon.c @@ -32,7 +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[] = { diff --git a/shared-bindings/vectorio/Rectangle.c b/shared-bindings/vectorio/Rectangle.c index a4f3e12e693e..ad864f2c2d01 100644 --- a/shared-bindings/vectorio/Rectangle.c +++ b/shared-bindings/vectorio/Rectangle.c @@ -25,7 +25,8 @@ //| :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 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[] = { diff --git a/shared-bindings/watchdog/__init__.c b/shared-bindings/watchdog/__init__.c index df55ab7c1608..5281f1c3fc36 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 diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index 27a5907894bf..9475ee3b319f 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -310,7 +310,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_station_obj, wifi_radio_stop_station); //| authmode: Optional[AuthMode] = None, //| max_connections: Optional[int] = 4 //| ) -> None: -//| """Starts an Access Point with the specified ssid and password. +//| """Starts running 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. @@ -344,7 +344,7 @@ STATIC mp_obj_t wifi_radio_start_ap(size_t n_args, const mp_obj_t *pos_args, mp_ 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) { - authmodes |= cp_enum_value(&wifi_authmode_type, item); + authmodes |= cp_enum_value(&wifi_authmode_type, item, MP_QSTR_authmode); } } @@ -376,7 +376,7 @@ STATIC mp_obj_t wifi_radio_start_ap(size_t n_args, const mp_obj_t *pos_args, mp_ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_start_ap_obj, 1, wifi_radio_start_ap); //| def stop_ap(self) -> None: -//| """Stops the Access Point.""" +//| """Stops the access point.""" //| ... STATIC mp_obj_t wifi_radio_stop_ap(mp_obj_t self) { common_hal_wifi_radio_stop_ap(self); @@ -384,6 +384,16 @@ STATIC mp_obj_t wifi_radio_stop_ap(mp_obj_t self) { } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_ap_obj, wifi_radio_stop_ap); +//| ap_active: bool +//| """True if running as an access point. (read-only)""" +STATIC mp_obj_t wifi_radio_get_ap_active(mp_obj_t self) { + return mp_obj_new_bool(common_hal_wifi_radio_get_ap_active(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ap_active_obj, wifi_radio_get_ap_active); + +MP_PROPERTY_GETTER(wifi_radio_ap_active_obj, + (mp_obj_t)&wifi_radio_get_ap_active_obj); + //| def connect( //| self, //| ssid: Union[str | ReadableBuffer], @@ -464,11 +474,20 @@ STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_m } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_connect_obj, 1, wifi_radio_connect); +//| connected: bool +//| """True if connected to an access point (read-only).""" +STATIC mp_obj_t wifi_radio_get_connected(mp_obj_t self) { + return mp_obj_new_bool(common_hal_wifi_radio_get_connected(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_connected_obj, wifi_radio_get_connected); + +MP_PROPERTY_GETTER(wifi_radio_connected_obj, + (mp_obj_t)&wifi_radio_get_connected_obj); + //| ipv4_gateway: Optional[ipaddress.IPv4Address] -//| """IP v4 Address of the station gateway when connected to an access point. None otherwise.""" +//| """IP v4 Address of the station gateway when connected to an access point. None otherwise. (read-only)""" STATIC mp_obj_t wifi_radio_get_ipv4_gateway(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_gateway(self); - } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_gateway_obj, wifi_radio_get_ipv4_gateway); @@ -476,10 +495,9 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_gateway_obj, (mp_obj_t)&wifi_radio_get_ipv4_gateway_obj); //| ipv4_gateway_ap: Optional[ipaddress.IPv4Address] -//| """IP v4 Address of the access point gateway, when enabled. None otherwise.""" +//| """IP v4 Address of the access point gateway, when enabled. None otherwise. (read-only)""" STATIC mp_obj_t wifi_radio_get_ipv4_gateway_ap(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_gateway_ap(self); - } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_gateway_ap_obj, wifi_radio_get_ipv4_gateway_ap); @@ -487,10 +505,9 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_gateway_ap_obj, (mp_obj_t)&wifi_radio_get_ipv4_gateway_ap_obj); //| ipv4_subnet: Optional[ipaddress.IPv4Address] -//| """IP v4 Address of the station subnet when connected to an access point. None otherwise.""" +//| """IP v4 Address of the station subnet when connected to an access point. None otherwise. (read-only)""" STATIC mp_obj_t wifi_radio_get_ipv4_subnet(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_subnet(self); - } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_subnet_obj, wifi_radio_get_ipv4_subnet); @@ -498,10 +515,9 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_subnet_obj, (mp_obj_t)&wifi_radio_get_ipv4_subnet_obj); //| ipv4_subnet_ap: Optional[ipaddress.IPv4Address] -//| """IP v4 Address of the access point subnet, when enabled. None otherwise.""" +//| """IP v4 Address of the access point subnet, when enabled. None otherwise. (read-only)""" STATIC mp_obj_t wifi_radio_get_ipv4_subnet_ap(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_subnet_ap(self); - } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_subnet_ap_obj, wifi_radio_get_ipv4_subnet_ap); @@ -538,10 +554,9 @@ STATIC mp_obj_t wifi_radio_set_ipv4_address(size_t n_args, const mp_obj_t *pos_a STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_set_ipv4_address_obj, 1, wifi_radio_set_ipv4_address); //| ipv4_address: Optional[ipaddress.IPv4Address] -//| """IP v4 Address of the station when connected to an access point. None otherwise.""" +//| """IP v4 Address of the station when connected to an access point. None otherwise. (read-only)""" STATIC mp_obj_t _wifi_radio_get_ipv4_address(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_address(self); - } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_address_obj, _wifi_radio_get_ipv4_address); @@ -552,7 +567,6 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_address_obj, //| """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); - } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_address_ap_obj, wifi_radio_get_ipv4_address_ap); @@ -563,7 +577,6 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_address_ap_obj, //| """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); - } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ipv4_dns_obj, wifi_radio_get_ipv4_dns); @@ -582,7 +595,6 @@ MP_PROPERTY_GETSET(wifi_radio_ipv4_dns_obj, //| """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); - } MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ap_info_obj, wifi_radio_get_ap_info); @@ -656,12 +668,14 @@ STATIC const mp_rom_map_elem_t wifi_radio_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_start_ap), MP_ROM_PTR(&wifi_radio_start_ap_obj) }, { MP_ROM_QSTR(MP_QSTR_stop_ap), MP_ROM_PTR(&wifi_radio_stop_ap_obj) }, + { MP_ROM_QSTR(MP_QSTR_ap_active), MP_ROM_PTR(&wifi_radio_ap_active_obj) }, { MP_ROM_QSTR(MP_QSTR_start_dhcp), MP_ROM_PTR(&wifi_radio_start_dhcp_client_obj) }, { MP_ROM_QSTR(MP_QSTR_stop_dhcp), MP_ROM_PTR(&wifi_radio_stop_dhcp_client_obj) }, { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&wifi_radio_connect_obj) }, // { MP_ROM_QSTR(MP_QSTR_connect_to_enterprise), MP_ROM_PTR(&wifi_radio_connect_to_enterprise_obj) }, + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&wifi_radio_connected_obj) }, { MP_ROM_QSTR(MP_QSTR_ap_info), MP_ROM_PTR(&wifi_radio_ap_info_obj) }, { MP_ROM_QSTR(MP_QSTR_ipv4_dns), MP_ROM_PTR(&wifi_radio_ipv4_dns_obj) }, @@ -674,9 +688,6 @@ STATIC const mp_rom_map_elem_t wifi_radio_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_set_ipv4_address), MP_ROM_PTR(&wifi_radio_set_ipv4_address_obj) }, - // { MP_ROM_QSTR(MP_QSTR_access_point_active), MP_ROM_PTR(&wifi_radio_access_point_active_obj) }, - // { MP_ROM_QSTR(MP_QSTR_start_access_point), MP_ROM_PTR(&wifi_radio_start_access_point_obj) }, - { MP_ROM_QSTR(MP_QSTR_ping), MP_ROM_PTR(&wifi_radio_ping_obj) }, }; diff --git a/shared-bindings/wifi/Radio.h b/shared-bindings/wifi/Radio.h index dbaeb9cce8fc..1fb70ef818e7 100644 --- a/shared-bindings/wifi/Radio.h +++ b/shared-bindings/wifi/Radio.h @@ -95,11 +95,13 @@ 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, uint32_t authmodes, uint8_t max_connections); extern void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self); +extern bool common_hal_wifi_radio_get_ap_active(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_start_dhcp_client(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_stop_dhcp_client(wifi_radio_obj_t *self); extern 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); +extern bool common_hal_wifi_radio_get_connected(wifi_radio_obj_t *self); extern mp_obj_t common_hal_wifi_radio_get_ap_info(wifi_radio_obj_t *self); extern mp_obj_t common_hal_wifi_radio_get_ipv4_dns(wifi_radio_obj_t *self); diff --git a/shared-bindings/zlib/__init__.c b/shared-bindings/zlib/__init__.c index d9c2a0181064..ba02914638c3 100644 --- a/shared-bindings/zlib/__init__.c +++ b/shared-bindings/zlib/__init__.c @@ -46,6 +46,7 @@ //| The `zlib` module allows limited functionality similar to the CPython zlib library. //| This module allows to decompress binary data compressed with DEFLATE algorithm //| (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 diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index 1c5de4d93425..397a83713318 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -33,7 +33,10 @@ #include "py/runtime.h" #include "shared-module/audiocore/__init__.h" -#include "shared-module/audiocore/RawSample.h" + +#if defined(__arm__) && __arm__ +#include "cmsis_compiler.h" +#endif void common_hal_audiomixer_mixer_construct(audiomixer_mixer_obj_t *self, uint8_t voice_count, @@ -140,7 +143,7 @@ static inline uint32_t mult16signed(uint32_t val, int32_t mul) { float mod_mul = (float)mul / (float)((1 << 15) - 1); for (int8_t i = 0; i < 2; i++) { int16_t ai = (val >> (sizeof(uint16_t) * 8 * i)); - int32_t intermediate = ai * mod_mul; + int32_t intermediate = (int32_t)(ai * mod_mul); if (intermediate > SHRT_MAX) { intermediate = SHRT_MAX; } else if (intermediate < SHRT_MIN) { diff --git a/shared-module/audiomixer/MixerVoice.c b/shared-module/audiomixer/MixerVoice.c index bb58b0c11117..f4d2a6514e52 100644 --- a/shared-module/audiomixer/MixerVoice.c +++ b/shared-module/audiomixer/MixerVoice.c @@ -42,12 +42,12 @@ void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t *se self->parent = parent; } -float common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self) { - return (float)self->level / (1 << 15); +mp_float_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self) { + return (mp_float_t)self->level / (1 << 15); } -void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, float level) { - self->level = level * (1 << 15); +void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_float_t level) { + self->level = (uint16_t)(level * (1 << 15)); } void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t *self, mp_obj_t sample, bool loop) { diff --git a/shared-module/bitmaptools/__init__.c b/shared-module/bitmaptools/__init__.c index 67b5254b32a8..0ded6d6abbb1 100644 --- a/shared-module/bitmaptools/__init__.c +++ b/shared-module/bitmaptools/__init__.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2021 Kevin Matocha + * Copyright (c) 2021 Kevin Matocha, Jose David Montoya * * 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,6 +24,7 @@ * THE SOFTWARE. */ +#include "shared/runtime/interrupt_char.h" #include "shared-bindings/bitmaptools/__init__.h" #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Palette.h" @@ -39,6 +40,9 @@ #include #include +#define BITMAP_DEBUG(...) (void)0 +// #define BITMAP_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) + void common_hal_bitmaptools_rotozoom(displayio_bitmap_t *self, int16_t ox, int16_t oy, int16_t dest_clip0_x, int16_t dest_clip0_y, int16_t dest_clip1_x, int16_t dest_clip1_y, @@ -376,6 +380,10 @@ void common_hal_bitmaptools_boundary_fill(displayio_bitmap_t *destination, } mp_obj_list_get(fill_area, &list_length, &fill_points); + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + return; + } } // set dirty the area so displayio will draw @@ -384,37 +392,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 +405,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 +416,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 +470,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; @@ -720,7 +784,7 @@ void common_hal_bitmaptools_dither(displayio_bitmap_t *dest_bitmap, displayio_bi bitmaptools_dither_algorithm_info_t *info = algorithms[algorithm]; // rowdata holds 3 rows of data. Each one is larger than the input - // bitmap's width, beacuse `mx` extra pixels are allocated at the start and + // bitmap's width, because `mx` extra pixels are allocated at the start and // end of the row so that no conditionals are needed when storing the error data. int16_t rowdata[(width + 2 * info->mx) * 3]; int16_t *rows[3] = { @@ -857,3 +921,64 @@ void common_hal_bitmaptools_alphablend(displayio_bitmap_t *dest, displayio_bitma } } } + +STATIC void draw_circle(displayio_bitmap_t *destination, + int16_t x, int16_t y, + int16_t radius, uint32_t value) { + + int16_t d, yb; + + mp_arg_validate_int_range(x, SHRT_MIN, SHRT_MAX, MP_QSTR_x); + mp_arg_validate_int_range(y, SHRT_MIN, SHRT_MAX, MP_QSTR_y); + + x = MIN(x, destination->width); + x = MAX(0, x); + y = MIN(y, destination->height); + y = MAX(0, y); + + BITMAP_DEBUG("x, y, radius (%4d, %4d, %4d)\n", x, y, radius); + + yb = radius; + d = 3 - 2 * radius; + + // Bresenham's circle algorithm + for (int xb = 0; xb <= yb; xb++) { + displayio_bitmap_write_pixel(destination, xb + x, yb + y, value); + displayio_bitmap_write_pixel(destination, -xb + x, -yb + y, value); + displayio_bitmap_write_pixel(destination, -xb + x, yb + y, value); + displayio_bitmap_write_pixel(destination, xb + x, -yb + y, value); + displayio_bitmap_write_pixel(destination, yb + x, xb + y, value); + displayio_bitmap_write_pixel(destination, -yb + x, xb + y, value); + displayio_bitmap_write_pixel(destination, -yb + x, -xb + y, value); + displayio_bitmap_write_pixel(destination, yb + x, -xb + y, value); + if (d <= 0) { + d = d + (4 * xb) + 6; + } else { + d = d + 4 * (xb - yb) + 10; + yb = yb - 1; + } + } +} + +void common_hal_bitmaptools_draw_circle(displayio_bitmap_t *destination, + int16_t x, int16_t y, + int16_t radius, + uint32_t value) { + + + // update the dirty area + int16_t xbb0, xbb1, ybb0, ybb1; + + xbb0 = x - radius; + xbb1 = x + radius; + ybb0 = y - radius; + ybb1 = y + radius; + + 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_circle(destination, x, y, radius, value); +} diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 6c64830dcea0..c9212f6a8534 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -29,6 +29,7 @@ #include #include "py/runtime.h" +#include "py/gc.h" enum { ALIGN_BITS = 8 * sizeof(uint32_t) }; @@ -48,8 +49,10 @@ void common_hal_displayio_bitmap_construct_from_buffer(displayio_bitmap_t *self, self->width = width; self->height = height; self->stride = stride(width, bits_per_value); + self->data_alloc = false; if (!data) { data = m_malloc(self->stride * height * sizeof(uint32_t), false); + self->data_alloc = true; } self->data = data; self->read_only = read_only; @@ -79,6 +82,16 @@ void common_hal_displayio_bitmap_construct_from_buffer(displayio_bitmap_t *self, self->dirty_area.y2 = height; } +void common_hal_displayio_bitmap_deinit(displayio_bitmap_t *self) { + if (self->data_alloc) { + gc_free(self->data); + } + self->data = NULL; +} + +bool common_hal_displayio_bitmap_deinited(displayio_bitmap_t *self) { + return self->data == NULL; +} uint16_t common_hal_displayio_bitmap_get_height(displayio_bitmap_t *self) { return self->height; @@ -128,9 +141,17 @@ void displayio_bitmap_set_dirty_area(displayio_bitmap_t *self, const displayio_a } void displayio_bitmap_write_pixel(displayio_bitmap_t *self, int16_t x, int16_t y, uint32_t value) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only")); + } // 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; @@ -155,6 +176,9 @@ void displayio_bitmap_write_pixel(displayio_bitmap_t *self, int16_t x, int16_t y void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t skip_index, bool skip_index_none) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only")); + } // Copy region of "source" bitmap into "self" bitmap at location x,y in the "self" // If skip_value is encountered in the source bitmap, it will not be copied. // If skip_value is `None`, then all pixels are copied. @@ -208,6 +232,9 @@ void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16 } void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, int16_t y, uint32_t value) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only")); + } // update the dirty region displayio_area_t a = {x, y, x + 1, y + 1, NULL}; displayio_bitmap_set_dirty_area(self, &a); @@ -218,7 +245,7 @@ void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, } displayio_area_t *displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t *tail) { - if (self->dirty_area.x1 == self->dirty_area.x2) { + if (self->dirty_area.x1 == self->dirty_area.x2 || self->read_only) { return tail; } self->dirty_area.next = tail; @@ -226,11 +253,17 @@ displayio_area_t *displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, d } void displayio_bitmap_finish_refresh(displayio_bitmap_t *self) { + if (self->read_only) { + return; + } self->dirty_area.x1 = 0; self->dirty_area.x2 = 0; } void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only")); + } displayio_area_t a = {0, 0, self->width, self->height, NULL}; displayio_bitmap_set_dirty_area(self, &a); diff --git a/shared-module/displayio/Bitmap.h b/shared-module/displayio/Bitmap.h index 0373ae80c5c6..2025e56282c5 100644 --- a/shared-module/displayio/Bitmap.h +++ b/shared-module/displayio/Bitmap.h @@ -45,6 +45,7 @@ typedef struct { displayio_area_t dirty_area; uint16_t bitmask; bool read_only; + bool data_alloc; // did bitmap allocate data or someone else } displayio_bitmap_t; void displayio_bitmap_finish_refresh(displayio_bitmap_t *self); diff --git a/shared-module/displayio/ColorConverter.c b/shared-module/displayio/ColorConverter.c index 707601a3e7fd..7064569e2d1a 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 7e4e9819acdf..c1e46035ca4b 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 8367e23b599d..01d8c544ad4a 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -136,7 +136,9 @@ void common_hal_displayio_display_construct(displayio_display_obj_t *self, // Set the group after initialization otherwise we may send pixels while we delay in // initialization. - common_hal_displayio_display_set_root_group(self, &circuitpython_splash); + if (!circuitpython_splash.in_group) { + common_hal_displayio_display_set_root_group(self, &circuitpython_splash); + } common_hal_displayio_display_set_auto_refresh(self, auto_refresh); } @@ -423,7 +425,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); @@ -438,7 +439,9 @@ void reset_display(displayio_display_obj_t *self) { 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); + if (!circuitpython_splash.in_group) { + 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/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c index d8765996508e..74f828aea871 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,33 @@ #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; + bool core_grayscale = true; 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; + core_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, core_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 +84,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 +93,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; @@ -193,6 +208,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); } @@ -211,9 +228,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; @@ -326,8 +342,10 @@ 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->acep) { + 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; @@ -335,6 +353,8 @@ STATIC bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t * } 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); @@ -366,6 +386,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) { @@ -393,6 +443,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 55feaf964b1f..f2398398eaf5 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/I2CDisplay.c b/shared-module/displayio/I2CDisplay.c index 8fae5d31fd32..f38e4d629679 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 2863dffb193e..c9a9d7d9f2e2 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 1bd168b354d9..c61b9ebc8202 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,34 @@ 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. + _displayio_color_t *color = &self->colors[palette_index]; + // Check the grayscale settings because EPaperDisplay will change them on + // the same object. + if (!self->dither && + color->cached_colorspace == colorspace && + color->cached_colorspace_grayscale_bit == colorspace->grayscale_bit && + color->cached_colorspace_grayscale == colorspace->grayscale) { + 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) { + color->cached_colorspace = colorspace; + color->cached_color = output_color->pixel; + color->cached_colorspace_grayscale = colorspace->grayscale; + color->cached_colorspace_grayscale_bit = colorspace->grayscale_bit; + } } bool displayio_palette_needs_refresh(displayio_palette_t *self) { diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h index 49f03b56c780..050423d05268 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,10 @@ 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; + uint8_t cached_colorspace_grayscale_bit; + bool cached_colorspace_grayscale; bool transparent; // This may have additional bits added later for blending. } _displayio_color_t; @@ -74,11 +75,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 769c334ac682..e5573ac34ca9 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/framebufferio/FramebufferDisplay.h b/shared-module/framebufferio/FramebufferDisplay.h index b53461aad50e..47f31d794f79 100644 --- a/shared-module/framebufferio/FramebufferDisplay.h +++ b/shared-module/framebufferio/FramebufferDisplay.h @@ -66,7 +66,7 @@ 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); diff --git a/shared-module/gifio/OnDiskGif.c b/shared-module/gifio/OnDiskGif.c new file mode 100644 index 000000000000..aeb4f7bb74d6 --- /dev/null +++ b/shared-module/gifio/OnDiskGif.c @@ -0,0 +1,213 @@ +/* + * 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; +} + +void common_hal_gifio_ondiskgif_deinit(gifio_ondiskgif_t *self) { + self->file = NULL; + common_hal_displayio_bitmap_deinit(self->bitmap); + self->bitmap = NULL; +} + +bool common_hal_gifio_ondiskgif_deinited(gifio_ondiskgif_t *self) { + return self->bitmap == NULL; +} + +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 000000000000..c40781ef1fe8 --- /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 d795c0d5e768..07bd3324f997 100644 --- a/shared-module/is31fl3741/FrameBuffer.c +++ b/shared-module/is31fl3741/FrameBuffer.c @@ -172,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, self->height); + common_hal_is31fl3741_draw_pixel(self->is31fl3741, x, y, color, self->mapping, self->scale_height); } } } else { @@ -193,7 +193,7 @@ 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, self->height); + common_hal_is31fl3741_draw_pixel(self->is31fl3741, x, y, color, self->mapping, self->scale_height); buffer++; } } else { diff --git a/shared-module/msgpack/__init__.c b/shared-module/msgpack/__init__.c index d32550722cc7..3a34731d7714 100644 --- a/shared-module/msgpack/__init__.c +++ b/shared-module/msgpack/__init__.c @@ -102,6 +102,16 @@ STATIC uint32_t read4(msgpack_stream_t *s) { return res; } +STATIC uint64_t read8(msgpack_stream_t *s) { + uint64_t res = 0; + read(s, &res, 8); + int n = 1; + if (*(char *)&n == 1) { + res = __builtin_bswap64(res); + } + return res; +} + STATIC size_t read_size(msgpack_stream_t *s, uint8_t len_index) { size_t res = 0; switch (len_index) { @@ -207,7 +217,7 @@ STATIC void pack_bin(msgpack_stream_t *s, const uint8_t *data, size_t len) { } } -STATIC void pack_ext(msgpack_stream_t *s, int8_t code, const uint8_t *data, size_t len) { +STATIC void pack_ext(msgpack_stream_t *s, int8_t code, const uint8_t *data, size_t len) { if (len == 1) { write1(s, 0xd4); } else if (len == 2) { @@ -424,22 +434,39 @@ STATIC mp_obj_t unpack(msgpack_stream_t *s, mp_obj_t ext_hook, bool use_list) { return unpack_bytes(s, read_size(s, code - 0xc4)); } case 0xcc: // uint8 + return MP_OBJ_NEW_SMALL_INT((uint8_t)read1(s)); case 0xd0: // int8 return MP_OBJ_NEW_SMALL_INT((int8_t)read1(s)); case 0xcd: // uint16 + return MP_OBJ_NEW_SMALL_INT((uint16_t)read2(s)); case 0xd1: // int16 return MP_OBJ_NEW_SMALL_INT((int16_t)read2(s)); case 0xce: // uint32 + return mp_obj_new_int_from_uint((uint32_t)read4(s)); case 0xd2: // int32 - return MP_OBJ_NEW_SMALL_INT((int32_t)read4(s)); - case 0xca: { - union Float { mp_float_t f; - uint32_t u; + return mp_obj_new_int((int32_t)read4(s)); + case 0xcf: // uint 64 + return mp_obj_new_int_from_ull((uint64_t)read8(s)); + case 0xd3: // int 64 + return mp_obj_new_int_from_ll((int64_t)read8(s)); + case 0xca: { // float + union Float { + mp_float_t f; + uint32_t u; }; union Float data; data.u = read4(s); return mp_obj_new_float(data.f); } + case 0xcb: { // double + union Double { + uint64_t u; + double d; + }; + union Double data; + data.u = read8(s); + return mp_obj_new_float_from_d(data.d); + } case 0xd9: case 0xda: case 0xdb: { @@ -483,11 +510,8 @@ STATIC mp_obj_t unpack(msgpack_stream_t *s, mp_obj_t ext_hook, bool use_list) { // ext 8, 16, 32 return unpack_ext(s, read_size(s, code - 0xc7), ext_hook); case 0xc1: // never used - case 0xcb: // float 64 - case 0xcf: // uint 64 - case 0xd3: // int 64 default: - mp_raise_NotImplementedError(translate("64 bit types")); + mp_raise_ValueError(translate("Invalid format")); } } diff --git a/shared-module/onewireio/OneWire.c b/shared-module/onewireio/OneWire.c index aeb4dcb00dda..f00cf572dd7a 100644 --- a/shared-module/onewireio/OneWire.c +++ b/shared-module/onewireio/OneWire.c @@ -59,8 +59,10 @@ bool common_hal_onewireio_onewire_reset(onewireio_onewire_obj_t *self) { common_hal_mcu_delay_us(70); bool value = common_hal_digitalio_digitalinout_get_value(&self->pin); common_hal_mcu_delay_us(410); + // test if bus returned high (idle) and not stuck at low + bool idle = common_hal_digitalio_digitalinout_get_value(&self->pin); common_hal_mcu_enable_interrupts(); - return value; + return value || !idle; } bool common_hal_onewireio_onewire_read_bit(onewireio_onewire_obj_t *self) { diff --git a/shared-module/os/getenv.c b/shared-module/os/getenv.c index 870973c5d2c6..76cbf48daebc 100644 --- a/shared-module/os/getenv.c +++ b/shared-module/os/getenv.c @@ -72,7 +72,7 @@ STATIC void close_file(file_arg *active_file) { // nothing } STATIC bool is_eof(file_arg *active_file) { - return f_eof(active_file); + return f_eof(active_file) || f_error(active_file); } // Return 0 if there is no next character (EOF). diff --git a/shared-module/sharpdisplay/SharpMemoryFramebuffer.c b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c index 285abb1dbe46..3bb7f00e1b26 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 abc951baf5f6..75abb2ff10d5 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 7b6eec7e1b09..060972d0c33d 100644 --- a/shared-module/storage/__init__.c +++ b/shared-module/storage/__init__.c @@ -127,6 +127,7 @@ static bool usb_drive_set_enabled(bool enabled) { if (tud_connected()) { return false; } + filesystem_set_internal_writable_by_usb(enabled); storage_usb_is_enabled = enabled; return true; } diff --git a/shared-module/struct/__init__.c b/shared-module/struct/__init__.c index e87321ae798c..11e122915c62 100644 --- a/shared-module/struct/__init__.c +++ b/shared-module/struct/__init__.c @@ -129,14 +129,10 @@ void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte *end_p, size mp_raise_RuntimeError(translate("buffer too small")); } - size_t i; + size_t i = 0; byte *p_base = p; - for (i = 0; i < n_args;) { + while (*fmt) { mp_uint_t sz = 1; - if (*fmt == '\0') { - // more arguments given than used by format string; CPython raises struct.error here - mp_raise_RuntimeError(translate("too many arguments provided with the given format")); - } struct_validate_format(*fmt); if (unichar_isdigit(*fmt)) { @@ -144,14 +140,17 @@ void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte *end_p, size } if (*fmt == 's') { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[i++], &bufinfo, MP_BUFFER_READ); - mp_uint_t to_copy = sz; - if (bufinfo.len < to_copy) { - to_copy = bufinfo.len; + if (i < n_args) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[i], &bufinfo, MP_BUFFER_READ); + mp_uint_t to_copy = sz; + if (bufinfo.len < to_copy) { + to_copy = bufinfo.len; + } + memcpy(p, bufinfo.buf, to_copy); + memset(p + to_copy, 0, sz - to_copy); } - memcpy(p, bufinfo.buf, to_copy); - memset(p + to_copy, 0, sz - to_copy); + i++; p += sz; } else { while (sz--) { @@ -159,13 +158,16 @@ void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte *end_p, size if (*fmt == 'x') { mp_binary_set_val(fmt_type, *fmt, MP_OBJ_NEW_SMALL_INT(0), p_base, &p); } else { - mp_binary_set_val(fmt_type, *fmt, args[i], p_base, &p); + if (i < n_args) { + mp_binary_set_val(fmt_type, *fmt, args[i], p_base, &p); + } i++; } } } fmt++; } + (void)mp_arg_validate_length(n_args, i, MP_QSTR_values); } mp_obj_tuple_t *shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p, bool exact_size) { diff --git a/shared-module/synthio/MidiTrack.c b/shared-module/synthio/MidiTrack.c index f02747d7349e..f8b39c29e383 100644 --- a/shared-module/synthio/MidiTrack.c +++ b/shared-module/synthio/MidiTrack.c @@ -27,10 +27,6 @@ #include "py/runtime.h" #include "shared-bindings/synthio/MidiTrack.h" -#define LOUDNESS 0x4000 // 0.5 -#define BITS_PER_SAMPLE 16 -#define BYTES_PER_SAMPLE (BITS_PER_SAMPLE / 8) -#define SILENCE 0x80 STATIC NORETURN void raise_midi_stream_error(uint32_t pos) { mp_raise_ValueError_varg(translate("Error in MIDI stream at position %d"), pos); @@ -47,36 +43,42 @@ STATIC uint8_t parse_note(const uint8_t *buffer, uint32_t len, uint32_t *pos) { return note; } -STATIC void terminate_span(synthio_miditrack_obj_t *self, uint16_t *dur, uint16_t *max_dur) { +STATIC void terminate_span(synthio_miditrack_obj_t *self, uint16_t *dur) { if (*dur) { self->track[self->total_spans - 1].dur = *dur; - if (*dur > *max_dur) { - *max_dur = *dur; - } *dur = 0; } else { self->total_spans--; } } -STATIC void add_span(synthio_miditrack_obj_t *self, uint8_t note1, uint8_t note2) { - synthio_midi_span_t span = { 0, {note1, note2} }; - self->track = m_realloc(self->track, - (self->total_spans + 1) * sizeof(synthio_midi_span_t)); - self->track[self->total_spans++] = span; +STATIC void add_span(synthio_miditrack_obj_t *self, const synthio_midi_span_t *span) { + self->track = m_renew(synthio_midi_span_t, self->track, self->total_spans, self->total_spans + 1); + self->track[self->total_spans++] = *span; +} + +STATIC void change_span_note(synthio_miditrack_obj_t *self, uint8_t old_note, uint8_t new_note, uint16_t *dur) { + synthio_midi_span_t span = self->track[self->total_spans - 1]; + if (synthio_span_change_note(&span, old_note, new_note)) { + terminate_span(self, dur); + add_span(self, &span); + *dur = 0; + } } void common_hal_synthio_miditrack_construct(synthio_miditrack_obj_t *self, - const uint8_t *buffer, uint32_t len, uint32_t tempo, uint32_t sample_rate) { + const uint8_t *buffer, uint32_t len, uint32_t tempo, uint32_t sample_rate, + const int16_t *waveform, uint16_t waveform_length) { - synthio_midi_span_t initial = { 0, {SILENCE, SILENCE} }; - self->sample_rate = sample_rate; + self->synth.sample_rate = sample_rate; self->track = m_malloc(sizeof(synthio_midi_span_t), false); + synthio_span_init(self->track); self->next_span = 0; self->total_spans = 1; - *self->track = initial; + self->synth.waveform = waveform; + self->synth.waveform_length = waveform_length; - uint16_t dur = 0, max_dur = 0; + uint16_t dur = 0; uint32_t pos = 0; while (pos < len) { uint8_t c; @@ -91,37 +93,19 @@ void common_hal_synthio_miditrack_construct(synthio_miditrack_obj_t *self, raise_midi_stream_error(pos); } + // dur is carried over here so that if a note on/off message doesn't actually produce a change, the + // underlying "span" is extended. Otherwise, it is zeroed out in the call to `terminate_span`. dur += delta * sample_rate / tempo; switch (buffer[pos++] >> 4) { case 8: { // Note Off uint8_t note = parse_note(buffer, len, &pos); - - // Ignore if not a note which is playing - synthio_midi_span_t last_span = self->track[self->total_spans - 1]; - if (last_span.note[0] == note || last_span.note[1] == note) { - terminate_span(self, &dur, &max_dur); - if (last_span.note[0] == note) { - add_span(self, last_span.note[1], SILENCE); - } else { - add_span(self, last_span.note[0], SILENCE); - } - } + change_span_note(self, note, SYNTHIO_SILENCE, &dur); break; } case 9: { // Note On uint8_t note = parse_note(buffer, len, &pos); - - // Ignore if two notes are already playing - synthio_midi_span_t last_span = self->track[self->total_spans - 1]; - if (last_span.note[1] == SILENCE) { - terminate_span(self, &dur, &max_dur); - if (last_span.note[0] == SILENCE) { - add_span(self, note, SILENCE); - } else { - add_span(self, last_span.note[0], note); - } - } + change_span_note(self, SYNTHIO_SILENCE, note, &dur); break; } case 10: @@ -142,27 +126,29 @@ void common_hal_synthio_miditrack_construct(synthio_miditrack_obj_t *self, raise_midi_stream_error(pos); } } - terminate_span(self, &dur, &max_dur); + terminate_span(self, &dur); - self->buffer_length = max_dur * BYTES_PER_SAMPLE; - self->buffer = m_malloc(self->buffer_length, false); + uint16_t max_dur = 0; + for (int i = 0; i < self->total_spans; i++) { + max_dur = MAX(self->track[i].dur, max_dur); + } + synthio_synth_init(&self->synth, max_dur); } void common_hal_synthio_miditrack_deinit(synthio_miditrack_obj_t *self) { - m_free(self->buffer); - self->buffer = NULL; - m_free(self->track); + synthio_synth_deinit(&self->synth); + m_del(synthio_midi_span_t, self->track, self->total_spans + 1); self->track = NULL; } bool common_hal_synthio_miditrack_deinited(synthio_miditrack_obj_t *self) { - return self->buffer == NULL; + return synthio_synth_deinited(&self->synth); } uint32_t common_hal_synthio_miditrack_get_sample_rate(synthio_miditrack_obj_t *self) { - return self->sample_rate; + return self->synth.sample_rate; } uint8_t common_hal_synthio_miditrack_get_bits_per_sample(synthio_miditrack_obj_t *self) { - return BITS_PER_SAMPLE; + return SYNTHIO_BITS_PER_SAMPLE; } uint8_t common_hal_synthio_miditrack_get_channel_count(synthio_miditrack_obj_t *self) { return 1; @@ -170,47 +156,29 @@ uint8_t common_hal_synthio_miditrack_get_channel_count(synthio_miditrack_obj_t * void synthio_miditrack_reset_buffer(synthio_miditrack_obj_t *self, bool single_channel_output, uint8_t channel) { - + synthio_synth_reset_buffer(&self->synth, single_channel_output, channel); + self->synth.span.dur = 0; self->next_span = 0; } -STATIC const uint16_t notes[] = {8372, 8870, 9397, 9956, 10548, 11175, 11840, - 12544, 13290, 14080, 14917, 15804}; // 9th octave - audioio_get_buffer_result_t synthio_miditrack_get_buffer(synthio_miditrack_obj_t *self, bool single_channel_output, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length) { - if (self->next_span >= self->total_spans) { - *buffer_length = 0; - return GET_BUFFER_DONE; + if (self->synth.span.dur == 0) { + if (self->next_span >= self->total_spans) { + *buffer_length = 0; + return GET_BUFFER_DONE; + } + self->synth.span = self->track[self->next_span++]; } - synthio_midi_span_t span = self->track[self->next_span++]; - *buffer_length = span.dur * BYTES_PER_SAMPLE; - uint8_t octave1 = span.note[0] / 12; // 0..10 - uint8_t octave2 = span.note[1] / 12; // 0..10 - int32_t base_freq1 = notes[span.note[0] % 12]; - int32_t base_freq2 = notes[span.note[1] % 12]; - int32_t sample_rate = self->sample_rate; - - for (uint16_t i = 0; i < span.dur; i++) { - int16_t semiperiod1 = span.note[0] == SILENCE ? 0 : - ((base_freq1 * i * 2) / sample_rate) >> (10 - octave1); - int16_t semiperiod2 = span.note[1] == SILENCE ? semiperiod1 : - ((base_freq2 * i * 2) / sample_rate) >> (10 - octave2); - self->buffer[i] = ((semiperiod1 % 2 + semiperiod2 % 2) - 1) * LOUDNESS; - } - *buffer = (uint8_t *)self->buffer; + synthio_synth_synthesize(&self->synth, buffer, buffer_length, single_channel_output ? 0 : channel); - return self->next_span >= self->total_spans ? + return (self->synth.span.dur == 0 && self->next_span >= self->total_spans) ? GET_BUFFER_DONE : GET_BUFFER_MORE_DATA; } void synthio_miditrack_get_buffer_structure(synthio_miditrack_obj_t *self, bool single_channel_output, bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing) { - - *single_buffer = true; - *samples_signed = true; - *max_buffer_length = self->buffer_length; - *spacing = 1; + return synthio_synth_get_buffer_structure(&self->synth, single_channel_output, single_buffer, samples_signed, max_buffer_length, spacing); } diff --git a/shared-module/synthio/MidiTrack.h b/shared-module/synthio/MidiTrack.h index 0af174ebc13a..e301ef355f42 100644 --- a/shared-module/synthio/MidiTrack.h +++ b/shared-module/synthio/MidiTrack.h @@ -31,19 +31,12 @@ #include "shared-module/synthio/__init__.h" -typedef struct { - uint16_t dur; - uint8_t note[2]; -} synthio_midi_span_t; - typedef struct { mp_obj_base_t base; - uint32_t sample_rate; - uint16_t *buffer; - uint16_t buffer_length; - synthio_midi_span_t *track; + synthio_synth_t synth; uint16_t next_span; uint16_t total_spans; + synthio_midi_span_t *track; } synthio_miditrack_obj_t; diff --git a/shared-module/synthio/Synthesizer.c b/shared-module/synthio/Synthesizer.c new file mode 100644 index 000000000000..25c91ecbe078 --- /dev/null +++ b/shared-module/synthio/Synthesizer.c @@ -0,0 +1,105 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * + * 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/synthio/Synthesizer.h" + + + +void common_hal_synthio_synthesizer_construct(synthio_synthesizer_obj_t *self, + uint32_t sample_rate, const int16_t *waveform, uint16_t waveform_length) { + + self->synth.sample_rate = sample_rate; + self->synth.waveform = waveform; + self->synth.waveform_length = waveform_length; + synthio_synth_init(&self->synth, SYNTHIO_MAX_DUR); + common_hal_synthio_synthesizer_release_all(self); +} + +void common_hal_synthio_synthesizer_deinit(synthio_synthesizer_obj_t *self) { + synthio_synth_deinit(&self->synth); +} +bool common_hal_synthio_synthesizer_deinited(synthio_synthesizer_obj_t *self) { + return synthio_synth_deinited(&self->synth); +} + +uint32_t common_hal_synthio_synthesizer_get_sample_rate(synthio_synthesizer_obj_t *self) { + return self->synth.sample_rate; +} +uint8_t common_hal_synthio_synthesizer_get_bits_per_sample(synthio_synthesizer_obj_t *self) { + return SYNTHIO_BITS_PER_SAMPLE; +} +uint8_t common_hal_synthio_synthesizer_get_channel_count(synthio_synthesizer_obj_t *self) { + return 1; +} + +void synthio_synthesizer_reset_buffer(synthio_synthesizer_obj_t *self, + bool single_channel_output, uint8_t channel) { + synthio_synth_reset_buffer(&self->synth, single_channel_output, channel); +} + +audioio_get_buffer_result_t synthio_synthesizer_get_buffer(synthio_synthesizer_obj_t *self, + bool single_channel_output, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length) { + self->synth.span.dur = SYNTHIO_MAX_DUR; + synthio_synth_synthesize(&self->synth, buffer, buffer_length, single_channel_output ? channel : 0); + return GET_BUFFER_MORE_DATA; +} + +void synthio_synthesizer_get_buffer_structure(synthio_synthesizer_obj_t *self, bool single_channel_output, + bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing) { + return synthio_synth_get_buffer_structure(&self->synth, single_channel_output, single_buffer, samples_signed, max_buffer_length, spacing); +} + +void common_hal_synthio_synthesizer_release_all(synthio_synthesizer_obj_t *self) { + synthio_span_init(&self->synth.span); +} +void common_hal_synthio_synthesizer_release(synthio_synthesizer_obj_t *self, mp_obj_t to_release) { + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(to_release, &iter_buf); + mp_obj_t item; + while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + synthio_span_change_note(&self->synth.span, mp_arg_validate_int_range(mp_obj_get_int(item), 0, 127, MP_QSTR_note), SYNTHIO_SILENCE); + } +} + +void common_hal_synthio_synthesizer_press(synthio_synthesizer_obj_t *self, mp_obj_t to_press) { + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(to_press, &iter_buf); + mp_obj_t item; + while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + synthio_span_change_note(&self->synth.span, SYNTHIO_SILENCE, mp_arg_validate_int_range(mp_obj_get_int(item), 0, 127, MP_QSTR_note)); + } +} + +mp_obj_t common_hal_synthio_synthesizer_get_pressed_notes(synthio_synthesizer_obj_t *self) { + mp_obj_tuple_t *result = MP_OBJ_TO_PTR(mp_obj_new_tuple(synthio_span_count_active_channels(&self->synth.span), NULL)); + for (size_t i = 0, j = 0; i < CIRCUITPY_SYNTHIO_MAX_CHANNELS; i++) { + if (self->synth.span.note[i] != SYNTHIO_SILENCE) { + result->items[j++] = MP_OBJ_NEW_SMALL_INT(self->synth.span.note[i]); + } + } + return MP_OBJ_FROM_PTR(result); +} diff --git a/shared-module/synthio/Synthesizer.h b/shared-module/synthio/Synthesizer.h new file mode 100644 index 000000000000..256b6137f208 --- /dev/null +++ b/shared-module/synthio/Synthesizer.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * Copyright (c) 2023 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 "shared-module/synthio/__init__.h" + +typedef struct { + mp_obj_base_t base; + synthio_synth_t synth; +} synthio_synthesizer_obj_t; + + +// These are not available from Python because it may be called in an interrupt. +void synthio_synthesizer_reset_buffer(synthio_synthesizer_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t synthio_synthesizer_get_buffer(synthio_synthesizer_obj_t *self, + bool single_channel_output, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes + +void synthio_synthesizer_get_buffer_structure(synthio_synthesizer_obj_t *self, bool single_channel_output, + bool *single_buffer, bool *samples_signed, + uint32_t *max_buffer_length, uint8_t *spacing); diff --git a/shared-module/synthio/__init__.c b/shared-module/synthio/__init__.c index e69de29bb2d1..11e4c1dcc90b 100644 --- a/shared-module/synthio/__init__.c +++ b/shared-module/synthio/__init__.c @@ -0,0 +1,172 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * Copyright (c) 2023 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-module/synthio/__init__.h" +#include "py/runtime.h" + +STATIC const int16_t square_wave[] = {-32768, 32767}; + +STATIC const uint16_t notes[] = {8372, 8870, 9397, 9956, 10548, 11175, 11840, + 12544, 13290, 14080, 14917, 15804}; // 9th octave + +int synthio_span_count_active_channels(synthio_midi_span_t *span) { + int result = 0; + for (int i = 0; i < CIRCUITPY_SYNTHIO_MAX_CHANNELS; i++) { + if (span->note[i] != SYNTHIO_SILENCE) { + result += 1; + } + } + return result; +} + + +void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t *buffer_length, uint8_t channel) { + + if (channel == synth->other_channel) { + *buffer_length = synth->last_buffer_length; + *bufptr = (uint8_t *)(synth->buffers[synth->other_buffer_index] + channel); + return; + } + + synth->buffer_index = !synth->buffer_index; + synth->other_channel = 1 - channel; + synth->other_buffer_index = synth->buffer_index; + int16_t *out_buffer = (int16_t *)(void *)synth->buffers[synth->buffer_index]; + + uint16_t dur = MIN(SYNTHIO_MAX_DUR, synth->span.dur); + synth->span.dur -= dur; + memset(out_buffer, 0, synth->buffer_length); + + int32_t sample_rate = synth->sample_rate; + int active_channels = synthio_span_count_active_channels(&synth->span); + const int16_t *waveform = synth->waveform; + uint32_t waveform_length = synth->waveform_length; + if (active_channels) { + int16_t loudness = 0xffff / (1 + 2 * active_channels); + for (int chan = 0; chan < CIRCUITPY_SYNTHIO_MAX_CHANNELS; chan++) { + if (synth->span.note[chan] == SYNTHIO_SILENCE) { + synth->accum[chan] = 0; + continue; + } + uint8_t octave = synth->span.note[chan] / 12; + uint16_t base_freq = notes[synth->span.note[chan] % 12]; + uint32_t accum = synth->accum[chan]; +#define SHIFT (16) + // rate = base_freq * waveform_length + // den = sample_rate * 2 ^ (10 - octave) + // den = sample_rate * 2 ^ 10 / 2^octave + // dds_rate = 2^SHIFT * rate / den + // dds_rate = 2^(SHIFT-10+octave) * base_freq * waveform_length / sample_rate + uint32_t dds_rate = (sample_rate / 2 + ((uint64_t)(base_freq * waveform_length) << (SHIFT - 10 + octave))) / sample_rate; + + for (uint16_t i = 0; i < dur; i++) { + accum += dds_rate; + if (accum > waveform_length << SHIFT) { + accum -= waveform_length << SHIFT; + } + int16_t idx = accum >> SHIFT; + out_buffer[i] += (waveform[idx] * loudness) / 65536; + } + synth->accum[chan] = accum; + } + } + + *buffer_length = synth->last_buffer_length = dur * SYNTHIO_BYTES_PER_SAMPLE; + *bufptr = (uint8_t *)out_buffer; +} + +void synthio_synth_reset_buffer(synthio_synth_t *synth, bool single_channel_output, uint8_t channel) { + if (single_channel_output && channel == 1) { + return; + } + synth->other_channel = -1; +} + +bool synthio_synth_deinited(synthio_synth_t *synth) { + return synth->buffers[0] == NULL; +} + +void synthio_synth_deinit(synthio_synth_t *synth) { + m_del(uint8_t, synth->buffers[0], synth->buffer_length); + m_del(uint8_t, synth->buffers[1], synth->buffer_length); + synth->buffers[0] = NULL; + synth->buffers[1] = NULL; +} + +void synthio_synth_init(synthio_synth_t *synth, uint16_t max_dur) { + synth->buffer_length = MIN(SYNTHIO_MAX_DUR, max_dur) * SYNTHIO_BYTES_PER_SAMPLE; + synth->buffers[0] = m_malloc(synth->buffer_length, false); + synth->buffers[1] = m_malloc(synth->buffer_length, false); + synth->other_channel = -1; +} + +void synthio_synth_get_buffer_structure(synthio_synth_t *synth, bool single_channel_output, + bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing) { + *single_buffer = false; + *samples_signed = true; + *max_buffer_length = synth->buffer_length; + *spacing = 1; +} + +void synthio_synth_parse_waveform(mp_buffer_info_t *bufinfo_waveform, mp_obj_t waveform_obj) { + *bufinfo_waveform = ((mp_buffer_info_t) { .buf = (void *)square_wave, .len = 4 }); + + if (waveform_obj != mp_const_none) { + mp_get_buffer_raise(waveform_obj, bufinfo_waveform, MP_BUFFER_READ); + if (bufinfo_waveform->typecode != 'h') { + mp_raise_ValueError_varg(translate("%q must be array of type 'h'"), MP_QSTR_waveform); + } + } + mp_arg_validate_length_range(bufinfo_waveform->len / 2, 2, 1024, MP_QSTR_waveform); +} + +void synthio_span_init(synthio_midi_span_t *span) { + span->dur = 0; + for (size_t i = 0; i < CIRCUITPY_SYNTHIO_MAX_CHANNELS; i++) { span->note[i] = SYNTHIO_SILENCE; + } +} + +STATIC int find_channel_with_note(const synthio_midi_span_t *span, uint8_t note) { + for (int i = 0; i < CIRCUITPY_SYNTHIO_MAX_CHANNELS; i++) { + if (span->note[i] == note) { + return i; + } + } + return -1; +} + +bool synthio_span_change_note(synthio_midi_span_t *span, uint8_t old_note, uint8_t new_note) { + if (new_note != SYNTHIO_SILENCE && find_channel_with_note(span, new_note) != -1) { + return false; // note already pressed, do nothing + } + int channel = find_channel_with_note(span, old_note); + if (channel != -1) { + span->note[channel] = new_note; + return true; + } + return false; +} diff --git a/shared-module/synthio/__init__.h b/shared-module/synthio/__init__.h index d9d98a534166..e14e5ead103e 100644 --- a/shared-module/synthio/__init__.h +++ b/shared-module/synthio/__init__.h @@ -24,9 +24,41 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_MODULE_SYNTHIO__INIT__H -#define MICROPY_INCLUDED_SHARED_MODULE_SYNTHIO__INIT__H +#pragma once + +#define SYNTHIO_BITS_PER_SAMPLE (16) +#define SYNTHIO_BYTES_PER_SAMPLE (SYNTHIO_BITS_PER_SAMPLE / 8) +#define SYNTHIO_MAX_DUR (256) +#define SYNTHIO_SILENCE (0x80) #include "shared-module/audiocore/__init__.h" -#endif // MICROPY_INCLUDED_SHARED_MODULE_SYNTHIO__INIT__H +typedef struct { + uint16_t dur; + uint8_t note[CIRCUITPY_SYNTHIO_MAX_CHANNELS]; +} synthio_midi_span_t; + +typedef struct { + uint32_t sample_rate; + int16_t *buffers[2]; + const int16_t *waveform; + uint16_t buffer_length; + uint16_t last_buffer_length; + uint8_t other_channel, buffer_index, other_buffer_index; + uint16_t waveform_length; + synthio_midi_span_t span; + uint32_t accum[CIRCUITPY_SYNTHIO_MAX_CHANNELS]; +} synthio_synth_t; + +void synthio_span_init(synthio_midi_span_t *span); +void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **buffer, uint32_t *buffer_length, uint8_t channel); +void synthio_synth_deinit(synthio_synth_t *synth); +bool synthio_synth_deinited(synthio_synth_t *synth); +void synthio_synth_init(synthio_synth_t *synth, uint16_t max_dur); +void synthio_synth_get_buffer_structure(synthio_synth_t *synth, bool single_channel_output, + bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing); +void synthio_synth_reset_buffer(synthio_synth_t *synth, bool single_channel_output, uint8_t channel); +void synthio_synth_parse_waveform(mp_buffer_info_t *bufinfo_waveform, mp_obj_t waveform_obj); + +bool synthio_span_change_note(synthio_midi_span_t *span, uint8_t old_note, uint8_t new_note); +int synthio_span_count_active_channels(synthio_midi_span_t *span); diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index 81431d5d7aea..706c94eec332 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -61,12 +61,9 @@ uint16_t common_hal_usb_core_device_get_idProduct(usb_core_device_obj_t *self) { } STATIC xfer_result_t _get_string_result; -STATIC bool _transfer_done_cb(uint8_t daddr, tusb_control_request_t const *request, xfer_result_t result) { - // Store the result so we stop waiting for the transfer. We don't need the other data for now. - (void)daddr; - (void)request; - _get_string_result = result; - return true; +STATIC void _transfer_done_cb(tuh_xfer_t *xfer) { + // Store the result so we stop waiting for the transfer. + _get_string_result = xfer->result; } STATIC void _wait_for_callback(void) { @@ -89,7 +86,7 @@ STATIC mp_obj_t _get_string(const uint16_t *temp_buf) { mp_obj_t common_hal_usb_core_device_get_serial_number(usb_core_device_obj_t *self) { _get_string_result = 0xff; uint16_t temp_buf[127]; - if (!tuh_descriptor_string_serial_get(self->device_number, 0, temp_buf, MP_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + if (!tuh_descriptor_get_serial_string(self->device_number, 0, temp_buf, MP_ARRAY_SIZE(temp_buf), _transfer_done_cb, 0)) { return mp_const_none; } _wait_for_callback(); @@ -99,7 +96,7 @@ mp_obj_t common_hal_usb_core_device_get_serial_number(usb_core_device_obj_t *sel mp_obj_t common_hal_usb_core_device_get_product(usb_core_device_obj_t *self) { _get_string_result = 0xff; uint16_t temp_buf[127]; - if (!tuh_descriptor_string_product_get(self->device_number, 0, temp_buf, MP_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + if (!tuh_descriptor_get_product_string(self->device_number, 0, temp_buf, MP_ARRAY_SIZE(temp_buf), _transfer_done_cb, 0)) { return mp_const_none; } _wait_for_callback(); @@ -109,7 +106,7 @@ mp_obj_t common_hal_usb_core_device_get_product(usb_core_device_obj_t *self) { mp_obj_t common_hal_usb_core_device_get_manufacturer(usb_core_device_obj_t *self) { _get_string_result = 0xff; uint16_t temp_buf[127]; - if (!tuh_descriptor_string_manufacturer_get(self->device_number, 0, temp_buf, MP_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + if (!tuh_descriptor_get_manufacturer_string(self->device_number, 0, temp_buf, MP_ARRAY_SIZE(temp_buf), _transfer_done_cb, 0)) { return mp_const_none; } _wait_for_callback(); @@ -125,11 +122,8 @@ mp_obj_t common_hal_usb_core_device_read(usb_core_device_obj_t *self, mp_int_t e } xfer_result_t control_result; -STATIC bool _control_complete_cb(uint8_t dev_addr, tusb_control_request_t const *request, xfer_result_t result) { - (void)dev_addr; - (void)request; - control_result = result; - return true; +STATIC void _control_complete_cb(tuh_xfer_t *xfer) { + control_result = xfer->result; } mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, @@ -145,11 +139,17 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, .wIndex = wIndex, .wLength = len }; + tuh_xfer_t xfer = { + .daddr = self->device_number, + .ep_addr = 0, + .setup = &request, + .buffer = buffer, + .complete_cb = _control_complete_cb, + }; + control_result = XFER_RESULT_STALLED; - bool result = tuh_control_xfer(self->device_number, - &request, - buffer, - _control_complete_cb); + + bool result = tuh_control_xfer(&xfer); if (!result) { mp_raise_usb_core_USBError(NULL); } diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c index 680bb83893df..6f530bfef8af 100644 --- a/shared-module/usb_hid/Device.c +++ b/shared-module/usb_hid/Device.c @@ -293,24 +293,40 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t // Callback invoked when we receive Set_Report request through control endpoint void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) { (void)itf; - if (report_type == HID_REPORT_TYPE_INVALID) { - report_id = buffer[0]; - buffer++; - bufsize--; + + usb_hid_device_obj_t *hid_device = NULL; + size_t id_idx; + + if (report_id == 0 && report_type == HID_REPORT_TYPE_INVALID) { + // This could be a report with a non-zero report ID in the first byte, or + // it could be for report ID 0. + // Heuristic: see if there's a device with report ID 0, and if its report length matches + // the size of the incoming buffer. In that case, assume the first byte is not the report ID, + // but is data. Otherwise use the first byte as the report id. + if (usb_hid_get_device_with_report_id(0, &hid_device, &id_idx) && + hid_device && + hid_device->out_report_buffers[id_idx] && + hid_device->out_report_lengths[id_idx] == bufsize) { + // Use as is, with report_id 0. + } else { + // No matching report ID 0, so use the first byte as the report ID. + report_id = buffer[0]; + buffer++; + bufsize--; + } } else if (report_type != HID_REPORT_TYPE_OUTPUT && report_type != HID_REPORT_TYPE_FEATURE) { return; } - usb_hid_device_obj_t *hid_device; - size_t id_idx; - // Find device with this report id, and get the report id index. - if (usb_hid_get_device_with_report_id(report_id, &hid_device, &id_idx)) { + // report_id might be changed due to parsing above, so test again. + if ((report_id == 0 && report_type == HID_REPORT_TYPE_INVALID) || + // Fetch the matching device if we don't already have the report_id 0 device. + (usb_hid_get_device_with_report_id(report_id, &hid_device, &id_idx) && + hid_device && + hid_device->out_report_buffers[id_idx] && + hid_device->out_report_lengths[id_idx] == bufsize)) { // If a report of the correct size has been read, save it in the proper OUT report buffer. - if (hid_device && - 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; - } + memcpy(hid_device->out_report_buffers[id_idx], buffer, bufsize); + hid_device->out_report_buffers_updated[id_idx] = true; } } diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index 20e1405d9a5e..fab12c664e15 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -278,7 +278,7 @@ void common_hal_vectorio_vector_shape_set_location(vectorio_vector_shape_t *self mp_arg_validate_length(tuple_len, 2, MP_QSTR_location); 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); + mp_int_t y = mp_arg_validate_type_int(tuple_items[1], MP_QSTR_y); bool dirty = false; if (self->x != x) { check_bounds_and_set_x(self, x); @@ -406,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/netutils/dhcpserver.c b/shared/netutils/dhcpserver.c index d396a2ba5674..3f90a06e46ac 100644 --- a/shared/netutils/dhcpserver.c +++ b/shared/netutils/dhcpserver.c @@ -277,8 +277,8 @@ static void dhcp_server_process(void *arg, struct udp_pcb *upcb, struct pbuf *p, opt_write_n(&opt, DHCP_OPT_SERVER_ID, 4, &d->ip.addr); opt_write_n(&opt, DHCP_OPT_SUBNET_MASK, 4, &d->nm.addr); - opt_write_n(&opt, DHCP_OPT_ROUTER, 4, &d->ip.addr); // aka gateway; can have mulitple addresses - opt_write_u32(&opt, DHCP_OPT_DNS, DEFAULT_DNS); // can have mulitple addresses + opt_write_n(&opt, DHCP_OPT_ROUTER, 4, &d->ip.addr); // aka gateway; can have multiple addresses + opt_write_u32(&opt, DHCP_OPT_DNS, DEFAULT_DNS); // can have multiple addresses opt_write_u32(&opt, DHCP_OPT_IP_LEASE_TIME, DEFAULT_LEASE_TIME_S); *opt++ = DHCP_OPT_END; dhcp_socket_sendto(&d->udp, &dhcp_msg, opt - (uint8_t *)&dhcp_msg, 0xffffffff, PORT_DHCP_CLIENT); diff --git a/shared/runtime/pyexec.c b/shared/runtime/pyexec.c index 87219d18f5db..aeb92f59d3b6 100644 --- a/shared/runtime/pyexec.c +++ b/shared/runtime/pyexec.c @@ -643,7 +643,7 @@ int pyexec_friendly_repl(void) { // If the user gets to here and interrupts are disabled then // they'll never see the prompt, traceback etc. The USB REPL needs // interrupts to be enabled or no transfers occur. So we try to - // do the user a favor and reenable interrupts. + // do the user a favor and re-enable interrupts. if (query_irq() == IRQ_STATE_DISABLED) { enable_irq(IRQ_STATE_ENABLED); mp_hal_stdout_tx_str("MPY: enabling IRQs\r\n"); diff --git a/supervisor/background_callback.h b/supervisor/background_callback.h index 651ac020a638..36b0017f0cae 100644 --- a/supervisor/background_callback.h +++ b/supervisor/background_callback.h @@ -37,8 +37,9 @@ * To schedule the work, use background_callback_add, with fun as the * function to call and data pointing to the object itself. * - * Next time run_background_tasks_if_tick is called, the callback will - * be run and removed from the linked list. + * Next time background_callback_run_all() is called, the callback will + * be run and removed from the linked list. Use `RUN_BACKGROUND_TASKS;` instead + * of calling background_callback_run_all() directly. * * Queueing a task that is already queued does nothing. Unconditionally * re-queueing it from its own background task will cause it to run during the @@ -46,6 +47,12 @@ * don't do that. * * background_callback_add can be called from interrupt context. + * + * If your work isn't triggered by an event, then it may be better implemented + * using ticks, which runs tasks every millisecond or so. Ticks are enabled with + * supervisor_enable_tick() and disabled with supervisor_disable_tick(). When + * enabled, a timer will schedule a callback to supervisor_background_tick(), + * which includes port_background_tick(), every millisecond. */ typedef void (*background_callback_fun)(void *data); typedef struct background_callback { diff --git a/supervisor/linker.h b/supervisor/linker.h index 58068c1a4b72..9666c4ca121b 100644 --- a/supervisor/linker.h +++ b/supervisor/linker.h @@ -32,7 +32,8 @@ #if defined(IMXRT10XX) || defined(FOMU) || defined(STM32H7) || defined(RASPBERRYPI) #define PLACE_IN_DTCM_DATA(name) name __attribute__((section(".dtcm_data." #name))) #define PLACE_IN_DTCM_BSS(name) name __attribute__((section(".dtcm_bss." #name))) -#define PLACE_IN_ITCM(name) __attribute__((section(".itcm." #name))) name +// Don't inline ITCM functions because that may pull them out of ITCM into other sections. +#define PLACE_IN_ITCM(name) __attribute__((section(".itcm." #name),noinline,aligned(4))) name #else #define PLACE_IN_DTCM_DATA(name) name #define PLACE_IN_DTCM_BSS(name) name diff --git a/supervisor/messages/default.h b/supervisor/messages/default.h deleted file mode 100644 index 8cdd671b3110..000000000000 --- 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 2fb24385c1ce..7b48a3f13b6d 100644 --- a/supervisor/port.h +++ b/supervisor/port.h @@ -90,14 +90,19 @@ 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 and happens *very* often. Use +// port_background_tick() when possible. void port_background_task(void); -// Take port specific actions at the beginning and end of background tasks. +// Take port specific actions at the beginning and end of background ticks. // This is used e.g., to set a monitoring pin for debug purposes. "Actual -// work" should be done in port_background_task() instead. -void port_start_background_task(void); -void port_finish_background_task(void); +// work" should be done in port_background_tick() instead. +void port_start_background_tick(void); +void port_finish_background_tick(void); // 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 @@ -124,4 +129,8 @@ void port_post_boot_py(bool heap_valid); // A default weak implementation is provided that does nothing. void port_boot_info(void); +// Some ports want to mark additional pointers as gc roots. +// A default weak implementation is provided that does nothing. +void port_gc_collect(void); + #endif // MICROPY_INCLUDED_SUPERVISOR_PORT_H diff --git a/supervisor/shared/background_callback.c b/supervisor/shared/background_callback.c index 88ffc159110f..80f70b528a34 100644 --- a/supervisor/shared/background_callback.c +++ b/supervisor/shared/background_callback.c @@ -42,7 +42,7 @@ STATIC volatile background_callback_t *volatile callback_head, *volatile callbac MP_WEAK void port_wake_main_task(void) { } -void background_callback_add_core(background_callback_t *cb) { +void PLACE_IN_ITCM(background_callback_add_core)(background_callback_t * cb) { CALLBACK_CRITICAL_BEGIN; if (cb->prev || callback_head == cb) { CALLBACK_CRITICAL_END; @@ -62,18 +62,19 @@ void background_callback_add_core(background_callback_t *cb) { port_wake_main_task(); } -void background_callback_add(background_callback_t *cb, background_callback_fun fun, void *data) { +void PLACE_IN_ITCM(background_callback_add)(background_callback_t * cb, background_callback_fun fun, void *data) { cb->fun = fun; cb->data = data; background_callback_add_core(cb); } -bool PLACE_IN_ITCM(background_callback_pending)(void) { +bool inline background_callback_pending(void) { return callback_head != NULL; } 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 6fe5d570b896..bb44ab0f005b 100644 --- a/supervisor/shared/bluetooth/bluetooth.c +++ b/supervisor/shared/bluetooth/bluetooth.c @@ -158,7 +158,7 @@ STATIC void supervisor_bluetooth_start_advertising(void) { _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); @@ -179,7 +179,7 @@ STATIC void supervisor_bluetooth_start_advertising(void) { } 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, diff --git a/supervisor/shared/bluetooth/serial.c b/supervisor/shared/bluetooth/serial.c index 2edf3c784f18..a5f4d776b36f 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/display.c b/supervisor/shared/display.c index 0a066e8016b6..26585c54d505 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -159,6 +159,14 @@ void supervisor_stop_terminal(void) { #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; diff --git a/supervisor/shared/display.h b/supervisor/shared/display.h index fcaab10818f3..0eb9bc507f40 100644 --- a/supervisor/shared/display.h +++ b/supervisor/shared/display.h @@ -54,6 +54,7 @@ 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 141ad7e5f860..f72518ac5003 100644 --- a/supervisor/shared/external_flash/external_flash.c +++ b/supervisor/shared/external_flash/external_flash.c @@ -97,7 +97,7 @@ static bool write_flash(uint32_t address, const uint8_t *data, uint32_t data_len if (flash_device == NULL) { return false; } - // Don't bother writing if the data is all 1s. Thats equivalent to the flash + // Don't bother writing if the data is all 1s. That's equivalent to the flash // state after an erase. if (!flash_device->no_erase_cmd) { // Only do this if the device has an erase command diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index 1eab59c384f2..345f55f2f116 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -33,6 +33,7 @@ #include "py/mpstate.h" #include "supervisor/flash.h" +#include "supervisor/linker.h" static mp_vfs_mount_t _mp_vfs; static fs_user_mount_t _internal_vfs; @@ -165,7 +166,7 @@ bool filesystem_init(bool create_allowed, bool force_create) { return true; } -void filesystem_flush(void) { +void PLACE_IN_ITCM(filesystem_flush)(void) { // Reset interval before next flush. filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS; supervisor_flash_flush(); diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c index dfd7cf2050c9..53815c9836f9 100644 --- a/supervisor/shared/flash.c +++ b/supervisor/shared/flash.c @@ -132,7 +132,7 @@ static mp_uint_t flash_write_blocks(const uint8_t *src, uint32_t block_num, uint } } -void supervisor_flash_flush(void) { +void PLACE_IN_ITCM(supervisor_flash_flush)(void) { #if INTERNAL_FLASH_FILESYSTEM port_internal_flash_flush(); #else diff --git a/supervisor/shared/micropython.c b/supervisor/shared/micropython.c index ebc0aef2d1ae..5ee0061544a4 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/reload.c b/supervisor/shared/reload.c index 4e351704f8a9..da2ffc26e176 100644 --- a/supervisor/shared/reload.c +++ b/supervisor/shared/reload.c @@ -82,15 +82,19 @@ inline bool autoreload_is_enabled() { } void autoreload_trigger() { - if (autoreload_enabled & !autoreload_suspended) { - last_autoreload_trigger = supervisor_ticks_ms32(); - // Guard against the rare time that ticks is 0; - if (last_autoreload_trigger == 0) { - last_autoreload_trigger += 1; - } - // Initiate a reload of the VM immediately. Later code will pause to - // wait for the autoreload to become ready. Doing the VM exit - // immediately is clearer for the user. + if (!autoreload_enabled || autoreload_suspended != 0) { + return; + } + bool reload_initiated = autoreload_pending(); + last_autoreload_trigger = supervisor_ticks_ms32(); + // Guard against the rare time that ticks is 0; + if (last_autoreload_trigger == 0) { + last_autoreload_trigger += 1; + } + // Initiate a reload of the VM immediately. Later code will pause to + // wait for the autoreload to become ready. Doing the VM exit + // immediately is clearer for the user. + if (!reload_initiated) { reload_initiate(RUN_REASON_AUTO_RELOAD); } } @@ -111,5 +115,5 @@ bool autoreload_ready() { } bool autoreload_pending(void) { - return last_autoreload_trigger != 0; + return last_autoreload_trigger > 0; } diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index d23b78d6242b..0ab97fc9a96c 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -34,6 +34,7 @@ #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/ResetReason.h" +#include "supervisor/linker.h" #include "supervisor/serial.h" #include "supervisor/shared/rgb_led_colors.h" #include "supervisor/shared/status_leds.h" @@ -43,20 +44,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 +73,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,20 +115,20 @@ 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. + // Restore the original state of the saved word if no reset occurred 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) { +void PLACE_IN_ITCM(safe_mode_on_next_reset)(safe_mode_t reason) { port_set_saved_word(SAFE_MODE_DATA_GUARD | (reason << 8)); } // 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) { +void __attribute__((noinline,)) PLACE_IN_ITCM(reset_into_safe_mode)(safe_mode_t reason) { + 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,105 +142,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: + 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("The BOOT button was pressed at start up.\n"); - #endif - #if defined(BOARD_USER_SAFE_MODE_ACTION) || defined(CIRCUITPY_BOOT_BUTTON) - // Output a user safe mode string if it's set. - serial_write_compressed(message); - message = translate("To exit, please reset the board without requesting safe mode."); - // The final piece is printed below. + message = translate("You pressed the BOOT button at start up"); + #else + message = translate("You pressed the reset button during boot."); #endif 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 SAFE_MODE_PROGRAMMATIC: + message = translate("The `microcontroller` module was used to boot into safe mode."); break; - case PROGRAMMATIC_SAFE_MODE: - message = translate("The `microcontroller` module was used to boot into safe mode. Press reset to exit safe mode."); + #if CIRCUITPY_SAFEMODE_PY + case SAFE_MODE_SAFEMODE_PY_ERROR: + message = translate("Error in safemode.py."); 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)."); + #endif + case SAFE_MODE_STACK_OVERFLOW: + message = translate("Heap was corrupted because the stack was too small. Increase stack size."); break; - case USB_TOO_MANY_ENDPOINTS: + 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 0c8d018bfe8a..005488552ea7 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 5680d8afe035..e683e8eb7c42 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -192,6 +192,12 @@ bool serial_connected(void) { } #endif + #if CIRCUITPY_TERMINALIO + if (supervisor_terminal_started()) { + return true; + } + #endif + if (port_serial_connected()) { return true; diff --git a/supervisor/shared/stack.c b/supervisor/shared/stack.c index fa8d019fea3f..148bb0bbd5e2 100644 --- a/supervisor/shared/stack.c +++ b/supervisor/shared/stack.c @@ -35,7 +35,7 @@ extern uint32_t _estack; // Requested size. -static uint32_t next_stack_size = CIRCUITPY_DEFAULT_STACK_SIZE; +static uint32_t next_stack_size = 0; static uint32_t current_stack_size = 0; // Actual location and size, may be larger than requested. static uint32_t *stack_limit = NULL; @@ -49,11 +49,15 @@ static void allocate_stack(void) { stack_limit = port_stack_get_limit(); stack_length = (port_stack_get_top() - stack_limit) * sizeof(uint32_t); current_stack_size = stack_length; + next_stack_size = stack_length; } else { mp_uint_t regs[10]; mp_uint_t sp = cpu_get_regs_and_sp(regs); mp_uint_t c_size = (mp_uint_t)port_stack_get_top() - sp; + if (next_stack_size == 0) { + next_stack_size = CIRCUITPY_DEFAULT_STACK_SIZE; + } supervisor_allocation *stack_alloc = allocate_memory(c_size + next_stack_size + EXCEPTION_STACK_SIZE, true, false); if (stack_alloc == NULL) { stack_alloc = allocate_memory(c_size + CIRCUITPY_DEFAULT_STACK_SIZE + EXCEPTION_STACK_SIZE, true, false); @@ -74,7 +78,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); } } @@ -103,8 +107,12 @@ size_t stack_get_length(void) { return stack_length; } -void set_next_stack_size(uint32_t size) { +bool set_next_stack_size(uint32_t size) { + if (port_has_fixed_stack()) { + return false; + } next_stack_size = size; + return true; } uint32_t get_next_stack_size(void) { diff --git a/supervisor/shared/stack.h b/supervisor/shared/stack.h index 4acda57354a2..4a03fcf2752e 100644 --- a/supervisor/shared/stack.h +++ b/supervisor/shared/stack.h @@ -37,7 +37,7 @@ void stack_resize(void); 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); +bool 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 index 4f5fa064644e..16d23fe54102 100644 --- a/supervisor/shared/status_bar.c +++ b/supervisor/shared/status_bar.c @@ -78,8 +78,8 @@ void supervisor_status_bar_update(void) { !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; + bool prev_console_disable = false; + bool prev_display_disable = false; if (disable_console_writes) { prev_console_disable = serial_console_write_disable(true); diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c index 429ca35d60b9..b91257c8c805 100644 --- a/supervisor/shared/tick.c +++ b/supervisor/shared/tick.c @@ -65,8 +65,8 @@ static volatile uint64_t last_finished_tick = 0; static volatile size_t tick_enable_count = 0; -static void supervisor_background_tasks(void *unused) { - port_start_background_task(); +static void supervisor_background_tick(void *unused) { + port_start_background_tick(); assert_heap_ok(); @@ -80,16 +80,16 @@ static void supervisor_background_tasks(void *unused) { filesystem_background(); - port_background_task(); + port_background_tick(); assert_heap_ok(); last_finished_tick = port_get_raw_ticks(NULL); - port_finish_background_task(); + port_finish_background_tick(); } -bool supervisor_background_tasks_ok(void) { +bool supervisor_background_ticks_ok(void) { return port_get_raw_ticks(NULL) - last_finished_tick < 1024; } @@ -103,7 +103,7 @@ void supervisor_tick(void) { keypad_tick(); #endif - background_callback_add(&tick_callback, supervisor_background_tasks, NULL); + background_callback_add(&tick_callback, supervisor_background_tick, NULL); } uint64_t supervisor_ticks_ms64() { @@ -117,11 +117,6 @@ uint32_t supervisor_ticks_ms32() { return supervisor_ticks_ms64(); } - -void PLACE_IN_ITCM(supervisor_run_background_tasks_if_tick)() { - background_callback_run_all(); -} - void mp_hal_delay_ms(mp_uint_t delay_ms) { uint64_t start_tick = port_get_raw_ticks(NULL); // Adjust the delay to ticks vs ms. diff --git a/supervisor/shared/tick.h b/supervisor/shared/tick.h index d805aeb09974..5f537ad2ed16 100644 --- a/supervisor/shared/tick.h +++ b/supervisor/shared/tick.h @@ -54,13 +54,6 @@ extern uint32_t supervisor_ticks_ms32(void); */ extern uint64_t supervisor_ticks_ms64(void); -/** @brief Run background ticks, but only about every millisecond. - * - * Normally, this is not called directly. Instead use the RUN_BACKGROUND_TASKS - * macro. - */ -extern void supervisor_run_background_if_tick(void); - extern void supervisor_enable_tick(void); extern void supervisor_disable_tick(void); @@ -70,6 +63,6 @@ extern void supervisor_disable_tick(void); * Note that when ticks are not enabled, this function can return false; this is * intended. */ -extern bool supervisor_background_tasks_ok(void); +extern bool supervisor_background_ticks_ok(void); #endif diff --git a/supervisor/shared/translate/compressed_string.h b/supervisor/shared/translate/compressed_string.h index e331a5866fcf..f524010db544 100644 --- a/supervisor/shared/translate/compressed_string.h +++ b/supervisor/shared/translate/compressed_string.h @@ -62,7 +62,7 @@ // // The "data" / "tail" construct is so that the struct's last member is a // "flexible array". However, the _only_ member is not permitted to be -// a flexible member, so we have to declare the first byte as a separte +// a flexible member, so we have to declare the first byte as a separate // member of the structure. // // For translations where length needs 8 bits, this saves about 1.5 diff --git a/supervisor/shared/translate/translate_impl.h b/supervisor/shared/translate/translate_impl.h index 1c144197cb7c..13da8c656b5c 100644 --- a/supervisor/shared/translate/translate_impl.h +++ b/supervisor/shared/translate/translate_impl.h @@ -48,7 +48,9 @@ inline #if !CIRCUITPY_LTO || CIRCUITPY_DEBUG < 1 __attribute__((always_inline)) #endif -const compressed_string_t *translate(const char *original) { +// Prevent instrumenting this because that disables the inlining we rely of for code size +// optimization. +__attribute__((no_instrument_function)) const compressed_string_t *translate(const char *original) { #ifndef NO_QSTR #define QDEF(id, hash, len, str) #define TRANSLATION(english_id, number) if (strcmp(original, english_id) == 0) { return &translation##number; } else diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index fa85cddb83fa..1d600e115866 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -220,18 +220,22 @@ static void usb_background_do(void *unused) { usb_background(); } -void usb_background_schedule(void) { +void PLACE_IN_ITCM(usb_background_schedule)(void) { background_callback_add(&usb_callback, usb_background_do, NULL); } -void usb_irq_handler(int instance) { +void PLACE_IN_ITCM(usb_irq_handler)(int instance) { + #if CFG_TUSB_MCU != OPT_MCU_RP2040 + // For rp2040, IRQ handler is already installed and invoked automatically if (instance == CIRCUITPY_USB_DEVICE_INSTANCE) { tud_int_handler(instance); - } else if (instance == CIRCUITPY_USB_HOST_INSTANCE) { - #if CIRCUITPY_USB_HOST + } + #if CIRCUITPY_USB_HOST + else if (instance == CIRCUITPY_USB_HOST_INSTANCE) { tuh_int_handler(instance); - #endif } + #endif + #endif usb_background_schedule(); } diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c index fa4cf9607e72..e7cffee3516e 100644 --- a/supervisor/shared/usb/usb_desc.c +++ b/supervisor/shared/usb/usb_desc.c @@ -228,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, @@ -258,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; diff --git a/supervisor/shared/web_workflow/static/blinka_16x16.ico b/supervisor/shared/web_workflow/static/blinka_16x16.ico deleted file mode 100644 index ff2937dfee32..000000000000 Binary files a/supervisor/shared/web_workflow/static/blinka_16x16.ico and /dev/null differ diff --git a/supervisor/shared/web_workflow/static/blinka_32x32.ico b/supervisor/shared/web_workflow/static/blinka_32x32.ico new file mode 100644 index 000000000000..5aca98376a1f Binary files /dev/null and b/supervisor/shared/web_workflow/static/blinka_32x32.ico differ diff --git a/supervisor/shared/web_workflow/static/directory.html b/supervisor/shared/web_workflow/static/directory.html index cf9ff507f902..56498c1329c8 100644 --- a/supervisor/shared/web_workflow/static/directory.html +++ b/supervisor/shared/web_workflow/static/directory.html @@ -3,7 +3,6 @@ - @@ -21,4 +20,5 @@

 


+📁  + diff --git a/supervisor/shared/web_workflow/static/directory.js b/supervisor/shared/web_workflow/static/directory.js index a89d5e5602bd..2068ca38ea72 100644 --- a/supervisor/shared/web_workflow/static/directory.js +++ b/supervisor/shared/web_workflow/static/directory.js @@ -267,3 +267,13 @@ new_directory_name.oninput = () => { } window.onhashchange = refresh_list; + +window.addEventListener("pageshow", function (event) { + var historyTraversal = event.persisted || + (typeof window.performance != "undefined" && + window.performance.navigation.type === 2); + if (historyTraversal) { + // Handle page restore. + window.location.reload(); + } +}); diff --git a/supervisor/shared/web_workflow/static/serial.html b/supervisor/shared/web_workflow/static/serial.html index 91939534432f..24fb3a3d3206 100644 --- a/supervisor/shared/web_workflow/static/serial.html +++ b/supervisor/shared/web_workflow/static/serial.html @@ -4,7 +4,6 @@ Simple client - @@ -16,11 +15,13 @@
Ctrl +
+ diff --git a/supervisor/shared/web_workflow/static/serial.js b/supervisor/shared/web_workflow/static/serial.js index 5c644795a003..52cde953961c 100644 --- a/supervisor/shared/web_workflow/static/serial.js +++ b/supervisor/shared/web_workflow/static/serial.js @@ -72,6 +72,17 @@ input.addEventListener("beforeinput", function(e) { } }); +window.addEventListener("unload", function() { + if (ws.readyState == WebSocket.OPEN) { + ws.close(); + } +}); + +let ctrl_b = document.querySelector("#b"); +ctrl_b.onclick = function() { + ws.send("\x02"); +} + let ctrl_c = document.querySelector("#c"); ctrl_c.onclick = function() { ws.send("\x03"); diff --git a/supervisor/shared/web_workflow/static/welcome.html b/supervisor/shared/web_workflow/static/welcome.html index efbb30e31238..ffd23b72e91c 100644 --- a/supervisor/shared/web_workflow/static/welcome.html +++ b/supervisor/shared/web_workflow/static/welcome.html @@ -4,7 +4,6 @@ CircuitPython - @@ -30,5 +29,6 @@

Device Info:

Here are other CircuitPython devices on your network:

+ diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index c34c3b3c9f32..94732cf52ccb 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -24,6 +24,9 @@ * THE SOFTWARE. */ +// Include strchrnul() +#define _GNU_SOURCE + #include #include @@ -49,6 +52,7 @@ #include "shared-bindings/hashlib/__init__.h" #include "shared-bindings/hashlib/Hash.h" +#include "lib/oofatfs/diskio.h" #if CIRCUITPY_MDNS #include "shared-bindings/mdns/RemoteService.h" @@ -84,8 +88,8 @@ typedef struct { char destination[256]; char header_key[64]; char header_value[256]; - // We store the origin so we can reply back with it. - char origin[64]; + char origin[64]; // We store the origin so we can reply back with it. + char host[64]; // We store the host to check against origin. size_t content_length; size_t offset; uint64_t timestamp_ms; @@ -124,6 +128,7 @@ static socketpool_socket_obj_t active; static _request active_request; static char _api_password[64]; +static char web_instance_name[50]; // Store the encoded IP so we don't duplicate work. static uint32_t _encoded_ip = 0; @@ -200,6 +205,16 @@ STATIC void _update_encoded_ip(void) { } } +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 CIRCUITPY_STATUS_BAR bool supervisor_web_workflow_status_dirty(void) { return common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj) != _last_enabled || @@ -250,6 +265,7 @@ void supervisor_start_web_workflow(void) { 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_DEEP_SLEEP_ALARM && reset_reason != RESET_REASON_UNKNOWN && reset_reason != RESET_REASON_SOFTWARE) { return; @@ -264,10 +280,18 @@ void supervisor_start_web_workflow(void) { } result = common_hal_os_getenv_str("CIRCUITPY_WIFI_PASSWORD", password, sizeof(password)); - if (result != GETENV_OK) { + if (result == GETENV_ERR_NOT_FOUND) { + // if password is unspecified, assume an open network + password[0] = '\0'; + } else if (result != GETENV_OK) { return; } + result = common_hal_os_getenv_str("CIRCUITPY_WEB_INSTANCE_NAME", web_instance_name, sizeof(web_instance_name)); + if (result != GETENV_OK || web_instance_name[0] == '\0') { + strcpy(web_instance_name, MICROPY_HW_BOARD_NAME); + } + 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); @@ -288,20 +312,12 @@ void supervisor_start_web_workflow(void) { return; } - 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); + (void)common_hal_os_getenv_int("CIRCUITPY_WEB_API_PORT", &web_api_port); bool first_start = pool.base.type != &socketpool_socketpool_type; - bool port_changed = new_port != web_api_port; if (first_start) { - port_changed = false; - #if CIRCUITPY_MDNS - mdns_server_construct(&mdns, true); - mdns.base.type = &mdns_server_type; - common_hal_mdns_server_set_instance_name(&mdns, MICROPY_HW_BOARD_NAME); - #endif pool.base.type = &socketpool_socketpool_type; common_hal_socketpool_socketpool_construct(&pool, &common_hal_wifi_radio_obj); @@ -310,21 +326,25 @@ void supervisor_start_web_workflow(void) { websocket_init(); } - if (port_changed) { - common_hal_socketpool_socket_close(&listening); + + if (!common_hal_socketpool_socket_get_closed(&active)) { + common_hal_socketpool_socket_close(&active); } - if (first_start || port_changed) { - web_api_port = new_port; - #if CIRCUITPY_MDNS + + #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, web_instance_name); + } + } + 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); } - + #endif 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); @@ -332,6 +352,16 @@ void supervisor_start_web_workflow(void) { _api_password[0] = ':'; _base64_in_place(_api_password, strlen(_api_password), sizeof(_api_password) - 1); } + + if (common_hal_socketpool_socket_get_closed(&listening)) { + socketpool_socket(&pool, SOCKETPOOL_AF_INET, SOCKETPOOL_SOCK_STREAM, &listening); + common_hal_socketpool_socket_settimeout(&listening, 0); + // Bind to any ip. (Not checking for failures) + common_hal_socketpool_socket_bind(&listening, "", 0, web_api_port); + common_hal_socketpool_socket_listen(&listening, 1); + } + // Wake polling thread (maybe) + socketpool_socket_poll_resume(); #endif } @@ -427,48 +457,33 @@ static bool _endswith(const char *str, const char *suffix) { return strcmp(str + (strlen(str) - strlen(suffix)), suffix) == 0; } -const char *ok_hosts[] = { - "127.0.0.1", - "localhost", -}; - -static bool _origin_ok(const char *origin) { - const char *http = "http://"; +const char http_scheme[] = "http://"; +#define PREFIX_HTTP_LEN (sizeof(http_scheme) - 1) - // 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. - // TODO: Support DHCP hostname in addition to MDNS. - #if CIRCUITPY_MDNS - const char *local = ".local"; - const char *hostname = common_hal_mdns_server_get_hostname(&mdns); - const char *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] == ':')) { +static bool _origin_ok(_request *request) { + // Origin may be 'null' + if (request->origin[0] == '\0') { return true; } - #else - const char *end; - #endif - - _update_encoded_ip(); - end = origin + strlen(http) + strlen(_our_ip_encoded); - if (strncmp(origin + strlen(http), _our_ip_encoded, strlen(_our_ip_encoded)) == 0 && - (end[0] == '\0' || end[0] == ':')) { + // Origin has http prefix? + if (strncmp(request->origin, http_scheme, PREFIX_HTTP_LEN) != 0) { + // Not HTTP scheme request - ok + request->origin[0] = '\0'; return true; } - - for (size_t i = 0; i < MP_ARRAY_SIZE(ok_hosts); i++) { - // 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] == ':')) { + // Host given? + if (request->host[0] != '\0') { + // OK if host and origin match (fqdn + port #) + if (strcmp(request->host, &request->origin[PREFIX_HTTP_LEN]) == 0) { + return true; + } + // DEBUG: OK if origin is 'localhost' (ignoring port #) + *strchrnul(&request->origin[PREFIX_HTTP_LEN], ':') = '\0'; + if (strcmp(&request->origin[PREFIX_HTTP_LEN], "localhost") == 0) { return true; } } + // Otherwise deny request return false; } @@ -489,8 +504,8 @@ static void _cors_header(socketpool_socket_obj_t *socket, _request *request) { _send_strs(socket, "Access-Control-Allow-Credentials: true\r\n", "Vary: Origin, Accept, Upgrade\r\n", - "Access-Control-Allow-Origin: ", request->origin, "\r\n", - NULL); + "Access-Control-Allow-Origin: ", + (request->origin[0] == '\0') ? "*" : request->origin, "\r\n", NULL); } static void _reply_continue(socketpool_socket_obj_t *socket, _request *request) { @@ -730,12 +745,13 @@ 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)); - #else - size_t total_results = 0; #endif socketpool_socket_send(socket, (const uint8_t *)OK_JSON, strlen(OK_JSON)); _cors_header(socket, request); @@ -772,24 +788,27 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request * _send_str(socket, "\r\n"); mp_print_t _socket_print = {socket, _print_chunk}; - #if CIRCUITPY_MDNS - const char *hostname = common_hal_mdns_server_get_hostname(&mdns); - #else const char *hostname = ""; + const char *instance_name = ""; + #if CIRCUITPY_MDNS + if (!common_hal_mdns_server_deinited(&mdns)) { + hostname = common_hal_mdns_server_get_hostname(&mdns); + instance_name = common_hal_mdns_server_get_instance_name(&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, " + "{\"web_api_version\": 2, " "\"version\": \"" MICROPY_GIT_TAG "\", " "\"build_date\": \"" MICROPY_BUILD_DATE "\", " - "\"board_name\": \"" MICROPY_HW_BOARD_NAME "\", " + "\"board_name\": \"%s\", " "\"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); + "\"port\": %d, ", instance_name, 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); @@ -804,6 +823,32 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request * _send_chunk(socket, ""); } +static void _reply_with_diskinfo_json(socketpool_socket_obj_t *socket, _request *request) { + _send_str(socket, OK_JSON); + _cors_header(socket, request); + _send_str(socket, "\r\n"); + mp_print_t _socket_print = {socket, _print_chunk}; + + DWORD free_clusters; + FATFS *fs = filesystem_circuitpy(); + FRESULT blk_result = f_getfree(fs, &free_clusters); + uint16_t block_size; + if (blk_result == FR_OK) { + disk_ioctl(fs, GET_SECTOR_SIZE, &block_size); + } + + uint16_t total_size = fs->n_fatent - 2; + + mp_printf(&_socket_print, + "{\"free\": %d, " + "\"block_size\": %d, " + "\"total\": %d}", free_clusters * block_size, block_size, total_size * block_size); + + // Empty chunk signals the end of the response. + _send_chunk(socket, ""); +} + + // 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. @@ -944,7 +989,7 @@ STATIC_FILE(edit_js); STATIC_FILE(style_css); STATIC_FILE(serial_html); STATIC_FILE(serial_js); -STATIC_FILE(blinka_16x16_ico); +STATIC_FILE(blinka_32x32_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; @@ -1020,9 +1065,15 @@ static void _decode_percents(char *str) { static bool _reply(socketpool_socket_obj_t *socket, _request *request) { if (request->redirect) { #if CIRCUITPY_MDNS - _reply_redirect(socket, request, request->path); + 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)) { + } else if (!_origin_ok(request)) { _reply_forbidden(socket, request); } else if (strncmp(request->path, "/fs/", 4) == 0) { if (strcasecmp(request->method, "OPTIONS") == 0) { @@ -1198,6 +1249,8 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { _reply_with_devices_json(socket, request); } else if (strcmp(path, "/version.json") == 0) { _reply_with_version_json(socket, request); + } else if (strcmp(path, "/diskinfo.json") == 0) { + _reply_with_diskinfo_json(socket, request); } else if (strcmp(path, "/serial/") == 0) { if (!request->authenticated) { if (_api_password[0] != '\0') { @@ -1233,7 +1286,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { } else if (strcmp(request->path, "/favicon.ico") == 0) { // TODO: Autogenerate this based on the blinka bitmap and change the // palette based on MAC address. - _REPLY_STATIC(socket, request, blinka_16x16_ico); + _REPLY_STATIC(socket, request, blinka_32x32_ico); } else { _reply_missing(socket, request); } @@ -1244,6 +1297,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { static void _reset_request(_request *request) { request->state = STATE_METHOD; request->origin[0] = '\0'; + request->host[0] = '\0'; request->content_length = 0; request->offset = 0; request->timestamp_ms = 0; @@ -1263,9 +1317,15 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) uint8_t c; // This code assumes header lines are terminated with \r\n while (more && !error) { + int len = socketpool_socket_recv_into(socket, &c, 1); if (len != 1) { more = false; + if (len == 0 || len == -MP_ENOTCONN) { + // Disconnect - clear 'in-progress' + _reset_request(request); + common_hal_socketpool_socket_close(socket); + } break; } if (!request->in_progress) { @@ -1346,6 +1406,8 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) 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)] == ':'); + strncpy(request->host, request->header_value, sizeof(request->host) - 1); + request->host[sizeof(request->host) - 1] = '\0'; } else if (strcasecmp(request->header_key, "Content-Length") == 0) { request->content_length = strtoul(request->header_value, NULL, 10); } else if (strcasecmp(request->header_key, "Expect") == 0) { @@ -1353,7 +1415,8 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) } 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); + strncpy(request->origin, request->header_value, sizeof(request->origin) - 1); + request->origin[sizeof(request->origin) - 1] = '\0'; } else if (strcasecmp(request->header_key, "X-Timestamp") == 0) { request->timestamp_ms = strtoull(request->header_value, NULL, 10); } else if (strcasecmp(request->header_key, "Upgrade") == 0) { @@ -1392,6 +1455,7 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) } bool reload = _reply(socket, request); _reset_request(request); + common_hal_socketpool_socket_close(socket); autoreload_resume(AUTORELOAD_SUSPEND_WEB); if (reload) { autoreload_trigger(); @@ -1399,45 +1463,52 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) } -void supervisor_web_workflow_background(void) { - // 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; +void supervisor_web_workflow_background(void *data) { + while (true) { // 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); + if (active_request.in_progress) { + break; + } } else { - // Close the active socket if it is no longer connected. - common_hal_socketpool_socket_close(&active); + // Close the active socket if necessary + 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; + if (!common_hal_socketpool_socket_get_closed(&active)) { + common_hal_socketpool_socket_close(&active); + } int newsoc = socketpool_socket_accept(&listening, (uint8_t *)&ip, &port, &active); if (newsoc == -EBADF) { common_hal_socketpool_socket_close(&listening); - return; + break; } if (newsoc > 0) { common_hal_socketpool_socket_settimeout(&active, 0); - _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; + continue; } + break; } - websocket_background(); + break; } + // Resume polling + socketpool_socket_poll_resume(); + + return; } void supervisor_stop_web_workflow(void) { diff --git a/supervisor/shared/web_workflow/web_workflow.h b/supervisor/shared/web_workflow/web_workflow.h index 166219c87684..85205b04d621 100644 --- a/supervisor/shared/web_workflow/web_workflow.h +++ b/supervisor/shared/web_workflow/web_workflow.h @@ -28,15 +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); +void supervisor_web_workflow_background(void *data); 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 7612066fa614..0b829bb6f859 100644 --- a/supervisor/shared/web_workflow/websocket.c +++ b/supervisor/shared/web_workflow/websocket.c @@ -42,7 +42,6 @@ typedef struct { uint8_t frame_len; uint8_t payload_len_size; bool masked; - bool closed; uint8_t mask[4]; int frame_index; size_t payload_remaining; @@ -52,22 +51,23 @@ typedef struct { // 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; void websocket_init(void) { 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) { - if (!cp_serial.closed) { + if (!common_hal_socketpool_socket_get_closed(&cp_serial.socket)) { 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; @@ -79,12 +79,14 @@ void websocket_handoff(socketpool_socket_obj_t *socket) { } bool websocket_connected(void) { - return _incoming_ringbuf.size > 0 && !cp_serial.closed && common_hal_socketpool_socket_get_connected(&cp_serial.socket); + return _incoming_ringbuf.size > 0 && + !common_hal_socketpool_socket_get_closed(&cp_serial.socket) && + 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 < 1) { return false; } return true; @@ -158,8 +160,6 @@ static void _read_next_frame_header(void) { if (cp_serial.payload_remaining == 0) { cp_serial.frame_index = 0; if (cp_serial.opcode == 0x8) { - cp_serial.closed = true; - common_hal_socketpool_socket_close(&cp_serial.socket); } } @@ -244,6 +244,10 @@ 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)) { @@ -253,4 +257,5 @@ void websocket_background(void) { } ringbuf_put(&_incoming_ringbuf, c); } + in_web_background = false; } diff --git a/supervisor/shared/workflow.c b/supervisor/shared/workflow.c index f3bc99cb5eb5..64f1021df25b 100644 --- a/supervisor/shared/workflow.c +++ b/supervisor/shared/workflow.c @@ -46,15 +46,7 @@ #if CIRCUITPY_WEB_WORKFLOW #include "supervisor/shared/web_workflow/web_workflow.h" #endif -static background_callback_t workflow_background_cb; - -static bool workflow_started = false; - -static void workflow_background(void *data) { - #if CIRCUITPY_WEB_WORKFLOW - supervisor_web_workflow_background(); - #endif -} +static background_callback_t workflow_background_cb = {NULL, NULL}; // Called during a VM reset. Doesn't actually reset things. void supervisor_workflow_reset(void) { @@ -63,31 +55,18 @@ void supervisor_workflow_reset(void) { #endif #if CIRCUITPY_WEB_WORKFLOW - supervisor_start_web_workflow(); + if (workflow_background_cb.fun) { + supervisor_start_web_workflow(); + supervisor_workflow_request_background(); + } #endif - - workflow_background_cb.fun = workflow_background; - workflow_background_cb.data = NULL; - supervisor_workflow_request_background(); } void supervisor_workflow_request_background(void) { - if (!workflow_started) { - return; + if (workflow_background_cb.fun) { + workflow_background_cb.data = NULL; + background_callback_add_core(&workflow_background_cb); } - background_callback_add_core(&workflow_background_cb); -} - -// Return true as soon as USB communication with host has started, -// even before enumeration is done. -// Not that some chips don't notice when USB is unplugged after first being plugged in, -// so this is not perfect, but tud_suspended() check helps. -bool supervisor_workflow_connecting(void) { - #if CIRCUITPY_USB - return tud_connected() && !tud_suspended(); - #else - return false; - #endif } // Return true if host has completed connection to us (such as USB enumeration). @@ -120,9 +99,10 @@ void supervisor_workflow_start(void) { #if CIRCUITPY_WEB_WORKFLOW supervisor_start_web_workflow(); + memset(&workflow_background_cb, 0, sizeof(workflow_background_cb)); + workflow_background_cb.fun = supervisor_web_workflow_background; #endif - workflow_started = true; } FRESULT supervisor_workflow_mkdir_parents(FATFS *fs, char *path) { diff --git a/supervisor/stub/safe_mode.c b/supervisor/stub/safe_mode.c index b62cc05d7859..ea5187da28a5 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/stub/stack.c b/supervisor/stub/stack.c index 2abc197878ce..bb6e0d4cb0ae 100644 --- a/supervisor/stub/stack.c +++ b/supervisor/stub/stack.c @@ -39,8 +39,9 @@ void stack_init(void) { void stack_resize(void) { } -void set_next_stack_size(uint32_t size) { +bool set_next_stack_size(uint32_t size) { (void)size; + return true; } uint32_t get_current_stack_size(void) { diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 801025f41af8..c461c5353f04 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -163,7 +163,6 @@ ifeq ($(CIRCUITPY_USB),1) SRC_SUPERVISOR += \ lib/tinyusb/src/host/hub.c \ lib/tinyusb/src/host/usbh.c \ - lib/tinyusb/src/host/usbh_control.c \ endif endif diff --git a/tests/basics/annotate_var.py b/tests/basics/annotate_var.py index 3f767e4a7350..a359b229b1a9 100644 --- a/tests/basics/annotate_var.py +++ b/tests/basics/annotate_var.py @@ -1,4 +1,4 @@ -# test PEP 526, varible annotations +# test PEP 526, variable annotations x: int print("x" in globals()) diff --git a/tests/basics/int_big1.py b/tests/basics/int_big1.py index 40d16c455bf3..f6e4b61d1d16 100644 --- a/tests/basics/int_big1.py +++ b/tests/basics/int_big1.py @@ -1,4 +1,4 @@ -# to test arbitrariy precision integers +# to test arbitrary precision integers x = 1000000000000000000000000000000 xn = -1000000000000000000000000000000 diff --git a/tests/basics/struct1.py b/tests/basics/struct1.py index ec29ea90801f..2ac900bbc7da 100644 --- a/tests/basics/struct1.py +++ b/tests/basics/struct1.py @@ -79,7 +79,7 @@ except: print("Unknown type") -# Initially repitition counters were supported only for strings, +# Initially repetition counters were supported only for strings, # but later were implemented for all. print(struct.unpack("<3B2h", b"foo\x12\x34\xff\xff")) print(struct.pack("<3B", 1, 2, 3)) diff --git a/tests/basics/with_return.py b/tests/basics/with_return.py index fd848f133136..af65a5b98438 100644 --- a/tests/basics/with_return.py +++ b/tests/basics/with_return.py @@ -30,7 +30,7 @@ def f(): return (i, j) print(f()) -# multiple for loops within nested withs +# multiple for loops within nested with statements def f(): with CtxMgr(1): for i in [1, 2]: @@ -41,7 +41,7 @@ def f(): return (i, j, k, l) print(f()) -# multiple for loops that are optimised, and nested withs +# multiple for loops that are optimised, and nested with statements def f(): with CtxMgr(1): for i in range(1, 3): diff --git a/tests/circuitpython/aes.py b/tests/circuitpython/aes.py index 40adc020c68d..b47c4279d326 100644 --- a/tests/circuitpython/aes.py +++ b/tests/circuitpython/aes.py @@ -97,3 +97,47 @@ cipher.decrypt_into(cyphertext[i : i + 16], output) print(str(hexlify(output), "")) print() + +print("truncated-CTR-1") +## Truncated CTR test case +plaintext = unhexlify("6bc1bee22e409f96e93d7e117393172a" "ae2d") + +key = unhexlify("2b7e151628aed2a6abf7158809cf4f3c") +counter = unhexlify("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") +cyphertext = bytearray(len(plaintext)) +cipher = aesio.AES(key, aesio.MODE_CTR, IV=counter) +for i in range(0, len(plaintext), 16): + output = memoryview(cyphertext)[i : i + 16] + cipher.encrypt_into(plaintext[i : i + 16], output) + print(str(hexlify(output), "")) +print() + +plaintext = bytearray(len(plaintext)) +cipher = aesio.AES(key, aesio.MODE_CTR, IV=counter) +for i in range(0, len(plaintext), 16): + output = memoryview(plaintext)[i : i + 16] + cipher.decrypt_into(cyphertext[i : i + 16], output) + print(str(hexlify(output), "")) +print() + +print("truncated-CTR-2") +## Truncated CTR test case #2 +plaintext = unhexlify("6bc1bee22e409f96e93d7e117393172a" "ae") + +key = unhexlify("2b7e151628aed2a6abf7158809cf4f3c") +counter = unhexlify("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") +cyphertext = bytearray(len(plaintext)) +cipher = aesio.AES(key, aesio.MODE_CTR, IV=counter) +cipher.encrypt_into(plaintext, cyphertext) +for i in range(0, len(plaintext), 16): + output = memoryview(cyphertext)[i : i + 16] + print(str(hexlify(output), "")) +print() + +plaintext = bytearray(len(plaintext)) +cipher = aesio.AES(key, aesio.MODE_CTR, IV=counter) +cipher.decrypt_into(cyphertext, plaintext) +for i in range(0, len(plaintext), 16): + output = memoryview(plaintext)[i : i + 16] + print(str(hexlify(output), "")) +print() diff --git a/tests/circuitpython/aes.py.exp b/tests/circuitpython/aes.py.exp index da0f8c29b115..17a2bfe12a5f 100644 --- a/tests/circuitpython/aes.py.exp +++ b/tests/circuitpython/aes.py.exp @@ -34,3 +34,17 @@ ae2d8a571e03ac9c9eb76fac45af8e51 30c81c46a35ce411e5fbc1191a0a52ef f69f2445df4f9b17ad2b417be66c3710 +truncated-CTR-1 +874d6191b620e3261bef6864990db6ce +9806 + +6bc1bee22e409f96e93d7e117393172a +ae2d + +truncated-CTR-2 +874d6191b620e3261bef6864990db6ce +98 + +6bc1bee22e409f96e93d7e117393172a +ae + diff --git a/tests/circuitpython/miditrack.py b/tests/circuitpython/miditrack.py new file mode 100644 index 000000000000..53a8ca631df7 --- /dev/null +++ b/tests/circuitpython/miditrack.py @@ -0,0 +1,20 @@ +import array + +try: + from synthio import MidiTrack + from audiocore import get_buffer, get_structure +except ImportError: + print("SKIP") + raise SystemExit + +SCORE = b"\0\x90@\0\x20\x90b\0\x20\x80@\0\0\x80\b\0" + +with MidiTrack(SCORE, sample_rate=8000, tempo=640) as m: + print(get_structure(m)) + print(get_buffer(m)) + +with MidiTrack( + SCORE, sample_rate=8000, tempo=640, waveform=array.array("h", [0, 32767, 0, -32768]) +) as m: + print(get_structure(m)) + print(get_buffer(m)) diff --git a/tests/circuitpython/miditrack.py.exp b/tests/circuitpython/miditrack.py.exp new file mode 100644 index 000000000000..bfb082bfe7fd --- /dev/null +++ b/tests/circuitpython/miditrack.py.exp @@ -0,0 +1,4 @@ +(0, 1, 512, 1) +(1, b'V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\xaa*\xaa*') +(0, 1, 512, 1) +(1, b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd5V\xd5V\xd5V\xd5V\xd5V\xd5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa*\xaa*\xaa*\xaa*\xaa*\xaa*\x00\x00\x00\x00') diff --git a/tests/circuitpython/struct_nargs.py b/tests/circuitpython/struct_nargs.py new file mode 100644 index 000000000000..0a0cb140c379 --- /dev/null +++ b/tests/circuitpython/struct_nargs.py @@ -0,0 +1,38 @@ +import struct + + +def do_pack(*args): + try: + print(struct.pack(*args)) + except Exception as e: + print("ERROR") + + +do_pack("H") +do_pack("H", 1) +do_pack("H", 1, 2) + +do_pack("2H") +do_pack("2H", 1) +do_pack("2H", 1, 2) + +do_pack("3H") +do_pack("3H", 1) +do_pack("3H", 1, 2) +do_pack("3H", 1, 2, 3) +do_pack("3H", 1, 2, 3, 4) + +do_pack("4sH", b"x") +do_pack("4sH", b"x", 1) +do_pack("4sH", b"x", 1, 2) + +do_pack("4s2H", b"x") +do_pack("4s2H", b"x", 1) +do_pack("4s2H", b"x", 1, 2) +do_pack("4s2H", b"x", 1, 2, 3) + +do_pack("4s3H", b"x") +do_pack("4s3H", b"x", 1) +do_pack("4s3H", b"x", 1, 2) +do_pack("4s3H", b"x", 1, 2, 3) +do_pack("4s3H", b"x", 1, 2, 3, 4) diff --git a/tests/circuitpython/synthesizer.py b/tests/circuitpython/synthesizer.py new file mode 100644 index 000000000000..bdb273f861ab --- /dev/null +++ b/tests/circuitpython/synthesizer.py @@ -0,0 +1,24 @@ +import struct +import synthio +import audiocore + + +def dump_samples(): + print(struct.unpack("12h", audiocore.get_buffer(s)[1][:24])) + + +s = synthio.Synthesizer(sample_rate=8000) +print(s.pressed) +dump_samples() + +s.press((80,)) +print(s.pressed) +dump_samples() + +s.press((91,)) +print(s.pressed) +dump_samples() + +s.release_then_press((80,)) +print(s.pressed) +dump_samples() diff --git a/tests/circuitpython/synthesizer.py.exp b/tests/circuitpython/synthesizer.py.exp new file mode 100644 index 000000000000..79c88b3248fe --- /dev/null +++ b/tests/circuitpython/synthesizer.py.exp @@ -0,0 +1,8 @@ +() +(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) +(80,) +(-10922, -10922, -10922, -10922, 10922, 10922, 10922, 10922, 10922, -10922, -10922, -10922) +(80, 91) +(0, 0, 13106, 13106, 0, -13106, -13106, 0, 13106, 13106, 0, 0) +(91,) +(-10922, 10922, 10922, 10922, -10922, -10922, 10922, 10922, 10922, -10922, -10922, 10922) diff --git a/tests/cpydiff/core_fstring_repr.py b/tests/cpydiff/core_fstring_repr.py index fcadcbf1b991..df80abf795b3 100644 --- a/tests/cpydiff/core_fstring_repr.py +++ b/tests/cpydiff/core_fstring_repr.py @@ -2,7 +2,7 @@ categories: Core description: f-strings don't support the !r, !s, and !a conversions cause: MicroPython is optimised for code space. -workaround: Use repr(), str(), and ascii() explictly. +workaround: Use repr(), str(), and ascii() explicitly. """ diff --git a/tests/cpydiff/core_import_path.py b/tests/cpydiff/core_import_path.py index 04fc4bd5bbe1..959fd571f57a 100644 --- a/tests/cpydiff/core_import_path.py +++ b/tests/cpydiff/core_import_path.py @@ -1,7 +1,7 @@ """ categories: Core,import description: __path__ attribute of a package has a different type (single string instead of list of strings) in MicroPython -cause: MicroPython does't support namespace packages split across filesystem. Beyond that, MicroPython's import system is highly optimized for minimal memory usage. +cause: MicroPython doesn't support namespace packages split across filesystem. Beyond that, MicroPython's import system is highly optimized for minimal memory usage. workaround: Details of import handling is inherently implementation dependent. Don't rely on such details in portable applications. """ import modules diff --git a/tests/cpydiff/core_import_split_ns_pkgs.py b/tests/cpydiff/core_import_split_ns_pkgs.py index 62bf337a22bf..5c92b63124a5 100644 --- a/tests/cpydiff/core_import_split_ns_pkgs.py +++ b/tests/cpydiff/core_import_split_ns_pkgs.py @@ -1,6 +1,6 @@ """ categories: Core,import -description: MicroPython does't support namespace packages split across filesystem. +description: MicroPython doesn't support namespace packages split across filesystem. cause: MicroPython's import system is highly optimized for simplicity, minimal memory usage, and minimal filesystem search overhead. workaround: Don't install modules belonging to the same namespace package in different directories. For MicroPython, it's recommended to have at most 3-component module search paths: for your current application, per-user (writable), system-wide (non-writable). """ diff --git a/tests/extmod/framebuf_palette.py b/tests/extmod/framebuf_palette.py index 84db834c1500..f5b15fda7394 100644 --- a/tests/extmod/framebuf_palette.py +++ b/tests/extmod/framebuf_palette.py @@ -30,6 +30,6 @@ print(fbd.pixel(0, 0) == fg) print(fbd.pixel(7, 7) == fg) -print(fbd.pixel(8, 8) == 0) # Ouside blit +print(fbd.pixel(8, 8) == 0) # Outside blit print(fbd.pixel(0, 1) == bg) print(fbd.pixel(1, 0) == bg) diff --git a/tests/extmod/framebuf_subclass.py b/tests/extmod/framebuf_subclass.py index a9e3c5efc791..4cd9ea4eb5fa 100644 --- a/tests/extmod/framebuf_subclass.py +++ b/tests/extmod/framebuf_subclass.py @@ -34,6 +34,7 @@ def foo(self): 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/uasyncio_exception.py b/tests/extmod/uasyncio_exception.py index aae55d63207a..4e4f978dc209 100644 --- a/tests/extmod/uasyncio_exception.py +++ b/tests/extmod/uasyncio_exception.py @@ -9,6 +9,7 @@ print("SKIP") raise SystemExit + # main task raising an exception async def main(): print("main start") @@ -21,6 +22,7 @@ async def main(): except ValueError as er: print("ValueError", er.args[0]) + # sub-task raising an exception async def task(): print("task start") @@ -40,6 +42,7 @@ async def main(): 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/uctypes_sizeof_layout.py b/tests/extmod/uctypes_sizeof_layout.py index 2108e8150215..c710ecde953f 100644 --- a/tests/extmod/uctypes_sizeof_layout.py +++ b/tests/extmod/uctypes_sizeof_layout.py @@ -13,7 +13,7 @@ # uctypes.NATIVE is default print(uctypes.sizeof(desc) == uctypes.sizeof(desc, uctypes.NATIVE)) -# Here we assume that that we run on a platform with convential ABI +# Here we assume that that we run on a platform with conventional ABI # (which rounds up structure size based on max alignment). For platforms # where that doesn't hold, this tests should be just disabled in the runner. print(uctypes.sizeof(desc, uctypes.NATIVE) > uctypes.sizeof(desc, uctypes.LITTLE_ENDIAN)) diff --git a/tests/extmod/utimeq1.py b/tests/extmod/utimeq1.py index ddbc969afb29..688e5b834ff9 100644 --- a/tests/extmod/utimeq1.py +++ b/tests/extmod/utimeq1.py @@ -125,7 +125,7 @@ def edge_case(edge, offset): # We expect diff to be always positive, per the definition of heappop() which should return # the smallest value. -# This is the edge case where this invariant breaks, due to assymetry of two's-complement +# This is the edge case where this invariant breaks, due to asymmetry of two's-complement # range - there's one more negative integer than positive, so heappushing values like below # will then make ticks_diff() return the minimum negative value. We could make heappop # return them in a different order, but ticks_diff() result would be the same. Conclusion: diff --git a/tests/extmod/vfs_fat_case.py b/tests/extmod/vfs_fat_case.py new file mode 100644 index 000000000000..40d67da9b824 --- /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 000000000000..64b5e7b27a10 --- /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 10e92d6940ee..935f01d24fd5 100644 --- a/tests/extmod/vfs_fat_fileio1.py +++ b/tests/extmod/vfs_fat_fileio1.py @@ -13,7 +13,6 @@ 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 7c75a6d044d9..6094b5a6f1bb 100644 --- a/tests/extmod/vfs_fat_fileio2.py +++ b/tests/extmod/vfs_fat_fileio2.py @@ -13,7 +13,6 @@ class RAMFS: - SEC_SIZE = 512 def __init__(self, blocks): diff --git a/tests/extmod/vfs_fat_more.py b/tests/extmod/vfs_fat_more.py index 1b7b04ee6368..f5de72940218 100644 --- a/tests/extmod/vfs_fat_more.py +++ b/tests/extmod/vfs_fat_more.py @@ -12,7 +12,6 @@ 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 e447ff4eb312..1998319dbe40 100644 --- a/tests/extmod/vfs_fat_oldproto.py +++ b/tests/extmod/vfs_fat_oldproto.py @@ -13,7 +13,6 @@ 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 4b793911021d..a22d480dfd9f 100644 --- a/tests/extmod/vfs_fat_ramdisk.py +++ b/tests/extmod/vfs_fat_ramdisk.py @@ -13,7 +13,6 @@ 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 69d4a8cbbda1..649a53db1470 100644 --- a/tests/extmod/vfs_fat_ramdisklarge.py +++ b/tests/extmod/vfs_fat_ramdisklarge.py @@ -14,7 +14,6 @@ class RAMBDevSparse: - SEC_SIZE = 512 def __init__(self, blocks): diff --git a/tests/feature_check/README b/tests/feature_check/README index 3b7b6cba4174..0f55e7ece455 100644 --- a/tests/feature_check/README +++ b/tests/feature_check/README @@ -1,4 +1,4 @@ This directory doesn't contain real tests, but code snippets to detect -various interpreter features, which can't be/inconvenient to detecte by +various interpreter features, which can't be/inconvenient to detected by other means. Scripts here are executed by run-tests.py at the beginning of testsuite to decide what other test groups to run/exclude. diff --git a/tests/import/module_getattr.py b/tests/import/module_getattr.py index df7a6218156c..9ca0d184559b 100644 --- a/tests/import/module_getattr.py +++ b/tests/import/module_getattr.py @@ -8,6 +8,7 @@ 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 6535a495d4e0..208709a25f74 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 ed4720122ed3..d8b68c25f36a 100644 --- a/tests/micropython/const2.py +++ b/tests/micropython/const2.py @@ -11,6 +11,7 @@ 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 @@ def f(self): 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 58788b1dbcf6..950717189087 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 @@ def gen(g): print(next(g)) micropython.heap_unlock() + # Yielding from a user iterator class G: def __init__(self): diff --git a/tests/micropython/native_closure.py b/tests/micropython/native_closure.py index 07014e90dac2..8182cfea70ec 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 g(): print(f()()) + # closing over an argument @micropython.native def f(x): @@ -28,6 +30,7 @@ def g(): 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 fb42f9e25ede..7ea45b1497ab 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 @@ def gen1(x): 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 f5ef807fe13f..f40fcb240708 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 @@ def native_test(x): 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 492b59085c77..6a2152b28c71 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 @@ def f(): 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 3d31248df0fe..26b9243e03d4 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 4e20b2385679..9c0b98af9038 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 8e3225331a42..27c73fa79581 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 d5ebf837bdde..752261ff5093 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 41389c751d39..f9267f65cab8 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 @@ def viper_raise(x: int): 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 8f0be487d626..cc77134bd48c 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 055c08d8e53d..91673f2c1087 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 61335af221c7..f5822a66820f 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 @@ def f(): 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 3af148171e29..3e0a4f664046 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 @@ def f1(x: bool): 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 d640c8ae0f5d..40fbf6fb3154 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 cff18941064f..ecd4f1039182 100644 --- a/tests/misc/non_compliant.py +++ b/tests/misc/non_compliant.py @@ -39,7 +39,7 @@ except NotImplementedError: print("NotImplementedError") -# uPy raises TypeError, shold be ValueError +# uPy raises TypeError, should be ValueError try: "%c" % b"\x01\x02" except (TypeError, ValueError): @@ -111,6 +111,7 @@ except NotImplementedError: print("NotImplementedError") + # can't assign attributes to a function def f(): pass @@ -127,6 +128,7 @@ def f(): 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 43065df4ae9b..1199f1f4eb13 100644 --- a/tests/misc/sys_settrace_generator.py +++ b/tests/misc/sys_settrace_generator.py @@ -48,11 +48,9 @@ def make_gen(): 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 a60ca955d7c7..fcf034af2545 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/benchrun.py b/tests/perf_bench/benchrun.py index 90c303dd29cb..87b6489d07a2 100644 --- a/tests/perf_bench/benchrun.py +++ b/tests/perf_bench/benchrun.py @@ -4,7 +4,7 @@ def bm_run(N, M): except ImportError: import time - ticks_us = lambda: int(time.perf_counter() * 1000000) + ticks_us = lambda: int(time.monotonic_ns() // 1000) ticks_diff = lambda a, b: a - b # Pick sensible parameters given N, M diff --git a/tests/perf_bench/bm_nqueens.py b/tests/perf_bench/bm_nqueens.py index 773dd3f7edd8..160f1178aa87 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 0743737cb723..8a9c58bb380b 100644 --- a/tests/perf_bench/misc_aes.py +++ b/tests/perf_bench/misc_aes.py @@ -33,6 +33,7 @@ )) # 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 606fc3b77201..24f6d5a7716e 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-perfbench.py b/tests/run-perfbench.py index 5f299281fdbc..3d3639e0577e 100755 --- a/tests/run-perfbench.py +++ b/tests/run-perfbench.py @@ -7,8 +7,12 @@ import os import subprocess import sys +import time import argparse from glob import glob +from rich.live import Live +from rich.console import Console +from rich.table import Table sys.path.append("../tools") import pyboard @@ -37,7 +41,7 @@ def compute_stats(lst): return avg, var**0.5 -def run_script_on_target(target, script): +def run_script_on_target(target, script, run_command=None): output = b"" err = None @@ -45,50 +49,72 @@ def run_script_on_target(target, script): # Run via pyboard interface try: target.enter_raw_repl() + start_ts = time.monotonic_ns() output = target.exec_(script) + if run_command: + start_ts = time.monotonic_ns() + output = target.exec_(run_command) + end_ts = time.monotonic_ns() except pyboard.PyboardError as er: + end_ts = time.monotonic_ns() err = er + finally: + target.exit_raw_repl() else: # Run local executable try: + if run_command: + script += run_command + start_ts = time.monotonic_ns() p = subprocess.run( target, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, input=script ) + end_ts = time.monotonic_ns() output = p.stdout except subprocess.CalledProcessError as er: + end_ts = time.monotonic_ns() err = er - return str(output.strip(), "ascii"), err + return str(output.strip(), "ascii"), err, (end_ts - start_ts) // 1000 def run_feature_test(target, test): with open("feature_check/" + test + ".py", "rb") as f: script = f.read() - output, err = run_script_on_target(target, script) + output, err, _ = run_script_on_target(target, script) if err is None: return output else: return "CRASH: %r" % err -def run_benchmark_on_target(target, script): - output, err = run_script_on_target(target, script) +def run_benchmark_on_target(target, script, run_command=None): + output, err, runtime_us = run_script_on_target(target, script, run_command) if err is None: time, norm, result = output.split(None, 2) try: - return int(time), int(norm), result + return int(time), int(norm), result, runtime_us except ValueError: - return -1, -1, "CRASH: %r" % output + return -1, -1, "CRASH: %r" % output, runtime_us else: - return -1, -1, "CRASH: %r" % err + return -1, -1, "CRASH: %r" % err, runtime_us -def run_benchmarks(target, param_n, param_m, n_average, test_list): +def run_benchmarks(console, target, param_n, param_m, n_average, test_list): skip_complex = run_feature_test(target, "complex") != "complex" skip_native = run_feature_test(target, "native_check") != "native" + table = Table(show_header=True) + table.add_column("Test") + table.add_column("Time", justify="right") + table.add_column("Score", justify="right") + table.add_column("Ref Time", justify="right") + + live = Live(table, console=console) + live.start() + for test_file in sorted(test_list): - print(test_file + ": ", end="") + # print(test_file + ": ", end="") # Check if test should be skipped skip = ( @@ -99,6 +125,7 @@ def run_benchmarks(target, param_n, param_m, n_average, test_list): ) if skip: print("skip") + table.add_row(test_file, *(["skip"] * 6)) continue # Create test script @@ -106,7 +133,7 @@ def run_benchmarks(target, param_n, param_m, n_average, test_list): test_script = f.read() with open(BENCH_SCRIPT_DIR + "benchrun.py", "rb") as f: test_script += f.read() - test_script += b"bm_run(%u, %u)\n" % (param_n, param_m) + bm_run = b"bm_run(%u, %u)\n" % (param_n, param_m) # Write full test script if needed if 0: @@ -115,12 +142,15 @@ def run_benchmarks(target, param_n, param_m, n_average, test_list): # Run MicroPython a given number of times times = [] + runtimes = [] scores = [] error = None result_out = None for _ in range(n_average): - time, norm, result = run_benchmark_on_target(target, test_script) - if time < 0 or norm < 0: + self_time, norm, result, runtime_us = run_benchmark_on_target( + target, test_script, bm_run + ) + if self_time < 0 or norm < 0: error = result break if result_out is None: @@ -128,30 +158,43 @@ def run_benchmarks(target, param_n, param_m, n_average, test_list): elif result != result_out: error = "FAIL self" break - times.append(time) - scores.append(1e6 * norm / time) + times.append(self_time) + runtimes.append(runtime_us) + scores.append(1e6 * norm / self_time) # Check result against truth if needed if error is None and result_out != "None": - _, _, result_exp = run_benchmark_on_target(PYTHON_TRUTH, test_script) + _, _, result_exp, _ = run_benchmark_on_target(PYTHON_TRUTH, test_script, bm_run) if result_out != result_exp: error = "FAIL truth" if error is not None: - print(error) + print(test_file, error) + if error == "no matching params": + table.add_row(test_file, *([None] * 3)) + else: + table.add_row(test_file, *(["error"] * 3)) else: t_avg, t_sd = compute_stats(times) + r_avg, r_sd = compute_stats(runtimes) s_avg, s_sd = compute_stats(scores) - print( - "{:.2f} {:.4f} {:.2f} {:.4f}".format( - t_avg, 100 * t_sd / t_avg, s_avg, 100 * s_sd / s_avg - ) + # print( + # "{:.2f} {:.4f} {:.2f} {:.4f} {:.2f} {:.4f}".format( + # t_avg, 100 * t_sd / t_avg, s_avg, 100 * s_sd / s_avg, r_avg, 100 * r_sd / r_avg + # ) + # ) + table.add_row( + test_file, + f"{t_avg:.2f}±{100 * t_sd / t_avg:.1f}%", + f"{s_avg:.2f}±{100 * s_sd / s_avg:.1f}%", + f"{r_avg:.2f}±{100 * r_sd / r_avg:.1f}%", ) if 0: print(" times: ", times) print(" scores:", scores) - sys.stdout.flush() + live.update(table, refresh=True) + live.stop() def parse_output(filename): @@ -268,9 +311,10 @@ def main(): else: tests = sorted(args.files) + console = Console() print("N={} M={} n_average={}".format(N, M, n_average)) - run_benchmarks(target, N, M, n_average, tests) + run_benchmarks(console, target, N, M, n_average, tests) if isinstance(target, pyboard.Pyboard): target.exit_raw_repl() diff --git a/tests/stress/qstr_limit.py b/tests/stress/qstr_limit.py index d8ce0cf7cd15..08b10a039f50 100644 --- a/tests/stress/qstr_limit.py +++ b/tests/stress/qstr_limit.py @@ -17,6 +17,7 @@ def make_id(n, base="a"): continue print(var in g) + # calling a function with kwarg def f(**k): print(k) @@ -36,6 +37,7 @@ def f(**k): 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 8c2139765847..e051abb84d0f 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 @@ def gen(): 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 9b52e0c01643..7bacabec3afb 100644 --- a/tests/thread/mutate_bytearray.py +++ b/tests/thread/mutate_bytearray.py @@ -9,6 +9,7 @@ # 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 0840dcafba72..fb87190e7706 100644 --- a/tests/thread/mutate_dict.py +++ b/tests/thread/mutate_dict.py @@ -9,6 +9,7 @@ # 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 8ba91cbde380..cc0ad9885dd9 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 @@ def __init__(self): 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 8ce15c085201..4df86b3008cd 100644 --- a/tests/thread/mutate_list.py +++ b/tests/thread/mutate_list.py @@ -9,6 +9,7 @@ # 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 61169b8aa97a..587a3a259ad6 100644 --- a/tests/thread/mutate_set.py +++ b/tests/thread/mutate_set.py @@ -9,6 +9,7 @@ # 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 673337563d1b..199fe3c88ce3 100644 --- a/tests/thread/stress_aes.py +++ b/tests/thread/stress_aes.py @@ -40,6 +40,7 @@ )) # 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_lock1.py b/tests/thread/thread_lock1.py index e7066402cabc..f49f57ce8375 100644 --- a/tests/thread/thread_lock1.py +++ b/tests/thread/thread_lock1.py @@ -32,7 +32,7 @@ with lock: print(lock.locked()) -# test that lock is unlocked if an error is rasied +# test that lock is unlocked if an error is raised try: with lock: print(lock.locked()) diff --git a/tests/thread/thread_qstr1.py b/tests/thread/thread_qstr1.py index 2099f94bdbf5..9e7d7f032694 100644 --- a/tests/thread/thread_qstr1.py +++ b/tests/thread/thread_qstr1.py @@ -10,6 +10,7 @@ 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 3a58e3f72b5e..32817287e9d9 100644 --- a/tests/unicode/unicode_id.py +++ b/tests/unicode/unicode_id.py @@ -10,6 +10,7 @@ β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 582d90e1bce6..c750ca0e95af 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -30,20 +30,21 @@ ame__ mport 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 +_uasyncio aesio array audiocore +audiomixer binascii bitmaptools btree +cexample cmath collections cppexample +displayio errno ffi framebuf +gc hashlib json math +qrio rainbowio re struct +synthio 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 utime utimeq uzlib +zlib ime utime utimeq diff --git a/tools/analyze_heap_dump.py b/tools/analyze_heap_dump.py index d9b3dda59966..ede990929d0c 100755 --- a/tools/analyze_heap_dump.py +++ b/tools/analyze_heap_dump.py @@ -446,7 +446,7 @@ def save_allocated_block(end, current_allocation): current_allocation = 1 elif block_state == AT_TAIL and current_allocation > 0: # In gc_free the logging happens before the tail is freed. So checking - # current_allocation > 0 ensures we only extend an allocation thats started. + # current_allocation > 0 ensures we only extend an allocation that's started. current_allocation += 1 longest_free = max(longest_free, current_free) # if current_free > 0: diff --git a/tools/build_board_info.py b/tools/build_board_info.py index f810d942a713..f73f83b5ee81 100755 --- a/tools/build_board_info.py +++ b/tools/build_board_info.py @@ -6,10 +6,12 @@ import json import os +import requests import subprocess import sys import sh import base64 +from io import StringIO from datetime import date from sh.contrib import git @@ -58,9 +60,13 @@ def get_languages(list_all=False): 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 @@ -91,7 +97,19 @@ def get_current_info(): response = response.json() git_info = commit_sha, response["sha"] - current_list = json.loads(base64.b64decode(response["content"]).decode("utf-8")) + + if response["content"] != "": + # if the file is there + current_list = json.loads(base64.b64decode(response["content"]).decode("utf-8")) + else: + # if too big, the file is not included + download_url = response["download_url"] + response = requests.get(download_url) + if not response.ok: + print(response.text) + raise RuntimeError("cannot get previous files.json") + current_list = response.json() + current_info = {} for info in current_list: current_info[info["id"]] = info @@ -118,10 +136,10 @@ def create_pr(changes, updated, git_info, user): pr_title = "Automated website update for release {}".format(changes["new_release"]) boards = "" if changes["new_boards"]: - boards = "New boards:\n* " + "\n* ".join(changes["new_boards"]) + boards = "New boards:\n* " + "\n* ".join(sorted(changes["new_boards"])) languages = "" if changes["new_languages"]: - languages = "New languages:\n* " + "\n* ".join(changes["new_languages"]) + languages = "New languages:\n* " + "\n* ".join(sorted(changes["new_languages"])) message = "Automated website update for release {} by Blinka.\n\n{}\n\n{}\n".format( changes["new_release"], boards, languages ) diff --git a/tools/build_memory_info.py b/tools/build_memory_info.py index 722c548a1c28..09d2e72a6416 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 @@ 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 @@ 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 @@ 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 309d91c368b3..341ae2d67f0f 100755 --- a/tools/build_release_files.py +++ b/tools/build_release_files.py @@ -11,6 +11,7 @@ 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 @@ -18,7 +19,7 @@ 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" @@ -29,6 +30,11 @@ 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) @@ -44,6 +50,9 @@ 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) os.makedirs(bin_directory, exist_ok=True) @@ -66,13 +75,20 @@ 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, @@ -86,10 +102,6 @@ success = "\033[31mfailed\033[0m" other_output = "" - extensions = [ - extension.strip() - for extension in board_settings["CIRCUITPY_BUILD_EXTENSIONS"].split(",") - ] for extension in extensions: temp_filename = "../ports/{port}/{build}/firmware.{extension}".format( @@ -127,4 +139,16 @@ # 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 index e38c98f40ef7..58e86148edab 100644 --- a/tools/ci_changes_per_commit.py +++ b/tools/ci_changes_per_commit.py @@ -18,7 +18,7 @@ } nodes { commit { - checkSuites(first: 3) { + checkSuites(first: 100) { nodes { conclusion workflowRun { @@ -39,7 +39,7 @@ } """ -QUERY_CHECKRUNS = """ +QUERY_CHECK_RUNS = """ query ($checkSuiteID: ID!, $afterFailedRun: String, $afterIncompleteRun: String, $includeFailedRuns: Boolean!, $includeIncompleteRuns: Boolean!) { @@ -92,7 +92,7 @@ } -query_variables_checkruns = { +query_variables_check_runs = { "checkSuiteID": "", "afterFailedRun": None, "afterIncompleteRun": None, @@ -111,13 +111,11 @@ def __init__(self, query, variables={}, headers={}): self.headers = headers def paginate(self, page_info, name): - has_page = ( - page_info["hasNextPage"] if name.startswith("after") else page_info["hasPreviousPage"] - ) + 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 page_info["startCursor"] - ) + self.variables[name] = page_info[ + "endCursor" if name.startswith("after") else "startCursor" + ] return has_page def fetch(self): @@ -141,64 +139,72 @@ def set_output(name, value): print(f"Would set GitHub actions output {name} to '{value}'") -def get_commit_and_checksuite(query_commits): - commits = query_commits.fetch()["data"]["repository"]["pullRequest"]["commits"] - - if commits["totalCount"] > 0: - for commit in reversed(commits["nodes"]): - commit = commit["commit"] - commit_sha = commit["oid"] - if commit_sha == os.environ["EXCLUDE_COMMIT"]: - continue - checksuites = commit["checkSuites"] - if checksuites["totalCount"] > 0: - for checksuite in checksuites["nodes"]: - if checksuite["workflowRun"]["workflow"]["name"] == "Build CI": - return [ - commit_sha, - checksuite["id"] if checksuite["conclusion"] != "SUCCESS" else None, - ] - else: - if query_commits.paginate(commits["pageInfo"], "beforeCommit"): - return get_commit_and_checksuite(query_commits) - - return [None, None] - - -def append_runs_to_list(runs, bad_runs_by_matrix): - regex_matrix = re.compile("^build-[^ ]+") - regex_board = re.compile("\([^ ]+\)$") - for run in runs["nodes"]: - name = run["name"] - res_matrix = regex_matrix.search(name) - if res_matrix: - matrix = res_matrix.group() - if matrix not in bad_runs_by_matrix: - bad_runs_by_matrix[matrix] = [] - res_board = regex_board.search(name) - if res_board: - bad_runs_by_matrix[matrix].append(res_board.group()[1:-1]) +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"] + have_dependent_jobs = ["scheduler", "mpy-cross", "tests"] -def get_bad_checkruns(query_checkruns): - more_pages = True - bad_runs_by_matrix = {} while more_pages: - checkruns = query_checkruns.fetch()["data"]["node"] - run_types = ["failed", "incomplete"] + 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" - append_runs_to_list(checkruns[run_type], bad_runs_by_matrix) + for check_run in check_runs[run_type]["nodes"]: + name = check_run["name"] + + if any([name.startswith(job) for job in have_dependent_jobs]): + return {} + + if name.startswith("ports"): + matrix_job = name.rsplit(" (", 1)[1][:-1] + bad_runs.setdefault("ports", []).append(matrix_job) + else: + bad_runs[name] = True - if query_checkruns.paginate(checkruns[run_type]["pageInfo"], "after" + run_type_camel): - query_checkruns.variables["include" + run_type_camel] = True + 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_by_matrix + return bad_runs + + +def set_commit(commit): + set_output("commit_sha", commit["sha"]) + set_output("commit_depth", commit["depth"]) def main(): @@ -207,26 +213,26 @@ def main(): "/" ) - commit, checksuite = get_commit_and_checksuite(query_commits) + commit, check_suite = get_commit_depth_and_check_suite(query_commits) - if checksuite is None: - if commit is None: - print("No checkSuites found -> Abort") + if not check_suite: + if commit: + set_commit(commit) else: - set_output("commit", commit) + print("Abort: No check suite found") quit() - query_checkruns = Query(QUERY_CHECKRUNS, query_variables_checkruns, headers) - query_checkruns.variables["checkSuiteID"] = checksuite + query_check_runs = Query(QUERY_CHECK_RUNS, query_variables_check_runs, headers) + query_check_runs.variables["checkSuiteID"] = check_suite - checkruns = get_bad_checkruns(query_checkruns) + check_runs = get_bad_check_runs(query_check_runs) - if len(checkruns) == 0: - print("No checkRuns found -> Abort") + if not check_runs: + print("Abort: No check runs found") quit() - set_output("commit", commit) - set_output("checkruns", json.dumps(checkruns)) + set_commit(commit) + set_output("check_runs", json.dumps(check_runs)) if __name__ == "__main__": diff --git a/tools/ci_check_duplicate_usb_vid_pid.py b/tools/ci_check_duplicate_usb_vid_pid.py index 4e5c48c90df3..f20630e8868f 100644 --- a/tools/ci_check_duplicate_usb_vid_pid.py +++ b/tools/ci_check_duplicate_usb_vid_pid.py @@ -54,6 +54,7 @@ "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", @@ -61,6 +62,7 @@ "espressif_esp32s2_devkitc_1_n8r2", ], "0x239A:0x102E": ["weact_studio_pico", "weact_studio_pico_16mb"], + "0x303A:0x8166": ["yd_esp32_s3_n8r8", "yd_esp32_s3_n16r8"], } cli_parser = argparse.ArgumentParser( diff --git a/tools/ci_fetch_deps.py b/tools/ci_fetch_deps.py index 515c3b198fc7..b77bea72f991 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/", @@ -46,6 +43,7 @@ "lib/tinyusb/", "data/nvm.toml/", ], + "silabs": ["extmod/ulab/", "data/nvm.toml/"], "stm": ["extmod/ulab/", "lib/mp3/", "lib/protomatter/", "lib/tinyusb/", "data/nvm.toml/"] # omit unix which is part of the "test" target below } @@ -58,71 +56,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) + + +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 main(): + submodules = [] + submodules_tags = [] + + print("Target:", TARGET) + + 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}") + + 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) -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") - -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}") - - 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(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, - ) - - run( - "Fetch the submodule sha", - "git submodule foreach 'git fetch --tags --depth 1 origin $sha1 && git checkout -q $sha1'", - ) +if __name__ == "__main__": + main() diff --git a/tools/ci_set_matrix.py b/tools/ci_set_matrix.py index 77f58742cd81..f549b6f6f1e1 100755 --- a/tools/ci_set_matrix.py +++ b/tools/ci_set_matrix.py @@ -26,6 +26,7 @@ import sys import json import pathlib +import subprocess from concurrent.futures import ThreadPoolExecutor tools_dir = pathlib.Path(__file__).resolve().parent @@ -41,48 +42,75 @@ all_ports_all_boards, ) -PORT_TO_ARCH = { - "atmel-samd": "arm", - "broadcom": "aarch", - "cxd56": "arm", - "espressif": "espressif", - "litex": "riscv", - "mimxrt10xx": "arm", - "nrf": "arm", - "raspberrypi": "arm", - "stm": "arm", +# Files that never influence board builds +IGNORE_BOARD = { + ".devcontainer", + "docs", + "tests", + "tools/ci_changes_per_commit.py", + "tools/ci_check_duplicate_usb_vid_pid.py", + "tools/ci_set_matrix.py", } -IGNORE = [ - "tools/ci_set_matrix.py", - "tools/ci_check_duplicate_usb_vid_pid.py", -] +PATTERN_DOCS = ( + r"^(?:\.github|docs|extmod\/ulab)|" + r"^(?:(?:ports\/\w+\/bindings|shared-bindings)\S+\.c|tools\/extract_pyi\.py|\.readthedocs\.yml|conf\.py|requirements-doc\.txt)$|" + r"(?:-stubs|\.(?:md|MD|rst|RST))$" +) + +PATTERN_WINDOWS = { + ".github/", + "extmod/", + "lib/", + "mpy-cross/", + "ports/unix/", + "py/", + "tools/", + "requirements-dev.txt", +} + + +def git_diff(pattern: str): + return set( + subprocess.run( + f"git diff {pattern} --name-only", + capture_output=True, + shell=True, + ) + .stdout.decode("utf-8") + .split("\n")[:-1] + ) + -# Files in these directories never influence board builds -IGNORE_DIRS = ["tests", "docs", ".devcontainer"] +compute_diff = bool(os.environ.get("BASE_SHA") and os.environ.get("HEAD_SHA")) if len(sys.argv) > 1: print("Using files list on commandline") - changed_files = sys.argv[1:] - last_failed_jobs = {} + changed_files = set(sys.argv[1:]) +elif compute_diff: + print("Using files list by computing diff") + changed_files = git_diff("$BASE_SHA...$HEAD_SHA") + if os.environ.get("GITHUB_EVENT_NAME") == "pull_request": + changed_files.intersection_update(git_diff("$GITHUB_SHA~...$GITHUB_SHA")) 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("\\", "")) + print("Using files list in CHANGED_FILES") + changed_files = set(json.loads(os.environ.get("CHANGED_FILES") or "[]")) - 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) +print("Using jobs list in LAST_FAILED_JOBS") +last_failed_jobs = json.loads(os.environ.get("LAST_FAILED_JOBS") or "{}") + + +def print_enclosed(title, content): + print("::group::" + title) + print(content) + print("::endgroup::") -def set_output(name, value): +print_enclosed("Log: changed_files", changed_files) +print_enclosed("Log: last_failed_jobs", last_failed_jobs) + + +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) @@ -90,26 +118,24 @@ def set_output(name, value): print(f"Would set GitHub actions output {name} to '{value}'") -def set_boards_to_build(build_all): - # Get boards in json format - boards_info_json = build_board_info.get_board_mapping() +def set_boards(build_all: bool): all_board_ids = set() - port_to_boards = {} + boards_to_build = all_board_ids if build_all else set() + board_to_port = {} - board_settings = {} - for board_id in boards_info_json: - info = boards_info_json[board_id] - if info.get("alias", False): + port_to_board = {} + board_setting = {} + + for id, info in build_board_info.get_board_mapping().items(): + if info.get("alias"): continue - all_board_ids.add(board_id) port = info["port"] - if port not in port_to_boards: - port_to_boards[port] = set() - port_to_boards[port].add(board_id) - board_to_port[board_id] = port + all_board_ids.add(id) + board_to_port[id] = port + port_to_board.setdefault(port, set()).add(id) def compute_board_settings(boards): - need = set(boards) - set(board_settings.keys()) + need = set(boards) - set(board_setting.keys()) if not need: return @@ -120,146 +146,163 @@ def get_settings(board): ) with ThreadPoolExecutor(max_workers=os.cpu_count()) as ex: - board_settings.update(ex.map(get_settings, need)) - - boards_to_build = all_board_ids + board_setting.update(ex.map(get_settings, need)) 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( + pattern_port = re.compile(r"^ports/([^/]+)/") + pattern_board = re.compile(r"^ports/[^/]+/boards/([^/]+)/") + pattern_module = re.compile( r"^(ports/[^/]+/(?:common-hal|bindings)|shared-bindings|shared-module)/([^/]+)/" ) - for p in changed_files: + + for file in changed_files: + if len(all_board_ids) == len(boards_to_build): + break + + if any([file.startswith(path) for path in IGNORE_BOARD]): + continue + # See if it is board specific - board_matches = board_pattern.search(p) + board_matches = pattern_board.search(file) if board_matches: - board = board_matches.group(1) - boards_to_build.add(board) + boards_to_build.add(board_matches.group(1)) continue # See if it is port specific - port_matches = port_pattern.search(p) + port_matches = pattern_port.search(file) + module_matches = pattern_module.search(file) 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]) + boards_to_build.update(port_to_board[port]) continue - # Check the ignore list to see if the file isn't used on board builds. - if p in IGNORE: - 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 file.startswith("frozen") or file.startswith("supervisor") or module_matches: + boards = port_to_board[port] if port else all_board_ids + compute_board_settings(boards) - if any([p.startswith(d) for d in IGNORE_DIRS]): - continue + for board in boards: + settings = board_setting[board] - # 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: + # Check frozen files to see if they are in each board + if file.startswith("frozen"): + if file in settings.get("FROZEN_MPY_DIRS", ""): 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" - ): + # Check supervisor files + # This is useful for limiting workflow changes to the relevant boards + if file.startswith("supervisor"): + if file in settings["SRC_SUPERVISOR"]: boards_to_build.add(board) continue + if file.startswith("supervisor/shared/web_workflow/static/"): + web_workflow = settings["CIRCUITPY_WEB_WORKFLOW"] + + while web_workflow.startswith("$("): + web_workflow = settings[web_workflow[2:-1]] + + if 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": []} + # Append previously failed boards + boards_to_build.update(last_failed_jobs.get("ports", [])) + + 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): - print(" ", board) 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) - - # Set the step outputs for each architecture - for arch in arch_to_boards: - # Append previous failed jobs - if f"build-{arch}" in last_failed_jobs: - failed_boards = last_failed_jobs[f"build-{arch}"] - for board in failed_boards: - if not board in arch_to_boards[arch]: - print(" ", board) - arch_to_boards[arch].append(board) - # Set Output - set_output(f"boards-{arch}", json.dumps(sorted(arch_to_boards[arch]))) - - -def set_docs_to_build(build_all): - if "build-doc" in last_failed_jobs: - build_all = True - - doc_match = build_all - if not build_all: - doc_pattern = re.compile( - r"^(?:.github/workflows/|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 - break + port_to_boards_to_build.setdefault(port, []).append(board) + print(" ", board) + + if port_to_boards_to_build: + port_to_boards_to_build["ports"] = sorted(list(port_to_boards_to_build.keys())) # Set the step outputs - print("Building docs:", doc_match) - set_output("build-doc", doc_match) + set_output("ports", json.dumps(port_to_boards_to_build)) + + +def set_docs(run: bool): + if not run: + if last_failed_jobs.get("docs"): + run = True + else: + pattern_doc = 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 pattern_doc.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 + ): + run = True + break + # Set the step outputs + print("Building docs:", run) + set_output("docs", run) + + +def set_windows(run: bool): + if not run: + if last_failed_jobs.get("windows"): + run = True + else: + for file in changed_files: + for pattern in PATTERN_WINDOWS: + if file.startswith(pattern) and not any( + [file.startswith(path) for path in IGNORE_BOARD] + ): + run = True + break + else: + continue + break -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 + # Set the step outputs + print("Building windows:", run) + set_output("windows", run) def main(): - build_all = check_changed_files() - set_docs_to_build(build_all) - set_boards_to_build(build_all) + run_all = not changed_files and not compute_diff + print("Running: " + ("all" if run_all else "conditionally")) + # Set jobs + set_docs(run_all) + set_windows(run_all) + set_boards(run_all) if __name__ == "__main__": diff --git a/tools/codeformat.py b/tools/codeformat.py index 223c2bad4509..f76e5f06810f 100644 --- a/tools/codeformat.py +++ b/tools/codeformat.py @@ -71,6 +71,7 @@ "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. diff --git a/tools/cortex-m-fault-gdb.py b/tools/cortex-m-fault-gdb.py new file mode 100644 index 000000000000..31b76aa1d45a --- /dev/null +++ b/tools/cortex-m-fault-gdb.py @@ -0,0 +1,106 @@ +"""Source this file into gdb `source ../../tools/cortex-m-fault-gdb.py` then run + `cortex-m-fault` to print basic info about the fault registers.""" + +SCS = 0xE000E000 +SCB = SCS + 0x0D00 +CPUID = SCB + 0x000 # (R/ ) CPUID Base Register */ +ICSR = SCB + 0x004 # (R/W) Interrupt Control and State Register */ +VTOR = SCB + 0x008 # (R/W) Vector Table Offset Register */ +AIRCR = SCB + 0x00C # (R/W) Application Interrupt and Reset Control Register */ +SCR = SCB + 0x010 # (R/W) System Control Register */ +CCR = SCB + 0x014 # (R/W) Configuration Control Register */ +SHCSR = SCB + 0x024 # (R/W) System Handler Control and State Register */ +CFSR = SCB + 0x028 # (R/W) Configurable Fault Status Register */ +HFSR = SCB + 0x02C # (R/W) HardFault Status Register */ +DFSR = SCB + 0x030 # (R/W) Debug Fault Status Register */ +MMFAR = SCB + 0x034 # (R/W) MemManage Fault Address Register */ +BFAR = SCB + 0x038 # (R/W) BusFault Address Register */ +AFSR = SCB + 0x03C # (R/W) Auxiliary Fault Status Register */ + +PARTS = {0xC27: "Cortex M7"} + +EXCEPTIONS = { + 0: "Thread mode", + 2: "Non Maskable Interrupt", + 3: "Hard Fault", + 4: "MemManage Fault", + 5: "Bus Fault", + 6: "Usage Fault", + 11: "SVCAll", + 14: "PendSV", + 15: "SysTick", +} + + +class CortexMFault(gdb.Command): + def __init__(self): + super(CortexMFault, self).__init__("cortex-m-fault", gdb.COMMAND_USER) + + def _read(self, address): + i = gdb.selected_inferior() + return i.read_memory(address, 4).cast("I")[0] + + def invoke(self, arg, from_tty): + cpuid = self._read(CPUID) + implementer = cpuid >> 24 + if implementer != 0x41: + raise RuntimeError() + variant = (cpuid >> 20) & 0xF + constant = (cpuid >> 16) & 0xF + if constant != 0xF: + raise RuntimeError() + revision = cpuid & 0xF + part_no = (cpuid >> 4) & 0xFFF + print(PARTS[part_no]) + icsr = self._read(ICSR) + if (icsr & (1 << 11)) != 0: + print("No preempted exceptions") + else: + print("Another exception was preempted") + vectactive = icsr & 0x1FF + if vectactive != 0: + if vectactive in EXCEPTIONS: + print(EXCEPTIONS[vectactive]) + else: + print(vectactive - 16) + + vtor = self._read(VTOR) + # print(hex(self._read(SHCSR))) + cfsr = self._read(CFSR) + ufsr = cfsr >> 16 + bfsr = (cfsr >> 8) & 0xFF + mmfsr = cfsr & 0xFF + print("ufsr", hex(ufsr), "bfsr", hex(bfsr), "mmfsr", hex(mmfsr)) + if (bfsr & (1 << 7)) != 0: + print("Bad address", hex(self._read(BFAR))) + if (bfsr & (1 << 3)) != 0: + print("Unstacking from exception error") + if (bfsr & (1 << 2)) != 0: + print("Imprecise data bus error") + if (bfsr & (1 << 1)) != 0: + print("Precise data bus error") + if (bfsr & (1 << 0)) != 0: + print("Instruction bus error") + + if (mmfsr & (1 << 7)) != 0: + print("Bad address", hex(self._read(MMFAR))) + if (mmfsr & (1 << 3)) != 0: + print("Unstacking from exception error") + if (mmfsr & (1 << 1)) != 0: + print("Data access violation") + if (mmfsr & (1 << 0)) != 0: + print("Instruction access violation") + + if (ufsr & (1 << 8)) != 0: + print("Unaligned access") + if (ufsr & (1 << 0)) != 0: + print("Undefined instruction") + hfsr = self._read(HFSR) + if (hfsr & (1 << 30)) != 0: + print("Forced hard fault") + if (hfsr & (1 << 1)) != 0: + print("Bus fault when reading vector table") + print("VTOR", hex(vtor)) + + +CortexMFault() diff --git a/tools/cpboard.py b/tools/cpboard.py index 1f399d1dfcb6..12d7d374a35e 100644 --- a/tools/cpboard.py +++ b/tools/cpboard.py @@ -9,6 +9,7 @@ # SPDX-License-Identifier: MIT import os +import pathlib import re import serial import sys @@ -80,6 +81,7 @@ def read_until(self, ending, timeout=10): else: timeout_count += 1 if timeout is not None and timeout_count >= 100 * timeout: + print("timeout") raise TimeoutError(110, "timeout waiting for", ending) time.sleep(0.01) return data @@ -93,16 +95,18 @@ def write(self, data, chunk_size=None): for i in range(0, len(data), chunk_size): chunk = data[i : min(i + chunk_size, len(data))] self.session += chunk - self.serial.write(chunk) + c = self.serial.write(chunk) + if c < len(chunk): + raise RuntimeError() time.sleep(0.01) def reset(self): # Use read() since serial.reset_input_buffer() fails with termios.error now and then self.read() self.session = b"" - self.write(b"\r" + REPL.CHAR_CTRL_C + REPL.CHAR_CTRL_C) # interrupt any running program + self.write(REPL.CHAR_CTRL_C + REPL.CHAR_CTRL_C) # interrupt any running program self.write(b"\r" + REPL.CHAR_CTRL_B) # enter or reset friendly repl - data = self.read_until(b">>> ") + self.read_until(b">>> ", timeout=60) def execute(self, code, timeout=10, wait_for_response=True): self.read() # Throw away @@ -161,7 +165,10 @@ def __init__(self, dev): self._path = mount[0][1] else: name = os.path.basename(dev) - sh.pmount("-tvfat", dev, name, _timeout=10) + try: + sh.pmount("-tvfat", dev, name, _timeout=10) + except sh.CommandNotFound: + raise ValueError() self.mountpoint = "/media/" + name self._path = self.mountpoint @@ -347,7 +354,7 @@ def from_usb(cls, baudrate=115200, wait=0, timeout=10, **kwargs): return cls(dev, baudrate=baudrate, wait=wait, timeout=timeout) def __init__(self, device, baudrate=115200, wait=0, timeout=10): - self.device = device + self.device = str(pathlib.Path(device).resolve()) self.usb_dev = None try: # Is it a usb.core.Device? @@ -357,7 +364,7 @@ def __init__(self, device, baudrate=115200, wait=0, timeout=10): else: serials = [serial for serial in os.listdir("/dev/serial/by-path") if portstr in serial] if len(serials) != 1: - raise RuntimeError("Can't find excatly one matching usb serial device") + raise RuntimeError("Can't find exactly one matching usb serial device") self.device = os.path.realpath("/dev/serial/by-path/" + serials[0]) self.usb_dev = device @@ -370,6 +377,10 @@ def __init__(self, device, baudrate=115200, wait=0, timeout=10): self.bootloader = False self.repl = REPL(self) + # Disable autoreload so that file copies won't mess us up. + with self: + self.exec("import supervisor;supervisor.runtime.autoreload = False") + def __enter__(self): self.open() return self @@ -507,9 +518,12 @@ def disk(self): part = [part for part in disks if "part1" in part] if not part: - raise RuntimeError("Disk not found for: " + self.device) + return None - return Disk(part[0]) + try: + return Disk(part[0]) + except ValueError: + return None @property def firmware(self): @@ -548,18 +562,33 @@ def execfile(self, filename, timeout=10): class Pyboard: def __init__(self, device, baudrate=115200, user="micro", password="python", wait=0): self.board = CPboard.from_try_all(device, baudrate=baudrate, wait=wait) - with self.board.disk as disk: - disk.copy("skip_if.py") + disk = self.board.disk + if disk: + with disk as open_disk: + open_disk.copy("skip_if.py") def close(self): self.board.close() def enter_raw_repl(self): self.board.open() + self.board.repl.reset() + + def exit_raw_repl(self): + self.close() def execfile(self, filename): return self.board.execfile(filename) + def exec_(self, command, data_consumer=None): + try: + output, error = self.board.repl.execute(command, timeout=20000, wait_for_response=True) + except OSError as e: + raise CPboardError("timeout", e) + if error: + raise CPboardError("exception", output, error) + return output + def eval_namedtuple(board, command): from collections import namedtuple diff --git a/tools/describe b/tools/describe index e20c2ffa4427..0f3b541e3cd7 100755 --- a/tools/describe +++ b/tools/describe @@ -1,3 +1,6 @@ #!/bin/sh -# Add any supplied arguments. -git describe --first-parent --dirty --tags --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 5f4f9c95613e..e6bc703c021a 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}") diff --git a/tools/gen_crt_bundle.py b/tools/gen_crt_bundle.py index eb314bf25e81..da0d8837a952 100755 --- a/tools/gen_crt_bundle.py +++ b/tools/gen_crt_bundle.py @@ -72,7 +72,6 @@ def __init__(self): 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)) @@ -161,7 +160,6 @@ def create_bundle(self): 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=",") diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py index e5ce775e4a70..350988bab0c0 100644 --- a/tools/gen_display_resources.py +++ b/tools/gen_display_resources.py @@ -121,7 +121,7 @@ def _load_row(self, y, row): blinka_size = 16 c_file.write( """\ -uint32_t blinka_bitmap_data[32] = { +const uint32_t blinka_bitmap_data[32] = { 0x00000011, 0x11000000, 0x00000111, 0x53100000, 0x00000111, 0x56110000, @@ -145,7 +145,7 @@ def _load_row(self, y, row): blinka_size = 12 c_file.write( """\ -uint32_t blinka_bitmap_data[28] = { +const uint32_t blinka_bitmap_data[28] = { 0x00000111, 0x00000000, 0x00001153, 0x10000000, 0x00001156, 0x11000000, @@ -164,11 +164,11 @@ def _load_row(self, y, row): c_file.write( """\ -displayio_bitmap_t blinka_bitmap = {{ +const displayio_bitmap_t blinka_bitmap = {{ .base = {{.type = &displayio_bitmap_type }}, .width = {0}, .height = {0}, - .data = blinka_bitmap_data, + .data = (uint32_t*) blinka_bitmap_data, .stride = 2, .bits_per_value = 4, .x_shift = 3, @@ -180,51 +180,25 @@ def _load_row(self, y, row): _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 + {{ // Purple + .rgb888 = 0x8428bc }}, - {{ - .rgb888 = 0xff89bc, - .rgb565 = 0xFCB8, - .luma = 0xb5, - .hue = 222, - .chroma = 118 + {{ // Pink + .rgb888 = 0xff89bc }}, - {{ - .rgb888 = 0x7beffe, - .rgb565 = 0x869F, - .luma = 0xe0, - .hue = 124, - .chroma = 131 + {{ // Light blue + .rgb888 = 0x7beffe }}, - {{ - .rgb888 = 0x51395f, - .rgb565 = 0x5A0D, - .luma = 0x47, - .hue = 185, - .chroma = 38 + {{ // Dark purple + .rgb888 = 0x51395f }}, - {{ - .rgb888 = 0xffffff, - .rgb565 = 0xffff, - .luma = 0xff, - .chroma = 0 + {{ // White + .rgb888 = 0xffffff }}, - {{ - .rgb888 = 0x0736a0, - .rgb565 = 0x01f5, - .luma = 0x44, - .hue = 147, - .chroma = 153 + {{ // Dark Blue + .rgb888 = 0x0736a0 }}, }}; @@ -237,7 +211,7 @@ def _load_row(self, y, row): displayio_tilegrid_t supervisor_blinka_sprite = {{ .base = {{.type = &displayio_tilegrid_type }}, - .bitmap = &blinka_bitmap, + .bitmap = (displayio_bitmap_t*) &blinka_bitmap, .pixel_shader = &blinka_palette, .x = 0, .y = 0, @@ -270,16 +244,10 @@ def _load_row(self, y, row): #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 }, }; diff --git a/tools/gendoc.py b/tools/gendoc.py index bf79b3cf5fab..e7eb011b7c01 100644 --- a/tools/gendoc.py +++ b/tools/gendoc.py @@ -11,6 +11,7 @@ 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: @@ -522,7 +523,7 @@ def main(): description="Generate documentation for pyboard API from C files." ) cmd_parser.add_argument( - "--outdir", metavar="", default="gendoc-out", help="ouput directory" + "--outdir", metavar="", default="gendoc-out", help="output directory" ) cmd_parser.add_argument("--format", default="html", help="output format: html or rst") cmd_parser.add_argument("files", nargs="+", help="input files") diff --git a/tools/makemanifest.py b/tools/makemanifest.py index 8cdc3eb7741b..b2856889b9e3 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -164,7 +164,7 @@ def system(cmd): def convert_path(path): - # Perform variable substituion. + # Perform variable substitution. for name, value in VARS.items(): path = path.replace("$({})".format(name), value) # Convert to absolute path (so that future operations don't rely on diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 32b064d35f63..02ea656c99bd 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -107,6 +107,7 @@ def access(self, idx): 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 000000000000..1ed594b84f97 --- /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 30263d2e0238..eb835961f67e 100755 --- a/tools/preprocess_frozen_modules.py +++ b/tools/preprocess_frozen_modules.py @@ -21,10 +21,10 @@ def version_string(path=None, *, valid_semver=False): version = tag.strip().decode("utf-8", "strict") except subprocess.CalledProcessError: describe = subprocess.check_output("git describe --tags", shell=True, cwd=path) - tag, additional_commits, commitish = ( + tag, additional_commits, commit_ish = ( describe.strip().decode("utf-8", "strict").rsplit("-", maxsplit=2) ) - commitish = commitish[1:] + commit_ish = commit_ish[1:] if valid_semver: version_info = semver.parse_version_info(tag) if not version_info.prerelease: @@ -33,12 +33,12 @@ def version_string(path=None, *, valid_semver=False): + "-alpha.0.plus." + additional_commits + "+" - + commitish + + commit_ish ) else: - version = tag + ".plus." + additional_commits + "+" + commitish + version = tag + ".plus." + additional_commits + "+" + commit_ish else: - version = commitish + version = commit_ish return version @@ -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/pydfu.py b/tools/pydfu.py index ce34b08a5884..57a8708e5d17 100755 --- a/tools/pydfu.py +++ b/tools/pydfu.py @@ -483,7 +483,7 @@ def get_memory_layout(device): def list_dfu_devices(*args, **kwargs): - """Prints a lits of devices detected in DFU mode.""" + """Prints a list of devices detected in DFU mode.""" devices = get_dfu_devices(*args, **kwargs) if not devices: raise SystemExit("No DFU capable devices found") diff --git a/tools/swo_function_trace.py b/tools/swo_function_trace.py new file mode 100644 index 000000000000..bdc1b0f84017 --- /dev/null +++ b/tools/swo_function_trace.py @@ -0,0 +1,143 @@ +"""This prints out Chrome Trace Formatted json that can be viewed in Perfetto or Spall. +https://ui.perfetto.dev/ +https://gravitymoth.com/spall/spall.html + +Format: +https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview# + +Connect a USB to Serial converter to the SWO pin and then provide the serial +device to this script. It should be 1MBaud SWO signal. CTRL-C when you've captured enough data and +then it'll process and output. + +pip install pysigrok-libsigrokdecode +python tools/swo_function_trace.py /dev/ttyACM0 build-metro_m7_1011/firmware.elf > trace.json +""" + +import serial +import sys +import sigrokdecode +import time +import json + +from elftools.elf.elffile import ELFFile + +f = open(sys.argv[-1], "rb") +ef = ELFFile(f) + +symtab = ef.get_section_by_name(".symtab") +symbols = {} +for s in symtab.iter_symbols(): + addr = s.entry["st_value"] + symbols[addr] = s.name +f.close() + +# sys.exit(0) + +decoder = sigrokdecode.get_decoder("arm_itm")() + +decoder.reset() +decoder.options = {"objdump": "", "elffile": ""} +decoder.start() + +dwt_timestamp = 0 +last_dwt_timestamp = 0 +streak = 0 +print("[") + +stack = [] + + +def emit(ts, addr, channel): + s = None + if addr in symbols: + s = symbols[addr] + else: + s = hex(addr) + if addr < 0x6000_0000: + s = "R:" + s + else: + s = "F:" + s + if channel[0] == "3": + stack.append(addr) + else: + if not stack or stack[-1] != addr: + return + stack.pop() + event = { + "name": s, + "ph": "B" if channel[0] == "3" else "E", + "ts": ts, + "pid": 0, + "tid": 0, + } + print(json.dumps(event), ",") + + +def decoder_cb(ss, es, data): + global streak + global last_dwt_timestamp + # print(ss, es, data) + ptype = data[0] + ts = (dwt_timestamp + (streak * 32)) / 500 + if ptype == 0: + event = {"name": data[1][0], "ph": "i", "ts": ts, "pid": 0, "tid": 0, "s": "g"} + print(json.dumps(event), ",") + if data[1][0] == "Overflow": + while stack: + emit(ts, stack[-1], "4:") + + if ptype in (0, 1): + return + if ptype == 2 and (data[1][0].startswith("3:") or data[1][0].startswith("4:")): + channel, addr = data[1][0].split() + addr = int(addr[2:], 16) + # if addr & 0x1 != 0: + # addr -= 1 + # print(dwt_timestamp + streak, channel, symbols[addr], hex(addr)) + emit(ts, addr, channel) + else: + # print(dwt_timestamp + streak, data) + pass + if dwt_timestamp == last_dwt_timestamp: + streak += 1 + else: + streak = 0 + + if last_dwt_timestamp > dwt_timestamp: + raise RuntimeError() + last_dwt_timestamp = dwt_timestamp + + +decoder.add_callback(sigrokdecode.OUTPUT_ANN, None, decoder_cb) + +s = serial.Serial(sys.argv[-2], 1000000) + + +buffers = [] +while True: + try: + start_ts = time.monotonic_ns() + b = s.read(s.in_waiting) + if b: + end_ts = time.monotonic_ns() + buffers.append((start_ts, end_ts, b)) + # print(len(b)) + # if len(buffers) > 10: + # break + except KeyboardInterrupt: + break + +time_per_bit = 1_000_000_000 / 1000000 + +min_gap = 100000000 +total_bytes = 0 +for start_ts, end_ts, buf in buffers: + # print(total_bytes, start_ts, end_ts, buf) + ts_per_byte = (end_ts - start_ts) / len(buf) + for i, b in enumerate(buf): + # print(total_bytes, hex(b)) + total_bytes += 1 + decoder.decode( + start_ts + ts_per_byte * i, start_ts + ts_per_byte * (i + 1), ("DATA", None, (b,)) + ) + dwt_timestamp = decoder.dwt_timestamp diff --git a/tools/swo_viewer.py b/tools/swo_viewer.py new file mode 100644 index 000000000000..327c450023c8 --- /dev/null +++ b/tools/swo_viewer.py @@ -0,0 +1,67 @@ +"""This prints out all parsed ITM packets. + +Connect a USB to Serial converter to the SWO pin and then provide the serial +device to this script. It should be 1MBaud SWO signal. CTRL-C when you've +captured enough data and then it'll process and output. + +pip install pysigrok-libsigrokdecode +python tools/swo_viewer.py /dev/ttyACM0 +""" + +import serial +import sys +import sigrokdecode +import time +import json + +decoder = sigrokdecode.get_decoder("arm_itm")() + +decoder.reset() +decoder.options = {"objdump": "", "elffile": ""} +decoder.start() + +dwt_timestamp = 0 +last_dwt_timestamp = 0 +streak = 0 + +stack = [] + + +def decoder_cb(ss, es, data): + global streak + global last_dwt_timestamp + print(dwt_timestamp, ss, es, data) + + +decoder.add_callback(sigrokdecode.OUTPUT_ANN, None, decoder_cb) + +s = serial.Serial(sys.argv[-2], 1000000) + +buffers = [] +while True: + try: + start_ts = time.monotonic_ns() + b = s.read(s.in_waiting) + if b: + end_ts = time.monotonic_ns() + buffers.append((start_ts, end_ts, b)) + # print(len(b)) + # if len(buffers) > 10: + # break + except KeyboardInterrupt: + break + +time_per_bit = 1_000_000_000 / 1000000 + +min_gap = 100000000 +total_bytes = 0 +for start_ts, end_ts, buf in buffers: + # print(total_bytes, start_ts, end_ts, buf) + ts_per_byte = (end_ts - start_ts) / len(buf) + for i, b in enumerate(buf): + # print(total_bytes, hex(b)) + total_bytes += 1 + decoder.decode( + start_ts + ts_per_byte * i, start_ts + ts_per_byte * (i + 1), ("DATA", None, (b,)) + ) + dwt_timestamp = decoder.dwt_timestamp diff --git a/tools/uncrustify.cfg b/tools/uncrustify.cfg index 88127112e81b..a92530fd9316 100644 --- a/tools/uncrustify.cfg +++ b/tools/uncrustify.cfg @@ -1323,7 +1323,7 @@ indent_using_block = true # true/false # 2: When the `:` is a continuation, indent it under `?` indent_ternary_operator = 0 # unsigned number -# Whether to indent the statments inside ternary operator. +# Whether to indent the statements inside ternary operator. indent_inside_ternary_operator = false # true/false # If true, the indentation of the chunks after a `return` sequence will be set at return indentation column. @@ -1779,7 +1779,7 @@ nl_func_call_args_multi_line = false # true/false # different lines. nl_func_call_end_multi_line = false # true/false -# Whether to respect nl_func_call_XXX option incase of closure args. +# Whether to respect nl_func_call_XXX option in case of closure args. nl_func_call_args_multi_line_ignore_closures = false # true/false # Whether to add a newline after '<' of a template parameter list. @@ -2570,7 +2570,7 @@ align_oc_decl_colon = false # true/false # (OC) Whether to not align parameters in an Objectve-C message call if first # colon is not on next line of the message call (the same way Xcode does -# aligment) +# alignment) align_oc_msg_colon_xcode_like = false # true/false # @@ -2916,28 +2916,28 @@ pp_define_at_level = false # true/false pp_ignore_define_body = false # true/false # Whether to indent case statements between #if, #else, and #endif. -# Only applies to the indent of the preprocesser that the case statements +# Only applies to the indent of the preprocessor that the case statements # directly inside of. # # Default: true pp_indent_case = true # true/false # Whether to indent whole function definitions between #if, #else, and #endif. -# Only applies to the indent of the preprocesser that the function definition +# Only applies to the indent of the preprocessor that the function definition # is directly inside of. # # Default: true pp_indent_func_def = true # true/false # Whether to indent extern C blocks between #if, #else, and #endif. -# Only applies to the indent of the preprocesser that the extern block is +# Only applies to the indent of the preprocessor that the extern block is # directly inside of. # # Default: true pp_indent_extern = true # true/false # Whether to indent braces directly inside #if, #else, and #endif. -# Only applies to the indent of the preprocesser that the braces are directly +# Only applies to the indent of the preprocessor that the braces are directly # inside of. # # Default: true diff --git a/tools/usb_descriptor b/tools/usb_descriptor deleted file mode 160000 index 2eaa6114b209..000000000000 --- a/tools/usb_descriptor +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2eaa6114b209fe7f0a795eda8d6a7b3b93d76d2e diff --git a/tools/verifygitlog.py b/tools/verifygitlog.py index cc4b80f4a97a..24171f9c6820 100755 --- a/tools/verifygitlog.py +++ b/tools/verifygitlog.py @@ -101,7 +101,7 @@ def run(args): def show_help(): print("usage: verifygitlog.py [-v -n -h] ...") - print("-v : increase verbosity, can be speficied multiple times") + print("-v : increase verbosity, can be specified multiple times") print("-n : do not print multi-line suggestions") print("-h : print this help message and exit") print("... : arguments passed to git log to retrieve commits to verify")