diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 6f84de6f60ea..690e5f46a4fc 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,3 +1,9 @@ +# all: Update Python formatting to ruff-format. +bbd8760bd9a2302e5abee29db279102bb11d7732 + +# all: Fix various spelling mistakes found by codespell 2.2.6. +cf490a70917a1b2d38ba9b58e763e0837d0f7ca7 + # all: Fix spelling mistakes based on codespell check. b1229efbd1509654dec6053865ab828d769e29db diff --git a/.gitattributes b/.gitattributes index e6d31d6aa31f..2d8496db5048 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,10 +8,12 @@ # These are binary so should never be modified by git. *.a binary +*.ico binary *.png binary *.jpg binary *.dxf binary *.mpy binary +*.der binary # These should also not be modified by git. tests/basics/string_cr_conversion.py -text diff --git a/.github/workflows/code_formatting.yml b/.github/workflows/code_formatting.yml index 81a2715f1b33..5cd7984f7ac1 100644 --- a/.github/workflows/code_formatting.yml +++ b/.github/workflows/code_formatting.yml @@ -10,20 +10,20 @@ jobs: code-formatting: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 - name: Install packages - run: source tools/ci.sh && ci_code_formatting_setup + run: source tools/ci.sh && ci_c_code_formatting_setup - name: Run code formatting - run: source tools/ci.sh && ci_code_formatting_run + run: source tools/ci.sh && ci_c_code_formatting_run - name: Check code formatting run: git diff --exit-code code-spelling: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 - name: Install packages run: source tools/ci.sh && ci_code_spell_setup - name: Run spell checker diff --git a/.github/workflows/code_size.yml b/.github/workflows/code_size.yml index 5d955703b666..a65a00201a7d 100644 --- a/.github/workflows/code_size.yml +++ b/.github/workflows/code_size.yml @@ -20,7 +20,7 @@ jobs: build: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 100 - name: Install packages @@ -36,7 +36,7 @@ jobs: run: echo $PR_NUMBER > pr_number - name: Upload diff if: github.event_name == 'pull_request' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: code-size-report path: | diff --git a/.github/workflows/code_size_comment.yml b/.github/workflows/code_size_comment.yml index 8baf76a47a7f..a394f7a14b05 100644 --- a/.github/workflows/code_size_comment.yml +++ b/.github/workflows/code_size_comment.yml @@ -15,7 +15,7 @@ jobs: steps: - name: 'Download artifact' id: download-artifact - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: result-encoding: string script: | @@ -56,7 +56,7 @@ jobs: run: unzip code-size-report.zip - name: Post comment to pull request if: steps.download-artifact.outputs.result == 'ok' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | diff --git a/.github/workflows/commit_formatting.yml b/.github/workflows/commit_formatting.yml index 0b27038f2d26..3fdcabc4ca73 100644 --- a/.github/workflows/commit_formatting.yml +++ b/.github/workflows/commit_formatting.yml @@ -10,9 +10,9 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: '100' - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 - name: Check commit message formatting run: source tools/ci.sh && ci_commit_formatting_run diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e9b17007476c..d01a4b50c981 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,6 +1,7 @@ name: Build docs on: + push: pull_request: paths: - docs/** @@ -14,9 +15,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 - name: Install Python packages - run: pip install Sphinx + run: pip install -r docs/requirements.txt - name: Build docs run: make -C docs/ html diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 450805a6bde4..6613f106625a 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -18,7 +18,7 @@ jobs: embedding: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build run: make -C examples/embedding -f micropython_embed.mk && make -C examples/embedding - name: Run diff --git a/.github/workflows/mpremote.yml b/.github/workflows/mpremote.yml index 14aef03e0773..ee91b6360b9b 100644 --- a/.github/workflows/mpremote.yml +++ b/.github/workflows/mpremote.yml @@ -11,18 +11,18 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: # Setting this to zero means fetch all history and tags, # which hatch-vcs can use to discover the version tag. fetch-depth: 0 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 - name: Install build tools run: pip install build - name: Build mpremote wheel run: cd tools/mpremote && python -m build --wheel - name: Archive mpremote wheel - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: mpremote path: | diff --git a/.github/workflows/mpy_format.yml b/.github/workflows/mpy_format.yml index 66abb19b81a4..baa02ce08d50 100644 --- a/.github/workflows/mpy_format.yml +++ b/.github/workflows/mpy_format.yml @@ -17,7 +17,7 @@ jobs: test: runs-on: ubuntu-20.04 # use 20.04 to get python2 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_mpy_format_setup - name: Test mpy-tool.py diff --git a/.github/workflows/ports.yml b/.github/workflows/ports.yml index fb574ad98190..1f262b0ba4be 100644 --- a/.github/workflows/ports.yml +++ b/.github/workflows/ports.yml @@ -17,6 +17,6 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build ports download metadata run: mkdir boards && ./tools/autobuild/build-downloads.py . ./boards diff --git a/.github/workflows/ports_cc3200.yml b/.github/workflows/ports_cc3200.yml index b58bc24b58b0..f178a140587d 100644 --- a/.github/workflows/ports_cc3200.yml +++ b/.github/workflows/ports_cc3200.yml @@ -21,7 +21,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_cc3200_setup - name: Build diff --git a/.github/workflows/ports_esp32.yml b/.github/workflows/ports_esp32.yml index 6fc009d4fee8..6872b9d12de7 100644 --- a/.github/workflows/ports_esp32.yml +++ b/.github/workflows/ports_esp32.yml @@ -18,20 +18,40 @@ concurrency: cancel-in-progress: true jobs: - build_idf402: + build_idf: + strategy: + fail-fast: false + matrix: + ci_func: # names are functions in ci.sh + - esp32_build_cmod_spiram_s2 + - esp32_build_s3_c3 runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 - - name: Install packages - run: source tools/ci.sh && ci_esp32_idf402_setup - - name: Build - run: source tools/ci.sh && ci_esp32_build + - uses: actions/checkout@v4 - build_idf44: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v3 - - name: Install packages - run: source tools/ci.sh && ci_esp32_idf44_setup - - name: Build - run: source tools/ci.sh && ci_esp32_build + - id: idf_ver + name: Read the ESP-IDF version + run: source tools/ci.sh && echo "IDF_VER=$IDF_VER" | tee "$GITHUB_OUTPUT" + + - name: Cached ESP-IDF install + id: cache_esp_idf + uses: actions/cache@v3 + with: + path: | + ./esp-idf/ + ~/.espressif/ + !~/.espressif/dist/ + ~/.cache/pip/ + key: esp-idf-${{ steps.idf_ver.outputs.IDF_VER }} + + - name: Install ESP-IDF packages + if: steps.cache_esp_idf.outputs.cache-hit != 'true' + run: source tools/ci.sh && ci_esp32_idf_setup + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: esp32-${{ matrix.ci_func }} + + - name: Build ci_${{matrix.ci_func }} + run: source tools/ci.sh && ci_${{ matrix.ci_func }} diff --git a/.github/workflows/ports_esp8266.yml b/.github/workflows/ports_esp8266.yml index ba89d5e9529e..5236edf40b95 100644 --- a/.github/workflows/ports_esp8266.yml +++ b/.github/workflows/ports_esp8266.yml @@ -21,7 +21,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_esp8266_setup && ci_esp8266_path >> $GITHUB_PATH - name: Build diff --git a/.github/workflows/ports_mimxrt.yml b/.github/workflows/ports_mimxrt.yml index d91562534188..614d7458079e 100644 --- a/.github/workflows/ports_mimxrt.yml +++ b/.github/workflows/ports_mimxrt.yml @@ -21,7 +21,7 @@ jobs: build: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_mimxrt_setup - name: Build diff --git a/.github/workflows/ports_nrf.yml b/.github/workflows/ports_nrf.yml index 89211217800b..d9cffb9778cb 100644 --- a/.github/workflows/ports_nrf.yml +++ b/.github/workflows/ports_nrf.yml @@ -21,7 +21,7 @@ jobs: build: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_nrf_setup - name: Build diff --git a/.github/workflows/ports_powerpc.yml b/.github/workflows/ports_powerpc.yml index a15c4da97fa6..c41b13e5ddff 100644 --- a/.github/workflows/ports_powerpc.yml +++ b/.github/workflows/ports_powerpc.yml @@ -21,7 +21,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_powerpc_setup - name: Build diff --git a/.github/workflows/ports_qemu-arm.yml b/.github/workflows/ports_qemu-arm.yml index 93ec4da76700..db3cd7871d59 100644 --- a/.github/workflows/ports_qemu-arm.yml +++ b/.github/workflows/ports_qemu-arm.yml @@ -22,7 +22,7 @@ jobs: build_and_test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_qemu_arm_setup - name: Build and run test suite diff --git a/.github/workflows/ports_renesas-ra.yml b/.github/workflows/ports_renesas-ra.yml index 33e17a385a1e..b1a30c2f1179 100644 --- a/.github/workflows/ports_renesas-ra.yml +++ b/.github/workflows/ports_renesas-ra.yml @@ -21,7 +21,7 @@ jobs: build_renesas_ra_board: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_renesas_ra_setup - name: Build diff --git a/.github/workflows/ports_rp2.yml b/.github/workflows/ports_rp2.yml index f042ff1151ab..5741b75d2aa7 100644 --- a/.github/workflows/ports_rp2.yml +++ b/.github/workflows/ports_rp2.yml @@ -21,7 +21,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_rp2_setup - name: Build diff --git a/.github/workflows/ports_samd.yml b/.github/workflows/ports_samd.yml index 9833a2fae2ef..5bf1826cd17b 100644 --- a/.github/workflows/ports_samd.yml +++ b/.github/workflows/ports_samd.yml @@ -21,7 +21,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_samd_setup - name: Build diff --git a/.github/workflows/ports_stm32.yml b/.github/workflows/ports_stm32.yml index b278ea862ce6..84d30b27f6e6 100644 --- a/.github/workflows/ports_stm32.yml +++ b/.github/workflows/ports_stm32.yml @@ -18,20 +18,18 @@ concurrency: cancel-in-progress: true jobs: - build_pyb: + build_stm32: + strategy: + fail-fast: false + matrix: + ci_func: # names are functions in ci.sh + - stm32_pyb_build + - stm32_nucleo_build runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_stm32_setup - - name: Build - run: source tools/ci.sh && ci_stm32_pyb_build + - name: Build ci_${{matrix.ci_func }} + run: source tools/ci.sh && ci_${{ matrix.ci_func }} - build_nucleo: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v3 - - name: Install packages - run: source tools/ci.sh && ci_stm32_setup - - name: Build - run: source tools/ci.sh && ci_stm32_nucleo_build diff --git a/.github/workflows/ports_teensy.yml b/.github/workflows/ports_teensy.yml deleted file mode 100644 index f1299603259a..000000000000 --- a/.github/workflows/ports_teensy.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: teensy port - -on: - push: - pull_request: - paths: - - '.github/workflows/*.yml' - - 'tools/**' - - 'py/**' - - 'extmod/**' - - 'shared/**' - - 'lib/**' - - 'drivers/**' - - 'ports/teensy/**' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Install packages - run: source tools/ci.sh && ci_teensy_setup - - name: Build - run: source tools/ci.sh && ci_teensy_build diff --git a/.github/workflows/ports_unix.yml b/.github/workflows/ports_unix.yml index 87c58055b988..2367eddbe6ea 100644 --- a/.github/workflows/ports_unix.yml +++ b/.github/workflows/ports_unix.yml @@ -23,7 +23,7 @@ jobs: minimal: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build run: source tools/ci.sh && ci_unix_minimal_build - name: Run main test suite @@ -35,7 +35,7 @@ jobs: reproducible: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build with reproducible date run: source tools/ci.sh && ci_unix_minimal_build env: @@ -46,7 +46,7 @@ jobs: standard: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build run: source tools/ci.sh && ci_unix_standard_build - name: Run main test suite @@ -55,10 +55,22 @@ jobs: if: failure() run: tests/run-tests.py --print-failures + standard_v2: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Build + run: source tools/ci.sh && ci_unix_standard_v2_build + - name: Run main test suite + run: source tools/ci.sh && ci_unix_standard_v2_run_tests + - name: Print failures + if: failure() + run: tests/run-tests.py --print-failures + coverage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_unix_coverage_setup - name: Build @@ -87,7 +99,7 @@ jobs: coverage_32bit: runs-on: ubuntu-20.04 # use 20.04 to get libffi-dev:i386 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_unix_32bit_setup - name: Build @@ -105,7 +117,7 @@ jobs: nanbox: runs-on: ubuntu-20.04 # use 20.04 to get python2, and libffi-dev:i386 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_unix_32bit_setup - name: Build @@ -119,7 +131,7 @@ jobs: float: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build run: source tools/ci.sh && ci_unix_float_build - name: Run main test suite @@ -131,7 +143,7 @@ jobs: stackless_clang: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_unix_clang_setup - name: Build @@ -145,7 +157,7 @@ jobs: float_clang: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_unix_clang_setup - name: Build @@ -159,7 +171,7 @@ jobs: settrace: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build run: source tools/ci.sh && ci_unix_settrace_build - name: Run main test suite @@ -171,7 +183,7 @@ jobs: settrace_stackless: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build run: source tools/ci.sh && ci_unix_settrace_stackless_build - name: Run main test suite @@ -183,8 +195,8 @@ jobs: macos: runs-on: macos-11.0 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: '3.8' - name: Build @@ -198,7 +210,7 @@ jobs: qemu_mips: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_unix_qemu_mips_setup - name: Build @@ -212,7 +224,7 @@ jobs: qemu_arm: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_unix_qemu_arm_setup - name: Build diff --git a/.github/workflows/ports_webassembly.yml b/.github/workflows/ports_webassembly.yml index 2e0865662f06..880f15ab3446 100644 --- a/.github/workflows/ports_webassembly.yml +++ b/.github/workflows/ports_webassembly.yml @@ -20,7 +20,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_webassembly_setup - name: Build diff --git a/.github/workflows/ports_windows.yml b/.github/workflows/ports_windows.yml index b31718c59140..4b1f4ea791e2 100644 --- a/.github/workflows/ports_windows.yml +++ b/.github/workflows/ports_windows.yml @@ -21,7 +21,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_windows_setup - name: Build diff --git a/.github/workflows/ports_zephyr.yml b/.github/workflows/ports_zephyr.yml index f64401b316a5..f6f328c9277e 100644 --- a/.github/workflows/ports_zephyr.yml +++ b/.github/workflows/ports_zephyr.yml @@ -20,7 +20,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install packages run: source tools/ci.sh && ci_zephyr_setup - name: Install Zephyr diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml index b8e43dc78f17..1159a1882d60 100644 --- a/.github/workflows/ruff.yml +++ b/.github/workflows/ruff.yml @@ -1,10 +1,11 @@ # https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python -name: Python code lint with ruff +name: Python code lint and formatting with ruff on: [push, pull_request] jobs: ruff: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - run: pip install --user ruff - - run: ruff --format=github . + - uses: actions/checkout@v4 + - run: pip install --user ruff==0.1.3 + - run: ruff check --output-format=github . + - run: ruff format --diff . diff --git a/.gitmodules b/.gitmodules index 992fec3d1836..75bffdadddeb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -56,3 +56,6 @@ [submodule "lib/micropython-lib"] path = lib/micropython-lib url = https://github.com/micropython/micropython-lib.git +[submodule "lib/protobuf-c"] + path = lib/protobuf-c + url = https://github.com/protobuf-c/protobuf-c.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e9815a4b2e64..3004bc567721 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,8 +2,8 @@ repos: - repo: local hooks: - id: codeformat - name: MicroPython codeformat.py for changed files - entry: tools/codeformat.py -v -f + name: MicroPython codeformat.py for changed C files + entry: tools/codeformat.py -v -c -f language: python - id: verifygitlog name: MicroPython git commit message format checker @@ -12,6 +12,7 @@ repos: verbose: true stages: [commit-msg] - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.265 + rev: v0.1.3 hooks: - id: ruff + - id: ruff-format diff --git a/CODECONVENTIONS.md b/CODECONVENTIONS.md index d44b382b25ea..d6b0a5926bf4 100644 --- a/CODECONVENTIONS.md +++ b/CODECONVENTIONS.md @@ -53,13 +53,16 @@ are then certifying and signing off against the following: Code auto-formatting ==================== -Both C and Python code are auto-formatted using the `tools/codeformat.py` -script. This uses [uncrustify](https://github.com/uncrustify/uncrustify) to -format C code and [black](https://github.com/psf/black) to format Python code. -After making changes, and before committing, run this tool to reformat your -changes to the correct style. Without arguments this tool will reformat all -source code (and may take some time to run). Otherwise pass as arguments to -the tool the files that changed and it will only reformat those. +Both C and Python code formatting are controlled for consistency across the +MicroPython codebase. C code is formatted using the `tools/codeformat.py` +script which uses [uncrustify](https://github.com/uncrustify/uncrustify). +Python code is linted and formatted using +[ruff & ruff format](https://github.com/astral-sh/ruff). +After making changes, and before committing, run `tools/codeformat.py` to +reformat your C code and `ruff format` for any Python code. Without +arguments this tool will reformat all source code (and may take some time +to run). Otherwise pass as arguments to the tool the files that changed, +and it will only reformat those. uncrustify ========== @@ -151,12 +154,22 @@ Tips: * To ignore the pre-commit message format check temporarily, start the commit message subject line with "WIP" (for "Work In Progress"). +Running pre-commit manually +=========================== + +Once pre-commit is installed as per the previous section it can be manually +run against the MicroPython python codebase to update file formatting on +demand, with either: +* `pre-commit run --all-files` to fix all files in the MicroPython codebase +* `pre-commit run --file ./path/to/my/file` to fix just one file +* `pre-commit run --file ./path/to/my/folder/*` to fix just one folder + Python code conventions ======================= Python code follows [PEP 8](https://legacy.python.org/dev/peps/pep-0008/) and -is auto-formatted using [black](https://github.com/psf/black) with a line-length -of 99 characters. +is auto-formatted using [ruff format](https://docs.astral.sh/ruff/formatter) +with a line-length of 99 characters. Naming conventions: - Module names are short and all lowercase; eg pyb, stm. diff --git a/LICENSE b/LICENSE index 31eb9813f2d6..9bd457b42ace 100644 --- a/LICENSE +++ b/LICENSE @@ -67,6 +67,8 @@ used during the build process and is not part of the compiled source code. /hal (BSD-3-clause) /simplelink (BSD-3-clause) /FreeRTOS (GPL-2.0 with FreeRTOS exception) + /esp32 + /ppp_set_auth.* (Apache-2.0) /stm32 /usbd*.c (MCD-ST Liberty SW License Agreement V2) /stm32_it.* (MIT + BSD-3-clause) @@ -76,8 +78,6 @@ used during the build process and is not part of the compiled source code. /*/stm32*.h (BSD-3-clause) /usbdev (MCD-ST Liberty SW License Agreement V2) /usbhost (MCD-ST Liberty SW License Agreement V2) - /teensy - /core (PJRC.COM) /zephyr /src (Apache-2.0) /tools diff --git a/README.md b/README.md index 6482899b251d..f5bc6d78f0a4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![CI badge](https://github.com/micropython/micropython/workflows/unix%20port/badge.svg)](https://github.com/micropython/micropython/actions?query=branch%3Amaster+event%3Apush) [![codecov](https://codecov.io/gh/micropython/micropython/branch/master/graph/badge.svg?token=I92PfD05sD)](https://codecov.io/gh/micropython/micropython) +[![Unix CI badge](https://github.com/micropython/micropython/actions/workflows/ports_unix.yml/badge.svg)](https://github.com/micropython/micropython/actions?query=branch%3Amaster+event%3Apush) [![STM32 CI badge](https://github.com/micropython/micropython/actions/workflows/ports_stm32.yml/badge.svg)](https://github.com/micropython/micropython/actions?query=branch%3Amaster+event%3Apush) [![Docs CI badge](https://github.com/micropython/micropython/actions/workflows/docs.yml/badge.svg)](https://docs.micropython.org/) [![codecov](https://codecov.io/gh/micropython/micropython/branch/master/graph/badge.svg?token=I92PfD05sD)](https://codecov.io/gh/micropython/micropython) The MicroPython project ======================= @@ -119,7 +119,6 @@ In addition, the following ports are provided in this repository: - [rp2](ports/rp2) -- Raspberry Pi RP2040 (including Pico and Pico W). - [samd](ports/samd) -- Microchip (formerly Atmel) SAMD21 and SAMD51. - [stm32](ports/stm32) -- STMicroelectronics STM32 family (including F0, F4, F7, G0, G4, H7, L0, L4, WB) - - [teensy](ports/teensy) -- Teensy 3.x. - [webassembly](ports/webassembly) -- Emscripten port targeting browsers and NodeJS. - [zephyr](ports/zephyr) -- Zephyr RTOS. diff --git a/docs/conf.py b/docs/conf.py index a966b3a02570..728e3c4285d8 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -19,55 +19,56 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath(".")) + +# The MICROPY_VERSION env var should be "vX.Y.Z" (or unset). +micropy_version = os.getenv("MICROPY_VERSION") or "latest" +micropy_all_versions = (os.getenv("MICROPY_ALL_VERSIONS") or "latest").split(",") +url_pattern = "%s/en/%%s" % (os.getenv("MICROPY_URL_PREFIX") or "/",) # The members of the html_context dict are available inside topindex.html -micropy_version = os.getenv('MICROPY_VERSION') or 'latest' -micropy_all_versions = (os.getenv('MICROPY_ALL_VERSIONS') or 'latest').split(',') -url_pattern = '%s/en/%%s' % (os.getenv('MICROPY_URL_PREFIX') or '/',) html_context = { - 'cur_version':micropy_version, - 'all_versions':[ - (ver, url_pattern % ver) for ver in micropy_all_versions - ], - 'downloads':[ - ('PDF', url_pattern % micropy_version + '/micropython-docs.pdf'), + "cur_version": micropy_version, + "all_versions": [(ver, url_pattern % ver) for ver in micropy_all_versions], + "downloads": [ + ("PDF", url_pattern % micropy_version + "/micropython-docs.pdf"), ], - 'is_release': micropy_version != 'latest', + "is_release": micropy_version != "latest", } # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', + "sphinx.ext.autodoc", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", + "sphinx.ext.coverage", + "sphinxcontrib.jquery", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['templates'] +templates_path = ["templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = 'MicroPython' -copyright = '- The MicroPython Documentation is Copyright © 2014-2023, Damien P. George, Paul Sokolovsky, and contributors' +project = "MicroPython" +copyright = "- The MicroPython Documentation is Copyright © 2014-2023, Damien P. George, Paul Sokolovsky, and contributors" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -79,41 +80,41 @@ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['build', '.venv'] +exclude_patterns = ["build", ".venv"] # The reST default role (used for this markup: `text`) to use for all # documents. -default_role = 'any' +default_role = "any" # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # Global include files. Sphinx docs suggest using rst_epilog in preference # of rst_prolog, so we follow. Absolute paths below mean "from the base @@ -125,144 +126,148 @@ # -- Options for HTML output ---------------------------------------------- # on_rtd is whether we are on readthedocs.org -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' +on_rtd = os.environ.get("READTHEDOCS", None) == "True" if not on_rtd: # only import and set the theme if we're building docs locally try: import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.'] + + html_theme = "sphinx_rtd_theme" + html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), "."] except: - html_theme = 'default' - html_theme_path = ['.'] + html_theme = "default" + html_theme_path = ["."] else: - html_theme_path = ['.'] + html_theme_path = ["."] # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = ['.'] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = '../../logo/trans-logo.png' +# html_logo = '../../logo/trans-logo.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -html_favicon = 'static/favicon.ico' +html_favicon = "static/favicon.ico" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['static'] +html_static_path = ["static"] # Add a custom CSS file for HTML generation html_css_files = [ - 'custom.css', + "custom.css", ] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -html_last_updated_fmt = '%d %b %Y' +html_last_updated_fmt = "%d %b %Y" # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. html_additional_pages = {"index": "topindex.html"} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'MicroPythondoc' +htmlhelp_basename = "MicroPythondoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -# Include 3 levels of headers in PDF ToC -'preamble': r'\setcounter{tocdepth}{2}', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Include 3 levels of headers in PDF ToC + "preamble": r"\setcounter{tocdepth}{2}", } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'MicroPython.tex', 'MicroPython Documentation', - 'Damien P. George, Paul Sokolovsky, and contributors', 'manual'), + ( + master_doc, + "MicroPython.tex", + "MicroPython Documentation", + "Damien P. George, Paul Sokolovsky, and contributors", + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # Enable better Unicode support so that `make latexpdf` doesn't fail latex_engine = "xelatex" @@ -272,12 +277,17 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'micropython', 'MicroPython Documentation', - ['Damien P. George, Paul Sokolovsky, and contributors'], 1), + ( + "index", + "micropython", + "MicroPython Documentation", + ["Damien P. George, Paul Sokolovsky, and contributors"], + 1, + ), ] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------- @@ -286,23 +296,29 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'MicroPython', 'MicroPython Documentation', - 'Damien P. George, Paul Sokolovsky, and contributors', 'MicroPython', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "MicroPython", + "MicroPython Documentation", + "Damien P. George, Paul Sokolovsky, and contributors", + "MicroPython", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'python': ('https://docs.python.org/3.5', None)} +intersphinx_mapping = {"python": ("https://docs.python.org/3.5", None)} diff --git a/docs/develop/gettingstarted.rst b/docs/develop/gettingstarted.rst index c2d3816d425a..a17a320671f5 100644 --- a/docs/develop/gettingstarted.rst +++ b/docs/develop/gettingstarted.rst @@ -100,7 +100,7 @@ For the stm32 port, the ARM cross-compiler is required: .. code-block:: bash - $ sudo apt-get install arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-newlib + $ sudo apt-get install gcc-arm-none-eabi libnewlib-arm-none-eabi See the `ARM GCC toolchain `_ @@ -228,7 +228,7 @@ You can also specify which board to use: .. code-block:: bash $ cd ports/stm32 - $ make submodules + $ make BOARD= submodules $ make BOARD= See `ports/stm32/boards `_ @@ -245,7 +245,7 @@ that you use a virtual environment: $ python3 -m venv env $ source env/bin/activate - $ pip install sphinx + $ pip install -r docs/requirements.txt Navigate to the ``docs`` directory: diff --git a/docs/develop/porting.rst b/docs/develop/porting.rst index fab8a751b849..63919b97a6cc 100644 --- a/docs/develop/porting.rst +++ b/docs/develop/porting.rst @@ -151,9 +151,6 @@ The following is an example of an ``mpconfigport.h`` file: #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) - // Enable u-modules to be imported with their standard name, like sys. - #define MICROPY_MODULE_WEAK_LINKS (1) - // Fine control over Python builtins, classes, modules, etc. #define MICROPY_PY_ASYNC_AWAIT (0) #define MICROPY_PY_BUILTINS_SET (0) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index e19c6ecb4089..08df25b0554d 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -57,7 +57,6 @@ The :mod:`esp32` module:: import esp32 - esp32.hall_sensor() # read the internal hall sensor esp32.raw_temperature() # read the internal temperature of the MCU, in Fahrenheit esp32.ULP() # access to the Ultra-Low-Power Co-processor @@ -102,7 +101,7 @@ A useful function for connecting to your local WiFi network is:: print('network config:', wlan.ifconfig()) Once the network is established the :mod:`socket ` module can be used -to create and use TCP/UDP sockets as usual, and the ``urequests`` module for +to create and use TCP/UDP sockets as usual, and the ``requests`` module for convenient HTTP requests. After a call to ``wlan.connect()``, the device will by default retry to connect @@ -137,20 +136,12 @@ The keyword arguments for the constructor defining the PHY type and interface ar or output. Suitable values are Pin.IN and Pin.OUT. - ref_clk=pin-object # defines the Pin used for ref_clk. -The options ref_clk_mode and ref_clk require at least esp-idf version 4.4. For -earlier esp-idf versions, these parameters must be defined by kconfig board options. - These are working configurations for LAN interfaces of popular boards:: # Olimex ESP32-GATEWAY: power controlled by Pin(5) # Olimex ESP32 PoE and ESP32-PoE ISO: power controlled by Pin(12) lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), power=machine.Pin(5), - phy_type=network.PHY_LAN8720, phy_addr=0) - - # or with dynamic ref_clk pin configuration - - lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), power=machine.Pin(5), phy_type=network.PHY_LAN8720, phy_addr=0, ref_clk=machine.Pin(17), ref_clk_mode=machine.Pin.OUT) @@ -159,21 +150,17 @@ These are working configurations for LAN interfaces of popular boards:: lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), phy_type=network.PHY_LAN8720, phy_addr=1, power=None) + # Wireless-Tag's WT32-ETH01 v1.4 + + lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), + phy_type=network.PHY_LAN8720, phy_addr=1, + power=machine.Pin(16)) + # Espressif ESP32-Ethernet-Kit_A_V1.2 lan = network.LAN(id=0, mdc=Pin(23), mdio=Pin(18), power=Pin(5), phy_type=network.PHY_IP101, phy_addr=1) -A suitable definition of the PHY interface in a sdkconfig.board file is:: - - CONFIG_ETH_PHY_INTERFACE_RMII=y - CONFIG_ETH_RMII_CLK_OUTPUT=y - CONFIG_ETH_RMII_CLK_OUT_GPIO=17 - CONFIG_LWIP_LOCAL_HOSTNAME="ESP32_POE" - -The value assigned to CONFIG_ETH_RMII_CLK_OUT_GPIO may vary depending on the -board's wiring. - Delay and timing ---------------- @@ -343,6 +330,19 @@ possible at the same frequency. See more examples in the :ref:`esp32_pwm` tutorial. +DAC (digital to analog conversion) +---------------------------------- + +On the ESP32, DAC functionality is available on pins 25, 26. +On the ESP32S2, DAC functionality is available on pins 17, 18. + +Use the DAC:: + + from machine import DAC, Pin + + dac = DAC(Pin(25)) # create an DAC object acting on a pin + dac.write(128) # set a raw analog value in the range 0-255, 50% now + ADC (analog to digital conversion) ---------------------------------- diff --git a/docs/esp32/tutorial/img/mem32_gpio_output.jpg b/docs/esp32/tutorial/img/mem32_gpio_output.jpg new file mode 100755 index 000000000000..5544202871eb Binary files /dev/null and b/docs/esp32/tutorial/img/mem32_gpio_output.jpg differ diff --git a/docs/esp32/tutorial/peripheral_access.rst b/docs/esp32/tutorial/peripheral_access.rst index 3304c341de87..ecdec101f7ef 100644 --- a/docs/esp32/tutorial/peripheral_access.rst +++ b/docs/esp32/tutorial/peripheral_access.rst @@ -42,3 +42,83 @@ for this: The MCPWM0 peripheral is in bit position 17 of the above two registers, hence the value of ``DPORT_PWM0_CLK_EN``. + +Synchronous access to pins directly via registers +------------------------------------------------- + +The following code shows how to access pins directly via registers. It has been +tested on a generic ESP32 board. It configures pins 16, 17, 32 and 33 in output +mode via registers, and switches pin output values via registers. Pins 16 and +17 are switched simultaneously. + +.. code-block:: python3 + + from micropython import const + from machine import mem32, Pin + + GPIO_OUT_REG = const(0x3FF44004) # GPIO 0-31 output register + GPIO_OUT1_REG = const(0x3FF44010) # GPIO 32-39 output register + + GPIO_ENABLE_REG = const(0x3FF44020) # GPIO 0-31 output enable register + GPIO_ENABLE1_REG = const(0x3FF4402C) # GPIO 32-39 output enable register + + M16 = 1 << 16 # Pin(16) bit mask + M17 = 1 << 17 # Pin(17) bit mask + + M32 = 1 << (32-32) # Pin(32) bit mask + M33 = 1 << (33-32) # Pin(33) bit mask + + # Enable pin output mode like + # p16 = Pin(16, mode=Pin.OUT) + # p17 = Pin(17, mode=Pin.OUT) + # p32 = Pin(32, mode=Pin.OUT) + # p33 = Pin(33, mode=Pin.OUT) + mem32[GPIO_ENABLE_REG] = mem32[GPIO_ENABLE_REG] | M16 | M17 + mem32[GPIO_ENABLE1_REG] = mem32[GPIO_ENABLE1_REG] | M32 | M33 + + print(hex(mem32[GPIO_OUT_REG]), hex(mem32[GPIO_OUT1_REG])) + + # Set outputs to 1 like + # p16(1) + # p17(1) + # p32(1) + # p33(1) + mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] | M16 | M17 + mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] | M32 | M33 + + print(hex(mem32[GPIO_OUT_REG]), hex(mem32[GPIO_OUT1_REG])) + + # Set outputs to 0 like + # p16(0) + # p17(0) + # p32(0) + # p33(0) + mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] & ~(M16 | M17) + mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] & ~(M32 | M33) + + print(hex(mem32[GPIO_OUT_REG]), hex(mem32[GPIO_OUT1_REG])) + + while True: + # Set outputs to 1 + mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] | M16 | M17 + mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] | M32 | M33 + + # Set outputs to 0 + mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] & ~(M16 | M17) + mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] & ~(M32 | M33) + + +Output is:: + + 0x0 0x0 + 0x30000 0x3 + 0x0 0x0 + +Pins 16 and 17 are switched synchronously: + +.. image:: img/mem32_gpio_output.jpg + +Same image on pins 32 and 33. + +Note that pins 34-36 and 39 are inputs only. Also pins 1 and 3 are Tx, Rx of the REPL UART, +pins 6-11 are connected to the built-in SPI flash. diff --git a/docs/esp32/tutorial/pwm.rst b/docs/esp32/tutorial/pwm.rst index 12d10a86b947..2650284d35f4 100644 --- a/docs/esp32/tutorial/pwm.rst +++ b/docs/esp32/tutorial/pwm.rst @@ -50,7 +50,7 @@ low all of the time. * Example of a smooth frequency change:: - from utime import sleep + from time import sleep from machine import Pin, PWM F_MIN = 500 @@ -75,7 +75,7 @@ low all of the time. * Example of a smooth duty change:: - from utime import sleep + from time import sleep from machine import Pin, PWM DUTY_MAX = 2**16 - 1 diff --git a/docs/library/asyncio.rst b/docs/library/asyncio.rst new file mode 100644 index 000000000000..b57f1ee04eae --- /dev/null +++ b/docs/library/asyncio.rst @@ -0,0 +1,364 @@ +:mod:`asyncio` --- asynchronous I/O scheduler +============================================= + +.. module:: asyncio + :synopsis: asynchronous I/O scheduler for writing concurrent code + +|see_cpython_module| +`asyncio `_ + +Example:: + + import asyncio + + async def blink(led, period_ms): + while True: + led.on() + await asyncio.sleep_ms(5) + led.off() + await asyncio.sleep_ms(period_ms) + + async def main(led1, led2): + asyncio.create_task(blink(led1, 700)) + asyncio.create_task(blink(led2, 400)) + await asyncio.sleep_ms(10_000) + + # Running on a pyboard + from pyb import LED + asyncio.run(main(LED(1), LED(2))) + + # Running on a generic board + from machine import Pin + asyncio.run(main(Pin(1), Pin(2))) + +Core functions +-------------- + +.. function:: create_task(coro) + + Create a new task from the given coroutine and schedule it to run. + + Returns the corresponding `Task` object. + +.. function:: current_task() + + Return the `Task` object associated with the currently running task. + +.. function:: run(coro) + + Create a new task from the given coroutine and run it until it completes. + + Returns the value returned by *coro*. + +.. function:: sleep(t) + + Sleep for *t* seconds (can be a float). + + This is a coroutine. + +.. function:: sleep_ms(t) + + Sleep for *t* milliseconds. + + This is a coroutine, and a MicroPython extension. + +Additional functions +-------------------- + +.. function:: wait_for(awaitable, timeout) + + Wait for the *awaitable* to complete, but cancel it if it takes longer + than *timeout* seconds. If *awaitable* is not a task then a task will be + created from it. + + If a timeout occurs, it cancels the task and raises ``asyncio.TimeoutError``: + this should be trapped by the caller. The task receives + ``asyncio.CancelledError`` which may be ignored or trapped using ``try...except`` + or ``try...finally`` to run cleanup code. + + Returns the return value of *awaitable*. + + This is a coroutine. + +.. function:: wait_for_ms(awaitable, timeout) + + Similar to `wait_for` but *timeout* is an integer in milliseconds. + + This is a coroutine, and a MicroPython extension. + +.. function:: gather(*awaitables, return_exceptions=False) + + Run all *awaitables* concurrently. Any *awaitables* that are not tasks are + promoted to tasks. + + Returns a list of return values of all *awaitables*. + + This is a coroutine. + +class Task +---------- + +.. class:: Task() + + This object wraps a coroutine into a running task. Tasks can be waited on + using ``await task``, which will wait for the task to complete and return + the return value of the task. + + Tasks should not be created directly, rather use `create_task` to create them. + +.. method:: Task.cancel() + + Cancel the task by injecting ``asyncio.CancelledError`` into it. The task may + ignore this exception. Cleanup code may be run by trapping it, or via + ``try ... finally``. + +class Event +----------- + +.. class:: Event() + + Create a new event which can be used to synchronise tasks. Events start + in the cleared state. + +.. method:: Event.is_set() + + Returns ``True`` if the event is set, ``False`` otherwise. + +.. method:: Event.set() + + Set the event. Any tasks waiting on the event will be scheduled to run. + + Note: This must be called from within a task. It is not safe to call this + from an IRQ, scheduler callback, or other thread. See `ThreadSafeFlag`. + +.. method:: Event.clear() + + Clear the event. + +.. method:: Event.wait() + + Wait for the event to be set. If the event is already set then it returns + immediately. + + This is a coroutine. + +class ThreadSafeFlag +-------------------- + +.. class:: ThreadSafeFlag() + + Create a new flag which can be used to synchronise a task with code running + outside the asyncio loop, such as other threads, IRQs, or scheduler + callbacks. Flags start in the cleared state. The class does not currently + work under the Unix build of MicroPython. + +.. method:: ThreadSafeFlag.set() + + Set the flag. If there is a task waiting on the flag, it will be scheduled + to run. + +.. method:: ThreadSafeFlag.clear() + + Clear the flag. This may be used to ensure that a possibly previously-set + flag is clear before waiting for it. + +.. method:: ThreadSafeFlag.wait() + + Wait for the flag to be set. If the flag is already set then it returns + immediately. The flag is automatically reset upon return from ``wait``. + + A flag may only be waited on by a single task at a time. + + This is a coroutine. + +class Lock +---------- + +.. class:: Lock() + + Create a new lock which can be used to coordinate tasks. Locks start in + the unlocked state. + + In addition to the methods below, locks can be used in an ``async with`` statement. + +.. method:: Lock.locked() + + Returns ``True`` if the lock is locked, otherwise ``False``. + +.. method:: Lock.acquire() + + Wait for the lock to be in the unlocked state and then lock it in an atomic + way. Only one task can acquire the lock at any one time. + + This is a coroutine. + +.. method:: Lock.release() + + Release the lock. If any tasks are waiting on the lock then the next one in the + queue is scheduled to run and the lock remains locked. Otherwise, no tasks are + waiting an the lock becomes unlocked. + +TCP stream connections +---------------------- + +.. function:: open_connection(host, port, ssl=None) + + Open a TCP connection to the given *host* and *port*. The *host* address will be + resolved using `socket.getaddrinfo`, which is currently a blocking call. + If *ssl* is a `ssl.SSLContext` object, this context is used to create the transport; + if *ssl* is ``True``, a default context is used. + + Returns a pair of streams: a reader and a writer stream. + Will raise a socket-specific ``OSError`` if the host could not be resolved or if + the connection could not be made. + + This is a coroutine. + +.. function:: start_server(callback, host, port, backlog=5, ssl=None) + + Start a TCP server on the given *host* and *port*. The *callback* will be + called with incoming, accepted connections, and be passed 2 arguments: reader + and writer streams for the connection. + + If *ssl* is a `ssl.SSLContext` object, this context is used to create the transport. + + Returns a `Server` object. + + This is a coroutine. + +.. class:: Stream() + + This represents a TCP stream connection. To minimise code this class implements + both a reader and a writer, and both ``StreamReader`` and ``StreamWriter`` alias to + this class. + +.. method:: Stream.get_extra_info(v) + + Get extra information about the stream, given by *v*. The valid values for *v* are: + ``peername``. + +.. method:: Stream.close() + + Close the stream. + +.. method:: Stream.wait_closed() + + Wait for the stream to close. + + This is a coroutine. + +.. method:: Stream.read(n=-1) + + Read up to *n* bytes and return them. If *n* is not provided or -1 then read all + bytes until EOF. The returned value will be an empty bytes object if EOF is + encountered before any bytes are read. + + This is a coroutine. + +.. method:: Stream.readinto(buf) + + Read up to n bytes into *buf* with n being equal to the length of *buf*. + + Return the number of bytes read into *buf*. + + This is a coroutine, and a MicroPython extension. + +.. method:: Stream.readexactly(n) + + Read exactly *n* bytes and return them as a bytes object. + + Raises an ``EOFError`` exception if the stream ends before reading *n* bytes. + + This is a coroutine. + +.. method:: Stream.readline() + + Read a line and return it. + + This is a coroutine. + +.. method:: Stream.write(buf) + + Accumulated *buf* to the output buffer. The data is only flushed when + `Stream.drain` is called. It is recommended to call `Stream.drain` immediately + after calling this function. + +.. method:: Stream.drain() + + Drain (write) all buffered output data out to the stream. + + This is a coroutine. + +.. class:: Server() + + This represents the server class returned from `start_server`. It can be used + in an ``async with`` statement to close the server upon exit. + +.. method:: Server.close() + + Close the server. + +.. method:: Server.wait_closed() + + Wait for the server to close. + + This is a coroutine. + +Event Loop +---------- + +.. function:: get_event_loop() + + Return the event loop used to schedule and run tasks. See `Loop`. + +.. function:: new_event_loop() + + Reset the event loop and return it. + + Note: since MicroPython only has a single event loop this function just + resets the loop's state, it does not create a new one. + +.. class:: Loop() + + This represents the object which schedules and runs tasks. It cannot be + created, use `get_event_loop` instead. + +.. method:: Loop.create_task(coro) + + Create a task from the given *coro* and return the new `Task` object. + +.. method:: Loop.run_forever() + + Run the event loop until `stop()` is called. + +.. method:: Loop.run_until_complete(awaitable) + + Run the given *awaitable* until it completes. If *awaitable* is not a task + then it will be promoted to one. + +.. method:: Loop.stop() + + Stop the event loop. + +.. method:: Loop.close() + + Close the event loop. + +.. method:: Loop.set_exception_handler(handler) + + Set the exception handler to call when a Task raises an exception that is not + caught. The *handler* should accept two arguments: ``(loop, context)``. + +.. method:: Loop.get_exception_handler() + + Get the current exception handler. Returns the handler, or ``None`` if no + custom handler is set. + +.. method:: Loop.default_exception_handler(context) + + The default exception handler that is called. + +.. method:: Loop.call_exception_handler(context) + + Call the current exception handler. The argument *context* is passed through and + is a dictionary containing keys: ``'message'``, ``'exception'``, ``'future'``. diff --git a/docs/library/deflate.rst b/docs/library/deflate.rst new file mode 100644 index 000000000000..fad577870518 --- /dev/null +++ b/docs/library/deflate.rst @@ -0,0 +1,182 @@ +:mod:`deflate` -- deflate compression & decompression +===================================================== + +.. module:: deflate + :synopsis: deflate compression & decompression + +This module allows compression and decompression of binary data with the +`DEFLATE algorithm `_ +(commonly used in the zlib library and gzip archiver). + +**Availability:** + +* Added in MicroPython v1.21. + +* Decompression: Enabled via the ``MICROPY_PY_DEFLATE`` build option, on by default + on ports with the "extra features" level or higher (which is most boards). + +* Compression: Enabled via the ``MICROPY_PY_DEFLATE_COMPRESS`` build option, on + by default on ports with the "full features" level or higher (generally this means + you need to build your own firmware to enable this). + +Classes +------- + +.. class:: DeflateIO(stream, format=AUTO, wbits=0, close=False, /) + + This class can be used to wrap a *stream* which is any + :term:`stream-like ` object such as a file, socket, or stream + (including :class:`io.BytesIO`). It is itself a stream and implements the + standard read/readinto/write/close methods. + + The *stream* must be a blocking stream. Non-blocking streams are currently + not supported. + + The *format* can be set to any of the constants defined below, and defaults + to ``AUTO`` which for decompressing will auto-detect gzip or zlib streams, + and for compressing it will generate a raw stream. + + The *wbits* parameter sets the base-2 logarithm of the DEFLATE dictionary + window size. So for example, setting *wbits* to ``10`` sets the window size + to 1024 bytes. Valid values are ``5`` to ``15`` inclusive (corresponding to + window sizes of 32 to 32k bytes). + + If *wbits* is set to ``0`` (the default), then for compression a window size + of 256 bytes will be used (as if *wbits* was set to 8). For decompression, it + depends on the format: + + * ``RAW`` will use 256 bytes (corresponding to *wbits* set to 8). + * ``ZLIB`` (or ``AUTO`` with zlib detected) will use the value from the zlib + header. + * ``GZIP`` (or ``AUTO`` with gzip detected) will use 32 kilobytes + (corresponding to *wbits* set to 15). + + See the :ref:`window size ` notes below for more information + about the window size, zlib, and gzip streams. + + If *close* is set to ``True`` then the underlying stream will be closed + automatically when the :class:`deflate.DeflateIO` stream is closed. This is + useful if you want to return a :class:`deflate.DeflateIO` stream that wraps + another stream and not have the caller need to know about managing the + underlying stream. + + If compression is enabled, a given :class:`deflate.DeflateIO` instance + supports both reading and writing. For example, a bidirectional stream like + a socket can be wrapped, which allows for compression/decompression in both + directions. + +Constants +--------- + +.. data:: deflate.AUTO + deflate.RAW + deflate.ZLIB + deflate.GZIP + + Supported values for the *format* parameter. + +Examples +-------- + +A typical use case for :class:`deflate.DeflateIO` is to read or write a compressed +file from storage: + +.. code:: python + + import deflate + + # Writing a zlib-compressed stream (uses the default window size of 256 bytes). + with open("data.gz", "wb") as f: + with deflate.DeflateIO(f, deflate.ZLIB) as d: + # Use d.write(...) etc + + # Reading a zlib-compressed stream (auto-detect window size). + with open("data.z", "rb") as f: + with deflate.DeflateIO(f, deflate.ZLIB) as d: + # Use d.read(), d.readinto(), etc. + +Because :class:`deflate.DeflateIO` is a stream, it can be used for example +with :meth:`json.dump` and :meth:`json.load` (and any other places streams can +be used): + +.. code:: python + + import deflate, json + + # Write a dictionary as JSON in gzip format, with a + # small (64 byte) window size. + config = { ... } + with open("config.gz", "wb") as f: + with deflate.DeflateIO(f, deflate.GZIP, 6) as f: + json.dump(config, f) + + # Read back that dictionary. + with open("config.gz", "rb") as f: + with deflate.DeflateIO(f, deflate.GZIP, 6) as f: + config = json.load(f) + +If your source data is not in a stream format, you can use :class:`io.BytesIO` +to turn it into a stream suitable for use with :class:`deflate.DeflateIO`: + +.. code:: python + + import deflate, io + + # Decompress a bytes/bytearray value. + compressed_data = get_data_z() + with deflate.DeflateIO(io.BytesIO(compressed_data), deflate.ZLIB) as d: + decompressed_data = d.read() + + # Compress a bytes/bytearray value. + uncompressed_data = get_data() + stream = io.BytesIO() + with deflate.DeflateIO(stream, deflate.ZLIB) as d: + d.write(uncompressed_data) + compressed_data = stream.getvalue() + +.. _deflate_wbits: + +Deflate window size +------------------- + +The window size limits how far back in the stream the (de)compressor can +reference. Increasing the window size will improve compression, but will require +more memory and make the compressor slower. + +If an input stream was compressed a given window size, then `DeflateIO` +using a smaller window size will fail mid-way during decompression with +:exc:`OSError`, but only if a back-reference actually refers back further +than the decompressor's window size. This means it may be possible to decompress +with a smaller window size. For example, this would trivially be the case if the +original uncompressed data is shorter than the window size. + +Decompression +~~~~~~~~~~~~~ + +The zlib format includes a header which specifies the window size that was used +to compress the data. This indicates the maximum window size required to +decompress this stream. If this header value is less than the specified *wbits* +value (or if *wbits* is unset), then the header value will be used. + +The gzip format does not include the window size in the header, and assumes that +all gzip compressors (e.g. the ``gzip`` utility, or CPython's implementation of +:class:`gzip.GzipFile`) use the maximum window size of 32kiB. For this reason, +if the *wbits* parameter is not set, the decompressor will use a 32 kiB window +size (corresponding to *wbits* set to 15). This means that to be able to +decompress an arbitrary gzip stream, you must have at least this much RAM +available. If you control the source data, consider instead using the zlib +format with a smaller window size. + +The raw format has no header and therefore does not include any information +about the window size. If *wbits* is not set, then it will default to a window +size of 256 bytes, which may not be large enough for a given stream. Therefore +it is recommended that you should always explicitly set *wbits* if using the raw +format. + +Compression +~~~~~~~~~~~ + +For compression, MicroPython will default to a window size of 256 bytes for all +formats. This provides a reasonable amount of compression with minimal memory +usage and fast compression time, and will generate output that will work with +any decompressor. diff --git a/docs/library/esp.rst b/docs/library/esp.rst index 8920c8241ea0..9c20b5e8b2d8 100644 --- a/docs/library/esp.rst +++ b/docs/library/esp.rst @@ -62,12 +62,35 @@ Functions .. function:: flash_erase(sector_no) -.. function:: osdebug(level) +.. function:: osdebug(uart_no) - Turn esp os debugging messages on or off. + .. note:: This is the ESP8266 form of this function. - The *level* parameter sets the threshold for the log messages for all esp components. - The log levels are defined as constants: + Change the level of OS serial debug log messages. On boot, + OS serial debug log messages are disabled. + + ``uart_no`` is the number of the UART peripheral which should receive + OS-level output, or ``None`` to disable OS serial debug log messages. + +.. function:: osdebug(uart_no, [level]) + :no-index: + + .. note:: This is the ESP32 form of this function. + + Change the level of OS serial debug log messages. On boot, OS + serial debug log messages are limited to Error output only. + + The behaviour of this function depends on the arguments passed to it. The + following combinations are supported: + + ``osdebug(None)`` restores the default OS debug log message level + (``LOG_ERROR``). + + ``osdebug(0)`` enables all available OS debug log messages (in the + default build configuration this is ``LOG_INFO``). + + ``osdebug(0, level)`` sets the OS debug log message level to the + specified value. The log levels are defined as constants: * ``LOG_NONE`` -- No log output * ``LOG_ERROR`` -- Critical errors, software module can not recover on its own @@ -77,6 +100,15 @@ Functions * ``LOG_VERBOSE`` -- Bigger chunks of debugging information, or frequent messages which can potentially flood the output + .. note:: ``LOG_DEBUG`` and ``LOG_VERBOSE`` are not compiled into the + MicroPython binary by default, to save size. A custom build with a + modified "``sdkconfig``" source file is needed to see any output + at these log levels. + + .. note:: Log output on ESP32 is automatically suspended in "Raw REPL" mode, + to prevent communications issues. This means OS level logging is never + seen when using ``mpremote run`` and similar tools. + .. function:: set_native_code_location(start, length) **Note**: ESP8266 only diff --git a/docs/library/esp32.rst b/docs/library/esp32.rst index d9241d545c46..422329bf1e80 100644 --- a/docs/library/esp32.rst +++ b/docs/library/esp32.rst @@ -44,10 +44,6 @@ Functions Read the raw value of the internal temperature sensor, returning an integer. -.. function:: hall_sensor() - - Read the raw value of the internal Hall sensor, returning an integer. - .. function:: idf_heap_info(capabilities) Returns information about the ESP-IDF heap memory regions. One of them contains @@ -55,8 +51,6 @@ Functions buffers and other data. This data is useful to get a sense of how much memory is available to ESP-IDF and the networking stack in particular. It may shed some light on situations where ESP-IDF operations fail due to allocation failures. - The information returned is *not* useful to troubleshoot Python allocation failures, - use `micropython.mem_info()` instead. The capabilities parameter corresponds to ESP-IDF's ``MALLOC_CAP_XXX`` values but the two most useful ones are predefined as `esp32.HEAP_DATA` for data heap regions and @@ -72,6 +66,21 @@ Functions [(240, 0, 0, 0), (7288, 0, 0, 0), (16648, 4, 4, 4), (79912, 35712, 35512, 35108), (15072, 15036, 15036, 15036), (113840, 0, 0, 0)] + .. note:: Free IDF heap memory in the `esp32.HEAP_DATA` region is available + to be automatically added to the MicroPython heap to prevent a + MicroPython allocation from failing. However, the information returned + here is otherwise *not* useful to troubleshoot Python allocation + failures. :func:`micropython.mem_info()` and :func:`gc.mem_free()` should + be used instead: + + The "max new split" value in :func:`micropython.mem_info()` output + corresponds to the largest free block of ESP-IDF heap that could be + automatically added on demand to the MicroPython heap. + + The result of :func:`gc.mem_free()` is the total of the current "free" + and "max new split" values printed by :func:`micropython.mem_info()`. + + Flash partitions ---------------- @@ -111,6 +120,11 @@ methods to enable over-the-air (OTA) updates. Sets the partition as the boot partition. + .. note:: Do not enter :func:`deepsleep` after changing + the OTA boot partition, without first performing a hard + :func:`reset` or power cycle. This ensures the bootloader + will validate the new image before booting. + .. method:: Partition.get_next_update() Gets the next update partition after this one, and returns a new Partition object. @@ -179,7 +193,7 @@ numbers specified in ``write_pulses`` are multiplied by the resolution to define the pulses. ``clock_div`` is an 8-bit divider (0-255) and each pulse can be defined by -multiplying the resolution by a 15-bit (0-32,768) number. There are eight +multiplying the resolution by a 15-bit (1-``PULSE_MAX``) number. There are eight channels (0-7) and each can have a different clock divider. So, in the example above, the 80MHz clock is divided by 8. Thus the @@ -212,7 +226,7 @@ For more details see Espressif's `ESP-IDF RMT documentation. ``100``) and the output level to apply the carrier to (a boolean as per *idle_level*). -.. method:: RMT.source_freq() +.. classmethod:: RMT.source_freq() Returns the source clock frequency. Currently the source clock is not configurable so this will always return 80MHz. @@ -250,10 +264,10 @@ For more details see Espressif's `ESP-IDF RMT documentation. **Mode 3:** *duration* and *data* are lists or tuples of equal length, specifying individual durations and the output level for each. - Durations are in integer units of the channel resolution (as described - above), between 1 and 32767 units. Output levels are any value that can - be converted to a boolean, with ``True`` representing high voltage and - ``False`` representing low. + Durations are in integer units of the channel resolution (as + described above), between 1 and ``PULSE_MAX`` units. Output levels + are any value that can be converted to a boolean, with ``True`` + representing high voltage and ``False`` representing low. If transmission of an earlier sequence is in progress then this method will block until that transmission is complete before beginning the new sequence. @@ -276,6 +290,13 @@ For more details see Espressif's `ESP-IDF RMT documentation. Passing in no argument will not change the channel. This function returns the current channel number. +Constants +--------- + +.. data:: RMT.PULSE_MAX + + Maximum integer that can be set for a pulse duration. + Ultra-Low-Power co-processor ---------------------------- diff --git a/docs/library/espnow.rst b/docs/library/espnow.rst index f821de59aa7f..f0b592dffc8a 100644 --- a/docs/library/espnow.rst +++ b/docs/library/espnow.rst @@ -287,7 +287,7 @@ after reboot/reset). This reduces the reliability of receiving ESP-NOW messages .. method:: ESPNow.irecv([timeout_ms]) - Works like `ESPNow.recv()` but will re-use internal bytearrays to store the + Works like `ESPNow.recv()` but will reuse internal bytearrays to store the return values: ``[mac, msg]``, so that no new memory is allocated on each call. @@ -632,7 +632,7 @@ Supporting asyncio ------------------ A supplementary module (`aioespnow`) is available to provide -:doc:`asyncio` support. +:doc:`asyncio` support. **Note:** Asyncio support is available on all ESP32 targets as well as those ESP8266 boards which include the asyncio module (ie. ESP8266 devices with at @@ -642,7 +642,7 @@ A small async server example:: import network import aioespnow - import uasyncio as asyncio + import asyncio # A WLAN interface must be active to send()/recv() network.WLAN(network.STA_IF).active(True) @@ -680,7 +680,7 @@ A small async server example:: asyncio.run(main(e, peer, 120, 10)) .. module:: aioespnow - :synopsis: ESP-NOW :doc:`uasyncio` support + :synopsis: ESP-NOW :doc:`asyncio` support .. class:: AIOESPNow() diff --git a/docs/library/gc.rst b/docs/library/gc.rst index c823aed3e688..2ba204e2293c 100644 --- a/docs/library/gc.rst +++ b/docs/library/gc.rst @@ -24,7 +24,7 @@ Functions .. function:: mem_alloc() - Return the number of bytes of heap RAM that are allocated. + Return the number of bytes of heap RAM that are allocated by Python code. .. admonition:: Difference to CPython :class: attention @@ -33,8 +33,8 @@ Functions .. function:: mem_free() - Return the number of bytes of available heap RAM, or -1 if this amount - is not known. + Return the number of bytes of heap RAM that is available for Python + code to allocate, or -1 if this amount is not known. .. admonition:: Difference to CPython :class: attention diff --git a/docs/library/gzip.rst b/docs/library/gzip.rst new file mode 100644 index 000000000000..f36f896db3a1 --- /dev/null +++ b/docs/library/gzip.rst @@ -0,0 +1,106 @@ +:mod:`gzip` -- gzip compression & decompression +=============================================== + +.. module:: gzip + :synopsis: gzip compression & decompression + +|see_cpython_module| :mod:`python:gzip`. + +This module allows compression and decompression of binary data with the +`DEFLATE algorithm `_ used by the gzip +file format. + +.. note:: Prefer to use :class:`deflate.DeflateIO` instead of the functions in this + module as it provides a streaming interface to compression and decompression + which is convenient and more memory efficient when working with reading or + writing compressed data to a file, socket, or stream. + +**Availability:** + +* This module is **not present by default** in official MicroPython firmware + releases as it duplicates functionality available in the :mod:`deflate + ` module. + +* A copy of this module can be installed (or frozen) + from :term:`micropython-lib` (`source `_). + See :ref:`packages` for more information. This documentation describes that module. + +* Compression support will only be available if compression support is enabled + in the built-in :mod:`deflate ` module. + +Functions +--------- + +.. function:: open(filename, mode, /) + + Wrapper around built-in :func:`open` returning a GzipFile instance. + +.. function:: decompress(data, /) + + Decompresses *data* into a bytes object. + +.. function:: compress(data, /) + + Compresses *data* into a bytes object. + +Classes +------- + +.. class:: GzipFile(*, fileobj, mode) + + This class can be used to wrap a *fileobj* which is any + :term:`stream-like ` object such as a file, socket, or stream + (including :class:`io.BytesIO`). It is itself a stream and implements the + standard read/readinto/write/close methods. + + When the *mode* argument is ``"rb"``, reads from the GzipFile instance will + decompress the data in the underlying stream and return decompressed data. + + If compression support is enabled then the *mode* argument can be set to + ``"wb"``, and writes to the GzipFile instance will be compressed and written + to the underlying stream. + + By default the GzipFile class will read and write data using the gzip file + format, including a header and footer with checksum and a window size of 512 + bytes. + + The **file**, **compresslevel**, and **mtime** arguments are not + supported. **fileobj** and **mode** must always be specified as keyword + arguments. + +Examples +-------- + +A typical use case for :class:`gzip.GzipFile` is to read or write a compressed +file from storage: + +.. code:: python + + import gzip + + # Reading: + with open("data.gz", "rb") as f: + with gzip.GzipFile(fileobj=f, mode="rb") as g: + # Use g.read(), g.readinto(), etc. + + # Same, but using gzip.open: + with gzip.open("data.gz", "rb") as f: + # Use f.read(), f.readinto(), etc. + + # Writing: + with open("data.gz", "wb") as f: + with gzip.GzipFile(fileobj=f, mode="wb") as g: + # Use g.write(...) etc + + # Same, but using gzip.open: + with gzip.open("data.gz", "wb") as f: + # Use f.write(...) etc + + # Write a dictionary as JSON in gzip format, with a + # small (64 byte) window size. + config = { ... } + with gzip.open("config.gz", "wb") as f: + json.dump(config, f) + +For guidance on working with gzip sources and choosing the window size see the +note at the :ref:`end of the deflate documentation `. diff --git a/docs/library/index.rst b/docs/library/index.rst index 985a7ad770d1..4a7f78ecf318 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -57,18 +57,21 @@ library. :maxdepth: 1 array.rst + asyncio.rst binascii.rst builtins.rst cmath.rst collections.rst errno.rst gc.rst + gzip.rst hashlib.rst heapq.rst io.rst json.rst math.rst os.rst + platform.rst random.rst re.rst select.rst @@ -77,7 +80,6 @@ library. struct.rst sys.rst time.rst - uasyncio.rst zlib.rst _thread.rst @@ -95,6 +97,7 @@ the following libraries. bluetooth.rst btree.rst cryptolib.rst + deflate.rst framebuf.rst machine.rst micropython.rst @@ -191,34 +194,27 @@ The following libraries are specific to the Zephyr port. Extending built-in libraries from Python ---------------------------------------- -Many built-in modules are actually named ``umodule`` rather than ``module``, but -MicroPython will alias any module prefixed with a ``u`` to the non-``u`` -version. This means that, for example, ``import time`` will first attempt to -resolve from the filesystem, and then failing that will fall back to the -built-in ``utime``. On the other hand, ``import utime`` will always go directly -to the built-in. +A subset of the built-in modules are able to be extended by Python code by +providing a module of the same name in the filesystem. This extensibility +applies to the following Python standard library modules which are built-in to +the firmware: ``array``, ``binascii``, ``collections``, ``errno``, ``gzip``, +``hashlib``, ``heapq``, ``io``, ``json``, ``os``, ``platform``, ``random``, +``re``, ``select``, ``socket``, ``ssl``, ``struct``, ``time`` ``zlib``, as well +as the MicroPython-specific ``machine`` module. All other built-in modules +cannot be extended from the filesystem. This allows the user to provide an extended implementation of a built-in library (perhaps to provide additional CPython compatibility or missing functionality). -The user-provided module (in ``module.py``) can still use the built-in -functionality by importing ``umodule`` directly (e.g. typically an extension -module ``time.py`` will do ``from utime import *``). This is used extensively -in :term:`micropython-lib`. See :ref:`packages` for more information. - -This extensibility applies to the following Python standard library modules -which are built-in to the firmware: ``array``, ``binascii``, ``collections``, -``errno``, ``hashlib``, ``heapq``, ``io``, ``json``, ``os``, ``platform``, -``random``, ``re``, ``select``, ``socket``, ``ssl``, ``struct``, ``sys``, -``time``, ``zlib``, as well as the MicroPython-specific libraries: ``bluepy``, -``bluetooth``, ``machine``, ``timeq``, ``websocket``. All other built-in -modules cannot be extended from the filesystem. - -*Other than when you specifically want to force the use of the built-in module, -we recommend always using* ``import module`` *rather than* ``import umodule``. - -**Note:** In MicroPython v1.21.0 and higher, it is now possible to force an -import of the built-in module by clearing ``sys.path`` during the import. For -example, in ``time.py``, you can write:: +This is used extensively in :term:`micropython-lib`, see :ref:`packages` for +more information. The filesystem module will typically do a wildcard import of +the built-in module in order to inherit all the globals (classes, functions and +variables) from the built-in. + +In MicroPython v1.21.0 and higher, to prevent the filesystem module from +importing itself, it can force an import of the built-in module it by +temporarily clearing ``sys.path`` during the import. For example, to extend the +``time`` module from Python, a file named ``time.py`` on the filesystem would +do the following:: _path = sys.path sys.path = () @@ -228,6 +224,25 @@ example, in ``time.py``, you can write:: sys.path = _path del _path -This is now the preferred way (instead of ``from utime import *``), as the -``u``-prefix will be removed from the names of built-in modules in a future -version of MicroPython. + def extra_method(): + pass + +The result is that ``time.py`` contains all the globals of the built-in ``time`` +module, but adds ``extra_method``. + +In earlier versions of MicroPython, you can force an import of a built-in module +by appending a ``u`` to the start of its name. For example, ``import utime`` +instead of ``import time``. For example, ``time.py`` on the filesystem could +look like:: + + from utime import * + + def extra_method(): + pass + +This way is still supported, but the ``sys.path`` method described above is now +preferred as the ``u``-prefix will be removed from the names of built-in +modules in a future version of MicroPython. + +*Other than when it specifically needs to force the use of the built-in module, +code should always use* ``import module`` *rather than* ``import umodule``. diff --git a/docs/library/io.rst b/docs/library/io.rst index 6b4b9f1a476f..caa59895227d 100644 --- a/docs/library/io.rst +++ b/docs/library/io.rst @@ -86,16 +86,6 @@ Functions Classes ------- -.. class:: FileIO(...) - - This is type of a file open in binary mode, e.g. using ``open(name, "rb")``. - You should not instantiate this class directly. - -.. class:: TextIOWrapper(...) - - This is type of a file open in text mode, e.g. using ``open(name, "rt")``. - You should not instantiate this class directly. - .. class:: StringIO([string]) .. class:: BytesIO([string]) diff --git a/docs/library/machine.ADCBlock.rst b/docs/library/machine.ADCBlock.rst index 56a468dd621b..eb94362d5597 100644 --- a/docs/library/machine.ADCBlock.rst +++ b/docs/library/machine.ADCBlock.rst @@ -39,9 +39,9 @@ Methods Configure the ADC peripheral. *bits* will set the resolution of the conversion process. -.. method:: ADCBlock.connect(channel) - ADCBlock.connect(source) - ADCBlock.connect(channel, source) +.. method:: ADCBlock.connect(channel, *, ...) + ADCBlock.connect(source, *, ...) + ADCBlock.connect(channel, source, *, ...) Connect up a channel on the ADC peripheral so it is ready for sampling, and return an :ref:`ADC ` object that represents that connection. @@ -56,3 +56,6 @@ Methods If both *channel* and *source* are given then they are connected together and made ready for sampling. + + Any additional keyword arguments are used to configure the returned ADC object, + via its :meth:`init ` method. diff --git a/docs/library/machine.I2S.rst b/docs/library/machine.I2S.rst index 2244ef4202dc..84edb94e78db 100644 --- a/docs/library/machine.I2S.rst +++ b/docs/library/machine.I2S.rst @@ -47,7 +47,7 @@ I2S objects can be created and initialized using:: 3 modes of operation are supported: - blocking - non-blocking - - uasyncio + - asyncio blocking:: @@ -63,13 +63,13 @@ non-blocking:: audio_in.irq(i2s_callback) # i2s_callback is called when buf is filled num_read = audio_in.readinto(buf) # returns immediately -uasyncio:: +asyncio:: - swriter = uasyncio.StreamWriter(audio_out) + swriter = asyncio.StreamWriter(audio_out) swriter.write(buf) await swriter.drain() - sreader = uasyncio.StreamReader(audio_in) + sreader = asyncio.StreamReader(audio_in) num_read = await sreader.readinto(buf) Some codec devices like the WM8960 or SGTL5000 require separate initialization diff --git a/docs/library/machine.WDT.rst b/docs/library/machine.WDT.rst index 95893cec36be..cf77df963208 100644 --- a/docs/library/machine.WDT.rst +++ b/docs/library/machine.WDT.rst @@ -25,9 +25,8 @@ Constructors Create a WDT object and start it. The timeout must be given in milliseconds. Once it is running the timeout cannot be changed and the WDT cannot be stopped either. - Notes: On the esp32 the minimum timeout is 1 second. On the esp8266 a timeout - cannot be specified, it is determined by the underlying system. On rp2040 devices, - the maximum timeout is 8388 ms. + Notes: On the esp8266 a timeout cannot be specified, it is determined by the underlying system. + On rp2040 devices, the maximum timeout is 8388 ms. Methods ------- diff --git a/docs/library/neopixel.rst b/docs/library/neopixel.rst index 543f2588125e..edcbc9345c30 100644 --- a/docs/library/neopixel.rst +++ b/docs/library/neopixel.rst @@ -9,9 +9,7 @@ This module provides a driver for WS2818 / NeoPixel LEDs. .. note:: This module is only included by default on the ESP8266, ESP32 and RP2 ports. On STM32 / Pyboard and others, you can either install the ``neopixel`` package using :term:`mip`, or you can download the module - directly from - `_ - and copy it to the filesystem. + directly from :term:`micropython-lib` and copy it to the filesystem. class NeoPixel -------------- diff --git a/docs/library/network.rst b/docs/library/network.rst index b13c84123ce7..cc508842942a 100644 --- a/docs/library/network.rst +++ b/docs/library/network.rst @@ -171,8 +171,8 @@ The following are functions available in the network module. .. function:: hostname([name]) - Get or set the hostname that will identify this device on the network. It is - applied to all interfaces. + Get or set the hostname that will identify this device on the network. It will + be used by all interfaces. This hostname is used for: * Sending to the DHCP server in the client request. (If using DHCP) @@ -182,6 +182,17 @@ The following are functions available in the network module. If the function is called without parameters, it returns the current hostname. + A change in hostname is typically only applied during connection. For DHCP + this is because the hostname is part of the DHCP client request, and the + implementation of mDNS in most ports only initialises the hostname once + during connection. For this reason, you must set the hostname before + activating/connecting your network interfaces. + + The length of the hostname is limited to 32 characters. + :term:`MicroPython ports ` may choose to set a lower + limit for memory reasons. If the given name does not fit, a `ValueError` + is raised. + The default hostname is typically the name of the board. .. function:: phy_mode([mode]) diff --git a/docs/library/platform.rst b/docs/library/platform.rst new file mode 100644 index 000000000000..c091477d84cb --- /dev/null +++ b/docs/library/platform.rst @@ -0,0 +1,38 @@ +:mod:`platform` -- access to underlying platform’s identifying data +=================================================================== + +.. module:: platform + :synopsis: access to underlying platform’s identifying data + +|see_cpython_module| :mod:`python:platform`. + +This module tries to retrieve as much platform-identifying data as possible. It +makes this information available via function APIs. + +Functions +--------- + +.. function:: platform() + + Returns a string identifying the underlying platform. This string is composed + of several substrings in the following order, delimited by dashes (``-``): + + - the name of the platform system (e.g. Unix, Windows or MicroPython) + - the MicroPython version + - the architecture of the platform + - the version of the underlying platform + - the concatenation of the name of the libc that MicroPython is linked to + and its corresponding version. + + For example, this could be + ``"MicroPython-1.20.0-xtensa-IDFv4.2.4-with-newlib3.0.0"``. + +.. function:: python_compiler() + + Returns a string identifying the compiler used for compiling MicroPython. + +.. function:: libc_ver() + + Returns a tuple of strings *(lib, version)*, where *lib* is the name of the + libc that MicroPython is linked to, and *version* the corresponding version + of this libc. diff --git a/docs/library/random.rst b/docs/library/random.rst index dd8b47c80f08..be56eb088eae 100644 --- a/docs/library/random.rst +++ b/docs/library/random.rst @@ -24,7 +24,7 @@ This module implements a pseudo-random number generator (PRNG). .. note:: The :func:`randrange`, :func:`randint` and :func:`choice` functions are only - available if the ``MICROPY_PY_URANDOM_EXTRA_FUNCS`` configuration option is + available if the ``MICROPY_PY_RANDOM_EXTRA_FUNCS`` configuration option is enabled. @@ -73,7 +73,7 @@ Other Functions supported by the port) initialise the PRNG with a true random number (usually a hardware generated random number). - The ``None`` case only works if ``MICROPY_PY_URANDOM_SEED_INIT_FUNC`` is + The ``None`` case only works if ``MICROPY_PY_RANDOM_SEED_INIT_FUNC`` is enabled by the port, otherwise it raises ``ValueError``. .. function:: choice(sequence) diff --git a/docs/library/ssl.rst b/docs/library/ssl.rst index 924b03b3541b..f9be27745379 100644 --- a/docs/library/ssl.rst +++ b/docs/library/ssl.rst @@ -15,36 +15,80 @@ Functions .. function:: ssl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, cadata=None, server_hostname=None, do_handshake=True) + Wrap the given *sock* and return a new wrapped-socket object. The implementation + of this function is to first create an `SSLContext` and then call the `SSLContext.wrap_socket` + method on that context object. The arguments *sock*, *server_side* and *server_hostname* are + passed through unchanged to the method call. The argument *do_handshake* is passed through as + *do_handshake_on_connect*. The remaining arguments have the following behaviour: + + - *cert_reqs* determines whether the peer (server or client) must present a valid certificate. + Note that for mbedtls based ports, ``ssl.CERT_NONE`` and ``ssl.CERT_OPTIONAL`` will not + validate any certificate, only ``ssl.CERT_REQUIRED`` will. + + - *cadata* is a bytes object containing the CA certificate chain (in DER format) that will + validate the peer's certificate. Currently only a single DER-encoded certificate is supported. + + Depending on the underlying module implementation in a particular + :term:`MicroPython port`, some or all keyword arguments above may be not supported. + +class SSLContext +---------------- + +.. class:: SSLContext(protocol, /) + + Create a new SSLContext instance. The *protocol* argument must be one of the ``PROTOCOL_*`` + constants. + +.. method:: SSLContext.load_cert_chain(certfile, keyfile) + + Load a private key and the corresponding certificate. The *certfile* is a string + with the file path of the certificate. The *keyfile* is a string with the file path + of the private key. + + .. admonition:: Difference to CPython + :class: attention + + MicroPython extension: *certfile* and *keyfile* can be bytes objects instead of + strings, in which case they are interpreted as the actual certificate/key data. + +.. method:: SSLContext.load_verify_locations(cafile=None, cadata=None) + + Load the CA certificate chain that will validate the peer's certificate. + *cafile* is the file path of the CA certificates. *cadata* is a bytes object + containing the CA certificates. Only one of these arguments should be provided. + +.. method:: SSLContext.get_ciphers() + + Get a list of enabled ciphers, returned as a list of strings. + +.. method:: SSLContext.set_ciphers(ciphers) + + Set the available ciphers for sockets created with this context. *ciphers* should be + a list of strings in the `IANA cipher suite format `_ . + +.. method:: SSLContext.wrap_socket(sock, *, server_side=False, do_handshake_on_connect=True, server_hostname=None) + Takes a `stream` *sock* (usually socket.socket instance of ``SOCK_STREAM`` type), - and returns an instance of ssl.SSLSocket, which wraps the underlying stream in - an SSL context. Returned object has the usual `stream` interface methods like + and returns an instance of ssl.SSLSocket, wrapping the underlying stream. + The returned object has the usual `stream` interface methods like ``read()``, ``write()``, etc. - A server-side SSL socket should be created from a normal socket returned from - :meth:`~socket.socket.accept()` on a non-SSL listening server socket. - - *do_handshake* determines whether the handshake is done as part of the ``wrap_socket`` + - *server_side* selects whether the wrapped socket is on the server or client side. + A server-side SSL socket should be created from a normal socket returned from + :meth:`~socket.socket.accept()` on a non-SSL listening server socket. + + - *do_handshake_on_connect* determines whether the handshake is done as part of the ``wrap_socket`` or whether it is deferred to be done as part of the initial reads or writes - (there is no ``do_handshake`` method as in CPython). For blocking sockets doing the handshake immediately is standard. For non-blocking sockets (i.e. when the *sock* passed into ``wrap_socket`` is in non-blocking mode) the handshake should generally be deferred because otherwise ``wrap_socket`` blocks until it completes. Note that in AXTLS the handshake can be deferred until the first read or write but it then blocks until completion. - - *cert_reqs* determines whether the peer (server or client) must present a valid certificate. - Note that for mbedtls based ports, ``ssl.CERT_NONE`` and ``ssl.CERT_OPTIONAL`` will not - validate any certificate, only ``ssl.CERT_REQUIRED`` will. - - - *cadata* is a bytes object containing the CA certificate chain (in DER format) that will - validate the peer's certificate. Currently only a single DER-encoded certificate is supported. - - *server_hostname* is for use as a client, and sets the hostname to check against the received server certificate. It also sets the name for Server Name Indication (SNI), allowing the server to present the proper certificate. - Depending on the underlying module implementation in a particular - :term:`MicroPython port`, some or all keyword arguments above may be not supported. - .. warning:: Some implementations of ``ssl`` module do NOT validate server certificates, @@ -55,6 +99,17 @@ Functions returns an object more similar to CPython's ``SSLObject`` which does not have these socket methods. +.. attribute:: SSLContext.verify_mode + + Set or get the behaviour for verification of peer certificates. Must be one of the + ``CERT_*`` constants. + +.. note:: + + ``ssl.CERT_REQUIRED`` requires the device's date/time to be properly set, e.g. using + `mpremote rtc --set ` or ``ntptime``, and ``server_hostname`` + must be specified when on the client side. + Exceptions ---------- @@ -65,8 +120,14 @@ Exceptions Constants --------- +.. data:: ssl.PROTOCOL_TLS_CLIENT + ssl.PROTOCOL_TLS_SERVER + + Supported values for the *protocol* parameter. + .. data:: ssl.CERT_NONE ssl.CERT_OPTIONAL ssl.CERT_REQUIRED - Supported values for *cert_reqs* parameter. + Supported values for *cert_reqs* parameter, and the :attr:`SSLContext.verify_mode` + attribute. diff --git a/docs/library/stm.rst b/docs/library/stm.rst index a181d6044cc1..970ab188344a 100644 --- a/docs/library/stm.rst +++ b/docs/library/stm.rst @@ -102,3 +102,39 @@ the second CPU, the RF core. Execute a HCI command on the SYS channel. The execution is synchronous. Returns a bytes object with the result of the SYS command. + +Functions specific to STM32WLxx MCUs +------------------------------------ + +These functions are available on STM32WLxx microcontrollers, and interact with +the integrated "SUBGHZ" radio modem peripheral. + +.. function:: subghz_cs(level) + + Sets the internal SPI CS pin attached to the radio peripheral. The ``level`` + argument is active-low: a truthy value means "CS pin high" and de-asserts the + signal, a falsey value means "CS pin low" and asserts the signal. + + The internal-only SPI bus corresponding to this CS signal can be instantiated + using :ref:`machine.SPI()` ``id`` value ``"SUBGHZ"``. + +.. function:: subghz_irq(handler) + + Sets the internal SUBGHZ radio interrupt handler to the provided + function. The handler function is called as a "hard" interrupt in response to + radio peripheral interrupts. See :ref:`isr_rules` for more information about + interrupt handlers in MicroPython. + + Calling this function with the handler argument set to None disables the IRQ. + + Due to a hardware limitation, each time this IRQ fires MicroPython disables + it before calling the handler. In order to receive another interrupt, Python + code should call ``subghz_irq()`` to set the handler again. This has the side + effect of re-enabling the IRQ. + +.. function:: subghz_is_busy() + + Return a ``bool`` corresponding to the internal "RFBUSYS" signal from the + radio peripheral. Before sending a new command to the radio over SPI then + this function should be polled until it returns ``False``, to confirm the + busy signal is de-asserted. diff --git a/docs/library/uasyncio.rst b/docs/library/uasyncio.rst deleted file mode 100644 index 4cbcfa9f98ad..000000000000 --- a/docs/library/uasyncio.rst +++ /dev/null @@ -1,360 +0,0 @@ -:mod:`uasyncio` --- asynchronous I/O scheduler -============================================== - -.. module:: uasyncio - :synopsis: asynchronous I/O scheduler for writing concurrent code - -|see_cpython_module| -`asyncio `_ - -Example:: - - import uasyncio - - async def blink(led, period_ms): - while True: - led.on() - await uasyncio.sleep_ms(5) - led.off() - await uasyncio.sleep_ms(period_ms) - - async def main(led1, led2): - uasyncio.create_task(blink(led1, 700)) - uasyncio.create_task(blink(led2, 400)) - await uasyncio.sleep_ms(10_000) - - # Running on a pyboard - from pyb import LED - uasyncio.run(main(LED(1), LED(2))) - - # Running on a generic board - from machine import Pin - uasyncio.run(main(Pin(1), Pin(2))) - -Core functions --------------- - -.. function:: create_task(coro) - - Create a new task from the given coroutine and schedule it to run. - - Returns the corresponding `Task` object. - -.. function:: current_task() - - Return the `Task` object associated with the currently running task. - -.. function:: run(coro) - - Create a new task from the given coroutine and run it until it completes. - - Returns the value returned by *coro*. - -.. function:: sleep(t) - - Sleep for *t* seconds (can be a float). - - This is a coroutine. - -.. function:: sleep_ms(t) - - Sleep for *t* milliseconds. - - This is a coroutine, and a MicroPython extension. - -Additional functions --------------------- - -.. function:: wait_for(awaitable, timeout) - - Wait for the *awaitable* to complete, but cancel it if it takes longer - than *timeout* seconds. If *awaitable* is not a task then a task will be - created from it. - - If a timeout occurs, it cancels the task and raises ``uasyncio.TimeoutError``: - this should be trapped by the caller. The task receives - ``uasyncio.CancelledError`` which may be ignored or trapped using ``try...except`` - or ``try...finally`` to run cleanup code. - - Returns the return value of *awaitable*. - - This is a coroutine. - -.. function:: wait_for_ms(awaitable, timeout) - - Similar to `wait_for` but *timeout* is an integer in milliseconds. - - This is a coroutine, and a MicroPython extension. - -.. function:: gather(*awaitables, return_exceptions=False) - - Run all *awaitables* concurrently. Any *awaitables* that are not tasks are - promoted to tasks. - - Returns a list of return values of all *awaitables*. - - This is a coroutine. - -class Task ----------- - -.. class:: Task() - - This object wraps a coroutine into a running task. Tasks can be waited on - using ``await task``, which will wait for the task to complete and return - the return value of the task. - - Tasks should not be created directly, rather use `create_task` to create them. - -.. method:: Task.cancel() - - Cancel the task by injecting ``uasyncio.CancelledError`` into it. The task may - ignore this exception. Cleanup code may be run by trapping it, or via - ``try ... finally``. - -class Event ------------ - -.. class:: Event() - - Create a new event which can be used to synchronise tasks. Events start - in the cleared state. - -.. method:: Event.is_set() - - Returns ``True`` if the event is set, ``False`` otherwise. - -.. method:: Event.set() - - Set the event. Any tasks waiting on the event will be scheduled to run. - - Note: This must be called from within a task. It is not safe to call this - from an IRQ, scheduler callback, or other thread. See `ThreadSafeFlag`. - -.. method:: Event.clear() - - Clear the event. - -.. method:: Event.wait() - - Wait for the event to be set. If the event is already set then it returns - immediately. - - This is a coroutine. - -class ThreadSafeFlag --------------------- - -.. class:: ThreadSafeFlag() - - Create a new flag which can be used to synchronise a task with code running - outside the uasyncio loop, such as other threads, IRQs, or scheduler - callbacks. Flags start in the cleared state. The class does not currently - work under the Unix build of MicroPython. - -.. method:: ThreadSafeFlag.set() - - Set the flag. If there is a task waiting on the flag, it will be scheduled - to run. - -.. method:: ThreadSafeFlag.clear() - - Clear the flag. This may be used to ensure that a possibly previously-set - flag is clear before waiting for it. - -.. method:: ThreadSafeFlag.wait() - - Wait for the flag to be set. If the flag is already set then it returns - immediately. The flag is automatically reset upon return from ``wait``. - - A flag may only be waited on by a single task at a time. - - This is a coroutine. - -class Lock ----------- - -.. class:: Lock() - - Create a new lock which can be used to coordinate tasks. Locks start in - the unlocked state. - - In addition to the methods below, locks can be used in an ``async with`` statement. - -.. method:: Lock.locked() - - Returns ``True`` if the lock is locked, otherwise ``False``. - -.. method:: Lock.acquire() - - Wait for the lock to be in the unlocked state and then lock it in an atomic - way. Only one task can acquire the lock at any one time. - - This is a coroutine. - -.. method:: Lock.release() - - Release the lock. If any tasks are waiting on the lock then the next one in the - queue is scheduled to run and the lock remains locked. Otherwise, no tasks are - waiting an the lock becomes unlocked. - -TCP stream connections ----------------------- - -.. function:: open_connection(host, port) - - Open a TCP connection to the given *host* and *port*. The *host* address will be - resolved using `socket.getaddrinfo`, which is currently a blocking call. - - Returns a pair of streams: a reader and a writer stream. - Will raise a socket-specific ``OSError`` if the host could not be resolved or if - the connection could not be made. - - This is a coroutine. - -.. function:: start_server(callback, host, port, backlog=5) - - Start a TCP server on the given *host* and *port*. The *callback* will be - called with incoming, accepted connections, and be passed 2 arguments: reader - and writer streams for the connection. - - Returns a `Server` object. - - This is a coroutine. - -.. class:: Stream() - - This represents a TCP stream connection. To minimise code this class implements - both a reader and a writer, and both ``StreamReader`` and ``StreamWriter`` alias to - this class. - -.. method:: Stream.get_extra_info(v) - - Get extra information about the stream, given by *v*. The valid values for *v* are: - ``peername``. - -.. method:: Stream.close() - - Close the stream. - -.. method:: Stream.wait_closed() - - Wait for the stream to close. - - This is a coroutine. - -.. method:: Stream.read(n=-1) - - Read up to *n* bytes and return them. If *n* is not provided or -1 then read all - bytes until EOF. The returned value will be an empty bytes object if EOF is - encountered before any bytes are read. - - This is a coroutine. - -.. method:: Stream.readinto(buf) - - Read up to n bytes into *buf* with n being equal to the length of *buf*. - - Return the number of bytes read into *buf*. - - This is a coroutine, and a MicroPython extension. - -.. method:: Stream.readexactly(n) - - Read exactly *n* bytes and return them as a bytes object. - - Raises an ``EOFError`` exception if the stream ends before reading *n* bytes. - - This is a coroutine. - -.. method:: Stream.readline() - - Read a line and return it. - - This is a coroutine. - -.. method:: Stream.write(buf) - - Accumulated *buf* to the output buffer. The data is only flushed when - `Stream.drain` is called. It is recommended to call `Stream.drain` immediately - after calling this function. - -.. method:: Stream.drain() - - Drain (write) all buffered output data out to the stream. - - This is a coroutine. - -.. class:: Server() - - This represents the server class returned from `start_server`. It can be used - in an ``async with`` statement to close the server upon exit. - -.. method:: Server.close() - - Close the server. - -.. method:: Server.wait_closed() - - Wait for the server to close. - - This is a coroutine. - -Event Loop ----------- - -.. function:: get_event_loop() - - Return the event loop used to schedule and run tasks. See `Loop`. - -.. function:: new_event_loop() - - Reset the event loop and return it. - - Note: since MicroPython only has a single event loop this function just - resets the loop's state, it does not create a new one. - -.. class:: Loop() - - This represents the object which schedules and runs tasks. It cannot be - created, use `get_event_loop` instead. - -.. method:: Loop.create_task(coro) - - Create a task from the given *coro* and return the new `Task` object. - -.. method:: Loop.run_forever() - - Run the event loop until `stop()` is called. - -.. method:: Loop.run_until_complete(awaitable) - - Run the given *awaitable* until it completes. If *awaitable* is not a task - then it will be promoted to one. - -.. method:: Loop.stop() - - Stop the event loop. - -.. method:: Loop.close() - - Close the event loop. - -.. method:: Loop.set_exception_handler(handler) - - Set the exception handler to call when a Task raises an exception that is not - caught. The *handler* should accept two arguments: ``(loop, context)``. - -.. method:: Loop.get_exception_handler() - - Get the current exception handler. Returns the handler, or ``None`` if no - custom handler is set. - -.. method:: Loop.default_exception_handler(context) - - The default exception handler that is called. - -.. method:: Loop.call_exception_handler(context) - - Call the current exception handler. The argument *context* is passed through and - is a dictionary containing keys: ``'message'``, ``'exception'``, ``'future'``. diff --git a/docs/library/wm8960.rst b/docs/library/wm8960.rst index add003630eb8..5abfb6a8a011 100644 --- a/docs/library/wm8960.rst +++ b/docs/library/wm8960.rst @@ -251,7 +251,7 @@ controlling its operation: .. method:: WM8960.expand_3d(level) - Enable Stereo 3D exansion. *level* is a number between 0 and 15. + Enable Stereo 3D expansion. *level* is a number between 0 and 15. A value of 0 disables the expansion. .. method:: WM8960.mono(active) diff --git a/docs/library/zephyr.DiskAccess.rst b/docs/library/zephyr.DiskAccess.rst index d19d81a962e2..3e5fa9a3575a 100644 --- a/docs/library/zephyr.DiskAccess.rst +++ b/docs/library/zephyr.DiskAccess.rst @@ -34,5 +34,5 @@ Methods These methods implement the simple and extended :ref:`block protocol ` defined by - :class:`uos.AbstractBlockDev`. + :class:`os.AbstractBlockDev`. diff --git a/docs/library/zephyr.FlashArea.rst b/docs/library/zephyr.FlashArea.rst index 306347d449ea..9cd4dd59d685 100644 --- a/docs/library/zephyr.FlashArea.rst +++ b/docs/library/zephyr.FlashArea.rst @@ -37,4 +37,4 @@ Methods These methods implement the simple and extended :ref:`block protocol ` defined by - :class:`uos.AbstractBlockDev`. + :class:`os.AbstractBlockDev`. diff --git a/docs/library/zlib.rst b/docs/library/zlib.rst index 96d6c245232b..54310b72f2a3 100644 --- a/docs/library/zlib.rst +++ b/docs/library/zlib.rst @@ -1,38 +1,82 @@ -:mod:`zlib` -- zlib decompression -================================= +:mod:`zlib` -- zlib compression & decompression +=============================================== .. module:: zlib - :synopsis: zlib decompression + :synopsis: zlib compression & decompression |see_cpython_module| :mod:`python:zlib`. -This module allows to decompress binary data compressed with +This module allows compression and decompression of binary data with the `DEFLATE algorithm `_ -(commonly used in zlib library and gzip archiver). Compression -is not yet implemented. +(commonly used in the zlib library and gzip archiver). + +.. note:: Prefer to use :class:`deflate.DeflateIO` instead of the functions in this + module as it provides a streaming interface to compression and decompression + which is convenient and more memory efficient when working with reading or + writing compressed data to a file, socket, or stream. + +**Availability:** + +* From MicroPython v1.21 onwards, this module may not be present by default on + all MicroPython firmware as it duplicates functionality available in + the :mod:`deflate ` module. + +* A copy of this module can be installed (or frozen) + from :term:`micropython-lib` (`source `_). + See :ref:`packages` for more information. This documentation describes that module. + +* Requires the built-in :mod:`deflate ` module (available since MicroPython v1.21) + +* Compression support will only be available if compression support is enabled + in the built-in :mod:`deflate ` module. Functions --------- -.. function:: decompress(data, wbits=0, bufsize=0, /) +.. function:: decompress(data, wbits=15, /) + + Decompresses *data* into a bytes object. + + The *wbits* parameter works the same way as for :meth:`zlib.compress` + with the following additional valid values: + + * ``0``: Automatically determine the window size from the zlib header + (*data* must be in zlib format). + * ``35`` to ``47``: Auto-detect either the zlib or gzip format. + + As for :meth:`zlib.compress`, see the :mod:`CPython documentation for zlib ` + for more information about the *wbits* parameter. As for :meth:`zlib.compress`, + MicroPython also supports smaller window sizes than CPython. See more + :ref:`MicroPython-specific details ` in the + :mod:`deflate ` module documentation. + + If the data to be decompressed requires a larger window size, it will + fail during decompression. + +.. function:: compress(data, wbits=15, /) - Return decompressed *data* as bytes. *wbits* is DEFLATE dictionary window - size used during compression (8-15, the dictionary size is power of 2 of - that value). Additionally, if value is positive, *data* is assumed to be - zlib stream (with zlib header). Otherwise, if it's negative, it's assumed - to be raw DEFLATE stream. *bufsize* parameter is for compatibility with - CPython and is ignored. + Compresses *data* into a bytes object. -.. class:: DecompIO(stream, wbits=0, /) + *wbits* allows you to configure the DEFLATE dictionary window size and the + output format. The window size allows you to trade-off memory usage for + compression level. A larger window size will allow the compressor to + reference fragments further back in the input. The output formats are "raw" + DEFLATE (no header/footer), zlib, and gzip, where the latter two + include a header and checksum. - Create a `stream` wrapper which allows transparent decompression of - compressed data in another *stream*. This allows to process compressed - streams with data larger than available heap size. In addition to - values described in :func:`decompress`, *wbits* may take values - 24..31 (16 + 8..15), meaning that input stream has gzip header. + The low four bits of the absolute value of *wbits* set the base-2 logarithm of + the DEFLATE dictionary window size. So for example, ``wbits=10``, + ``wbits=-10``, and ``wbits=26`` all set the window size to 1024 bytes. Valid + window sizes are ``5`` to ``15`` inclusive (corresponding to 32 to 32k bytes). - .. admonition:: Difference to CPython - :class: attention + Negative values of *wbits* between ``-5`` and ``-15`` correspond to "raw" + output mode, positive values between ``5`` and ``15`` correspond to zlib + output mode, and positive values between ``21`` and ``31`` correspond to + gzip output mode. - This class is MicroPython extension. It's included on provisional - basis and may be changed considerably or removed in later versions. + See the :mod:`CPython documentation for zlib ` for more + information about the *wbits* parameter. Note that MicroPython allows + for smaller window sizes, which is useful when memory is constrained while + still achieving a reasonable level of compression. It also speeds up + the compressor. See more :ref:`MicroPython-specific details ` + in the :mod:`deflate ` module documentation. diff --git a/docs/mimxrt/pinout.rst b/docs/mimxrt/pinout.rst index b5a7fbbfe08c..16bb4722734a 100644 --- a/docs/mimxrt/pinout.rst +++ b/docs/mimxrt/pinout.rst @@ -28,7 +28,7 @@ MIMXRT1060-EVK Debug USB D0/D1 D7/D6 D8/D9 MIMXRT1064-EVK Debug USB D0/D1 D7/D6 D8/D9 MIMXRT1170-EVK Debug USB D0/D1 D12/D11 D10/D13 Adafruit Metro M7 - D0/D1 D7/D3 A1/A0 -Olimex RT1010Py - RxD/TxD D5/D6 - +Olimex RT1010Py - RxD/TxD D7/D8 D5/D6 Seeed ARCH MIX - J3_19/J3_20 J4_16/J4_17 J4_06/J4_07 ================= =========== =========== =========== =========== diff --git a/docs/mimxrt/quickref.rst b/docs/mimxrt/quickref.rst index ab8bf8831bbb..578364c55a4c 100644 --- a/docs/mimxrt/quickref.rst +++ b/docs/mimxrt/quickref.rst @@ -92,9 +92,7 @@ Use the :ref:`machine.Pin ` class:: Available Pins follow the ranges and labelling of the respective board, like: -- 0-33 for Teensy 4.0, -- 0-21 for the MIMXRT10xx-EVK board, or 'D0-Dxx', or 'A0-Ann', -- 0-14 for the Olimex RT1010Py board, or 'D0'-'Dxx' and 'A0'-'Ann' +- 'D0-Dxx', or 'A0-Ann' for Teensy 4.0, MIMXRT10xx-EVK ns Olimex board, - 'J3_xx', 'J4_xx', 'J5_xx' for the Seeed ARCH MIX board, or the pin names of the Pin.board or Pin.cpu classes. @@ -106,9 +104,9 @@ Notes: * At the MIMXRT1010_EVK, pins D4, D5 and D9 of the Arduino connector are by default not connected to the MCU. For details refer to the schematics. * At the MIMXRT1170_EVK board, the inner rows of the Arduino connectors are assigned as follows: - - D16 - D23: J9, odd pin numbers; D17 is by default not connected. - - D24 - D27: J26, odd pin numbers; J63-J66 have to be closed to enable these pins. - - D29 - D36: J25, odd pin numbers; D29 and D30 are by default not connected. + - 'D16' - 'D23': J9, odd pin numbers; 'D17' is by default not connected. + - 'D24' - 'D27': J26, odd pin numbers; J63-J66 have to be closed to enable these pins. + - 'D29' - 'D36': J25, odd pin numbers; 'D29' and 'D30' are by default not connected. There's a higher-level abstraction :ref:`machine.Signal ` which can be used to invert a pin. Useful for illuminating active-low LEDs @@ -146,22 +144,22 @@ handling signal groups. :: from machine import Pin, PWM # create PWM object from a pin and set the frequency and duty cycle - pwm2 = PWM(Pin(2), freq=2000, duty_u16=32768) + pwm2 = PWM(Pin('D2'), freq=2000, duty_u16=32768) pwm2.freq() # get the current frequency pwm2.freq(1000) # set/change the frequency pwm2.duty_u16() # get the current duty cycle, range 0-65535 pwm2.duty_u16(200) # set the duty cycle, range 0-65535 pwm2.deinit() # turn off PWM on the pin # create a complementary signal pair on Pin 2 and 3 - pwm2 = PWM((2, 3), freq=2000, duty_ns=20000) + pwm2 = PWM(('D2', 'D3'), freq=2000, duty_ns=20000) # Create a group of four synchronized signals. - # Start with Pin(4) at submodule 0, which creates the sync pulse. - pwm4 = PWM(Pin(4), freq=1000, align=PWM.HEAD) - # Pins 5, 6, and 9 are pins at the same module - pwm5 = PWM(Pin(5), freq=1000, duty_u16=10000, align=PWM.HEAD, sync=True) - pwm6 = PWM(Pin(6), freq=1000, duty_u16=20000, align=PWM.HEAD, sync=True) - pwm9 = PWM(Pin(9), freq=1000, duty_u16=30000, align=PWM.HEAD, sync=True) + # Start with Pin('D4') at submodule 0, which creates the sync pulse. + pwm4 = PWM(Pin('D4'), freq=1000, align=PWM.HEAD) + # Pins D5, D6, and D9 are pins at the same module + pwm5 = PWM(Pin('D5'), freq=1000, duty_u16=10000, align=PWM.HEAD, sync=True) + pwm6 = PWM(Pin('D6', freq=1000, duty_u16=20000, align=PWM.HEAD, sync=True) + pwm9 = PWM(Pin('D9'), freq=1000, duty_u16=30000, align=PWM.HEAD, sync=True) pwm3 # show the PWM objects properties @@ -256,7 +254,7 @@ Use the :ref:`machine.ADC ` class:: from machine import ADC - adc = ADC(Pin(32)) # create ADC object on ADC pin + adc = ADC(Pin('A2')) # create ADC object on ADC pin adc.read_u16() # read value, 0-65536 across voltage range 0.0v - 3.3v The resolution of the ADC is 12 bit with 10 to 11 bit accuracy, irrespective of the @@ -274,7 +272,7 @@ Software SPI (using bit-banging) works on all pins, and is accessed via the # construct a SoftSPI bus on the given pins # polarity is the idle state of SCK # phase=0 means sample on the first edge of SCK, phase=1 means the second - spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4)) + spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin('D0'), mosi=Pin('D2'), miso=Pin('D4')) spi.init(baudrate=200000) # set the baudrate @@ -303,7 +301,7 @@ rates (up to 30Mhz). Hardware SPI is accessed via the from machine import SPI, Pin spi = SPI(0, 10000000) - cs_pin = Pin(6, Pin.OUT, value=1) + cs_pin = Pin('D6', Pin.OUT, value=1) cs_pin(0) spi.write('Hello World') cs_pin(1) @@ -331,7 +329,7 @@ accessed via the :ref:`machine.SoftI2C ` class:: from machine import Pin, SoftI2C - i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=100000) + i2c = SoftI2C(scl=Pin('D5'), sda=Pin('D4'), freq=100000) i2c.scan() # scan for devices @@ -365,7 +363,7 @@ See :ref:`machine.I2S `. Example using a Teensy 4.1 board with a si external Codec like UDA1334.:: from machine import I2S, Pin - i2s = I2S(2, sck=Pin(26), ws=Pin(27), sd=Pin(7), + i2s = I2S(2, sck=Pin('D26'), ws=Pin('D27'), sd=Pin('D7'), mode=I2S.TX, bts=16,format=I2S.STEREO, rate=44100,ibuf=40000) i2s.write(buf) # write buffer of audio samples to I2S device @@ -397,7 +395,7 @@ Example using the Teensy audio shield:: from machine import I2C, I2S, Pin from sgtl5000 import CODEC - i2s = I2S(1, sck=Pin(21), ws=Pin(20), sd=Pin(7), mck=Pin(23), + i2s = I2S(1, sck=Pin('D21'), ws=Pin('D20'), sd=Pin('D7'), mck=Pin('D23'), mode=I2S.TX, bits=16,rate=44100,format=I2S.STEREO, ibuf=40000, ) @@ -475,7 +473,7 @@ The OneWire driver is implemented in software and works on all pins:: from machine import Pin import onewire - ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12 + ow = onewire.OneWire(Pin('D12')) # create a OneWire bus on GPIO12 ow.scan() # return a list of devices on the bus ow.reset() # reset the bus ow.readbyte() # read a byte @@ -505,12 +503,12 @@ The DHT driver is implemented in software and works on all pins:: import dht import machine - d = dht.DHT11(machine.Pin(4)) + d = dht.DHT11(machine.Pin('D4')) d.measure() d.temperature() # eg. 23 (°C) d.humidity() # eg. 41 (% RH) - d = dht.DHT22(machine.Pin(4)) + d = dht.DHT22(machine.Pin('D4')) d.measure() d.temperature() # eg. 23.6 (°C) d.humidity() # eg. 41.3 (% RH) diff --git a/docs/readthedocs/settings/local_settings.py b/docs/readthedocs/settings/local_settings.py index 8d2bac7a7690..c6145dcc52ad 100644 --- a/docs/readthedocs/settings/local_settings.py +++ b/docs/readthedocs/settings/local_settings.py @@ -1,9 +1,10 @@ import os # Directory that the project lives in, aka ../.. -SITE_ROOT = '/'.join(os.path.dirname(__file__).split('/')[0:-2]) +SITE_ROOT = "/".join(os.path.dirname(__file__).split("/")[0:-2]) TEMPLATE_DIRS = ( - "%s/templates/" % SITE_ROOT, # Your custom template directory, before the RTD one to override it. - "%s/readthedocs/templates/" % SITE_ROOT, # Default RTD template dir + "%s/templates/" + % SITE_ROOT, # Your custom template directory, before the RTD one to override it. + "%s/readthedocs/templates/" % SITE_ROOT, # Default RTD template dir ) diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index d039bf7132f3..efaa8f607f72 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -32,7 +32,7 @@ Glossary callee-owned tuple This is a MicroPython-specific construct where, for efficiency - reasons, some built-in functions or methods may re-use the same + reasons, some built-in functions or methods may reuse the same underlying tuple object to return data. This avoids having to allocate a new tuple for every call, and reduces heap fragmentation. Programs should not hold references to callee-owned tuples and instead only diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 8ac92c22ebc1..98f6b6573769 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -31,3 +31,4 @@ implementation and the best practices to use them. asm_thumb2_index.rst filesystem.rst pyboard.py.rst + micropython2_migration.rst diff --git a/docs/reference/isr_rules.rst b/docs/reference/isr_rules.rst index bdb838c59058..ea330acad3aa 100644 --- a/docs/reference/isr_rules.rst +++ b/docs/reference/isr_rules.rst @@ -219,20 +219,20 @@ Exceptions If an ISR raises an exception it will not propagate to the main loop. The interrupt will be disabled unless the exception is handled by the ISR code. -Interfacing to uasyncio ------------------------ +Interfacing to asyncio +---------------------- -When an ISR runs it can preempt the `uasyncio` scheduler. If the ISR performs a `uasyncio` +When an ISR runs it can preempt the `asyncio` scheduler. If the ISR performs a `asyncio` operation the scheduler's operation can be disrupted. This applies whether the interrupt is hard or soft and also applies if the ISR has passed execution to another function via `micropython.schedule`. In particular creating or cancelling tasks is invalid in an ISR context. -The safe way to interact with `uasyncio` is to implement a coroutine with synchronisation performed by -`uasyncio.ThreadSafeFlag`. The following fragment illustrates the creation of a task in response +The safe way to interact with `asyncio` is to implement a coroutine with synchronisation performed by +`asyncio.ThreadSafeFlag`. The following fragment illustrates the creation of a task in response to an interrupt: .. code:: python - tsf = uasyncio.ThreadSafeFlag() + tsf = asyncio.ThreadSafeFlag() def isr(_): # Interrupt handler tsf.set() @@ -240,7 +240,7 @@ to an interrupt: async def foo(): while True: await tsf.wait() - uasyncio.create_task(bar()) + asyncio.create_task(bar()) In this example there will be a variable amount of latency between the execution of the ISR and the execution of ``foo()``. This is inherent to cooperative scheduling. The maximum latency is application diff --git a/docs/reference/micropython2_migration.rst b/docs/reference/micropython2_migration.rst new file mode 100644 index 000000000000..954488b8cdf4 --- /dev/null +++ b/docs/reference/micropython2_migration.rst @@ -0,0 +1,74 @@ +.. _micropython2_migration: + +MicroPython 2.0 Migration Guide +=============================== + +MicroPython 2.0 is the (currently in development, not yet available) next major +release of MicroPython. + +After maintaining API compatibility for almost a decade with the ``1.x`` series, in +order to unblock some project-wide improvements MicroPython 2.0 will introduce a +small number of breaking API changes that will require some programs to be +updated. This guide explains how to update your Python code to accommodate these +changes. + +This document is a work-in-progress. As more work is done on MicroPython 2.0, +more items will be added to the lists below. + +**Note:** There are currently no MicroPython 2.0 firmware builds available for +download. You can build it yourself by enabling the ``MICROPY_PREVIEW_VERSION_2`` +config option. As it gets closer to being ready for release, builds will be +provided for both ``1.x.y`` and ``2.0.0-preview``. + +Hardware and peripherals +------------------------ + +Overview +~~~~~~~~ + +The goal is to improve consistency in the :mod:`machine` APIs across different +ports, making it easier to write code, documentation, and tutorials that work on +any supported microcontroller. + +This means that some ports' APIs need to change to match other ports. + +Changes +~~~~~~~ + +*None yet* + +OS & filesystem +--------------- + +Overview +~~~~~~~~ + +The primary goal is to support the ability to execute :term:`.mpy files <.mpy +file>` directly from the filesystem without first copying them into RAM. This +improves code deployment time and reduces memory overhead and fragmentation. + +Additionally, a further goal is to support a more flexible way of configuring +partitions, filesystem types, and options like USB mass storage. + +Changes +~~~~~~~ + +*None yet* + +CPython compatibility +--------------------- + +Overview +~~~~~~~~ + +The goal is to improve compatibility with CPython by removing MicroPython +extensions from CPython APIs. In most cases this means moving existing +MicroPython-specific functions or classes to new modules. + +This makes it easier to write code that works on both CPython and MicroPython, +which is useful for development and testing. + +Changes +~~~~~~~ + +*None yet* diff --git a/docs/reference/mpremote.rst b/docs/reference/mpremote.rst index b82672536025..08ef5d31ff57 100644 --- a/docs/reference/mpremote.rst +++ b/docs/reference/mpremote.rst @@ -100,6 +100,8 @@ The full list of supported commands are: command output) - ``port:``: connect to the device with the given path (the first column from the ``connect list`` command output + - ``rfc2217://:``: connect to the device using serial over TCP + (e.g. a networked serial port based on RFC2217) - any valid device name/path, to connect to that device **Note:** Instead of using the ``connect`` command, there are several @@ -109,7 +111,7 @@ The full list of supported commands are: **Note:** The ``auto`` option will only detect USB serial ports, i.e. a serial port that has an associated USB VID/PID (i.e. CDC/ACM or FTDI-style - devices). Other types of serial ports + devices). Other types of serial ports will not be auto-detected. .. _mpremote_command_disconnect: diff --git a/docs/reference/mpyfiles.rst b/docs/reference/mpyfiles.rst index 1588eda57090..02bac3d411e0 100644 --- a/docs/reference/mpyfiles.rst +++ b/docs/reference/mpyfiles.rst @@ -86,7 +86,8 @@ and .mpy version. =================== ============ MicroPython release .mpy version =================== ============ -v1.20 and up 6.1 +v1.22.0 and up 6.2 +v1.20 - v1.21.0 6.1 v1.19.x 6 v1.12 - v1.18 5 v1.11 4 @@ -101,6 +102,7 @@ MicroPython repository at which the .mpy version was changed. =================== ======================================== .mpy version change Git commit =================== ======================================== +6.1 to 6.2 6967ff3c581a66f73e9f3d78975f47528db39980 6 to 6.1 d94141e1473aebae0d3c63aeaa8397651ad6fa01 5 to 6 f2040bfc7ee033e48acef9f289790f3b4e6b74e5 4 to 5 5716c5cf65e9b2cb46c2906f40302401bdd27517 diff --git a/docs/renesas-ra/tutorial/using_peripheral.rst b/docs/renesas-ra/tutorial/using_peripheral.rst index c50181b3d681..7296d8b3304f 100644 --- a/docs/renesas-ra/tutorial/using_peripheral.rst +++ b/docs/renesas-ra/tutorial/using_peripheral.rst @@ -12,9 +12,8 @@ To list supported modules, please enter:: help('modules') -Especially `machine` module and class :ref:`machine.Pin ` are very important for using -peripherals. Note that prefix 'u' is added to the module for MicroPython, -so you can see "umachine" in the list but you can use it like "import machine". +Especially `machine` module and class :ref:`machine.Pin ` are very +important for using peripherals. Using "from machine import Pin", Pin name is available corresponding to the RA MCU's pin name which are Pin.cpu.P000 and 'P000'. diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000000..824e9799c773 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +sphinx~=7.2.6 +sphinxcontrib.jquery==4.1 diff --git a/docs/samd/pinout.rst b/docs/samd/pinout.rst index 5fe1e14ecb37..272f7c58df08 100644 --- a/docs/samd/pinout.rst +++ b/docs/samd/pinout.rst @@ -17,44 +17,53 @@ Adafruit ItsyBitsy M0 Express pin assignment table === ==== ============ ==== ==== ====== ====== ====== ====== Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC === ==== ============ ==== ==== ====== ====== ====== ====== - 0 PA11 D0 11 19 0/3 2/3 1/1 0/3 - 1 PA10 D1 10 18 0/2 2/2 1/0 0/2 - 2 PA14 D2 14 - 2/2 4/2 3/0 0/4 - 3 PA09 D3 9 17 0/1 2/1 0/1 1/3 - 4 PA08 D4 - 16 0/0 2/0 0/0 1/2 - 5 PA15 D5 15 - 2/3 4/3 3/1 0/5 - 7 PA21 D7 5 - 5/3 3/3 7/1 0/7 - 9 PA07 D9 7 7 - 0/3 1/1 - - 10 PA18 D10 2 - 1/2 3/2 3/0 0/2 - 11 PA16 D11 0 - 1/0 3/0 2/0 0/6 - 12 PA19 D12 3 - 1/3 3/3 3/1 0/3 - 13 PA17 D13 1 - 1/1 3/1 2/1 0/7 - 14 PA02 A0 2 0 - - - - - 15 PB08 A1 8 2 - 4/0 4/0 - - 16 PB09 A2 9 3 - 4/1 4/1 - - 17 PA04 A3 4 4 - 0/0 0/0 - - 18 PA05 A4 5 5 - 0/1 0/1 - - 19 PB02 A5 2 - - 5/0 6/0 - - 20 PA22 SDA 6 - 3/0 5/0 4/0 0/4 - 21 PA23 SCL 7 - 3/1 5/1 4/1 0/5 - 22 PB10 MOSI 10 - - 4/2 5/0 0/4 - 23 PA12 MISO 12 - 2/0 4/0 2/0 0/6 - 24 PB11 SCK 11 - - 4/3 5/1 0/5 - 25 PA00 DOTSTAR_CLK 0 - - 1/0 2/0 - - 26 PA01 DOTSTAR_DATA 1 - - 1/1 2/1 - - 27 PB22 FLASH_MOSI 6 - - 5/2 7/0 - - 28 PB03 FLASH_MISO 3 - - 5/1 6/1 - - 29 PB23 FLASH_SCK 7 - - 5/3 7/1 - + 2 PA02 A0 2 0 - - - - + 40 PB08 A1 8 2 - 4/0 4/0 - + 41 PB09 A2 9 3 - 4/1 4/1 - + 4 PA04 A3 4 4 - 0/0 0/0 - + 5 PA05 A4 5 5 - 0/1 0/1 - + 34 PB02 A5 2 10 - 5/0 6/0 - + 11 PA11 D0 11 19 0/3 2/3 1/1 0/3 + 10 PA10 D1 10 18 0/2 2/2 1/0 0/2 + 14 PA14 D2 14 - 2/2 4/2 3/0 0/4 + 9 PA09 D3 9 17 0/1 2/1 0/1 1/3 + 8 PA08 D4 - 16 0/0 2/0 0/0 1/2 + 15 PA15 D5 15 - 2/3 4/3 3/1 0/5 + 21 PA21 D7 5 - 5/3 3/3 7/1 0/7 + 7 PA07 D9 7 7 - 0/3 1/1 - + 18 PA18 D10 2 - 1/2 3/2 3/0 0/2 + 16 PA16 D11 0 - 1/0 3/0 2/0 0/6 + 19 PA19 D12 3 - 1/3 3/3 3/1 0/3 + 17 PA17 D13 1 - 1/1 3/1 2/1 0/7 + 0 PA00 DOTSTAR_CLK 0 - - 1/0 2/0 - + 1 PA01 DOTSTAR_DATA 1 - - 1/1 2/1 - + 27 PA27 FLASH_CS 15 - - - - - + 35 PB03 FLASH_MISO 3 11 - 5/1 6/1 - + 54 PB22 FLASH_MOSI 6 - - 5/2 7/0 - + 55 PB23 FLASH_SCK 7 - - 5/3 7/1 - + 12 PA12 MISO 12 - 2/0 4/0 2/0 0/6 + 42 PB10 MOSI 10 - - 4/2 5/0 0/4 + 43 PB11 SCK 11 - - 4/3 5/1 0/5 + 23 PA23 SCL 7 - 3/1 5/1 4/1 0/5 + 22 PA22 SDA 6 - 3/0 5/0 4/0 0/4 + 30 PA30 SWCLK 10 - - 1/2 1/0 - + 31 PA31 SWDIO 11 - - 1/3 1/1 - + 24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2 + 25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3 + 3 PA03 3 1 - - - - + 6 PA06 6 6 - 0/2 1/0 - + 13 PA13 13 - 2/1 4/1 2/0 0/7 + 20 PA20 4 - 5/2 3/2 7/0 0/4 + 28 PA28 8 - - - - - === ==== ============ ==== ==== ====== ====== ====== ====== Description of the columns: - *Pin* - The number that is expected at ``machine.Pin(n)``, if the pin is given - as a number. This is NOT the GPIO number, but the board pin number, as - given in the board specific definition file. -- *GPIO* - The GPIO number. -- *Pin Name* - The name of a Pin which is expected argument to ``machine.Pin("name")``. + as a number. +- *GPIO* - The GPIO name, which can be used as argument to ``machine.Pin("name")``. +- *Pin Name* - The boards name, which can be used as argument to ``machine.Pin("name")``. - *IRQ* - The IRQ number assigned to that GPIO, used internally by ``Pin.irq()``. When using ``Pin.irq()``, different pins must use different IRQs - *ADC* - The ADC channel assigned to the pin. When using ADC, different pins must @@ -183,10 +192,9 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM Description of the columns: - *Pin* - The number that is expected at ``machine.Pin(n)``, if the pin is given - as a number. This is NOT the GPIO number, but the board pin number, as - given in the board specific definition file. -- *GPIO* - The GPIO number. -- *Pin Name* The name of a Pin which is expected argument to ``machine.Pin("name")``. + as a number. +- *GPIO* - The GPIO name, which can be used as argument to ``machine.Pin("name")``. +- *Pin Name* - The boards name, which can be used as argument to ``machine.Pin("name")``. - *IRQ* - The IRQ number assigned to that GPIO, used internally by ``Pin.irq()``. When using ``Pin.irq()``, different pins must use different IRQs - *ADC* - The ADC0/1 channel assigned to the pin. When using ADC, different pins must diff --git a/docs/templates/layout.html b/docs/templates/layout.html index 8563f02af00a..21dab5eb42f1 100644 --- a/docs/templates/layout.html +++ b/docs/templates/layout.html @@ -9,7 +9,7 @@ {% if is_release %}

- This is the v{{ release }} version of the MicroPython + This is the {{ release }} version of the MicroPython documentation. The latest development version of this page may be more current.

diff --git a/docs/zephyr/quickref.rst b/docs/zephyr/quickref.rst index 329a9c41c0cc..57262ffb5c63 100644 --- a/docs/zephyr/quickref.rst +++ b/docs/zephyr/quickref.rst @@ -19,7 +19,7 @@ See the corresponding section of the tutorial: :ref:`intro`. Delay and timing ---------------- -Use the :mod:`time ` module:: +Use the :mod:`time