diff --git a/.github/actions/deps/external/action.yml b/.github/actions/deps/external/action.yml index 5db7c04686..9e32e733a2 100644 --- a/.github/actions/deps/external/action.yml +++ b/.github/actions/deps/external/action.yml @@ -9,54 +9,31 @@ inputs: - cache - restore - platform: + port: required: false default: none - type: choice - options: - - arm - - aarch - - esp - - riscv - - none + type: string runs: using: composite steps: - # aarch - - name: Get aarch toolchain - if: inputs.platform == 'aarch' - run: | - wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz - sudo tar -C /usr --strip-components=1 -xaf gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz - sudo apt-get install -y mtools - shell: bash - - name: Install mkfs.fat - if: inputs.platform == 'aarch' - 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 - # arm - name: Get arm toolchain - if: inputs.platform == 'aarch' || inputs.platform == 'arm' + if: >- + inputs.port != 'none' && + inputs.port != 'litex' && + inputs.port != 'espressif' uses: carlosperate/arm-none-eabi-gcc-action@v1 with: release: '10-2020-q4' - # esp - - name: Get esp toolchain - if: inputs.platform == 'esp' + # espressif + - name: Get espressif toolchain + if: inputs.port == 'espressif' run: sudo apt-get install -y ninja-build shell: bash - name: Install IDF tools - if: inputs.platform == 'esp' + if: inputs.port == 'espressif' run: | echo "Installing ESP-IDF tools" $IDF_PATH/tools/idf_tools.py --non-interactive install required @@ -66,24 +43,16 @@ runs: rm -rf $IDF_TOOLS_PATH/dist shell: bash - name: Set environment - if: inputs.platform == 'esp' + 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 - # riscv - - name: Get riscv toolchain - if: inputs.platform == 'riscv' - 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 - # common - name: Cache python dependencies - if: inputs.platform != 'esp' + if: inputs.port != 'espressif' uses: ./.github/actions/deps/python with: action: ${{ inputs.action }} diff --git a/.github/actions/deps/ports/action.yml b/.github/actions/deps/ports/action.yml index a8c4f81a19..8125de2acc 100644 --- a/.github/actions/deps/ports/action.yml +++ b/.github/actions/deps/ports/action.yml @@ -19,10 +19,18 @@ runs: if [ -z $PORT ]; then (exit 1); else echo >> $GITHUB_OUTPUT "port=$PORT"; fi shell: bash - - name: Set up espressif port + - 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 nrf port + - name: Set up litex + if: steps.board-to-port.outputs.port == 'litex' + uses: ./.github/actions/deps/ports/litex + + - name: Set up nrf if: steps.board-to-port.outputs.port == 'nrf' uses: ./.github/actions/deps/ports/nrf diff --git a/.github/actions/deps/ports/broadcom/action.yml b/.github/actions/deps/ports/broadcom/action.yml new file mode 100644 index 0000000000..bd76c78262 --- /dev/null +++ b/.github/actions/deps/ports/broadcom/action.yml @@ -0,0 +1,21 @@ +name: Fetch broadcom port deps + +runs: + using: composite + steps: + - name: Get broadcom toolchain + run: | + wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz + sudo tar -C /usr --strip-components=1 -xaf gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz + sudo apt-get install -y mtools + shell: bash + - name: Install mkfs.fat + run: | + wget https://github.com/dosfstools/dosfstools/releases/download/v4.2/dosfstools-4.2.tar.gz + tar -xaf dosfstools-4.2.tar.gz + cd dosfstools-4.2 + ./configure + make -j 2 + cd src + echo >> $GITHUB_PATH $(pwd) + shell: bash diff --git a/.github/actions/deps/ports/litex/action.yml b/.github/actions/deps/ports/litex/action.yml new file mode 100644 index 0000000000..a89a222505 --- /dev/null +++ b/.github/actions/deps/ports/litex/action.yml @@ -0,0 +1,10 @@ +name: Fetch litex port deps + +runs: + using: composite + steps: + - name: Get litex toolchain + run: | + wget https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6.tar.gz + sudo tar -C /usr --strip-components=1 -xaf riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6.tar.gz + shell: bash diff --git a/.github/workflows/build-boards.yml b/.github/workflows/build-boards.yml index b975c131ee..85e789bf87 100644 --- a/.github/workflows/build-boards.yml +++ b/.github/workflows/build-boards.yml @@ -3,9 +3,6 @@ name: Build boards on: workflow_call: inputs: - platform: - required: true - type: string boards: required: true type: string @@ -19,7 +16,7 @@ on: required: false jobs: - build: + board: runs-on: ubuntu-22.04 env: CP_VERSION: ${{ inputs.cp-version }} @@ -38,6 +35,7 @@ jobs: with: python-version: 3.x - name: Set up port + id: set-up-port uses: ./.github/actions/deps/ports with: board: ${{ matrix.board }} @@ -47,7 +45,7 @@ jobs: - name: Set up external uses: ./.github/actions/deps/external with: - platform: ${{ inputs.platform }} + 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 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 19976f7c3d..e322004515 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,8 +9,6 @@ on: pull_request: release: types: [published] - check_suite: - types: [rerequested] concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -18,16 +16,11 @@ concurrency: jobs: scheduler: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: - build-doc: ${{ steps.set-matrix.outputs.build-doc }} - build-boards: ${{ steps.set-matrix.outputs.build-boards }} - build-windows: ${{ steps.set-matrix.outputs.build-windows }} - boards-aarch: ${{ steps.set-matrix.outputs.boards-aarch }} - boards-arm: ${{ steps.set-matrix.outputs.boards-arm }} - boards-atmel: ${{ steps.set-matrix.outputs.boards-atmel }} - boards-esp: ${{ steps.set-matrix.outputs.boards-esp }} - boards-riscv: ${{ steps.set-matrix.outputs.boards-riscv }} + 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 @@ -69,26 +62,27 @@ jobs: PULL: ${{ github.event.number }} GITHUB_TOKEN: ${{ github.token }} EXCLUDE_COMMIT: ${{ github.event.pull_request.head.sha }} - - name: Set head sha + - name: Set head sha (pull) if: github.event_name == 'pull_request' run: echo "HEAD_SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV - - name: Set base sha + - name: Set base sha (pull) if: github.event_name == 'pull_request' - run: | - git fetch --no-tags --no-recurse-submodules --depth=$((DEPTH + 1)) origin $HEAD_SHA - echo "BASE_SHA=$(git rev-list $HEAD_SHA --skip=$DEPTH --max-count=1)" >> $GITHUB_ENV + run: git cat-file -e $SHA && echo "BASE_SHA=$SHA" >> $GITHUB_ENV || true env: - DEPTH: ${{ steps.get-last-commit-with-checks.outputs.commit_depth || github.event.pull_request.commits }} - - name: Get changes - id: get-changes - if: github.event_name == 'pull_request' - run: echo $(git diff $BASE_SHA...$HEAD_SHA --name-only) | echo "changed_files=[\"$(sed "s/ /\", \"/g")\"]" >> $GITHUB_OUTPUT + 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 - working-directory: tools run: python3 -u ci_set_matrix.py + working-directory: tools env: - CHANGED_FILES: ${{ steps.get-changes.outputs.changed_files }} LAST_FAILED_JOBS: ${{ steps.get-last-commit-with-checks.outputs.check_runs }} tests: @@ -99,7 +93,7 @@ jobs: mpy-cross: needs: scheduler - if: needs.scheduler.outputs.build-boards == 'True' + if: needs.scheduler.outputs.ports != '{}' uses: ./.github/workflows/build-mpy-cross.yml secrets: inherit with: @@ -108,7 +102,7 @@ jobs: mpy-cross-mac: runs-on: macos-11 needs: scheduler - if: needs.scheduler.outputs.build-boards == 'True' + if: needs.scheduler.outputs.ports != '{}' env: CP_VERSION: ${{ needs.scheduler.outputs.cp-version }} steps: @@ -160,10 +154,10 @@ jobs: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - build-doc: + docs: runs-on: ubuntu-22.04 needs: scheduler - if: needs.scheduler.outputs.build-doc == 'True' + if: needs.scheduler.outputs.docs == 'True' env: CP_VERSION: ${{ needs.scheduler.outputs.cp-version }} steps: @@ -218,10 +212,10 @@ jobs: [ -z "$TWINE_USERNAME" ] || echo "Uploading dev release to PyPi" [ -z "$TWINE_USERNAME" ] || twine upload circuitpython-stubs/dist/* - build-windows: + windows: runs-on: windows-2022 needs: scheduler - if: needs.scheduler.outputs.build-windows == 'True' + if: needs.scheduler.outputs.windows == 'True' env: CP_VERSION: ${{ needs.scheduler.outputs.cp-version }} defaults: @@ -286,52 +280,15 @@ jobs: # ERROR: Platform MINGW64_NT-10.0-17763-x86_64 appears to be unsupported # https://github.com/espressif/esp-idf/issues/7062 - aarch: + ports: needs: [scheduler, mpy-cross, tests] - if: ${{ needs.scheduler.outputs.boards-aarch != '[]' }} + if: needs.scheduler.outputs.ports != '{}' uses: ./.github/workflows/build-boards.yml secrets: inherit + strategy: + fail-fast: false + matrix: + port: ${{ fromJSON(needs.scheduler.outputs.ports).ports }} with: - platform: aarch - boards: ${{ needs.scheduler.outputs.boards-aarch }} - cp-version: ${{ needs.scheduler.outputs.cp-version }} - - arm: - needs: [scheduler, mpy-cross, tests] - if: ${{ needs.scheduler.outputs.boards-arm != '[]' }} - uses: ./.github/workflows/build-boards.yml - secrets: inherit - with: - platform: arm - boards: ${{ needs.scheduler.outputs.boards-arm }} - cp-version: ${{ needs.scheduler.outputs.cp-version }} - - atmel: - needs: [scheduler, mpy-cross, tests] - if: ${{ needs.scheduler.outputs.boards-atmel != '[]' }} - uses: ./.github/workflows/build-boards.yml - secrets: inherit - with: - platform: arm - boards: ${{ needs.scheduler.outputs.boards-atmel }} - cp-version: ${{ needs.scheduler.outputs.cp-version }} - - esp: - needs: [scheduler, mpy-cross, tests] - if: ${{ needs.scheduler.outputs.boards-esp != '[]' }} - uses: ./.github/workflows/build-boards.yml - secrets: inherit - with: - platform: esp - boards: ${{ needs.scheduler.outputs.boards-esp }} - cp-version: ${{ needs.scheduler.outputs.cp-version }} - - riscv: - needs: [scheduler, mpy-cross, tests] - if: ${{ needs.scheduler.outputs.boards-riscv != '[]' }} - uses: ./.github/workflows/build-boards.yml - secrets: inherit - with: - platform: riscv - boards: ${{ needs.scheduler.outputs.boards-riscv }} + 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 96% rename from .github/workflows/create_website_pr.yml rename to .github/workflows/create-website-pr.yml index eeae8c8299..7f047d4b1e 100644 --- a/.github/workflows/create_website_pr.yml +++ b/.github/workflows/create-website-pr.yml @@ -6,7 +6,7 @@ name: Update CircuitPython.org on: release: - types: [published, rerequested] + types: [published] jobs: website: diff --git a/.github/workflows/build-boards-custom.yml b/.github/workflows/custom-board-build.yml similarity index 89% rename from .github/workflows/build-boards-custom.yml rename to .github/workflows/custom-board-build.yml index df8197d9ae..aa8044b0d2 100644 --- a/.github/workflows/build-boards-custom.yml +++ b/.github/workflows/custom-board-build.yml @@ -32,16 +32,6 @@ run-name: ${{ inputs.board }}-${{ inputs.language }}-${{ inputs.version }}${{ in jobs: build: runs-on: ubuntu-22.04 - env: - PLATFORM_atmel-samd: arm - PLATFORM_broadcom: aarch - PLATFORM_cxd56: arm - PLATFORM_espressif: esp - PLATFORM_litex: riscv - PLATFORM_mimxrt10xx: arm - PLATFORM_nrf: arm - PLATFORM_raspberrypi: arm - PLATFORM_stm: arm steps: - name: Set up repository run: | @@ -70,7 +60,7 @@ jobs: uses: ./.github/actions/deps/external with: action: cache - platform: ${{ env[format('PLATFORM_{0}', steps.set-up-port.outputs.port)] }} + 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 diff --git a/.github/workflows/notify.yml b/.github/workflows/notify-on-issue-label.yml similarity index 100% rename from .github/workflows/notify.yml rename to .github/workflows/notify-on-issue-label.yml diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index c0dff33564..2a3fcf9439 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 }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 12e8d2ef74..44146662f2 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -9,7 +9,7 @@ on: jobs: run: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: @@ -31,7 +31,7 @@ jobs: - name: Set up python uses: actions/setup-python@v4 with: - python-version: 3.x + python-version: 3.8 - name: Set up submodules uses: ./.github/actions/deps/submodules with: diff --git a/.gitmodules b/.gitmodules index 3de3c6a51e..2ba84b4305 100644 --- a/.gitmodules +++ b/.gitmodules @@ -309,8 +309,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 diff --git a/.readthedocs.yml b/.readthedocs.yml index 29a915766f..8f1b89cb67 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -14,7 +14,7 @@ build: python: "3" jobs: post_install: - - python tools/ci_fetch_deps.py build-doc + - python tools/ci_fetch_deps.py docs formats: - pdf diff --git a/BUILDING.md b/BUILDING.md index 4793824cf1..f108675b7c 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/lib/tinyusb b/lib/tinyusb index 73896a3b71..ea8ecea59a 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 73896a3b71c525a3ee4cefa7e35ce3b3a93786ef +Subproject commit ea8ecea59aa60a1028cce16b0f15bb33918b11af diff --git a/locale/ID.po b/locale/ID.po index 120333a7a2..f6960665b4 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -147,7 +147,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 "" @@ -245,7 +245,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" @@ -513,6 +513,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 @@ -686,7 +687,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 "" @@ -823,6 +824,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" @@ -1074,7 +1083,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 "" @@ -1259,8 +1268,7 @@ msgstr "" 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" @@ -1286,7 +1294,7 @@ msgstr "Ukuran potongan format tidak valid" 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 "" @@ -1295,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 "" @@ -1327,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 "" @@ -1688,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" @@ -1700,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" @@ -1883,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 "" @@ -1903,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 "" @@ -2358,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 "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 5e1dd8e193..560dffe6a4 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -144,7 +144,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 "" @@ -242,7 +242,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 "" @@ -510,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 @@ -681,7 +682,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 "" @@ -813,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 "" @@ -1064,7 +1073,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 "" @@ -1247,8 +1256,7 @@ msgstr "" 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 "" @@ -1274,7 +1282,7 @@ msgstr "" 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 "" @@ -1283,7 +1291,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 "" @@ -1315,7 +1323,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 "" @@ -1671,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 "" @@ -1683,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,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 "" @@ -1879,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 "" @@ -2330,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 "" diff --git a/locale/cs.po b/locale/cs.po index 0fa986c7c3..0ffdbdcc67 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -148,7 +148,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 "" @@ -246,7 +246,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" @@ -514,6 +514,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 @@ -687,7 +688,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 "" @@ -821,6 +822,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" @@ -1074,7 +1083,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" @@ -1259,8 +1268,7 @@ msgstr "Chybné BSSID" 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" @@ -1286,7 +1294,7 @@ msgstr "Neplatná velikost bloku" 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" @@ -1295,7 +1303,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" @@ -1327,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 "MAC adresa byla chybná" @@ -1684,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 "" @@ -1696,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 "" @@ -1874,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 "" @@ -1894,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 "" @@ -2345,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 "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 7060946cf8..9f2c83e8cc 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -155,7 +155,7 @@ 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" @@ -255,7 +255,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" @@ -523,6 +523,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 @@ -696,7 +697,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" @@ -835,6 +836,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 "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Beschädigte .mpy Datei" @@ -1093,7 +1102,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" @@ -1282,8 +1291,7 @@ msgstr "Ungültige BSSID" 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" @@ -1309,7 +1317,7 @@ msgstr "Ungültige format chunk size" 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" @@ -1318,7 +1326,7 @@ 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" @@ -1350,7 +1358,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" @@ -1713,11 +1721,11 @@ 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" @@ -1725,7 +1733,7 @@ msgstr "Zeit für Vorgang abgelaufen" 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 "Kein Speicher mehr verfügbar" @@ -1907,7 +1915,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" @@ -1927,7 +1935,7 @@ msgstr "RemoteTransmissionRequests limitiert auf 8 Bytes" msgid "Requested AES mode is unsupported" msgstr "Der angeforderte AES-Modus wird nicht unterstützt" -#: ports/espressif/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" @@ -2388,7 +2396,7 @@ msgstr "Wert Länge != Erforderliche feste Länge" msgid "Value length > max_length" msgstr "Länge des Wertes > max_length" -#: ports/espressif/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" diff --git a/locale/el.po b/locale/el.po index 24783d0351..81118aa8fd 100644 --- a/locale/el.po +++ b/locale/el.po @@ -152,7 +152,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 "" @@ -250,7 +250,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" @@ -519,6 +519,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 @@ -692,7 +693,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 ήταν άκυρο" @@ -834,6 +835,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 αρχείο" @@ -1085,7 +1094,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 "" @@ -1268,8 +1277,7 @@ msgstr "" 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 "" @@ -1295,7 +1303,7 @@ msgstr "" 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 "" @@ -1304,7 +1312,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 "" @@ -1336,7 +1344,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 "" @@ -1692,11 +1700,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 "" @@ -1704,7 +1712,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 "" @@ -1882,7 +1890,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 "" @@ -1902,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 "" @@ -2353,7 +2361,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 "" diff --git a/locale/en_GB.po b/locale/en_GB.po index 3b6e00e32d..9ced3137b9 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -151,7 +151,7 @@ msgstr "%q index out of range" 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 "" @@ -249,7 +249,7 @@ msgstr "%q, %q, and %q must all be the same length" 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 error 0x%x" @@ -517,6 +517,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 @@ -690,7 +691,7 @@ msgstr "CBC blocks must be multiples of 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 or checksum was invalid" @@ -824,6 +825,14 @@ msgstr "" "Connection has been disconnected and can no longer be used. Create a new " "connection." +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "Corrupt .mpy file" @@ -1075,7 +1084,7 @@ msgstr "Function requires 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 "Generic Failure" @@ -1260,8 +1269,7 @@ msgstr "Invalid BSSID" 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 "Invalid argument" @@ -1287,7 +1295,7 @@ msgstr "Invalid format chunk size" 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 "Invalid size" @@ -1296,7 +1304,7 @@ 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" @@ -1328,7 +1336,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 address was invalid" @@ -1688,11 +1696,11 @@ msgstr "Only one colour can be transparent at a time" 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 "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" @@ -1700,7 +1708,7 @@ msgstr "Operation timed out" 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 "Out of memory" @@ -1880,7 +1888,7 @@ 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" @@ -1900,7 +1908,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" @@ -2353,7 +2361,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" diff --git a/locale/es.po b/locale/es.po index 24a842500e..ee2af9d603 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: 2023-02-24 23:20+0000\n" -"Last-Translator: Luis Ruiz San Segundo \n" +"PO-Revision-Date: 2023-03-09 10:38+0000\n" +"Last-Translator: Jose David M \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.16-dev\n" +"X-Generator: Weblate 4.16.2-dev\n" #: main.c msgid "" @@ -163,7 +163,7 @@ msgstr "%q índice fuera de rango" 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" @@ -261,7 +261,7 @@ msgstr "%q, %q, y %q deben tener la misma longitud" 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" @@ -531,6 +531,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 @@ -706,7 +707,7 @@ msgstr "Los bloques CBC deben ser múltiplos de 16 bytes" msgid "CIRCUITPY drive could not be found or created." 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" @@ -846,6 +847,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" @@ -1104,7 +1113,7 @@ msgstr "La función requiere lock" msgid "GNSS init" 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" @@ -1297,8 +1306,7 @@ msgstr "BSSID inválido" msgid "Invalid MAC address" 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" @@ -1324,7 +1332,7 @@ msgstr "Formato de fragmento de formato no válido" msgid "Invalid multicast MAC address" 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" @@ -1333,7 +1341,7 @@ 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" @@ -1365,7 +1373,7 @@ msgstr "El Layer ya esta en un grupo" msgid "Layer must be a Group or TileGrid subclass" 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" @@ -1731,11 +1739,11 @@ msgstr "Solo un color puede ser transparente a la vez" msgid "Operation not permitted" 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" @@ -1743,7 +1751,7 @@ msgstr "Tiempo de espera agotado" msgid "Out of MDNS service slots" msgstr "No hay slots MDNS de servicio" -#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c +#: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" msgstr "Memoria agotada" @@ -1927,7 +1935,7 @@ 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" @@ -1947,7 +1955,7 @@ msgstr "RemoteTransmissionRequests limitado a 8 bytes" msgid "Requested AES mode is unsupported" msgstr "El modo AES solicitado no es compatible" -#: ports/espressif/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" @@ -2408,7 +2416,7 @@ msgstr "Tamaño del valor != del tamaño fijo requerido" msgid "Value length > max_length" msgstr "Tamaño de valor > max_length" -#: ports/espressif/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" diff --git a/locale/fil.po b/locale/fil.po index a05897f4fe..f943746a34 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -145,7 +145,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 "" @@ -244,7 +244,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 "" @@ -513,6 +513,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 @@ -687,7 +688,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 "" @@ -820,6 +821,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 "" @@ -1074,7 +1083,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 "" @@ -1259,8 +1268,7 @@ msgstr "" 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" @@ -1286,7 +1294,7 @@ msgstr "Mali ang format ng chunk size" 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 "" @@ -1295,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 "" @@ -1327,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 "" @@ -1686,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 "" @@ -1698,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,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 "" @@ -1895,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 "" @@ -2348,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 "" diff --git a/locale/fr.po b/locale/fr.po index 728cb901bf..424e16a1b5 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -160,7 +160,7 @@ 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 "" @@ -258,7 +258,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" @@ -526,6 +526,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 @@ -701,7 +702,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" @@ -847,6 +848,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" @@ -1107,7 +1116,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" @@ -1303,8 +1312,7 @@ msgstr "BSSID invalide" 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" @@ -1330,7 +1338,7 @@ msgstr "Taille de bloc de formatage invalide" 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,7 +1347,7 @@ 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" @@ -1371,7 +1379,7 @@ msgstr "Ce calque est déjà dans un groupe" msgid "Layer must be a Group or TileGrid subclass" msgstr "Le calque doit être une sous-classe de Group ou TileGrid" -#: ports/espressif/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" @@ -1737,11 +1745,11 @@ 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" @@ -1749,7 +1757,7 @@ msgstr "Timeout de l'opération" msgid "Out of MDNS service slots" 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" @@ -1934,7 +1942,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" @@ -1954,7 +1962,7 @@ msgstr "RemoteTransmissionRequests limité à 8 octets" msgid "Requested AES mode is unsupported" msgstr "Le mode AES demandé n'est pas supporté" -#: ports/espressif/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" @@ -2415,7 +2423,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" diff --git a/locale/hi.po b/locale/hi.po index 6f42103bc4..94a42e19f8 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -144,7 +144,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 "" @@ -242,7 +242,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 "" @@ -510,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 @@ -681,7 +682,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 "" @@ -813,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 "" @@ -1064,7 +1073,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 "" @@ -1247,8 +1256,7 @@ msgstr "" 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 "" @@ -1274,7 +1282,7 @@ msgstr "" 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 "" @@ -1283,7 +1291,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 "" @@ -1315,7 +1323,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 "" @@ -1671,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 "" @@ -1683,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,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 "" @@ -1879,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 "" @@ -2330,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 "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 52c8f1f6e4..5fb7e50d6b 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -148,7 +148,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 "" @@ -246,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 "%s errore 0x%x" @@ -516,6 +516,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 @@ -690,7 +691,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" @@ -823,6 +824,14 @@ msgid "" "connection." msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "" @@ -1076,7 +1085,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 "" @@ -1261,8 +1270,7 @@ msgstr "" 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" @@ -1288,7 +1296,7 @@ msgstr "" 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 +1305,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 +1337,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 "" @@ -1690,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 "" @@ -1702,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 "" @@ -1882,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 "" @@ -1902,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 "" @@ -2355,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 "" diff --git a/locale/ja.po b/locale/ja.po index 8bc8d0f49e..7e63cb55c3 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -151,7 +151,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" @@ -249,7 +249,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 "" @@ -517,6 +517,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 @@ -690,7 +691,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 "" @@ -824,6 +825,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 ファイル" @@ -1075,7 +1084,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 "" @@ -1260,8 +1269,7 @@ msgstr "不正なBSSID" 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 "不正な引数" @@ -1287,7 +1295,7 @@ msgstr "フォーマットチャンクのサイズが不正" 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 +1304,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 +1336,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 "" @@ -1686,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 "" @@ -1698,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,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 "" @@ -1895,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 "" @@ -2347,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 "" diff --git a/locale/ko.po b/locale/ko.po index 01624c24f7..129c9b4bcd 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -145,7 +145,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 "" @@ -243,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 "" @@ -511,6 +511,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 @@ -684,7 +685,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 "" @@ -816,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 "" @@ -1067,7 +1076,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 "" @@ -1250,8 +1259,7 @@ msgstr "" 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 "" @@ -1277,7 +1285,7 @@ msgstr "형식 청크 크기가 잘못되었습니다" 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 "" @@ -1286,7 +1294,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 "" @@ -1318,7 +1326,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 "" @@ -1674,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 "" @@ -1686,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,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 "" @@ -1882,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 "" @@ -2334,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 "" diff --git a/locale/nl.po b/locale/nl.po index 30b8c80352..87fdb61c60 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -144,7 +144,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 "" @@ -242,7 +242,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 "" @@ -510,6 +510,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 @@ -683,7 +684,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 "" @@ -818,6 +819,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" @@ -1070,7 +1079,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 "" @@ -1255,8 +1264,7 @@ msgstr "Ongeldig BSSID" 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" @@ -1282,7 +1290,7 @@ msgstr "Ongeldig formaat stuk grootte" 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 "" @@ -1291,7 +1299,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 "" @@ -1323,7 +1331,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 "" @@ -1685,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 "" @@ -1697,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 "" @@ -1880,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 "" @@ -1900,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 "" @@ -2353,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 "" diff --git a/locale/pl.po b/locale/pl.po index f2fed6df1c..1348c0f321 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -146,7 +146,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 "" @@ -244,7 +244,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 "" @@ -512,6 +512,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 @@ -685,7 +686,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 "" @@ -819,6 +820,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" @@ -1070,7 +1079,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 "" @@ -1255,8 +1264,7 @@ msgstr "" 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" @@ -1282,7 +1290,7 @@ msgstr "Zła wielkość fragmentu formatu" 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" @@ -1291,7 +1299,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" @@ -1323,7 +1331,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 "" @@ -1679,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 "" @@ -1691,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" @@ -1867,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" @@ -1887,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" @@ -2338,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 "" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index fb13d6c08b..fdf2eaaf31 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-02-26 06:37+0000\n" +"PO-Revision-Date: 2023-03-08 07:10+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.16-dev\n" +"X-Generator: Weblate 4.16.2-dev\n" #: main.c msgid "" @@ -161,7 +161,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" @@ -259,7 +259,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" @@ -531,6 +531,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 @@ -706,7 +707,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" @@ -845,6 +846,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" @@ -1100,7 +1109,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" @@ -1293,8 +1302,7 @@ msgstr "BSSID Inválido" 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" @@ -1320,7 +1328,7 @@ msgstr "Tamanho do pedaço de formato inválido" 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" @@ -1329,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" @@ -1361,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" @@ -1724,11 +1732,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" @@ -1736,7 +1744,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" @@ -1922,7 +1930,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" @@ -1942,7 +1950,7 @@ msgstr "As requisições de transmissões remotas é limitada a 8 bytes" msgid "Requested AES mode is unsupported" msgstr "O modo AES solicitado não é compatível" -#: ports/espressif/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" @@ -2402,7 +2410,7 @@ msgstr "Comprimento do valor != comprimento fixo necessário" msgid "Value length > max_length" msgstr "O comprimento do valor é > max_length" -#: ports/espressif/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" diff --git a/locale/ru.po b/locale/ru.po index c1d2e9d4de..0fe6cfac97 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -151,7 +151,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" @@ -249,7 +249,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" @@ -517,6 +517,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 @@ -694,7 +695,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 или контрольная сумма неправильная" @@ -838,6 +839,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 поврежден" @@ -1101,7 +1110,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 "Общий сбой" @@ -1292,8 +1301,7 @@ msgstr "Неверный BSSID" 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 "Недопустимый аргумент" @@ -1319,7 +1327,7 @@ msgstr "Неверный размер блока формата" 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 "Неверный размер" @@ -1328,7 +1336,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 "Неверное состояние" @@ -1362,7 +1370,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 адрес был недействительным" @@ -1727,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 "" @@ -1739,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 "" @@ -1920,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 "" @@ -1940,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 "" @@ -2393,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 "" diff --git a/locale/sv.po b/locale/sv.po index e7cafc4ddd..84ce4b6ecb 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-02-26 06:37+0000\n" +"PO-Revision-Date: 2023-03-08 07:10+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" "Language: sv\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.16-dev\n" +"X-Generator: Weblate 4.16.2-dev\n" #: main.c msgid "" @@ -160,7 +160,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" @@ -260,7 +260,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" @@ -528,6 +528,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 @@ -701,7 +702,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" @@ -837,6 +838,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" @@ -1091,7 +1100,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" @@ -1278,8 +1287,7 @@ msgstr "Ogiltig BSSID" 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" @@ -1305,7 +1313,7 @@ msgstr "Ogiltig formatsegmentstorlek" 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" @@ -1314,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" @@ -1346,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" @@ -1708,11 +1716,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" @@ -1720,7 +1728,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" @@ -1903,7 +1911,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" @@ -1923,7 +1931,7 @@ msgstr "RemoteTransmissionRequests begränsad till 8 byte" msgid "Requested AES mode is unsupported" msgstr "Det begärda AES-läget stöds inte" -#: ports/espressif/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" @@ -2378,7 +2386,7 @@ msgstr "Värdets längde ! = krävd fast längd" msgid "Value length > max_length" msgstr "Värdets längd > max_length" -#: ports/espressif/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" diff --git a/locale/tr.po b/locale/tr.po index 883715ee96..67a73375ea 100644 --- a/locale/tr.po +++ b/locale/tr.po @@ -152,7 +152,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" @@ -250,7 +250,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" @@ -519,6 +519,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 @@ -692,7 +693,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" @@ -825,6 +826,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ı" @@ -1080,7 +1089,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 "" @@ -1265,8 +1274,7 @@ msgstr "Geçersiz BSSID" 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" @@ -1293,7 +1301,7 @@ msgstr "Geçersiz biçim yığın boyutu" 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" @@ -1302,7 +1310,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" @@ -1334,7 +1342,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" @@ -1690,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 "" @@ -1702,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 "" @@ -1881,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 "" @@ -1901,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 "" @@ -2352,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 "" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index eebc16bc6c..485c30353d 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -163,7 +163,7 @@ 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" @@ -262,7 +262,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" @@ -530,6 +530,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 @@ -703,7 +704,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" @@ -838,6 +839,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 "" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "" + #: py/persistentcode.c msgid "Corrupt .mpy file" msgstr "sǔnhuài de .mpy wénjiàn" @@ -1095,7 +1104,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" @@ -1285,8 +1294,7 @@ msgstr "Wúxiào de BSSID" 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ù" @@ -1312,7 +1320,7 @@ msgstr "Géshì kuài dàxiǎo wúxiào" 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" @@ -1321,7 +1329,7 @@ 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" @@ -1353,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" @@ -1715,11 +1723,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í" @@ -1727,7 +1735,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ú" @@ -1908,7 +1916,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 +1936,7 @@ msgstr "RemoteTransmissionRequests xiànzhì wèi 8 gè zì jié" msgid "Requested AES mode is unsupported" msgstr "Qǐngqiú de AES móshì bù shòu zhīchí" -#: ports/espressif/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" @@ -2383,7 +2391,7 @@ msgstr "Zhí chángdù != Suǒ xū de gùdìng chángdù" msgid "Value length > max_length" msgstr "Zhí chángdù > zuìdà chángdù" -#: ports/espressif/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" diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 68beeaf129..0ac326d3cc 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -367,7 +367,7 @@ $(BUILD)/firmware.elf: $(OBJ) $(GENERATED_LD_FILE) $(STEPECHO) "LINK $@" $(Q)echo $(OBJ) > $(BUILD)/firmware.objs $(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--start-group $(LIBS) -Wl,--end-group - $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(GENERATED_LD_FILE) + $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(GENERATED_LD_FILE) $(BUILD) $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(STEPECHO) "Create $@" diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 720f487bb1..02776928ca 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -271,10 +271,17 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self, size_t bytes_remaining = len; // Maximum DMA transfer is 65535 - while (bytes_remaining > 0) { + 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; diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index 1c79691b33..2151c8e03c 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,8 +251,6 @@ ifneq ($(CIRCUITPY_BLEIO),0) SRC_C += common-hal/_bleio/ble_events.c endif -SRC_C += $(wildcard common-hal/espidf/*.c) - ifneq ($(CIRCUITPY_ESPCAMERA),0) SRC_CAMERA := \ $(wildcard common-hal/espcamera/*.c) \ @@ -259,6 +260,20 @@ 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) \ @@ -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/bindings/espnow/ESPNow.c b/ports/espressif/bindings/espnow/ESPNow.c new file mode 100644 index 0000000000..513966e1e8 --- /dev/null +++ b/ports/espressif/bindings/espnow/ESPNow.c @@ -0,0 +1,369 @@ +/* + * 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: Optional[int], phy_rate: Optional[int]) -> 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.""" +//| ... +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 (self != NULL) { + 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.""" +//| +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 0000000000..6aa011c501 --- /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 0000000000..f8bc8e8418 --- /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 0000000000..87fc51ee92 --- /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 0000000000..7b6cc5f668 --- /dev/null +++ b/ports/espressif/bindings/espnow/Peer.c @@ -0,0 +1,240 @@ +/* + * 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" + +// TODO: check peer already exist +// TODO: check peer dosen't exist + +//| 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, +//| encrypt: 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 encrypt: 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_encrypt }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_mac, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_lmk, MP_ARG_OBJ, { .u_obj = mp_const_none } }, + { MP_QSTR_channel, MP_ARG_INT, { .u_obj = mp_const_none } }, + { MP_QSTR_interface,MP_ARG_INT, { .u_obj = mp_const_none } }, + { MP_QSTR_encrypt, MP_ARG_BOOL,{ .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); + + 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); + + const mp_obj_t channel = args[ARG_channel].u_obj; + if (channel != mp_const_none) { + self->peer_info.channel = mp_arg_validate_int_range(mp_obj_get_int(channel), 0, 14, MP_QSTR_channel); + } + + const mp_obj_t interface = args[ARG_interface].u_obj; + if (interface != mp_const_none) { + self->peer_info.ifidx = (wifi_interface_t)mp_arg_validate_int_range(mp_obj_get_int(interface), 0, 1, MP_QSTR_interface); + } + + const mp_obj_t encrypt = args[ARG_encrypt].u_obj; + if (encrypt != mp_const_none) { + self->peer_info.encrypt = mp_obj_is_true(encrypt); + } + + 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 0000000000..e4cb828472 --- /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 0000000000..15d07c09d0 --- /dev/null +++ b/ports/espressif/bindings/espnow/Peers.c @@ -0,0 +1,140 @@ +/* + * 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" + +// TODO: Check for deinit + +//| 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 0000000000..e871ae86c0 --- /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 0000000000..da15be49ea --- /dev/null +++ b/ports/espressif/bindings/espnow/__init__.c @@ -0,0 +1,95 @@ +/* + * 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 +//| (`API docs `_). +//| +//| **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 0000000000..fb814a434f --- /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/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk index a8d02f082c..6d78999532 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_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk index 3fdb028f5e..d027443f56 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk @@ -9,3 +9,5 @@ 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_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk index 858d0b1859..d801afd493 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_ESPCAMERA = 0 diff --git a/ports/espressif/boards/brainboardz_neuron/mpconfigboard.h b/ports/espressif/boards/brainboardz_neuron/mpconfigboard.h index 9507917ead..72cda83c9b 100755 --- a/ports/espressif/boards/brainboardz_neuron/mpconfigboard.h +++ b/ports/espressif/boards/brainboardz_neuron/mpconfigboard.h @@ -31,3 +31,10 @@ #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/pins.c b/ports/espressif/boards/brainboardz_neuron/pins.c index b0cbb91563..5c198c20a7 100755 --- a/ports/espressif/boards/brainboardz_neuron/pins.c +++ b/ports/espressif/boards/brainboardz_neuron/pins.c @@ -25,13 +25,13 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, - { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, - { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_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) }, @@ -64,5 +64,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { 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/doit_esp32_devkit_v1/pins.c b/ports/espressif/boards/doit_esp32_devkit_v1/pins.c index 78c37897ac..8381fa0644 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/lolin_s3/mpconfigboard.mk b/ports/espressif/boards/lolin_s3/mpconfigboard.mk index c81e3e6fb9..56b42a419c 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_ESPCAMERA = 0 diff --git a/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h index 6a10db6061..bb8b00f327 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/common-hal/_bleio/CharacteristicBuffer.c b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c index 96de70bf84..cfc6018708 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) { diff --git a/ports/espressif/common-hal/_bleio/Connection.c b/ports/espressif/common-hal/_bleio/Connection.c index 63c85099e6..75def8ad76 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" diff --git a/ports/espressif/common-hal/_bleio/PacketBuffer.c b/ports/espressif/common-hal/_bleio/PacketBuffer.c index 3b3e51df61..d1d8c24123 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/busio/SPI.c b/ports/espressif/common-hal/busio/SPI.c index 0b894fa215..da9170a5b0 100644 --- a/ports/espressif/common-hal/busio/SPI.c +++ b/ports/espressif/common-hal/busio/SPI.c @@ -33,6 +33,7 @@ #include "driver/spi_common_internal.h" #define SPI_MAX_DMA_BITS (SPI_MAX_DMA_LEN * 8) +#define MAX_SPI_TRANSACTIONS 10 static bool spi_never_reset[SOC_SPI_PERIPH_NUM]; static spi_device_handle_t spi_handle[SOC_SPI_PERIPH_NUM]; @@ -59,7 +60,7 @@ static void set_spi_config(busio_spi_obj_t *self, .clock_speed_hz = baudrate, .mode = phase | (polarity << 1), .spics_io_num = -1, // No CS pin - .queue_size = 1, + .queue_size = MAX_SPI_TRANSACTIONS, .pre_cb = NULL }; esp_err_t result = spi_bus_add_device(self->host_id, &device_config, &spi_handle[self->host_id]); @@ -213,47 +214,61 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, mp_raise_ValueError(translate("No MISO Pin")); } - spi_transaction_t transaction = { 0 }; + spi_transaction_t transactions[MAX_SPI_TRANSACTIONS]; // Round to nearest whole set of bits int bits_to_send = len * 8 / self->bits * self->bits; if (len <= 4) { + memset(&transactions[0], 0, sizeof(spi_transaction_t)); if (data_out != NULL) { - memcpy(&transaction.tx_data, data_out, len); + memcpy(&transactions[0].tx_data, data_out, len); } - transaction.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA; - transaction.length = bits_to_send; - spi_device_transmit(spi_handle[self->host_id], &transaction); + transactions[0].flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA; + transactions[0].length = bits_to_send; + spi_device_transmit(spi_handle[self->host_id], &transactions[0]); if (data_in != NULL) { - memcpy(data_in, &transaction.rx_data, len); + memcpy(data_in, &transactions[0].rx_data, len); } } else { int offset = 0; int bits_remaining = bits_to_send; + int cur_trans = 0; while (bits_remaining && !mp_hal_is_interrupted()) { - memset(&transaction, 0, sizeof(transaction)); - transaction.length = - bits_remaining > SPI_MAX_DMA_BITS ? SPI_MAX_DMA_BITS : bits_remaining; + cur_trans = 0; + while (bits_remaining && (cur_trans != MAX_SPI_TRANSACTIONS)) { + memset(&transactions[cur_trans], 0, sizeof(spi_transaction_t)); - if (data_out != NULL) { - transaction.tx_buffer = data_out + offset; - } - if (data_in != NULL) { - transaction.rx_buffer = data_in + offset; + transactions[cur_trans].length = + bits_remaining > SPI_MAX_DMA_BITS ? SPI_MAX_DMA_BITS : bits_remaining; + + if (data_out != NULL) { + transactions[cur_trans].tx_buffer = data_out + offset; + } + if (data_in != NULL) { + transactions[cur_trans].rx_buffer = data_in + offset; + } + + bits_remaining -= transactions[cur_trans].length; + + // doesn't need ceil(); loop ends when bits_remaining is 0 + offset += transactions[cur_trans].length / 8; + cur_trans++; } - spi_device_transmit(spi_handle[self->host_id], &transaction); - bits_remaining -= transaction.length; + for (int i = 0; i < cur_trans; i++) { + spi_device_queue_trans(spi_handle[self->host_id], &transactions[i], portMAX_DELAY); + } - // doesn't need ceil(); loop ends when bits_remaining is 0 - offset += transaction.length / 8; - - RUN_BACKGROUND_TASKS; + spi_transaction_t *rtrans; + for (int x = 0; x < cur_trans; x++) { + RUN_BACKGROUND_TASKS; + spi_device_get_trans_result(spi_handle[self->host_id], &rtrans, portMAX_DELAY); + } } } return true; diff --git a/ports/espressif/common-hal/espcamera/Camera.c b/ports/espressif/common-hal/espcamera/Camera.c index e3e5ef49f9..574b4e846b 100644 --- a/ports/espressif/common-hal/espcamera/Camera.c +++ b/ports/espressif/common-hal/espcamera/Camera.c @@ -79,8 +79,7 @@ void common_hal_espcamera_camera_construct( if (common_hal_espidf_get_reserved_psram() == 0) { mp_raise_msg(&mp_type_MemoryError, translate( - "espcamera.Camera requires reserved PSRAM to be configured. " - "See the documentation for instructions.")); + "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]); diff --git a/ports/espressif/common-hal/espidf/__init__.c b/ports/espressif/common-hal/espidf/__init__.c index 183ebb3817..d2d00ebc56 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 0000000000..a048c7f9f1 --- /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 0000000000..6240788603 --- /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 0000000000..effc752f79 --- /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 0000000000..bb1950d98c --- /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/esp_error.c b/ports/espressif/esp_error.c deleted file mode 100644 index 4bc44674b7..0000000000 --- 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/mpconfigport.h b/ports/espressif/mpconfigport.h index c296be2024..e4733356bb 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 79515619ea..4637d971a4 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -82,6 +82,7 @@ CIRCUITPY_DUALBANK = 0 endif # Modules dependent on other modules +CIRCUITPY_ESPNOW ?= $(CIRCUITPY_WIFI) CIRCUITPY_GIFIO ?= $(CIRCUITPY_ESPCAMERA) CIRCUITPY_QRIO ?= $(CIRCUITPY_ESPCAMERA) diff --git a/ports/espressif/supervisor/port.c b/ports/espressif/supervisor/port.c index a71825afa5..db4a436b13 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" @@ -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 df9d6a801e..a11bef82bc 100644 --- a/ports/espressif/tools/build_memory_info.py +++ b/ports/espressif/tools/build_memory_info.py @@ -6,13 +6,12 @@ # SPDX-License-Identifier: MIT import csv +import json import os -import re import sys from elftools.elf.elffile import ELFFile -print() internal_memory = { "esp32": [ @@ -117,8 +116,12 @@ with open(sys.argv[1], "rb") as stream: # This file is the bin used_flash = os.stat(sys.argv[3]).st_size - free_flash = firmware_region - used_flash + +with open(f"{sys.argv[4]}/firmware.size.json", "w") as f: + json.dump({"used_flash": used_flash, "firmware_region": firmware_region}, f) + +print() print( "{:7} bytes used, {:7} bytes free in flash firmware space out of {} bytes ({}kB).".format( used_flash, free_flash, firmware_region, firmware_region / 1024 diff --git a/ports/litex/Makefile b/ports/litex/Makefile index efe99dc5b4..5556dea11d 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/nrf/Makefile b/ports/nrf/Makefile index 972b549f61..2267a582a4 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 $@" diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index ee0356b852..fafc817ca2 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 +$(BUILD)/sdk/src/rp2_common/pico_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 else INC_CYW43 := CFLAGS_CYW43 := SRC_SDK_CYW43 := SRC_CYW43 := -OBJ_CYW43 := SRC_LWIP := endif @@ -377,7 +371,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 $<" @@ -417,7 +411,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/boards/adafruit_feather_rp2040_dvi/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/board.c new file mode 100644 index 0000000000..331653173e --- /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 0000000000..06cfaf37f6 --- /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_GPIO16) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO14) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO8) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/mpconfigboard.mk new file mode 100644 index 0000000000..a60ff7b9a7 --- /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 0000000000..a41131dd22 --- /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 0000000000..e014ace05a --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/pins.c @@ -0,0 +1,52 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_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/lib/cyw43-driver b/ports/raspberrypi/lib/cyw43-driver index 2cf328d9e4..e52dd14a15 160000 --- a/ports/raspberrypi/lib/cyw43-driver +++ b/ports/raspberrypi/lib/cyw43-driver @@ -1 +1 @@ -Subproject commit 2cf328d9e41603405a037a29e081a7d30dd519e6 +Subproject commit e52dd14a15e6a53e6263840704470246aa77c5ce diff --git a/ports/raspberrypi/sdk b/ports/raspberrypi/sdk index 2e6142b15b..2ccab115de 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 a29ccb458a..ee99b1c609 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/usb.c b/ports/raspberrypi/supervisor/usb.c index d0e9b2e466..fb4f72134d 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/stm/Makefile b/ports/stm/Makefile index 094bee7aef..d6afeb5f29 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/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 43f4fb186a..c849a12851 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -226,6 +226,9 @@ CFLAGS += -DCIRCUITPY_ERRNO=$(CIRCUITPY_ERRNO) CIRCUITPY_ESPIDF ?= 0 CFLAGS += -DCIRCUITPY_ESPIDF=$(CIRCUITPY_ESPIDF) +CIRCUITPY_ESPNOW ?= 0 +CFLAGS += -DCIRCUITPY_ESPNOW=$(CIRCUITPY_ESPNOW) + CIRCUITPY_ESPULP ?= 0 CFLAGS += -DCIRCUITPY_ESPULP=$(CIRCUITPY_ESPULP) diff --git a/py/objtuple.h b/py/objtuple.h index 7bfb447fa4..ded265b47e 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/ringbuf.c b/py/ringbuf.c index 8a4cb33cbc..5936b64230 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/shared-bindings/aesio/aes.c b/shared-bindings/aesio/aes.c index 50e07a5b61..c5c50515ea 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. //| @@ -98,33 +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_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; - (void)mp_arg_validate_length(iv_length, AES_BLOCKLEN, MP_QSTR_IV); + 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) { diff --git a/shared-bindings/alarm/time/TimeAlarm.c b/shared-bindings/alarm/time/TimeAlarm.c index abbb050c64..86c96de1d4 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/bitmaptools/__init__.c b/shared-bindings/bitmaptools/__init__.c index 493ff93b09..1195e1811d 100644 --- a/shared-bindings/bitmaptools/__init__.c +++ b/shared-bindings/bitmaptools/__init__.c @@ -523,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 conecting points on provided bitmap with provided value +//| +//| :param bitmap dest_bitmap: Destination bitmap that will be written into +//| :param ReadableBuffer xs: x-pixel position of the polygon's vertices +//| :param ReadableBuffer ys: y-pixel position of the polygon's vertices +//| :param int value: Bitmap palette index that will be written into the +//| line in the destination bitmap +//| :param bool close: (Optional) Wether to connect first and last point. (True) +//| +//| .. code-block:: Python +//| +//| import board +//| import displayio +//| import bitmaptools +//| +//| display = board.DISPLAY +//| main_group = displayio.Group() +//| display.root_group = main_group +//| +//| palette = displayio.Palette(3) +//| palette[0] = 0xffffff +//| palette[1] = 0x0000ff +//| palette[2] = 0xff0000 +//| +//| bmp = displayio.Bitmap(128,128, 3) +//| bmp.fill(0) +//| +//| xs = bytes([4, 101, 101, 19]) +//| ys = bytes([4, 19, 121, 101]) +//| bitmaptools.draw_polygon(bmp, xs, ys, 1) +//| +//| xs = bytes([14, 60, 110]) +//| ys = bytes([14, 24, 90]) +//| bitmaptools.draw_polygon(bmp, xs, ys, 2) +//| +//| tilegrid = displayio.TileGrid(bitmap=bmp, pixel_shader=palette) +//| main_group.append(tilegrid) +//| +//| while True: +//| pass +//| """ +//| ... +//| +STATIC mp_obj_t bitmaptools_obj_draw_polygon(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_dest_bitmap, ARG_xs, ARG_ys, ARG_value, ARG_close}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_xs, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_ys, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_close, MP_ARG_BOOL, {.u_bool = true}}, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + displayio_bitmap_t *destination = MP_OBJ_TO_PTR(args[ARG_dest_bitmap].u_obj); // the destination bitmap + + mp_buffer_info_t xs_buf, ys_buf; + mp_get_buffer_raise(args[ARG_xs].u_obj, &xs_buf, MP_BUFFER_READ); + mp_get_buffer_raise(args[ARG_ys].u_obj, &ys_buf, MP_BUFFER_READ); + size_t xs_size = mp_binary_get_size('@', xs_buf.typecode, NULL); + size_t ys_size = mp_binary_get_size('@', ys_buf.typecode, NULL); + size_t xs_len = xs_buf.len / xs_size; + size_t ys_len = ys_buf.len / ys_size; + if (xs_size != ys_size) { + mp_raise_ValueError(translate("Coordinate arrays types have different sizes")); + } + if (xs_len != ys_len) { + mp_raise_ValueError(translate("Coordinate arrays have different lengths")); + } + + uint32_t value, color_depth; + value = args[ARG_value].u_int; + color_depth = (1 << destination->bits_per_value); + if (color_depth <= value) { + mp_raise_ValueError(translate("out of range of target")); + } + + bool close = args[ARG_close].u_bool; + + common_hal_bitmaptools_draw_polygon(destination, xs_buf.buf, ys_buf.buf, xs_len, xs_size, value, close); + + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_polygon_obj, 0, bitmaptools_obj_draw_polygon); + //| def arrayblit( //| bitmap: displayio.Bitmap, //| data: ReadableBuffer, @@ -784,6 +879,7 @@ STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_fill_region), MP_ROM_PTR(&bitmaptools_fill_region_obj) }, { MP_ROM_QSTR(MP_QSTR_boundary_fill), MP_ROM_PTR(&bitmaptools_boundary_fill_obj) }, { MP_ROM_QSTR(MP_QSTR_draw_line), MP_ROM_PTR(&bitmaptools_draw_line_obj) }, + { MP_ROM_QSTR(MP_QSTR_draw_polygon), MP_ROM_PTR(&bitmaptools_draw_polygon_obj) }, { MP_ROM_QSTR(MP_QSTR_dither), MP_ROM_PTR(&bitmaptools_dither_obj) }, { MP_ROM_QSTR(MP_QSTR_DitherAlgorithm), MP_ROM_PTR(&bitmaptools_dither_algorithm_type) }, }; diff --git a/shared-bindings/bitmaptools/__init__.h b/shared-bindings/bitmaptools/__init__.h index fb5c78911f..db72410cf6 100644 --- a/shared-bindings/bitmaptools/__init__.h +++ b/shared-bindings/bitmaptools/__init__.h @@ -64,6 +64,7 @@ void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination, int16_t x1, int16_t y1, uint32_t value); +void common_hal_bitmaptools_draw_polygon(displayio_bitmap_t *destination, void *xs, void *ys, size_t points_len, int point_size, uint32_t value, bool close); void common_hal_bitmaptools_readinto(displayio_bitmap_t *self, mp_obj_t *file, int element_size, int bits_per_pixel, bool reverse_pixels_in_word, bool swap_bytes, bool reverse_rows); void common_hal_bitmaptools_arrayblit(displayio_bitmap_t *self, void *data, int element_size, int x1, int y1, int x2, int y2, bool skip_specified, uint32_t skip_index); void common_hal_bitmaptools_dither(displayio_bitmap_t *dest_bitmap, displayio_bitmap_t *source_bitmap, displayio_colorspace_t colorspace, bitmaptools_dither_algorithm_t algorithm); diff --git a/shared-bindings/pwmio/PWMOut.c b/shared-bindings/pwmio/PWMOut.c index 24c0097c0c..784f87a025 100644 --- a/shared-bindings/pwmio/PWMOut.c +++ b/shared-bindings/pwmio/PWMOut.c @@ -271,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-module/bitmaptools/__init__.c b/shared-module/bitmaptools/__init__.c index 6354dd508a..8068bbe8b6 100644 --- a/shared-module/bitmaptools/__init__.c +++ b/shared-module/bitmaptools/__init__.c @@ -389,37 +389,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 @@ -493,6 +467,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; diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index 81431d5d7a..706c94eec3 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/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index fa85cddb83..5ac8454312 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -225,13 +225,17 @@ void usb_background_schedule(void) { } void 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 - tuh_int_handler(instance); - #endif } + #if CIRCUITPY_USB_HOST + else if (instance == CIRCUITPY_USB_HOST_INSTANCE) { + tuh_int_handler(instance); + } + #endif + #endif usb_background_schedule(); } diff --git a/supervisor/shared/web_workflow/websocket.c b/supervisor/shared/web_workflow/websocket.c index 7612066fa6..e55e09b3e7 100644 --- a/supervisor/shared/web_workflow/websocket.c +++ b/supervisor/shared/web_workflow/websocket.c @@ -52,6 +52,8 @@ 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; @@ -244,6 +246,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 +259,5 @@ void websocket_background(void) { } ringbuf_put(&_incoming_ringbuf, c); } + in_web_background = false; } diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 801025f41a..c461c5353f 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/tools/build_memory_info.py b/tools/build_memory_info.py index 722c548a1c..09d2e72a64 100755 --- a/tools/build_memory_info.py +++ b/tools/build_memory_info.py @@ -7,6 +7,8 @@ import re import sys +import json + # Handle size constants with K or M suffixes (allowed in .ld but not in Python). K_PATTERN = re.compile(r"([0-9]+)[kK]") @@ -15,11 +17,10 @@ K_REPLACE = r"(\1*1024)" M_PATTERN = re.compile(r"([0-9]+)[mM]") M_REPLACE = r"(\1*1024*1024)" -print() - text = 0 data = 0 bss = 0 + # stdin is the linker output. for line in sys.stdin: # Uncomment to see linker output. @@ -29,6 +30,7 @@ for line in sys.stdin: text, data, bss = map(int, line.split()[:3]) regions = {} + # This file is the linker script. with open(sys.argv[1], "r") as f: for line in f: @@ -51,6 +53,11 @@ used_flash = data + text free_flash = firmware_region - used_flash used_ram = data + bss free_ram = ram_region - used_ram + +with open(f"{sys.argv[2]}/firmware.size.json", "w") as f: + json.dump({"used_flash": used_flash, "firmware_region": firmware_region}, f) + +print() print( "{} bytes used, {} bytes free in flash firmware space out of {} bytes ({}kB).".format( used_flash, free_flash, firmware_region, firmware_region / 1024 diff --git a/tools/build_release_files.py b/tools/build_release_files.py index a4f28f1c1c..341ae2d67f 100755 --- a/tools/build_release_files.py +++ b/tools/build_release_files.py @@ -11,6 +11,7 @@ import subprocess import shutil import build_board_info as build_info import time +import json sys.path.append("../docs") from shared_bindings_matrix import get_settings_from_makefile @@ -18,7 +19,7 @@ from shared_bindings_matrix import get_settings_from_makefile for port in build_info.SUPPORTED_PORTS: result = subprocess.run("rm -rf ../ports/{port}/build*".format(port=port), shell=True) -PARALLEL = "-j 5" +PARALLEL = "-j 4" if "GITHUB_ACTION" in os.environ: PARALLEL = "-j 2" @@ -29,6 +30,11 @@ if "BOARDS" in os.environ: sha, version = build_info.get_version_info() +build_all = os.environ.get("GITHUB_EVENT_NAME") != "pull_request" + +LANGUAGE_FIRST = "en_US" +LANGUAGE_THRESHOLD = 10 * 1024 + languages = build_info.get_languages() all_languages = build_info.get_languages(list_all=True) @@ -44,6 +50,9 @@ for board in build_boards: 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) @@ -130,4 +139,16 @@ for board in build_boards: # Flush so we will see something before 10 minutes has passed. print(flush=True) + if (not build_all) and (language is LANGUAGE_FIRST) and (exit_status is 0): + try: + with open( + f"../ports/{board_info['port']}/{build_dir}/firmware.size.json", "r" + ) as f: + firmware = json.load(f) + if firmware["used_flash"] + LANGUAGE_THRESHOLD < firmware["firmware_region"]: + print("Skipping languages") + break + except FileNotFoundError: + pass + sys.exit(exit_status) diff --git a/tools/ci_changes_per_commit.py b/tools/ci_changes_per_commit.py index d5f621d263..58e86148ed 100644 --- a/tools/ci_changes_per_commit.py +++ b/tools/ci_changes_per_commit.py @@ -167,12 +167,11 @@ def get_commit_depth_and_check_suite(query_commits): def get_bad_check_runs(query_check_runs): + bad_runs = {} more_pages = True - bad_runs_by_matrix = {} run_types = ["failed", "incomplete"] - - regex_matrix = re.compile(r"^\S+ \/ (build|run) \(\S+\)$") + have_dependent_jobs = ["scheduler", "mpy-cross", "tests"] while more_pages: check_runs = query_check_runs.fetch()["data"]["node"] @@ -184,23 +183,23 @@ def get_bad_check_runs(query_check_runs): for check_run in check_runs[run_type]["nodes"]: name = check_run["name"] - res_matrix = regex_matrix.search(name) - if res_matrix: - matrix = name.split(" /", 1)[0] - matrix_job = name.split(" (", 1)[1][:-1] - bad_runs_by_matrix.setdefault(matrix, []).append(matrix_job) - elif name != "scheduler": - bad_runs_by_matrix[name] = True - else: + + 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_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): diff --git a/tools/ci_fetch_deps.py b/tools/ci_fetch_deps.py index 3b495f8758..1b292b9d73 100644 --- a/tools/ci_fetch_deps.py +++ b/tools/ci_fetch_deps.py @@ -78,13 +78,13 @@ def main(): submodules = ["extmod/ulab", "lib/", "tools/"] elif TARGET == "tests": submodules = ["extmod/ulab", "lib/", "tools/"] - elif TARGET == "build-doc": + 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 == "build-windows": + 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": diff --git a/tools/ci_set_matrix.py b/tools/ci_set_matrix.py index 02a1cbee73..fa53c81829 100755 --- a/tools/ci_set_matrix.py +++ b/tools/ci_set_matrix.py @@ -42,63 +42,70 @@ from shared_bindings_matrix import ( all_ports_all_boards, ) -PORT_TO_JOB = { - "atmel-samd": "atmel", - "broadcom": "aarch", - "cxd56": "arm", - "espressif": "esp", - "litex": "riscv", - "mimxrt10xx": "arm", - "nrf": "arm", - "raspberrypi": "arm", - "stm": "arm", -} - -IGNORE = [ - "tools/ci_set_matrix.py", +# 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", -] - -# Files in these directories never influence board builds -IGNORE_DIRS = ["tests", "docs", ".devcontainer"] + "tools/ci_set_matrix.py", +} PATTERN_DOCS = ( r"^(?:\.github|docs|extmod\/ulab)|" - r"^(?:(?:ports\/\w+\/bindings|shared-bindings)\S+\.c|tools\/extract_pyi\.py|conf\.py|requirements-doc\.txt)$|" + r"^(?:(?: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 = [ +PATTERN_WINDOWS = { ".github/", "extmod/", "lib/", "mpy-cross/", "ports/unix/", - "ports/windows/", "py/", - "requirements", "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] + ) + 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 os.environ.get("BASE_SHA") and os.environ.get("HEAD_SHA"): + 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::") + + +print_enclosed("Log: changed_files", changed_files) +print_enclosed("Log: last_failed_jobs", last_failed_jobs) def set_output(name: str, value): @@ -109,10 +116,7 @@ def set_output(name: str, value): print(f"Would set GitHub actions output {name} to '{value}'") -def set_boards_to_build(build_all: bool): - if last_failed_jobs.get("mpy-cross") or last_failed_jobs.get("tests"): - build_all = True - +def set_boards(build_all: bool): # Get boards in json format boards_info_json = build_board_info.get_board_mapping() all_board_ids = set() @@ -170,11 +174,7 @@ def set_boards_to_build(build_all: bool): boards_to_build.update(port_to_boards[port]) continue - # Check the ignore list to see if the file isn't used on board builds. - if p in IGNORE: - continue - - if any([p.startswith(d) for d in IGNORE_DIRS]): + if any([p.startswith(d) for d in IGNORE_BOARD]): continue # As a (nearly) last resort, for some certain files, we compute the settings from the @@ -224,18 +224,13 @@ def set_boards_to_build(build_all: bool): boards_to_build = all_board_ids break - # Split boards by job - job_to_boards = {"aarch": [], "arm": [], "atmel": [], "esp": [], "riscv": []} - # Append previously failed boards - for job in job_to_boards: - if job in last_failed_jobs: - for board in last_failed_jobs[job]: - boards_to_build.add(board) + boards_to_build.update(last_failed_jobs.get("ports") or []) - build_boards = bool(boards_to_build) - print("Building boards:", build_boards) - set_output("build-boards", build_boards) + 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): @@ -244,17 +239,19 @@ def set_boards_to_build(build_all: bool): # if this happens it's not in `board_to_port`. if not port: continue - job_to_boards[PORT_TO_JOB[port]].append(board) + port_to_boards_to_build.setdefault(port, []).append(board) print(" ", board) - # Set the step outputs for each job - for job in job_to_boards: - set_output(f"boards-{job}", json.dumps(job_to_boards[job])) + if port_to_boards_to_build: + port_to_boards_to_build["ports"] = sorted(list(port_to_boards_to_build.keys())) + + # Set the step outputs + set_output("ports", json.dumps(port_to_boards_to_build)) -def set_docs_to_build(build_doc: bool): +def set_docs(build_doc: bool): if not build_doc: - if last_failed_jobs.get("build-doc"): + if last_failed_jobs.get("docs"): build_doc = True else: doc_pattern = re.compile(PATTERN_DOCS) @@ -277,17 +274,19 @@ def set_docs_to_build(build_doc: bool): # Set the step outputs print("Building docs:", build_doc) - set_output("build-doc", build_doc) + set_output("docs", build_doc) -def set_windows_to_build(build_windows): +def set_windows(build_windows: bool): if not build_windows: - if last_failed_jobs.get("build-windows"): + if last_failed_jobs.get("windows"): build_windows = True else: for file in changed_files: for pattern in PATTERN_WINDOWS: - if file.startswith(pattern): + if file.startswith(pattern) and not any( + [file.startswith(d) for d in IGNORE_BOARD] + ): build_windows = True break else: @@ -296,23 +295,18 @@ def set_windows_to_build(build_windows): # Set the step outputs print("Building windows:", build_windows) - set_output("build-windows", build_windows) - - -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_output("windows", build_windows) def main(): - build_all = check_changed_files() - set_docs_to_build(build_all) - set_windows_to_build(build_all) - set_boards_to_build(build_all) + # Build all if no changed files + build_all = not changed_files + print("Running: " + ("all" if build_all else "conditionally")) + + # Set jobs + set_docs(build_all) + set_windows(build_all) + set_boards(build_all) if __name__ == "__main__":