mirror of
https://github.com/micropython/micropython.git
synced 2025-12-27 15:20:13 +01:00
Compare commits
22 Commits
dependabot
...
v1.24-rele
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ecfdd5d6f9 | ||
|
|
564ef28ad2 | ||
|
|
7118942a8c | ||
|
|
948863c0b8 | ||
|
|
33f50d4f20 | ||
|
|
eb0027b82f | ||
|
|
03bc561edb | ||
|
|
49b83ed44a | ||
|
|
4f4d683ea5 | ||
|
|
67f893852a | ||
|
|
20a6d82872 | ||
|
|
0c580f71ae | ||
|
|
4e78c611b4 | ||
|
|
159b54b7da | ||
|
|
c1a85bb6de | ||
|
|
72799f9973 | ||
|
|
164c549248 | ||
|
|
6f327684b7 | ||
|
|
a7d3bc2308 | ||
|
|
c0afff8f22 | ||
|
|
785c92df76 | ||
|
|
5c7ac55232 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -18,7 +18,6 @@
|
||||
# These should also not be modified by git.
|
||||
tests/basics/string_cr_conversion.py -text
|
||||
tests/basics/string_crlf_conversion.py -text
|
||||
tests/micropython/test_normalize_newlines.py.exp -text
|
||||
ports/stm32/pybcdc.inf_template -text
|
||||
ports/stm32/usbhost/** -text
|
||||
ports/cc3200/hal/aes.c -text
|
||||
|
||||
2
.github/workflows/biome.yml
vendored
2
.github/workflows/biome.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Biome
|
||||
uses: biomejs/setup-biome@v2
|
||||
with:
|
||||
|
||||
8
.github/workflows/code_formatting.yml
vendored
8
.github/workflows/code_formatting.yml
vendored
@@ -10,11 +10,11 @@ jobs:
|
||||
code-formatting:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
- name: Install packages
|
||||
run: tools/ci.sh c_code_formatting_setup
|
||||
run: source tools/ci.sh && ci_c_code_formatting_setup
|
||||
- name: Run code formatting
|
||||
run: tools/ci.sh c_code_formatting_run
|
||||
run: source tools/ci.sh && ci_c_code_formatting_run
|
||||
- name: Check code formatting
|
||||
run: git diff --exit-code
|
||||
|
||||
9
.github/workflows/code_size.yml
vendored
9
.github/workflows/code_size.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Check code size
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/*.yml'
|
||||
@@ -25,15 +26,15 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100
|
||||
- name: Install packages
|
||||
run: tools/ci.sh code_size_setup
|
||||
run: source tools/ci.sh && ci_code_size_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh code_size_build
|
||||
run: source tools/ci.sh && ci_code_size_build
|
||||
- name: Compute code size difference
|
||||
run: source tools/ci.sh && ci_code_size_report
|
||||
run: tools/metrics.py diff ~/size0 ~/size1 | tee diff
|
||||
- name: Save PR number
|
||||
if: github.event_name == 'pull_request'
|
||||
env:
|
||||
|
||||
4
.github/workflows/code_size_comment.yml
vendored
4
.github/workflows/code_size_comment.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
steps:
|
||||
- name: 'Download artifact'
|
||||
id: download-artifact
|
||||
uses: actions/github-script@v8
|
||||
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@v8
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
|
||||
4
.github/workflows/codespell.yml
vendored
4
.github/workflows/codespell.yml
vendored
@@ -6,8 +6,8 @@ jobs:
|
||||
codespell:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
# codespell version should be kept in sync with .pre-commit-config.yml
|
||||
- run: pip install --user codespell==2.4.1 tomli
|
||||
- run: pip install --user codespell==2.2.6 tomli
|
||||
- run: codespell
|
||||
|
||||
|
||||
10
.github/workflows/commit_formatting.yml
vendored
10
.github/workflows/commit_formatting.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: Check commit message formatting
|
||||
|
||||
on: [pull_request]
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -10,9 +10,9 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100
|
||||
- uses: actions/setup-python@v6
|
||||
fetch-depth: '100'
|
||||
- uses: actions/setup-python@v5
|
||||
- name: Check commit message formatting
|
||||
run: tools/ci.sh commit_formatting_run
|
||||
run: source tools/ci.sh && ci_commit_formatting_run
|
||||
|
||||
8
.github/workflows/docs.yml
vendored
8
.github/workflows/docs.yml
vendored
@@ -5,8 +5,6 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- docs/**
|
||||
- py/**
|
||||
- tests/cpydiff/**
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -17,11 +15,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
- name: Install Python packages
|
||||
run: pip install -r docs/requirements.txt
|
||||
- name: Build unix port
|
||||
run: tools/ci.sh unix_build_helper
|
||||
- name: Build docs
|
||||
run: make -C docs/ html
|
||||
|
||||
2
.github/workflows/examples.yml
vendored
2
.github/workflows/examples.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
embedding:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: make -C examples/embedding -f micropython_embed.mk && make -C examples/embedding
|
||||
- name: Run
|
||||
|
||||
4
.github/workflows/mpremote.yml
vendored
4
.github/workflows/mpremote.yml
vendored
@@ -11,12 +11,12 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- 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@v6
|
||||
- uses: actions/setup-python@v5
|
||||
- name: Install build tools
|
||||
run: pip install build
|
||||
- name: Build mpremote wheel
|
||||
|
||||
12
.github/workflows/mpy_format.yml
vendored
12
.github/workflows/mpy_format.yml
vendored
@@ -6,8 +6,6 @@ on:
|
||||
paths:
|
||||
- '.github/workflows/*.yml'
|
||||
- 'examples/**'
|
||||
- 'mpy-cross/**'
|
||||
- 'py/**'
|
||||
- 'tests/**'
|
||||
- 'tools/**'
|
||||
|
||||
@@ -17,12 +15,10 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04 # use 20.04 to get python2
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh mpy_format_setup
|
||||
run: source tools/ci.sh && ci_mpy_format_setup
|
||||
- name: Test mpy-tool.py
|
||||
run: tools/ci.sh mpy_format_test
|
||||
- name: Test mpy-cross debug emitter
|
||||
run: tools/ci.sh mpy_cross_debug_emitter
|
||||
run: source tools/ci.sh && ci_mpy_format_test
|
||||
|
||||
2
.github/workflows/ports.yml
vendored
2
.github/workflows/ports.yml
vendored
@@ -17,6 +17,6 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build ports download metadata
|
||||
run: mkdir boards && ./tools/autobuild/build-downloads.py . ./boards
|
||||
|
||||
33
.github/workflows/ports_alif.yml
vendored
33
.github/workflows/ports_alif.yml
vendored
@@ -1,33 +0,0 @@
|
||||
name: alif port
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/*.yml'
|
||||
- 'tools/**'
|
||||
- 'py/**'
|
||||
- 'extmod/**'
|
||||
- 'shared/**'
|
||||
- 'lib/**'
|
||||
- 'drivers/**'
|
||||
- 'ports/alif/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build_alif:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ci_func: # names are functions in ci.sh
|
||||
- alif_ae3_build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install packages
|
||||
run: tools/ci.sh alif_setup
|
||||
- name: Build ci_${{matrix.ci_func }}
|
||||
run: tools/ci.sh ${{ matrix.ci_func }}
|
||||
6
.github/workflows/ports_cc3200.yml
vendored
6
.github/workflows/ports_cc3200.yml
vendored
@@ -21,8 +21,8 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh cc3200_setup
|
||||
run: source tools/ci.sh && ci_cc3200_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh cc3200_build
|
||||
run: source tools/ci.sh && ci_cc3200_build
|
||||
|
||||
20
.github/workflows/ports_esp32.yml
vendored
20
.github/workflows/ports_esp32.yml
vendored
@@ -12,10 +12,6 @@ on:
|
||||
- 'lib/**'
|
||||
- 'drivers/**'
|
||||
- 'ports/esp32/**'
|
||||
schedule:
|
||||
# Scheduled run exists to keep master branch ESP-IDF cache entry hot
|
||||
# and prevent creating many redundant per-branch cache entries instead.
|
||||
- cron: "20 0 * * *"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -29,19 +25,17 @@ jobs:
|
||||
ci_func: # names are functions in ci.sh
|
||||
- esp32_build_cmod_spiram_s2
|
||||
- esp32_build_s3_c3
|
||||
- esp32_build_c2_c5_c6
|
||||
- esp32_build_p4
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- id: idf_ver
|
||||
name: Read the ESP-IDF version (including Python version)
|
||||
run: source tools/ci.sh && echo "IDF_VER=${IDF_VER}-py${PYTHON_VER}" | tee "$GITHUB_OUTPUT"
|
||||
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@v5
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
./esp-idf/
|
||||
@@ -52,7 +46,7 @@ jobs:
|
||||
|
||||
- name: Install ESP-IDF packages
|
||||
if: steps.cache_esp_idf.outputs.cache-hit != 'true'
|
||||
run: tools/ci.sh esp32_idf_setup
|
||||
run: source tools/ci.sh && ci_esp32_idf_setup
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
@@ -60,4 +54,4 @@ jobs:
|
||||
key: esp32-${{ matrix.ci_func }}
|
||||
|
||||
- name: Build ci_${{matrix.ci_func }}
|
||||
run: tools/ci.sh ${{ matrix.ci_func }}
|
||||
run: source tools/ci.sh && ci_${{ matrix.ci_func }}
|
||||
|
||||
6
.github/workflows/ports_esp8266.yml
vendored
6
.github/workflows/ports_esp8266.yml
vendored
@@ -21,8 +21,8 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh esp8266_setup && tools/ci.sh esp8266_path >> $GITHUB_PATH
|
||||
run: source tools/ci.sh && ci_esp8266_setup && ci_esp8266_path >> $GITHUB_PATH
|
||||
- name: Build
|
||||
run: tools/ci.sh esp8266_build
|
||||
run: source tools/ci.sh && ci_esp8266_build
|
||||
|
||||
8
.github/workflows/ports_mimxrt.yml
vendored
8
.github/workflows/ports_mimxrt.yml
vendored
@@ -19,15 +19,15 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
defaults:
|
||||
run:
|
||||
working-directory: 'micropython repo' # test build with space in path
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'micropython repo'
|
||||
- name: Install packages
|
||||
run: tools/ci.sh mimxrt_setup
|
||||
run: source tools/ci.sh && ci_mimxrt_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh mimxrt_build
|
||||
run: source tools/ci.sh && ci_mimxrt_build
|
||||
|
||||
8
.github/workflows/ports_nrf.yml
vendored
8
.github/workflows/ports_nrf.yml
vendored
@@ -19,10 +19,10 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh nrf_setup
|
||||
run: source tools/ci.sh && ci_nrf_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh nrf_build
|
||||
run: source tools/ci.sh && ci_nrf_build
|
||||
|
||||
6
.github/workflows/ports_powerpc.yml
vendored
6
.github/workflows/ports_powerpc.yml
vendored
@@ -21,8 +21,8 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh powerpc_setup
|
||||
run: source tools/ci.sh && ci_powerpc_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh powerpc_build
|
||||
run: source tools/ci.sh && ci_powerpc_build
|
||||
|
||||
34
.github/workflows/ports_qemu.yml
vendored
34
.github/workflows/ports_qemu.yml
vendored
@@ -20,21 +20,13 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build_and_test_arm:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ci_func: # names are functions in ci.sh
|
||||
- bigendian
|
||||
- sabrelite
|
||||
- thumb_softfp
|
||||
- thumb_hardfp
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh qemu_setup_arm
|
||||
- name: Build and run test suite ci_qemu_build_arm_${{ matrix.ci_func }}
|
||||
run: tools/ci.sh qemu_build_arm_${{ matrix.ci_func }}
|
||||
run: source tools/ci.sh && ci_qemu_setup_arm
|
||||
- name: Build and run test suite
|
||||
run: source tools/ci.sh && ci_qemu_build_arm
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
@@ -42,23 +34,11 @@ jobs:
|
||||
build_and_test_rv32:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh qemu_setup_rv32
|
||||
run: source tools/ci.sh && ci_qemu_setup_rv32
|
||||
- name: Build and run test suite
|
||||
run: tools/ci.sh qemu_build_rv32
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
build_and_test_rv64:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install packages
|
||||
run: tools/ci.sh qemu_setup_rv64
|
||||
- name: Build and run test suite
|
||||
run: tools/ci.sh qemu_build_rv64
|
||||
run: source tools/ci.sh && ci_qemu_build_rv32
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
8
.github/workflows/ports_renesas-ra.yml
vendored
8
.github/workflows/ports_renesas-ra.yml
vendored
@@ -19,11 +19,11 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build_renesas_ra_board:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh renesas_ra_setup
|
||||
run: source tools/ci.sh && ci_renesas_ra_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh renesas_ra_board_build
|
||||
run: source tools/ci.sh && ci_renesas_ra_board_build
|
||||
|
||||
|
||||
6
.github/workflows/ports_rp2.yml
vendored
6
.github/workflows/ports_rp2.yml
vendored
@@ -24,10 +24,10 @@ jobs:
|
||||
run:
|
||||
working-directory: 'micropython repo' # test build with space in path
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: 'micropython repo'
|
||||
- name: Install packages
|
||||
run: tools/ci.sh rp2_setup
|
||||
run: source tools/ci.sh && ci_rp2_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh rp2_build
|
||||
run: source tools/ci.sh && ci_rp2_build
|
||||
|
||||
6
.github/workflows/ports_samd.yml
vendored
6
.github/workflows/ports_samd.yml
vendored
@@ -21,8 +21,8 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh samd_setup
|
||||
run: source tools/ci.sh && ci_samd_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh samd_build
|
||||
run: source tools/ci.sh && ci_samd_build
|
||||
|
||||
8
.github/workflows/ports_stm32.yml
vendored
8
.github/workflows/ports_stm32.yml
vendored
@@ -26,11 +26,11 @@ jobs:
|
||||
- stm32_pyb_build
|
||||
- stm32_nucleo_build
|
||||
- stm32_misc_build
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh stm32_setup && tools/ci.sh stm32_path >> $GITHUB_PATH
|
||||
run: source tools/ci.sh && ci_stm32_setup
|
||||
- name: Build ci_${{matrix.ci_func }}
|
||||
run: tools/ci.sh ${{ matrix.ci_func }}
|
||||
run: source tools/ci.sh && ci_${{ matrix.ci_func }}
|
||||
|
||||
|
||||
247
.github/workflows/ports_unix.yml
vendored
247
.github/workflows/ports_unix.yml
vendored
@@ -23,11 +23,11 @@ jobs:
|
||||
minimal:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_minimal_build
|
||||
run: source tools/ci.sh && ci_unix_minimal_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_minimal_run_tests
|
||||
run: source tools/ci.sh && ci_unix_minimal_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
@@ -35,9 +35,9 @@ jobs:
|
||||
reproducible:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build with reproducible date
|
||||
run: tools/ci.sh unix_minimal_build
|
||||
run: source tools/ci.sh && ci_unix_minimal_build
|
||||
env:
|
||||
SOURCE_DATE_EPOCH: 1234567890
|
||||
- name: Check reproducible build date
|
||||
@@ -46,11 +46,11 @@ jobs:
|
||||
standard:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_standard_build
|
||||
run: source tools/ci.sh && ci_unix_standard_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_standard_run_tests
|
||||
run: source tools/ci.sh && ci_unix_standard_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
@@ -58,11 +58,11 @@ jobs:
|
||||
standard_v2:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_standard_v2_build
|
||||
run: source tools/ci.sh && ci_unix_standard_v2_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_standard_v2_run_tests
|
||||
run: source tools/ci.sh && ci_unix_standard_v2_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
@@ -70,30 +70,25 @@ jobs:
|
||||
coverage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
# Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
|
||||
# Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_coverage_setup
|
||||
run: source tools/ci.sh && ci_unix_coverage_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_coverage_build
|
||||
run: source tools/ci.sh && ci_unix_coverage_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_coverage_run_tests
|
||||
run: source tools/ci.sh && ci_unix_coverage_run_tests
|
||||
- name: Test merging .mpy files
|
||||
run: tools/ci.sh unix_coverage_run_mpy_merge_tests
|
||||
run: source tools/ci.sh && ci_unix_coverage_run_mpy_merge_tests
|
||||
- name: Build native mpy modules
|
||||
run: tools/ci.sh native_mpy_modules_build
|
||||
run: source tools/ci.sh && ci_native_mpy_modules_build
|
||||
- name: Test importing .mpy generated by mpy_ld.py
|
||||
run: tools/ci.sh unix_coverage_run_native_mpy_tests
|
||||
run: source tools/ci.sh && ci_unix_coverage_run_native_mpy_tests
|
||||
- name: Run gcov coverage analysis
|
||||
run: |
|
||||
(cd ports/unix && gcov -o build-coverage/py ../../py/*.c || true)
|
||||
(cd ports/unix && gcov -o build-coverage/extmod ../../extmod/*.c || true)
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v5
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
||||
@@ -103,47 +98,33 @@ jobs:
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
coverage_32bit:
|
||||
runs-on: ubuntu-22.04 # use 22.04 to get libffi-dev:i386
|
||||
runs-on: ubuntu-20.04 # use 20.04 to get libffi-dev:i386
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_32bit_setup
|
||||
run: source tools/ci.sh && ci_unix_32bit_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_coverage_32bit_build
|
||||
run: source tools/ci.sh && ci_unix_coverage_32bit_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_coverage_32bit_run_tests
|
||||
run: source tools/ci.sh && ci_unix_coverage_32bit_run_tests
|
||||
- name: Build native mpy modules
|
||||
run: tools/ci.sh native_mpy_modules_32bit_build
|
||||
run: source tools/ci.sh && ci_native_mpy_modules_32bit_build
|
||||
- name: Test importing .mpy generated by mpy_ld.py
|
||||
run: tools/ci.sh unix_coverage_32bit_run_native_mpy_tests
|
||||
run: source tools/ci.sh && ci_unix_coverage_32bit_run_native_mpy_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
nanbox:
|
||||
runs-on: ubuntu-22.04 # use 22.04 to get libffi-dev:i386
|
||||
runs-on: ubuntu-20.04 # use 20.04 to get python2, and libffi-dev:i386
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_32bit_setup
|
||||
run: source tools/ci.sh && ci_unix_32bit_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_nanbox_build
|
||||
run: source tools/ci.sh && ci_unix_nanbox_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_nanbox_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
longlong:
|
||||
runs-on: ubuntu-22.04 # use 22.04 to get libffi-dev:i386
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_32bit_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_longlong_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_longlong_run_tests
|
||||
run: source tools/ci.sh && ci_unix_nanbox_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
@@ -151,51 +132,51 @@ jobs:
|
||||
float:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_float_build
|
||||
run: source tools/ci.sh && ci_unix_float_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_float_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
gil_enabled:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_gil_enabled_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_gil_enabled_run_tests
|
||||
run: source tools/ci.sh && ci_unix_float_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
stackless_clang:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_clang_setup
|
||||
run: source tools/ci.sh && ci_unix_clang_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_stackless_clang_build
|
||||
run: source tools/ci.sh && ci_unix_stackless_clang_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_stackless_clang_run_tests
|
||||
run: source tools/ci.sh && ci_unix_stackless_clang_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
float_clang:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: source tools/ci.sh && ci_unix_clang_setup
|
||||
- name: Build
|
||||
run: source tools/ci.sh && ci_unix_float_clang_build
|
||||
- name: Run main test suite
|
||||
run: source tools/ci.sh && ci_unix_float_clang_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
settrace:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_clang_setup
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_float_clang_build
|
||||
run: source tools/ci.sh && ci_unix_settrace_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_float_clang_run_tests
|
||||
run: source tools/ci.sh && ci_unix_settrace_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
@@ -203,140 +184,68 @@ jobs:
|
||||
settrace_stackless:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
# Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
|
||||
# Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_settrace_stackless_build
|
||||
run: source tools/ci.sh && ci_unix_settrace_stackless_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_settrace_stackless_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
repr_b:
|
||||
runs-on: ubuntu-22.04 # use 22.04 to get libffi-dev:i386
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_32bit_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_repr_b_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_repr_b_run_tests
|
||||
run: source tools/ci.sh && ci_unix_settrace_stackless_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
macos:
|
||||
runs-on: macos-26
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.8'
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_macos_build
|
||||
run: source tools/ci.sh && ci_unix_macos_build
|
||||
- name: Run tests
|
||||
run: tools/ci.sh unix_macos_run_tests
|
||||
run: source tools/ci.sh && ci_unix_macos_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
qemu_mips:
|
||||
# ubuntu-22.04 is needed for older libffi.
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_qemu_mips_setup
|
||||
run: source tools/ci.sh && ci_unix_qemu_mips_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_qemu_mips_build
|
||||
run: source tools/ci.sh && ci_unix_qemu_mips_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_qemu_mips_run_tests
|
||||
run: source tools/ci.sh && ci_unix_qemu_mips_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
qemu_arm:
|
||||
# ubuntu-22.04 is needed for older libffi.
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_qemu_arm_setup
|
||||
run: source tools/ci.sh && ci_unix_qemu_arm_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_qemu_arm_build
|
||||
run: source tools/ci.sh && ci_unix_qemu_arm_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_qemu_arm_run_tests
|
||||
run: source tools/ci.sh && ci_unix_qemu_arm_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
qemu_riscv64:
|
||||
# ubuntu-22.04 is needed for older libffi.
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_qemu_riscv64_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_qemu_riscv64_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_qemu_riscv64_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
sanitize_address:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
# Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
|
||||
# Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_coverage_setup
|
||||
run: source tools/ci.sh && ci_unix_qemu_riscv64_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_sanitize_address_build
|
||||
run: source tools/ci.sh && ci_unix_qemu_riscv64_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_sanitize_address_run_tests
|
||||
- name: Test merging .mpy files
|
||||
run: tools/ci.sh unix_coverage_run_mpy_merge_tests
|
||||
- name: Build native mpy modules
|
||||
run: tools/ci.sh native_mpy_modules_build
|
||||
- name: Test importing .mpy generated by mpy_ld.py
|
||||
run: tools/ci.sh unix_coverage_run_native_mpy_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
sanitize_undefined:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
# Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
|
||||
# Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: Install packages
|
||||
run: tools/ci.sh unix_coverage_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh unix_sanitize_undefined_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh unix_sanitize_undefined_run_tests
|
||||
- name: Test merging .mpy files
|
||||
run: tools/ci.sh unix_coverage_run_mpy_merge_tests
|
||||
- name: Build native mpy modules
|
||||
run: tools/ci.sh native_mpy_modules_build
|
||||
- name: Test importing .mpy generated by mpy_ld.py
|
||||
run: tools/ci.sh unix_coverage_run_native_mpy_tests
|
||||
run: source tools/ci.sh && ci_unix_qemu_riscv64_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
9
.github/workflows/ports_webassembly.yml
vendored
9
.github/workflows/ports_webassembly.yml
vendored
@@ -11,7 +11,6 @@ on:
|
||||
- 'shared/**'
|
||||
- 'lib/**'
|
||||
- 'ports/webassembly/**'
|
||||
- 'tests/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -21,13 +20,13 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh webassembly_setup
|
||||
run: source tools/ci.sh && ci_webassembly_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh webassembly_build
|
||||
run: source tools/ci.sh && ci_webassembly_build
|
||||
- name: Run tests
|
||||
run: tools/ci.sh webassembly_run_tests
|
||||
run: source tools/ci.sh && ci_webassembly_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
45
.github/workflows/ports_windows.yml
vendored
45
.github/workflows/ports_windows.yml
vendored
@@ -28,12 +28,13 @@ jobs:
|
||||
visualstudio: ['2017', '2019', '2022']
|
||||
include:
|
||||
- visualstudio: '2017'
|
||||
runner: windows-latest
|
||||
vs_version: '[15, 16)'
|
||||
custom_vs_install: true
|
||||
- visualstudio: '2019'
|
||||
runner: windows-2019
|
||||
vs_version: '[16, 17)'
|
||||
custom_vs_install: true
|
||||
- visualstudio: '2022'
|
||||
runner: windows-2022
|
||||
vs_version: '[17, 18)'
|
||||
# trim down the number of jobs in the matrix
|
||||
exclude:
|
||||
@@ -41,25 +42,24 @@ jobs:
|
||||
configuration: Debug
|
||||
- visualstudio: '2019'
|
||||
configuration: Debug
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
CI_BUILD_CONFIGURATION: ${{ matrix.configuration }}
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Install Visual Studio ${{ matrix.visualstudio }}
|
||||
if: matrix.custom_vs_install
|
||||
shell: bash
|
||||
# Shell functions in this block are to retry intermittent corrupt
|
||||
# downloads (with a clean download dir) before failing the job outright
|
||||
- name: Install Visual Studio 2017
|
||||
if: matrix.visualstudio == '2017'
|
||||
run: |
|
||||
try () { ($@) || ($@) || ($@) || ($@) }
|
||||
clean_install () ( rm -rf $TEMP/chocolatey; choco install $1 )
|
||||
try clean_install visualstudio${{ matrix.visualstudio }}buildtools
|
||||
try clean_install visualstudio${{ matrix.visualstudio }}-workload-vctools
|
||||
try clean_install windows-sdk-8.1
|
||||
choco install visualstudio2017buildtools
|
||||
choco install visualstudio2017-workload-vctools
|
||||
choco install windows-sdk-8.1
|
||||
- uses: microsoft/setup-msbuild@v2
|
||||
with:
|
||||
vs-version: ${{ matrix.vs_version }}
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v5
|
||||
if: matrix.runner == 'windows-2019'
|
||||
with:
|
||||
python-version: '3.9'
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build mpy-cross.exe
|
||||
run: msbuild mpy-cross\mpy-cross.vcxproj -maxcpucount -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }}
|
||||
- name: Update submodules
|
||||
@@ -103,18 +103,13 @@ jobs:
|
||||
env: i686
|
||||
- sys: mingw64
|
||||
env: x86_64
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2022
|
||||
env:
|
||||
CHERE_INVOKING: enabled_from_arguments
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- uses: actions/setup-python@v6
|
||||
# note: can go back to installing mingw-w64-${{ matrix.env }}-python after
|
||||
# MSYS2 updates to Python >3.12 (due to settrace compatibility issue)
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.sys }}
|
||||
@@ -123,10 +118,10 @@ jobs:
|
||||
make
|
||||
mingw-w64-${{ matrix.env }}-gcc
|
||||
pkg-config
|
||||
mingw-w64-${{ matrix.env }}-python3
|
||||
git
|
||||
diffutils
|
||||
path-type: inherit # Remove when setup-python is removed
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build mpy-cross.exe
|
||||
run: make -C mpy-cross -j2
|
||||
- name: Update submodules
|
||||
@@ -144,8 +139,8 @@ jobs:
|
||||
cross-build-on-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh windows_setup
|
||||
run: source tools/ci.sh && ci_windows_setup
|
||||
- name: Build
|
||||
run: tools/ci.sh windows_build
|
||||
run: source tools/ci.sh && ci_windows_build
|
||||
|
||||
35
.github/workflows/ports_zephyr.yml
vendored
35
.github/workflows/ports_zephyr.yml
vendored
@@ -11,11 +11,6 @@ on:
|
||||
- 'shared/**'
|
||||
- 'lib/**'
|
||||
- 'ports/zephyr/**'
|
||||
- 'tests/**'
|
||||
schedule:
|
||||
# Scheduled run exists to keep master branch Zephyr cache entry hot
|
||||
# and prevent creating many redundant per-branch cache entries instead.
|
||||
- cron: "40 4 * * *"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -28,41 +23,21 @@ jobs:
|
||||
- uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
# Only free up a few things so this step runs quickly.
|
||||
# (android would save 9.6GiB, but takes about 13m)
|
||||
# (large-packages would save 4.6GiB, but takes about 3m)
|
||||
android: false
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
tool-cache: true
|
||||
swap-storage: false
|
||||
- uses: actions/checkout@v6
|
||||
- id: versions
|
||||
name: Read Zephyr version
|
||||
run: source tools/ci.sh && echo "ZEPHYR=$ZEPHYR_VERSION" | tee "$GITHUB_OUTPUT"
|
||||
- name: Cached Zephyr Workspace
|
||||
id: cache_workspace
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
# note that the Zephyr CI docker image is 15GB. At time of writing
|
||||
# GitHub caches are limited to 10GB total for a project. So we only
|
||||
# cache the "workspace"
|
||||
path: ./zephyrproject
|
||||
key: zephyr-workspace-${{ steps.versions.outputs.ZEPHYR }}
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: zephyr
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: tools/ci.sh zephyr_setup
|
||||
run: source tools/ci.sh && ci_zephyr_setup
|
||||
- name: Install Zephyr
|
||||
if: steps.cache_workspace.outputs.cache-hit != 'true'
|
||||
run: tools/ci.sh zephyr_install
|
||||
run: source tools/ci.sh && ci_zephyr_install
|
||||
- name: Build
|
||||
run: tools/ci.sh zephyr_build
|
||||
run: source tools/ci.sh && ci_zephyr_build
|
||||
- name: Run main test suite
|
||||
run: tools/ci.sh zephyr_run_tests
|
||||
run: source tools/ci.sh && ci_zephyr_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
6
.github/workflows/ruff.yml
vendored
6
.github/workflows/ruff.yml
vendored
@@ -6,8 +6,8 @@ jobs:
|
||||
ruff:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
# ruff version should be kept in sync with .pre-commit-config.yaml & also micropython-lib
|
||||
- run: pipx install ruff==0.11.6
|
||||
- uses: actions/checkout@v4
|
||||
# ruff version should be kept in sync with .pre-commit-config.yaml
|
||||
- run: pip install --user ruff==0.1.3
|
||||
- run: ruff check --output-format=github .
|
||||
- run: ruff format --diff .
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -24,11 +24,3 @@ user.props
|
||||
|
||||
# MacOS desktop metadata files
|
||||
.DS_Store
|
||||
|
||||
# Created by ci.sh zephyr targets
|
||||
/.ccache
|
||||
/zephyrproject
|
||||
|
||||
# Created by ci.sh esp8266 targets
|
||||
/xtensa-lx106-elf-standalone.tar.gz
|
||||
/xtensa-lx106-elf/
|
||||
|
||||
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -35,7 +35,7 @@
|
||||
url = https://github.com/bluekitchen/btstack.git
|
||||
[submodule "lib/nxp_driver"]
|
||||
path = lib/nxp_driver
|
||||
url = https://github.com/micropython/nxp_driver.git
|
||||
url = https://github.com/hathach/nxp_driver.git
|
||||
[submodule "lib/libhydrogen"]
|
||||
path = lib/libhydrogen
|
||||
url = https://github.com/jedisct1/libhydrogen.git
|
||||
@@ -68,9 +68,3 @@
|
||||
[submodule "lib/arduino-lib"]
|
||||
path = lib/arduino-lib
|
||||
url = https://github.com/arduino/arduino-lib-mpy.git
|
||||
[submodule "lib/alif_ensemble-cmsis-dfp"]
|
||||
path = lib/alif_ensemble-cmsis-dfp
|
||||
url = https://github.com/alifsemi/alif_ensemble-cmsis-dfp.git
|
||||
[submodule "lib/alif-security-toolkit"]
|
||||
path = lib/alif-security-toolkit
|
||||
url = https://github.com/micropython/alif-security-toolkit.git
|
||||
|
||||
@@ -12,14 +12,14 @@ repos:
|
||||
verbose: true
|
||||
stages: [commit-msg]
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
# Version should be kept in sync with .github/workflows/ruff.yml & also micropython-lib
|
||||
rev: v0.11.6
|
||||
# Version should be kept in sync with .github/workflows/ruff.yml
|
||||
rev: v0.1.3
|
||||
hooks:
|
||||
- id: ruff
|
||||
- id: ruff-format
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
# Version should be kept in sync with .github/workflows/codespell.yml
|
||||
rev: v2.4.1
|
||||
rev: v2.2.6
|
||||
hooks:
|
||||
- id: codespell
|
||||
name: Spellcheck for changed files (codespell)
|
||||
|
||||
@@ -206,21 +206,14 @@ adhere to the existing style and use `tools/codeformat.py` to check any changes.
|
||||
The main conventions, and things not enforceable via the auto-formatter, are
|
||||
described below.
|
||||
|
||||
As the MicroPython code base is over ten years old, not every source file
|
||||
conforms fully to these conventions. If making small changes to existing code,
|
||||
then it's usually acceptable to follow the existing code's style. New code or
|
||||
major changes should follow the conventions described here.
|
||||
|
||||
## White space
|
||||
|
||||
White space:
|
||||
- Expand tabs to 4 spaces.
|
||||
- Don't leave trailing whitespace at the end of a line.
|
||||
- For control blocks (if, for, while), put 1 space between the
|
||||
keyword and the opening parenthesis.
|
||||
- Put 1 space after a comma, and 1 space around operators.
|
||||
|
||||
## Braces
|
||||
|
||||
Braces:
|
||||
- Use braces for all blocks, even no-line and single-line pieces of
|
||||
code.
|
||||
- Put opening braces on the end of the line it belongs to, not on
|
||||
@@ -228,43 +221,18 @@ major changes should follow the conventions described here.
|
||||
- For else-statements, put the else on the same line as the previous
|
||||
closing brace.
|
||||
|
||||
## Header files
|
||||
|
||||
Header files:
|
||||
- Header files should be protected from multiple inclusion with #if
|
||||
directives. See an existing header for naming convention.
|
||||
|
||||
## Names
|
||||
|
||||
Names:
|
||||
- Use underscore_case, not camelCase for all names.
|
||||
- Use CAPS_WITH_UNDERSCORE for enums and macros.
|
||||
- When defining a type use underscore_case and put '_t' after it.
|
||||
|
||||
### Public names (declared in headers)
|
||||
|
||||
- MicroPython-specific names (especially any declared in `py/` and `extmod/`
|
||||
directories) should generally start with `mp_` or `MP_`.
|
||||
- Functions and variables declared in a header should generally share a longer
|
||||
common prefix. Usually the prefix matches the file name (i.e. items defined in
|
||||
`py/obj.c` are declared in `py/obj.h` and should be prefixed `mp_obj_`). There
|
||||
are exceptions, for example where one header file contains declarations
|
||||
implemented in multiple source files for expediency.
|
||||
|
||||
### Private names (specific to a single .c file)
|
||||
|
||||
- For static functions and variables exposed to Python (i.e. a static C function
|
||||
that is wrapped in `MP_DEFINE_CONST_FUN_...` and attached to a module), use
|
||||
the file-level shared common prefix, i.e. name them as if the function or
|
||||
variable was not static.
|
||||
- Other static definitions in source files (i.e. functions or variables defined
|
||||
in a .c file that are only used within that .c file) don't need any prefix
|
||||
(specifically: no `s_` or `_` prefix, and generally avoid adding the
|
||||
file-level common prefix).
|
||||
|
||||
## Integer types
|
||||
|
||||
MicroPython runs on 16, 32, and 64 bit machines, so it's important to use the
|
||||
correctly-sized (and signed) integer types. The general guidelines are:
|
||||
|
||||
Integer types: MicroPython runs on 16, 32, and 64 bit machines, so it's
|
||||
important to use the correctly-sized (and signed) integer types. The
|
||||
general guidelines are:
|
||||
- For most cases use mp_int_t for signed and mp_uint_t for unsigned
|
||||
integer values. These are guaranteed to be machine-word sized and
|
||||
therefore big enough to hold the value from a MicroPython small-int
|
||||
@@ -273,13 +241,11 @@ correctly-sized (and signed) integer types. The general guidelines are:
|
||||
- You can use int/uint, but remember that they may be 16-bits wide.
|
||||
- If in doubt, use mp_int_t/mp_uint_t.
|
||||
|
||||
## Comments
|
||||
|
||||
Comments:
|
||||
- Be concise and only write comments for things that are not obvious.
|
||||
- Use `// ` prefix, NOT `/* ... */`. No extra fluff.
|
||||
|
||||
## Memory allocation
|
||||
|
||||
Memory allocation:
|
||||
- Use m_new, m_renew, m_del (and friends) to allocate and free heap memory.
|
||||
These macros are defined in py/misc.h.
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2025 Damien P. George
|
||||
Copyright (c) 2013-2024 Damien P. George
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
93
README.md
93
README.md
@@ -80,8 +80,9 @@ This repository contains the following components:
|
||||
- [examples/](examples/) -- a few example Python scripts.
|
||||
|
||||
"make" is used to build the components, or "gmake" on BSD-based systems.
|
||||
You will also need bash, gcc, and Python 3.3+ available as the command `python3`.
|
||||
Some ports (rp2 and esp32) additionally use CMake.
|
||||
You will also need bash, gcc, and Python 3.3+ available as the command `python3`
|
||||
(if your system only has Python 2.7 then invoke make with the additional option
|
||||
`PYTHON=python2`). Some ports (rp2 and esp32) additionally use CMake.
|
||||
|
||||
Supported platforms & architectures
|
||||
-----------------------------------
|
||||
@@ -98,74 +99,28 @@ development and testing of MicroPython itself, as well as providing
|
||||
lightweight alternative to CPython on these platforms (in particular on
|
||||
embedded Linux systems).
|
||||
|
||||
Over twenty different MicroPython ports are provided in this repository,
|
||||
split across three
|
||||
[MicroPython Support Tiers](https://docs.micropython.org/en/latest/develop/support_tiers.html).
|
||||
The ["minimal"](ports/minimal) port provides an example of a very basic
|
||||
MicroPython port and can be compiled as both a standalone Linux binary as
|
||||
well as for ARM Cortex M4. Start with this if you want to port MicroPython to
|
||||
another microcontroller. Additionally the ["bare-arm"](ports/bare-arm) port
|
||||
is an example of the absolute minimum configuration, and is used to keep
|
||||
track of the code size of the core runtime and VM.
|
||||
|
||||
Tier 1 Ports
|
||||
============
|
||||
|
||||
👑 Ports in [Tier 1](https://docs.micropython.org/en/latest/develop/support_tiers.html)
|
||||
are mature and have the most active development, support and testing:
|
||||
|
||||
| Port | Target | Quick Reference |
|
||||
|--------------------------|----------------------------------------------------------------------------------------|----------------------------------------------------------------------|
|
||||
| [esp32](ports/esp32)* | Espressif ESP32 SoCs (ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C6) | [here](https://docs.micropython.org/en/latest/esp32/quickref.html) |
|
||||
| [mimxrt](ports/mimxrt) | NXP m.iMX RT | [here](https://docs.micropython.org/en/latest/mimxrt/quickref.html) |
|
||||
| [rp2](ports/rp2) | Raspberry Pi RP2040 and RP2350 | [here](https://docs.micropython.org/en/latest/rp2/quickref.html) |
|
||||
| [samd](ports/samd) | Microchip (formerly Atmel) SAMD21 and SAMD51 | [here](https://docs.micropython.org/en/latest/samd/quickref.html) |
|
||||
| [stm32](ports/stm32) | STMicroelectronics STM32 MCUs (F0, F4, F7, G0, G4, H5, H7, L0, L1, L4, N6, WB, WL) | [here](https://docs.micropython.org/en/latest/pyboard/quickref.html) |
|
||||
| [unix](ports/unix) | Linux, BSD, macOS, WSL | [here](https://docs.micropython.org/en/latest/unix/quickref.html) |
|
||||
| [windows](ports/windows) | Microsoft Windows | [here](https://docs.micropython.org/en/latest/unix/quickref.html) |
|
||||
|
||||
An asterisk indicates that the port has ongoing financial support from the vendor.
|
||||
|
||||
Tier 2 Ports
|
||||
============
|
||||
|
||||
✔ Ports in [Tier 2](https://docs.micropython.org/en/latest/develop/support_tiers.html)
|
||||
are less mature and less actively developed and tested than Tier 1, but
|
||||
still fully supported:
|
||||
|
||||
| Port | Target | Quick Reference |
|
||||
|----------------------------------|-------------------------------------------------------------|-------------------------------------------------------------------------|
|
||||
| [alif](ports/alif) | Alif Semiconductor Ensemble MCUs (E3, E7) | |
|
||||
| [embed](ports/embed) | Generates a set of .c/.h files for embedding into a project | |
|
||||
| [nrf](ports/nrf) | Nordic Semiconductor nRF51 and nRF52 | |
|
||||
| [renesas-ra](ports/renesas-ra) | Renesas RA family | [here](https://docs.micropython.org/en/latest/renesas-ra/quickref.html) |
|
||||
| [webassembly](ports/webassembly) | Emscripten port targeting browsers and NodeJS | |
|
||||
| [zephyr](ports/zephyr) | Zephyr RTOS | [here](https://docs.micropython.org/en/latest/zephyr/quickref.html) |
|
||||
|
||||
Tier 3 Ports
|
||||
============
|
||||
|
||||
Ports in [Tier 3](https://docs.micropython.org/en/latest/develop/support_tiers.html)
|
||||
are built in CI but not regularly tested by the MicroPython maintainers:
|
||||
|
||||
| Port | Target | Quick Reference |
|
||||
|----------------------------|-------------------------------------------------------------------|-------------------------------------------------------------------------|
|
||||
| [cc3200](ports/cc3200) | Texas Instruments CC3200 | [For WiPy](https://docs.micropython.org/en/latest/wipy/quickref.html) |
|
||||
| [esp8266](ports/esp8266) | Espressif ESP8266 SoC | [here](https://docs.micropython.org/en/latest/esp8266/quickref.html) |
|
||||
| [pic16bit](ports/pic16bit) | Microchip PIC 16-bit | |
|
||||
| [powerpc](ports/powerpc) | IBM PowerPC (including Microwatt) | |
|
||||
|
||||
Additional Ports
|
||||
================
|
||||
|
||||
In addition to the above there is a Tier M containing ports that are used
|
||||
primarily for maintenance, development and testing:
|
||||
|
||||
- The ["bare-arm"](ports/bare-arm) port is an example of the absolute minimum
|
||||
configuration that still includes the compiler, and is used to keep track
|
||||
of the code size of the core runtime and VM.
|
||||
|
||||
- The ["minimal"](ports/minimal) port provides an example of a very basic
|
||||
MicroPython port and can be compiled as both a standalone Linux binary as
|
||||
well as for ARM Cortex-M4. Start with this if you want to port MicroPython
|
||||
to another microcontroller.
|
||||
|
||||
- The [qemu](ports/qemu) port is a QEMU-based emulated target for Cortex-A,
|
||||
Cortex-M, RISC-V 32-bit and RISC-V 64-bit architectures.
|
||||
In addition, the following ports are provided in this repository:
|
||||
- [cc3200](ports/cc3200) -- Texas Instruments CC3200 (including PyCom WiPy).
|
||||
- [esp32](ports/esp32) -- Espressif ESP32 SoC (including ESP32S2, ESP32S3, ESP32C3, ESP32C6).
|
||||
- [esp8266](ports/esp8266) -- Espressif ESP8266 SoC.
|
||||
- [mimxrt](ports/mimxrt) -- NXP m.iMX RT (including Teensy 4.x).
|
||||
- [nrf](ports/nrf) -- Nordic Semiconductor nRF51 and nRF52.
|
||||
- [pic16bit](ports/pic16bit) -- Microchip PIC 16-bit.
|
||||
- [powerpc](ports/powerpc) -- IBM PowerPC (including Microwatt)
|
||||
- [qemu](ports/qemu) -- QEMU-based emulated target (for testing)
|
||||
- [renesas-ra](ports/renesas-ra) -- Renesas RA family.
|
||||
- [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)
|
||||
- [webassembly](ports/webassembly) -- Emscripten port targeting browsers and NodeJS.
|
||||
- [zephyr](ports/zephyr) -- Zephyr RTOS.
|
||||
|
||||
The MicroPython cross-compiler, mpy-cross
|
||||
-----------------------------------------
|
||||
|
||||
@@ -13,7 +13,8 @@ Building the documentation locally
|
||||
If you're making changes to the documentation, you may want to build the
|
||||
documentation locally so that you can preview your changes.
|
||||
|
||||
Install Sphinx and sphinx_rtd_theme, preferably in a virtualenv:
|
||||
Install Sphinx, and optionally (for the RTD-styling), sphinx_rtd_theme,
|
||||
preferably in a virtualenv:
|
||||
|
||||
pip install sphinx
|
||||
pip install sphinx_rtd_theme
|
||||
@@ -24,21 +25,6 @@ In `micropython/docs`, build the docs:
|
||||
|
||||
You'll find the index page at `micropython/docs/build/html/index.html`.
|
||||
|
||||
Documentation autobuild
|
||||
-----------------------
|
||||
|
||||
For a more convenient development experience, you can use `sphinx-autobuild`
|
||||
to automatically rebuild and serve the documentation when you make changes:
|
||||
|
||||
pip install sphinx-autobuild
|
||||
|
||||
Then run from the `micropython/docs` directory:
|
||||
|
||||
sphinx-autobuild . build/html
|
||||
|
||||
This will start a local web server (typically at `http://127.0.0.1:8000`)
|
||||
and automatically rebuild the documentation whenever you save changes to the source files.
|
||||
|
||||
Having readthedocs.org build the documentation
|
||||
----------------------------------------------
|
||||
|
||||
|
||||
27
docs/conf.py
27
docs/conf.py
@@ -36,9 +36,6 @@ html_context = {
|
||||
"is_release": micropy_version != "latest",
|
||||
}
|
||||
|
||||
# Authors used in various parts of the documentation.
|
||||
micropy_authors = "MicroPython authors and contributors"
|
||||
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
@@ -55,7 +52,6 @@ extensions = [
|
||||
"sphinx.ext.todo",
|
||||
"sphinx.ext.coverage",
|
||||
"sphinxcontrib.jquery",
|
||||
"sphinx_rtd_theme",
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
@@ -72,7 +68,7 @@ master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = "MicroPython"
|
||||
copyright = "- The MicroPython Documentation is Copyright © 2014-2025, " + micropy_authors
|
||||
copyright = "- The MicroPython Documentation is Copyright © 2014-2024, 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
|
||||
@@ -129,9 +125,20 @@ rst_epilog = """
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
import sphinx_rtd_theme
|
||||
# on_rtd is whether we are on readthedocs.org
|
||||
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
|
||||
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
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(), "."]
|
||||
except:
|
||||
html_theme = "default"
|
||||
html_theme_path = ["."]
|
||||
else:
|
||||
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
|
||||
@@ -237,7 +244,7 @@ latex_documents = [
|
||||
master_doc,
|
||||
"MicroPython.tex",
|
||||
"MicroPython Documentation",
|
||||
micropy_authors,
|
||||
"Damien P. George, Paul Sokolovsky, and contributors",
|
||||
"manual",
|
||||
),
|
||||
]
|
||||
@@ -274,7 +281,7 @@ man_pages = [
|
||||
"index",
|
||||
"micropython",
|
||||
"MicroPython Documentation",
|
||||
[micropy_authors],
|
||||
["Damien P. George, Paul Sokolovsky, and contributors"],
|
||||
1,
|
||||
),
|
||||
]
|
||||
@@ -293,7 +300,7 @@ texinfo_documents = [
|
||||
master_doc,
|
||||
"MicroPython",
|
||||
"MicroPython Documentation",
|
||||
micropy_authors,
|
||||
"Damien P. George, Paul Sokolovsky, and contributors",
|
||||
"MicroPython",
|
||||
"One line description of project.",
|
||||
"Miscellaneous",
|
||||
|
||||
@@ -106,7 +106,7 @@ See the `ARM GCC
|
||||
toolchain <https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads>`_
|
||||
for the latest details.
|
||||
|
||||
Python 3 is also required.
|
||||
Python is also required. Python 2 is supported for now, but we recommend using Python 3.
|
||||
Check that you have Python available on your system:
|
||||
|
||||
.. code-block:: bash
|
||||
@@ -278,86 +278,10 @@ To run a selection of tests on a board/device connected over USB use:
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd tests
|
||||
$ ./run-tests.py -t /dev/ttyACM0
|
||||
$ ./run-tests.py --target minimal --device /dev/ttyACM0
|
||||
|
||||
See also :ref:`writingtests`.
|
||||
|
||||
Additional make targets for developers
|
||||
--------------------------------------
|
||||
|
||||
In all ``make``-based ports, there is a target to print the size of a specific object file.
|
||||
When a change is confined to a single file, this is useful when testing variations to find smaller alternatives.
|
||||
|
||||
For instance, to print the size of ``objstr.o`` in the ``py/`` directory when making a unix standard build:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ make build-standard/py/objstr.sz
|
||||
|
||||
Similarly, there is a target to save the preprocessed version of a file:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ make build-standard/py/objstr.pp
|
||||
|
||||
In ``ports/unix`` there are additional targets related to running tests:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ make test//int # Run all tests matching the pattern "int"
|
||||
$ make test/ports/unix # Run all tests in ports/unix
|
||||
$ make test-failures # Re-run only the failed tests
|
||||
$ make print-failures # print the differences for failed tests
|
||||
$ make clean-failures # delete the .exp and .out files from failed tests
|
||||
|
||||
Using ci.sh locally
|
||||
-------------------
|
||||
|
||||
MicroPython uses GitHub Actions for continuous integration.
|
||||
To reduce dependence on any specific CI system, the actual build steps for Unix-based builds are in the file ``tools/ci.sh``.
|
||||
This can also be used as a script on developer desktops, with caveats:
|
||||
|
||||
* For most steps, An Ubuntu/Debian system similar to the one used during CI is assumed.
|
||||
* Some specific steps assume specific Ubuntu versions.
|
||||
* The setup steps may invoke the system package manager to install packages,
|
||||
download and install software from the internet, etc.
|
||||
|
||||
To get a usage message including the list of commands, run:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ tools/ci.sh --help
|
||||
|
||||
As an example, you can build and test the unix minimal port with:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ tools/ci.sh unix_minimal_build unix_minimal_run_tests
|
||||
|
||||
If you use the bash shell, you can add a ``ci`` command with tab completion:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ eval $(tools/ci.sh --bash-completion)
|
||||
|
||||
For the zsh shell, replace ``--bash-completion`` with ``--zsh-completion``.
|
||||
For the fish shell, replace ``--bash-completion`` with ``--fish-completion``.
|
||||
|
||||
Then, typing:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ ci unix_cov<tab>
|
||||
|
||||
This will complete the ci step name to ``unix_coverage_``.
|
||||
Pressing tab a second time will show the list of matching steps:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ ci unix_coverage_<tab>
|
||||
unix_coverage_32bit_build
|
||||
unix_coverage_32bit_run_native_mpy_tests…
|
||||
|
||||
Folder structure
|
||||
----------------
|
||||
|
||||
|
||||
@@ -24,4 +24,3 @@ MicroPython to a new platform and implementing a core MicroPython library.
|
||||
publiccapi.rst
|
||||
extendingmicropython.rst
|
||||
porting.rst
|
||||
support_tiers.rst
|
||||
|
||||
@@ -39,8 +39,7 @@ options for the ``ARCH`` variable, see below):
|
||||
* ``armv7emsp`` (ARM Thumb 2, single precision float, eg Cortex-M4F, Cortex-M7)
|
||||
* ``armv7emdp`` (ARM Thumb 2, double precision float, eg Cortex-M7)
|
||||
* ``xtensa`` (non-windowed, eg ESP8266)
|
||||
* ``xtensawin`` (windowed with window size 8, eg ESP32, ESP32S3)
|
||||
* ``rv32imc`` (RISC-V 32 bits with compressed instructions, eg ESP32C3, ESP32C6)
|
||||
* ``xtensawin`` (windowed with window size 8, eg ESP32)
|
||||
|
||||
When compiling and linking the native .mpy file the architecture must be chosen
|
||||
and the corresponding file can only be imported on that architecture. For more
|
||||
@@ -67,31 +66,14 @@ The known limitations are:
|
||||
|
||||
* static BSS variables are not supported; workaround: use global BSS variables
|
||||
|
||||
* thread-local storage variables are not supported on rv32imc; workaround: use
|
||||
global BSS variables or allocate some space on the heap to store them
|
||||
|
||||
So, if your C code has writable data, make sure the data is defined globally,
|
||||
without an initialiser, and only written to within functions.
|
||||
|
||||
The native module is not automatically linked against the standard static libraries
|
||||
like ``libm.a`` and ``libgcc.a``, which can lead to ``undefined symbol`` errors.
|
||||
You can link the runtime libraries by setting ``LINK_RUNTIME = 1``
|
||||
in your Makefile. Custom static libraries can also be linked by adding
|
||||
``MPY_LD_FLAGS += -l path/to/library.a``. Note that these are linked into
|
||||
the native module and will not be shared with other modules or the system.
|
||||
|
||||
Linker limitation: the native module is not linked against the symbol table of the
|
||||
full MicroPython firmware. Rather, it is linked against an explicit table of exported
|
||||
symbols found in ``mp_fun_table`` (in ``py/nativeglue.h``), that is fixed at firmware
|
||||
build time. It is thus not possible to simply call some arbitrary HAL/OS/RTOS/system
|
||||
function, for example, unless that resides at a fixed address. In that case, the path
|
||||
of a linkerscript containing a series of symbol names and their fixed address can be
|
||||
passed to ``mpy_ld.py`` via the ``--externs`` command line argument. That way symbols
|
||||
appearing in the linkerscript will take precedence over what is provided from object
|
||||
files, but at the moment the object files' implementation will still reside in the
|
||||
final MPY file. The linkerscript parser is limited in its capabilities, and is
|
||||
currently used only for parsing the ESP8266 port ROM symbols list (see
|
||||
``ports/esp8266/boards/eagle.rom.addr.v6.ld``).
|
||||
function, for example.
|
||||
|
||||
New symbols can be added to the end of the table and the firmware rebuilt.
|
||||
The symbols also need to be added to ``tools/mpy_ld.py``'s ``fun_table`` dict in the
|
||||
@@ -190,7 +172,7 @@ The file ``Makefile`` contains:
|
||||
# Source files (.c or .py)
|
||||
SRC = factorial.c
|
||||
|
||||
# Architecture to build for (x86, x64, armv6m, armv7m, xtensa, xtensawin, rv32imc)
|
||||
# Architecture to build for (x86, x64, armv6m, armv7m, xtensa, xtensawin)
|
||||
ARCH = x64
|
||||
|
||||
# Include to get the rules for compiling and linking the module
|
||||
@@ -228,26 +210,6 @@ other module, for example::
|
||||
print(factorial.factorial(10))
|
||||
# should display 3628800
|
||||
|
||||
Using Picolibc when building modules
|
||||
------------------------------------
|
||||
|
||||
Using `Picolibc <https://github.com/picolibc/picolibc>`_ as your C standard
|
||||
library is not only supported, but in fact it is the default for the rv32imc
|
||||
platform. However, there are a couple of things worth mentioning to make sure
|
||||
you don't run into problems later when building code.
|
||||
|
||||
Some pre-built Picolibc versions (for example, those provided by Ubuntu Linux
|
||||
as the ``picolibc-arm-none-eabi``, ``picolibc-riscv64-unknown-elf``, and
|
||||
``picolibc-xtensa-lx106-elf`` packages) assume thread-local storage (TLS) is
|
||||
available at runtime, but unfortunately MicroPython modules do not support that
|
||||
on some architectures (namely ``rv32imc``). This means that some
|
||||
functionalities provided by Picolibc will default to use TLS, returning an
|
||||
error either during compilation or during linking.
|
||||
|
||||
For an example on how this may affect you, the ``examples/natmod/btree``
|
||||
example module contains a workaround to make sure ``errno`` works (look for
|
||||
``__PICOLIBC_ERRNO_FUNCTION`` in the Makefile and follow the trail from there).
|
||||
|
||||
Further examples
|
||||
----------------
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ The basic MicroPython firmware is implemented in the main port file, e.g ``main.
|
||||
#include "py/compile.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "shared/runtime/gchelper.h"
|
||||
#include "shared/runtime/pyexec.h"
|
||||
|
||||
@@ -50,7 +51,7 @@ The basic MicroPython firmware is implemented in the main port file, e.g ``main.
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Initialise the MicroPython runtime.
|
||||
mp_cstack_init_with_sp_here(2048);
|
||||
mp_stack_ctrl_init();
|
||||
gc_init(heap, heap + sizeof(heap));
|
||||
mp_init();
|
||||
|
||||
@@ -161,6 +162,8 @@ The following is an example of an ``mpconfigport.h`` file:
|
||||
|
||||
// Type definitions for the specific machine.
|
||||
|
||||
typedef intptr_t mp_int_t; // must be pointer size
|
||||
typedef uintptr_t mp_uint_t; // must be pointer size
|
||||
typedef long mp_off_t;
|
||||
|
||||
// We need to provide a declaration/definition of alloca().
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
MicroPython Support Tiers
|
||||
=========================
|
||||
|
||||
MicroPython operates with a set of Support Tier levels for the various ports.
|
||||
Tiers 1, 2 and 3 are the main Tier levels with Tier 1 being the most mature and
|
||||
actively maintained. There is also Tier M for additional ports used primarily
|
||||
for maintenance, development and testing. These Tier levels are defined in the
|
||||
table below.
|
||||
|
||||
.. table::
|
||||
:widths: 40 9 9 9 9
|
||||
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
| | Tier 1 | Tier 2 | Tier 3 | Tier M |
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
| builds pass under CI | ✔ | ✔ | ✔ | ✔ |
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
| tests run under CI (where possible) | ✔ | ✔ | ✔ | ✔ |
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
| actively maintained | ✔ | ✔ | | ✔ |
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
| stable Python API | ✔ | ✔ | | |
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
| new features actively developed | ✔ | ✔ | | |
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
| tested on hardware for releases | ✔ | ✔ | | |
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
| prioritized bug reports | ✔ | | | ✔ |
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
| regressions warrant a patch release | ✔ | | | ✔ |
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
| has port-specific documentation | ✔ | | | |
|
||||
+-----------------------------------------------+--------+--------+--------+--------+
|
||||
|
||||
Lower Tiers may tick more boxes, but the above table defines the minimum requirements
|
||||
for a port to belong to a Tier.
|
||||
|
||||
Tier 1 ports:
|
||||
|
||||
- esp32
|
||||
- mimxrt
|
||||
- rp2
|
||||
- samd
|
||||
- stm32
|
||||
- unix
|
||||
- windows
|
||||
|
||||
Tier 2 ports:
|
||||
|
||||
- alif
|
||||
- embed
|
||||
- nrf
|
||||
- renesas-ra
|
||||
- webassembly
|
||||
- zephyr
|
||||
|
||||
Tier 3 ports:
|
||||
|
||||
- cc3200
|
||||
- esp8266
|
||||
- pic16bit
|
||||
- powerpc
|
||||
|
||||
Tier M ports:
|
||||
|
||||
- bare-arm
|
||||
- minimal
|
||||
- qemu
|
||||
@@ -60,7 +60,7 @@ Then to run on a board:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ ./run-tests.py -t /dev/ttyACM0
|
||||
$ ./run-tests.py --target minimal --device /dev/ttyACM0
|
||||
|
||||
And to run only a certain set of tests (eg a directory):
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@ Python 3.6 beta 1 was released on 12 Sep 2016, and a summary of the new features
|
||||
+--------------------------------------------------------+--------------------------------------------------+-----------------+
|
||||
| `PEP 468 <https://www.python.org/dev/peps/pep-0468/>`_ | Preserving the order of *kwargs* in a function | |
|
||||
+--------------------------------------------------------+--------------------------------------------------+-----------------+
|
||||
| `PEP 487 <https://www.python.org/dev/peps/pep-0487/>`_ | Simpler customization of class creation | Partial |
|
||||
| | | [#setname]_ |
|
||||
| `PEP 487 <https://www.python.org/dev/peps/pep-0487/>`_ | Simpler customization of class creation | |
|
||||
+--------------------------------------------------------+--------------------------------------------------+-----------------+
|
||||
| `PEP 520 <https://www.python.org/dev/peps/pep-0520/>`_ | Preserving Class Attribute Definition Order | |
|
||||
+--------------------------------------------------------+--------------------------------------------------+-----------------+
|
||||
@@ -199,7 +198,3 @@ Changes to built-in modules:
|
||||
+--------------------------------------------------------------------------------------------------------------+----------------+
|
||||
| The *compress()* and *decompress()* functions now accept keyword arguments | |
|
||||
+--------------------------------------------------------------------------------------------------------------+----------------+
|
||||
|
||||
.. rubric:: Notes
|
||||
|
||||
.. [#setname] Currently, only :func:`__set_name__` is implemented.
|
||||
|
||||
@@ -79,34 +79,34 @@ Networking
|
||||
WLAN
|
||||
^^^^
|
||||
|
||||
The :class:`network.WLAN` class in the :mod:`network` module::
|
||||
The :mod:`network` module::
|
||||
|
||||
import network
|
||||
|
||||
wlan = network.WLAN() # create station interface (the default, see below for an access point interface)
|
||||
wlan.active(True) # activate the interface
|
||||
wlan.scan() # scan for access points
|
||||
wlan.isconnected() # check if the station is connected to an AP
|
||||
wlan = network.WLAN(network.STA_IF) # create station interface
|
||||
wlan.active(True) # activate the interface
|
||||
wlan.scan() # scan for access points
|
||||
wlan.isconnected() # check if the station is connected to an AP
|
||||
wlan.connect('ssid', 'key') # connect to an AP
|
||||
wlan.config('mac') # get the interface's MAC address
|
||||
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
|
||||
wlan.config('mac') # get the interface's MAC address
|
||||
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
|
||||
|
||||
ap = network.WLAN(network.WLAN.IF_AP) # create access-point interface
|
||||
ap.config(ssid='ESP-AP') # set the SSID of the access point
|
||||
ap.config(max_clients=10) # set how many clients can connect to the network
|
||||
ap.active(True) # activate the interface
|
||||
ap = network.WLAN(network.AP_IF) # create access-point interface
|
||||
ap.config(ssid='ESP-AP') # set the SSID of the access point
|
||||
ap.config(max_clients=10) # set how many clients can connect to the network
|
||||
ap.active(True) # activate the interface
|
||||
|
||||
A useful function for connecting to your local WiFi network is::
|
||||
|
||||
def do_connect():
|
||||
import machine, network
|
||||
wlan = network.WLAN()
|
||||
import network
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
if not wlan.isconnected():
|
||||
print('connecting to network...')
|
||||
wlan.connect('ssid', 'key')
|
||||
while not wlan.isconnected():
|
||||
machine.idle()
|
||||
pass
|
||||
print('network config:', wlan.ipconfig('addr4'))
|
||||
|
||||
Once the network is established the :mod:`socket <socket>` module can be used
|
||||
@@ -121,20 +121,10 @@ calling ``wlan.config(reconnects=n)``, where n are the number of desired reconne
|
||||
attempts (0 means it won't retry, -1 will restore the default behaviour of trying
|
||||
to reconnect forever).
|
||||
|
||||
.. _esp32_network_lan:
|
||||
|
||||
LAN
|
||||
^^^
|
||||
|
||||
Built-in MAC (original ESP32)
|
||||
"""""""""""""""""""""""""""""
|
||||
|
||||
The original ESP32 SoC has a built-in Ethernet MAC. Using this MAC requires an
|
||||
external Ethernet PHY to be wired to the chip's EMAC pins. Most of the EMAC pin
|
||||
assignments are fixed, consult the ESP32 datasheet for details.
|
||||
|
||||
If the PHY is connected, the internal Ethernet MAC can be configured via
|
||||
the :class:`network.LAN` constructor::
|
||||
To use the wired interfaces one has to specify the pins and mode ::
|
||||
|
||||
import network
|
||||
|
||||
@@ -143,34 +133,20 @@ the :class:`network.LAN` constructor::
|
||||
lan.ipconfig('addr4') # get the interface's IPv4 addresses
|
||||
|
||||
|
||||
Required keyword arguments for the constructor:
|
||||
The keyword arguments for the constructor defining the PHY type and interface are:
|
||||
|
||||
- ``mdc`` and ``mdio`` - :class:`machine.Pin` objects (or integers) specifying
|
||||
the MDC and MDIO pins.
|
||||
- ``phy_type`` - Select the PHY device type. Supported devices are
|
||||
``PHY_GENERIC``,
|
||||
``PHY_LAN8710``, ``PHY_LAN8720``, ``PHY_IP101``, ``PHY_RTL8201``,
|
||||
``PHY_DP83848``, ``PHY_KSZ8041`` and ``PHY_KSZ8081``. These values are all
|
||||
constants defined in the ``network`` module.
|
||||
- ``phy_addr`` - The address number of the PHY device. Must be an integer in the
|
||||
range 0x00 to 0x1f, inclusive. Common values are ``0`` and ``1``.
|
||||
- mdc=pin-object # set the mdc and mdio pins.
|
||||
- mdio=pin-object
|
||||
- reset=pin-object # set the reset pin of the PHY device.
|
||||
- power=pin-object # set the pin which switches the power of the PHY device.
|
||||
- phy_type=<type> # Select the PHY device type. Supported devices are PHY_LAN8710,
|
||||
PHY_LAN8720, PH_IP101, PHY_RTL8201, PHY_DP83848 and PHY_KSZ8041
|
||||
- phy_addr=number # The address number of the PHY device.
|
||||
- ref_clk_mode=mode # Defines, whether the ref_clk at the ESP32 is an input
|
||||
or output. Suitable values are Pin.IN and Pin.OUT.
|
||||
- ref_clk=pin-object # defines the Pin used for ref_clk.
|
||||
|
||||
All of the above keyword arguments must be present to configure the interface.
|
||||
|
||||
Optional keyword arguments:
|
||||
|
||||
- ``reset`` - :class:`machine.Pin` object (or integer) specifying the PHY reset pin.
|
||||
- ``power`` - :class:`machine.Pin` object (or integer) specifying a pin which
|
||||
switches the power of the PHY device.
|
||||
- ``ref_clk`` - :class:`machine.Pin` object (or integer) specifying the pin used
|
||||
for the EMAC ``ref_clk`` signal. If not specified, the board default is used
|
||||
(typically GPIO 0, but may be different if a particular board has Ethernet.)
|
||||
- ``ref_clk_mode`` - Defines whether the EMAC ``ref_clk`` pin of the ESP32
|
||||
should be an input or an output. Suitable values are ``machine.Pin.IN`` and
|
||||
``machine.Pin.OUT``. If not specified, the board default is used
|
||||
(typically input, but may be different if a particular board has Ethernet.)
|
||||
|
||||
These are working configurations for LAN interfaces of some popular ESP32 boards::
|
||||
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)
|
||||
@@ -195,66 +171,6 @@ These are working configurations for LAN interfaces of some popular ESP32 boards
|
||||
lan = network.LAN(id=0, mdc=Pin(23), mdio=Pin(18), power=Pin(5),
|
||||
phy_type=network.PHY_IP101, phy_addr=1)
|
||||
|
||||
|
||||
.. _esp32_spi_ethernet:
|
||||
|
||||
SPI Ethernet Interface
|
||||
""""""""""""""""""""""
|
||||
|
||||
All ESP32 SoCs support external SPI Ethernet interface chips. These are Ethernet
|
||||
interfaces that connect via a SPI bus, rather than an Ethernet RMII interface.
|
||||
|
||||
.. note:: The only exception is the ESP32 ``d2wd`` variant, where this feature is disabled
|
||||
to save code size.
|
||||
|
||||
SPI Ethernet uses the same :class:`network.LAN` constructor, with a different
|
||||
set of keyword arguments::
|
||||
|
||||
import machine, network
|
||||
|
||||
spi = machine.SPI(1, sck=SCK_PIN, mosi=MOSI_PIN, miso=MISO_PIN)
|
||||
lan = network.LAN(spi=spi, cs=CS_PIN, ...) # Set the pin and mode configuration
|
||||
lan.active(True) # activate the interface
|
||||
lan.ipconfig('addr4') # get the interface's IPv4 addresses
|
||||
|
||||
Required keyword arguments for the constructor:
|
||||
|
||||
- ``spi`` - Should be a :class:`machine.SPI` object configured for this
|
||||
connection. Note that any clock speed configured on the SPI object is ignored,
|
||||
the SPI Ethernet clock speed is configured at compile time.
|
||||
- ``cs`` - :class:`machine.Pin` object (or integer) specifying the CS pin
|
||||
connected to the interface.
|
||||
- ``int`` - :class:`machine.Pin` object (or integer) specifying the INT pin
|
||||
connected to the interface.
|
||||
- ``phy_type`` - Select the SPI Ethernet interface type. Supported devices are
|
||||
``PHY_KSZ8851SNL``, ``PHY_DM9051``, ``PHY_W5500``. These values are all
|
||||
constants defined in the ``network`` module.
|
||||
- ``phy_addr`` - The address number of the PHY device. Must be an integer in the
|
||||
range 0x00 to 0x1f, inclusive. This is usually ``0`` for SPI Ethernet devices.
|
||||
|
||||
All of the above keyword arguments must be present to configure the interface.
|
||||
|
||||
Optional keyword arguments for the constructor:
|
||||
|
||||
- ``reset`` - :class:`machine.Pin` object (or integer) specifying the SPI Ethernet
|
||||
interface reset pin.
|
||||
- ``power`` - :class:`machine.Pin` object (or integer) specifying a pin which
|
||||
switches the power of the SPI Ethernet interface.
|
||||
|
||||
Here is a sample configuration for a WIZNet W5500 chip connected to pins on
|
||||
an ESP32-S3 development board::
|
||||
|
||||
import machine, network
|
||||
from machine import Pin, SPI
|
||||
|
||||
spi = SPI(1, sck=Pin(12), mosi=Pin(13), miso=Pin(14))
|
||||
lan = network.LAN(spi=spi, phy_type=network.PHY_W5500, phy_addr=0,
|
||||
cs=Pin(10), int=Pin(11))
|
||||
|
||||
.. note:: WIZnet W5500 Ethernet is also supported on some other MicroPython
|
||||
ports, but using a :ref:`different software interface
|
||||
<network.WIZNET5K>`.
|
||||
|
||||
Delay and timing
|
||||
----------------
|
||||
|
||||
@@ -271,10 +187,8 @@ Use the :mod:`time <time>` module::
|
||||
Timers
|
||||
------
|
||||
|
||||
The ESP32 port has one, two or four hardware timers, depending on the ESP32 device type.
|
||||
There is 1 timer for ESP32C2, 2 timers for ESP32C4, ESP32C6 and ESP32H4, and
|
||||
4 timers otherwise. Use the :ref:`machine.Timer <machine.Timer>` class
|
||||
with a timer ID of 0, 0 and 1, or from 0 to 3 (inclusive)::
|
||||
The ESP32 port has four hardware timers. Use the :ref:`machine.Timer <machine.Timer>` class
|
||||
with a timer ID from 0 to 3 (inclusive)::
|
||||
|
||||
from machine import Timer
|
||||
|
||||
@@ -284,12 +198,7 @@ with a timer ID of 0, 0 and 1, or from 0 to 3 (inclusive)::
|
||||
tim1 = Timer(1)
|
||||
tim1.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(1))
|
||||
|
||||
The period is in milliseconds. When using UART.IRQ_RXIDLE, timer 0 is needed for
|
||||
the IRQ_RXIDLE mechanism and must not be used otherwise.
|
||||
|
||||
Timer callbacks are scheduled as soft interrupts on this port; hard
|
||||
callbacks are not implemented. Specifying ``hard=True`` will raise
|
||||
a ValueError.
|
||||
The period is in milliseconds.
|
||||
|
||||
Virtual timers are not currently supported on this port.
|
||||
|
||||
@@ -391,7 +300,7 @@ for more details.
|
||||
|
||||
Use the :ref:`machine.PWM <machine.PWM>` class::
|
||||
|
||||
from machine import Pin, PWM, lightsleep
|
||||
from machine import Pin, PWM
|
||||
|
||||
pwm0 = PWM(Pin(0), freq=5000, duty_u16=32768) # create PWM object from a pin
|
||||
freq = pwm0.freq() # get current frequency
|
||||
@@ -401,7 +310,7 @@ Use the :ref:`machine.PWM <machine.PWM>` class::
|
||||
pwm0.duty(256) # set duty cycle from 0 to 1023 as a ratio duty/1023, (now 25%)
|
||||
|
||||
duty_u16 = pwm0.duty_u16() # get current duty cycle, range 0-65535
|
||||
pwm0.duty_u16(65536*3//4) # set duty cycle from 0 to 65535 as a ratio duty_u16/65535, (now 75%)
|
||||
pwm0.duty_u16(2**16*3//4) # set duty cycle from 0 to 65535 as a ratio duty_u16/65535, (now 75%)
|
||||
|
||||
duty_ns = pwm0.duty_ns() # get current pulse width in ns
|
||||
pwm0.duty_ns(250_000) # set pulse width in nanoseconds from 0 to 1_000_000_000/freq, (now 25%)
|
||||
@@ -410,35 +319,19 @@ Use the :ref:`machine.PWM <machine.PWM>` class::
|
||||
|
||||
pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go
|
||||
print(pwm2) # view PWM settings
|
||||
pwm2.deinit() # turn off PWM on the pin
|
||||
|
||||
pwm0 = PWM(Pin(0), duty_u16=16384) # The output is at a high level 25% of the time.
|
||||
pwm2 = PWM(Pin(2), duty_u16=16384, invert=1) # The output is at a low level 25% of the time.
|
||||
|
||||
pwm4 = PWM(Pin(4), lightsleep=True) # Allow PWM during light sleep mode
|
||||
|
||||
lightsleep(10*1000) # pwm0, pwm2 goes off, pwm4 stays on during 10s light sleep
|
||||
# pwm0, pwm2, pwm4 on after 10s light sleep
|
||||
|
||||
ESP chips have different hardware peripherals:
|
||||
|
||||
======================================================= ======== ========= ==========
|
||||
Hardware specification ESP32 ESP32-S2, ESP32-C2,
|
||||
ESP32-S3, ESP32-C3,
|
||||
ESP32-P4 ESP32-C5,
|
||||
ESP32-C6,
|
||||
ESP32-H2
|
||||
------------------------------------------------------- -------- --------- ----------
|
||||
Number of groups (speed modes) 2 1 1
|
||||
Number of timers per group 4 4 4
|
||||
Number of channels per group 8 8 6
|
||||
------------------------------------------------------- -------- --------- ----------
|
||||
Different PWM frequencies = (groups * timers) 8 4 4
|
||||
Total PWM channels (Pins, duties) = (groups * channels) 16 8 6
|
||||
======================================================= ======== ========= ==========
|
||||
|
||||
In light sleep, the ESP32 PWM can only operate in low speed mode, so only 4 timers and
|
||||
8 channels are available.
|
||||
===================================================== ======== ======== ========
|
||||
Hardware specification ESP32 ESP32-S2 ESP32-C3
|
||||
----------------------------------------------------- -------- -------- --------
|
||||
Number of groups (speed modes) 2 1 1
|
||||
Number of timers per group 4 4 4
|
||||
Number of channels per group 8 8 6
|
||||
----------------------------------------------------- -------- -------- --------
|
||||
Different PWM frequencies (groups * timers) 8 4 4
|
||||
Total PWM channels (Pins, duties) (groups * channels) 16 8 6
|
||||
===================================================== ======== ======== ========
|
||||
|
||||
A maximum number of PWM channels (Pins) are available on the ESP32 - 16 channels,
|
||||
but only 8 different PWM frequencies are available, the remaining 8 channels must
|
||||
@@ -548,63 +441,14 @@ Legacy methods:
|
||||
|
||||
Equivalent to ``ADC.block().init(bits=bits)``.
|
||||
|
||||
The only chip that can switch resolution to a lower one is the normal esp32.
|
||||
The C2 & S3 are stuck at 12 bits, while the S2 is at 13 bits.
|
||||
|
||||
For compatibility, the ``ADC`` object also provides constants matching the
|
||||
supported ADC resolutions, per chip:
|
||||
supported ADC resolutions:
|
||||
|
||||
ESP32:
|
||||
- ``ADC.WIDTH_9BIT`` = 9
|
||||
- ``ADC.WIDTH_10BIT`` = 10
|
||||
- ``ADC.WIDTH_11BIT`` = 11
|
||||
- ``ADC.WIDTH_12BIT`` = 12
|
||||
|
||||
ESP32 C3 & S3:
|
||||
- ``ADC.WIDTH_12BIT`` = 12
|
||||
|
||||
ESP32 S2:
|
||||
- ``ADC.WIDTH_13BIT`` = 13
|
||||
|
||||
.. method:: ADC.deinit()
|
||||
|
||||
Provided to deinit the adc driver.
|
||||
|
||||
Pulse Counter (pin pulse/edge counting)
|
||||
---------------------------------------
|
||||
|
||||
The ESP32 provides up to 8 pulse counter peripherals depending on the hardware,
|
||||
with id 0..7. These can be configured to count rising and/or falling edges on
|
||||
any input pin.
|
||||
|
||||
Use the :ref:`esp32.PCNT <esp32.PCNT>` class::
|
||||
|
||||
from machine import Pin
|
||||
from esp32 import PCNT
|
||||
|
||||
counter = PCNT(0, pin=Pin(2), rising=PCNT.INCREMENT) # create counter
|
||||
counter.start() # start counter
|
||||
count = counter.value() # read count, -32768..32767
|
||||
counter.value(0) # reset counter
|
||||
count = counter.value(0) # read and reset
|
||||
|
||||
The PCNT hardware supports monitoring multiple pins in a single unit to
|
||||
implement quadrature decoding or up/down signal counters.
|
||||
|
||||
See the :ref:`machine.Counter <machine.Counter>` and
|
||||
:ref:`machine.Encoder <machine.Encoder>` classes for simpler abstractions of
|
||||
common pulse counting applications::
|
||||
|
||||
from machine import Pin, Counter
|
||||
|
||||
counter = Counter(0, Pin(2)) # create a counter as above and start it
|
||||
count = counter.value() # read the count as an arbitrary precision signed integer
|
||||
|
||||
encoder = Encoder(0, Pin(12), Pin(14)) # create an encoder and begin counting
|
||||
count = encoder.value() # read the count as an arbitrary precision signed integer
|
||||
|
||||
Note that the id passed to these ``Counter()`` and ``Encoder()`` objects must be
|
||||
a PCNT id.
|
||||
|
||||
Software SPI bus
|
||||
----------------
|
||||
@@ -732,9 +576,7 @@ See :ref:`machine.RTC <machine.RTC>` ::
|
||||
from machine import RTC
|
||||
|
||||
rtc = RTC()
|
||||
rtc.datetime((2017, 8, 23, 0, 1, 12, 48, 0)) # set a specific date and
|
||||
# time, eg. 2017/8/23 1:12:48
|
||||
# the day-of-week value is ignored
|
||||
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
|
||||
rtc.datetime() # get date and time
|
||||
|
||||
WDT (Watchdog timer)
|
||||
@@ -820,7 +662,7 @@ See :ref:`machine.SDCard <machine.SDCard>`. ::
|
||||
|
||||
import machine, os, vfs
|
||||
|
||||
# On original ESP32, slot 2 uses pins sck=18, cs=5, miso=19, mosi=23
|
||||
# Slot 2 uses pins sck=18, cs=5, miso=19, mosi=23
|
||||
sd = machine.SDCard(slot=2)
|
||||
vfs.mount(sd, '/sd') # mount
|
||||
|
||||
@@ -837,14 +679,11 @@ The RMT is ESP32-specific and allows generation of accurate digital pulses with
|
||||
import esp32
|
||||
from machine import Pin
|
||||
|
||||
r = esp32.RMT(pin=Pin(18), resolution_hz=10000000)
|
||||
r # RMT(pin=18, source_freq=80000000, resolution_hz=10000000)
|
||||
# The channel resolution is based on resolution_hz, i.e. 100ns for 10000000
|
||||
r = esp32.RMT(0, pin=Pin(18), clock_div=8)
|
||||
r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8)
|
||||
# The channel resolution is 100ns (1/(source_freq/clock_div)).
|
||||
r.write_pulses((1, 20, 2, 40), 0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns
|
||||
|
||||
The ESP32-C2 family does not include any RMT peripheral, so this class is
|
||||
unavailable on those SoCs.
|
||||
|
||||
OneWire driver
|
||||
--------------
|
||||
|
||||
@@ -903,40 +742,28 @@ The APA106 driver extends NeoPixel, but internally uses a different colour order
|
||||
``NeoPixel`` object.
|
||||
|
||||
For low-level driving of a NeoPixel see `machine.bitstream`.
|
||||
This low-level driver uses an RMT channel by default.
|
||||
This low-level driver uses an RMT channel by default. To configure this see
|
||||
`RMT.bitstream_channel`.
|
||||
|
||||
APA102 (DotStar) uses a different driver as it has an additional clock pin.
|
||||
|
||||
Capacitive touch
|
||||
----------------
|
||||
|
||||
ESP32, ESP32-S2 and ESP32-S3 support capacitive touch via the ``TouchPad`` class
|
||||
in the ``machine`` module::
|
||||
Use the ``TouchPad`` class in the ``machine`` module::
|
||||
|
||||
from machine import TouchPad, Pin
|
||||
|
||||
t = TouchPad(Pin(14))
|
||||
t.read() # Returns a smaller number when touched
|
||||
|
||||
``TouchPad.read`` returns a value proportional to the capacitance between the
|
||||
pin and the board's Ground connection. On ESP32 the number becomes smaller when
|
||||
the pin (or connected touch pad) is touched, on ESP32-S2 and ESP32-S3 the number
|
||||
becomes larger when the pin is touched.
|
||||
``TouchPad.read`` returns a value relative to the capacitive variation. Small numbers (typically in
|
||||
the *tens*) are common when a pin is touched, larger numbers (above *one thousand*) when
|
||||
no touch is present. However the values are *relative* and can vary depending on the board
|
||||
and surrounding composition so some calibration may be required.
|
||||
|
||||
In all cases, a touch causes a significant change in the return value. Note the
|
||||
returned values are *relative* and can vary depending on the board and
|
||||
surrounding environment so some calibration (i.e. comparison to a baseline or
|
||||
rolling average) may be required.
|
||||
|
||||
========= ==============================================
|
||||
Chip Touch-enabled pins
|
||||
--------- ----------------------------------------------
|
||||
ESP32 0, 2, 4, 12, 13, 14, 15, 27, 32, 33
|
||||
ESP32-S2 1 to 14 inclusive
|
||||
ESP32-S3 1 to 14 inclusive
|
||||
========= ==============================================
|
||||
|
||||
Trying to assign to any other pins will result in a ``ValueError``.
|
||||
There are ten capacitive touch-enabled pins that can be used on the ESP32: 0, 2, 4, 12, 13
|
||||
14, 15, 27, 32, 33. Trying to assign to any other pins will result in a ``ValueError``.
|
||||
|
||||
Note that TouchPads can be used to wake an ESP32 from sleep::
|
||||
|
||||
|
||||
@@ -21,4 +21,3 @@ to `<https://www.python.org>`__.
|
||||
intro.rst
|
||||
pwm.rst
|
||||
peripheral_access.rst
|
||||
reset.rst
|
||||
|
||||
@@ -36,95 +36,104 @@ Getting the firmware
|
||||
|
||||
The first thing you need to do is download the most recent MicroPython firmware
|
||||
.bin file to load onto your ESP32 device. You can download it from the
|
||||
`MicroPython download page`_. Search for your particular board on this page.
|
||||
`MicroPython downloads page <https://micropython.org/download#esp32>`_.
|
||||
From here, you have 3 main choices:
|
||||
|
||||
.. note:: If you don't see your specific board on the download page, then it's
|
||||
very likely that one of the generic firmwares will work. These are
|
||||
listed at the top of the download page and have names matching the
|
||||
onboard Espressif chip (i.e. `ESP32 / WROOM`_, `ESP32-C3`_,
|
||||
`ESP32-S3`_, etc).
|
||||
* Stable firmware builds
|
||||
* Daily firmware builds
|
||||
* Daily firmware builds with SPIRAM support
|
||||
|
||||
However, you may need to double check with the vendor you purchased
|
||||
the board from.
|
||||
|
||||
From here, you have a choice to make:
|
||||
|
||||
* Download a stable firmware release.
|
||||
* Download a daily firmware "Preview" build.
|
||||
|
||||
If you are just starting with MicroPython, the best bet is to go for the stable
|
||||
Release firmware builds. If you are an advanced, experienced MicroPython ESP32
|
||||
user who would like to follow development closely and help with testing new
|
||||
features, then you may find the Preview builds useful.
|
||||
|
||||
.. _esp32_flashing:
|
||||
If you are just starting with MicroPython, the best bet is to go for the Stable
|
||||
firmware builds. If you are an advanced, experienced MicroPython ESP32 user
|
||||
who would like to follow development closely and help with testing new
|
||||
features, there are daily builds. If your board has SPIRAM support you can
|
||||
use either the standard firmware or the firmware with SPIRAM support, and in
|
||||
the latter case you will have access to more RAM for Python objects.
|
||||
|
||||
Deploying the firmware
|
||||
----------------------
|
||||
|
||||
Once you have the MicroPython firmware you need to load it onto your ESP32
|
||||
device. There are two main steps to do this: first you need to put your device
|
||||
in bootloader mode, and second you need to copy across the firmware. The exact
|
||||
procedure for these steps is highly dependent on the particular board.
|
||||
Once you have the MicroPython firmware you need to load it onto your ESP32 device.
|
||||
There are two main steps to do this: first you need to put your device in
|
||||
bootloader mode, and second you need to copy across the firmware. The exact
|
||||
procedure for these steps is highly dependent on the particular board and you will
|
||||
need to refer to its documentation for details.
|
||||
|
||||
Detailed steps can be found on the same `MicroPython download page`_ for your
|
||||
board. It's recommended that you follow the steps on the download page, as they
|
||||
are customised for your particular board.
|
||||
Fortunately, most boards have a USB connector, a USB-serial converter, and the DTR
|
||||
and RTS pins wired in a special way then deploying the firmware should be easy as
|
||||
all steps can be done automatically. Boards that have such features
|
||||
include the Adafruit Feather HUZZAH32, M5Stack, Wemos LOLIN32, and TinyPICO
|
||||
boards, along with the Espressif DevKitC, PICO-KIT, WROVER-KIT dev-kits.
|
||||
|
||||
For best results it is recommended to first erase the entire flash of your
|
||||
device before putting on new MicroPython firmware.
|
||||
|
||||
Currently we only support esptool.py to copy across the firmware. You can find
|
||||
this tool here: `<https://github.com/espressif/esptool/>`__, or install it
|
||||
using pip::
|
||||
|
||||
pip install esptool
|
||||
|
||||
Versions starting with 1.3 support both Python 2.7 and Python 3.4 (or newer).
|
||||
An older version (at least 1.2.1 is needed) works fine but will require Python
|
||||
2.7.
|
||||
|
||||
Using esptool.py you can erase the flash with the command::
|
||||
|
||||
esptool.py --port /dev/ttyUSB0 erase_flash
|
||||
|
||||
And then deploy the new firmware using::
|
||||
|
||||
esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 esp32-20180511-v1.9.4.bin
|
||||
|
||||
Notes:
|
||||
|
||||
* You might need to change the "port" setting to something else relevant for your
|
||||
PC
|
||||
* You may need to reduce the baudrate if you get errors when flashing
|
||||
(eg down to 115200 by adding ``--baud 115200`` into the command)
|
||||
* For some boards with a particular FlashROM configuration you may need to
|
||||
change the flash mode (eg by adding ``-fm dio`` into the command)
|
||||
* The filename of the firmware should match the file that you have
|
||||
|
||||
If the above commands run without error then MicroPython should be installed on
|
||||
your board! Skip ahead to :ref:`esp32_serial_prompt`.
|
||||
|
||||
.. _esp32_troubleshooting_install:
|
||||
|
||||
Troubleshooting installation problems
|
||||
-------------------------------------
|
||||
|
||||
If you experience problems during flashing or with running firmware immediately
|
||||
after flashing, here are some troubleshooting recommendations:
|
||||
|
||||
* Esptool will try to detect the serial port where your ESP32 is connected. If
|
||||
this doesn't work, or you have multiple serial ports, then you may need to
|
||||
manually specify the port by adding the ``--port`` option to the start of the
|
||||
``esptool.py`` command line. For example, ``esptool.py --port /dev/ttyUSB0
|
||||
<rest of line>`` for Linux or ``esptool --port COM4 <rest of line>`` for
|
||||
Windows.
|
||||
* If the board isn't responding to esptool at all, it may need to be manually
|
||||
reset into the bootloader download mode. Look for a button marked "BOOT" or
|
||||
"IO0" on your board and a second button marked "RESET" or "RST". If you have
|
||||
both buttons, try these steps:
|
||||
|
||||
1. Press "BOOT" (or "IO0") and hold it down.
|
||||
2. Press "RESET" (or "RST") and immediately release it.
|
||||
3. Release "BOOT" (or "IO0").
|
||||
4. Re-run the flashing steps from the download page.
|
||||
|
||||
If your board doesn't have these buttons, consult the board manufacturer's
|
||||
documentation about entering bootloader download mode.
|
||||
* If you get errors part-way through the flashing process then try reducing the
|
||||
speed of data transfer by removing the ``--baud 460800`` argument.
|
||||
* Hardware problems can cause flashing to fail. There are two common problems:
|
||||
bad power source quality, and defective hardware (especially very low cost
|
||||
unbranded development boards). Speaking of power source, not just raw amperage
|
||||
is important, but also low ripple and noise/EMI in general. The most reliable
|
||||
and convenient power source is a USB port.
|
||||
* If you still experience problems with flashing the firmware then please also
|
||||
refer to the `esptool Troubleshooting documentation`_.
|
||||
|
||||
.. _esp32_serial_prompt:
|
||||
your board!
|
||||
|
||||
Serial prompt
|
||||
-------------
|
||||
|
||||
Once you have the firmware on the device you can access the REPL (Python prompt)
|
||||
over either UART0, which might be connected to a USB-serial converter depending
|
||||
on your board, or the chip's built-in USB device. The baudrate is 115200.
|
||||
over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial
|
||||
converter, depending on your board. The baudrate is 115200.
|
||||
|
||||
From here you can now follow the ESP8266 tutorial, because these two Espressif chips
|
||||
are very similar when it comes to using MicroPython on them. The ESP8266 tutorial
|
||||
is found at :ref:`esp8266_tutorial` (but skip the Introduction section).
|
||||
|
||||
.. _esptool Troubleshooting documentation: https://docs.espressif.com/projects/esptool/en/latest/esp32/troubleshooting.html
|
||||
.. _MicroPython download page: https://micropython.org/download/?port=esp32
|
||||
.. _ESP32 / WROOM: https://micropython.org/download/ESP32_GENERIC
|
||||
.. _ESP32-C3: https://micropython.org/download/ESP32_GENERIC_C3
|
||||
.. _ESP32-S3: https://micropython.org/download/ESP32_GENERIC_S3
|
||||
Troubleshooting installation problems
|
||||
-------------------------------------
|
||||
|
||||
If you experience problems during flashing or with running firmware immediately
|
||||
after it, here are troubleshooting recommendations:
|
||||
|
||||
* Be aware of and try to exclude hardware problems. There are 2 common
|
||||
problems: bad power source quality, and worn-out/defective FlashROM.
|
||||
Speaking of power source, not just raw amperage is important, but also low
|
||||
ripple and noise/EMI in general. The most reliable and convenient power
|
||||
source is a USB port.
|
||||
|
||||
* The flashing instructions above use flashing speed of 460800 baud, which is
|
||||
good compromise between speed and stability. However, depending on your
|
||||
module/board, USB-UART converter, cables, host OS, etc., the above baud
|
||||
rate may be too high and lead to errors. Try a more common 115200 baud
|
||||
rate instead in such cases.
|
||||
|
||||
* To catch incorrect flash content (e.g. from a defective sector on a chip),
|
||||
add ``--verify`` switch to the commands above.
|
||||
|
||||
* If you still experience problems with flashing the firmware please
|
||||
refer to esptool.py project page, https://github.com/espressif/esptool
|
||||
for additional documentation and a bug tracker where you can report problems.
|
||||
|
||||
* If you are able to flash the firmware but the ``--verify`` option returns
|
||||
errors even after multiple retries the you may have a defective FlashROM chip.
|
||||
|
||||
@@ -11,20 +11,16 @@ compared with the length of a single period (low plus high time). Maximum
|
||||
duty cycle is when the pin is high all of the time, and minimum is when it is
|
||||
low all of the time.
|
||||
|
||||
* More comprehensive example with all **16 PWM channels and 8 timers**::
|
||||
* More comprehensive example with all 16 PWM channels and 8 timers::
|
||||
|
||||
from time import sleep
|
||||
from machine import Pin, PWM
|
||||
try:
|
||||
F = 10000 # Hz
|
||||
D = 65536 // 16 # 6.25%
|
||||
pins = (2, 4, 12, 13, 14, 15, 16, 18, 19, 22, 23, 25, 26, 27, 32, 33)
|
||||
f = 100 # Hz
|
||||
d = 1024 // 16 # 6.25%
|
||||
pins = (15, 2, 4, 16, 18, 19, 22, 23, 25, 26, 27, 14 , 12, 13, 32, 33)
|
||||
pwms = []
|
||||
for i, pin in enumerate(pins):
|
||||
f = F * (i // 2 + 1)
|
||||
d = min(65535, D * (i + 1))
|
||||
pwms.append(PWM(pin, freq=f, duty_u16=d))
|
||||
sleep(2 / f)
|
||||
pwms.append(PWM(Pin(pin), freq=f * (i // 2 + 1), duty= 1023 if i==15 else d * (i + 1)))
|
||||
print(pwms[i])
|
||||
finally:
|
||||
for pwm in pwms:
|
||||
@@ -35,100 +31,65 @@ low all of the time.
|
||||
|
||||
Output is::
|
||||
|
||||
PWM(Pin(2), freq=10000, duty_u16=4096)
|
||||
PWM(Pin(4), freq=10000, duty_u16=8192)
|
||||
PWM(Pin(12), freq=20000, duty_u16=12288)
|
||||
PWM(Pin(13), freq=20000, duty_u16=16384)
|
||||
PWM(Pin(14), freq=30030, duty_u16=20480)
|
||||
PWM(Pin(15), freq=30030, duty_u16=24576)
|
||||
PWM(Pin(16), freq=40000, duty_u16=28672)
|
||||
PWM(Pin(18), freq=40000, duty_u16=32768)
|
||||
PWM(Pin(19), freq=50000, duty_u16=36864)
|
||||
PWM(Pin(22), freq=50000, duty_u16=40960)
|
||||
PWM(Pin(23), freq=60060, duty_u16=45056)
|
||||
PWM(Pin(25), freq=60060, duty_u16=49152)
|
||||
PWM(Pin(26), freq=69930, duty_u16=53248)
|
||||
PWM(Pin(27), freq=69930, duty_u16=57344)
|
||||
PWM(Pin(32), freq=80000, duty_u16=61440)
|
||||
PWM(Pin(33), freq=80000, duty_u16=65535)
|
||||
PWM(Pin(15), freq=100, duty=64, resolution=10, mode=0, channel=0, timer=0)
|
||||
PWM(Pin(2), freq=100, duty=128, resolution=10, mode=0, channel=1, timer=0)
|
||||
PWM(Pin(4), freq=200, duty=192, resolution=10, mode=0, channel=2, timer=1)
|
||||
PWM(Pin(16), freq=200, duty=256, resolution=10, mode=0, channel=3, timer=1)
|
||||
PWM(Pin(18), freq=300, duty=320, resolution=10, mode=0, channel=4, timer=2)
|
||||
PWM(Pin(19), freq=300, duty=384, resolution=10, mode=0, channel=5, timer=2)
|
||||
PWM(Pin(22), freq=400, duty=448, resolution=10, mode=0, channel=6, timer=3)
|
||||
PWM(Pin(23), freq=400, duty=512, resolution=10, mode=0, channel=7, timer=3)
|
||||
PWM(Pin(25), freq=500, duty=576, resolution=10, mode=1, channel=0, timer=0)
|
||||
PWM(Pin(26), freq=500, duty=640, resolution=10, mode=1, channel=1, timer=0)
|
||||
PWM(Pin(27), freq=600, duty=704, resolution=10, mode=1, channel=2, timer=1)
|
||||
PWM(Pin(14), freq=600, duty=768, resolution=10, mode=1, channel=3, timer=1)
|
||||
PWM(Pin(12), freq=700, duty=832, resolution=10, mode=1, channel=4, timer=2)
|
||||
PWM(Pin(13), freq=700, duty=896, resolution=10, mode=1, channel=5, timer=2)
|
||||
PWM(Pin(32), freq=800, duty=960, resolution=10, mode=1, channel=6, timer=3)
|
||||
PWM(Pin(33), freq=800, duty=1023, resolution=10, mode=1, channel=7, timer=3)
|
||||
|
||||
|
||||
* Example of a **smooth frequency change**::
|
||||
* Example of a smooth frequency change::
|
||||
|
||||
from time import sleep
|
||||
from machine import Pin, PWM
|
||||
|
||||
F_MIN = 1000
|
||||
F_MAX = 10000
|
||||
F_MIN = 500
|
||||
F_MAX = 1000
|
||||
|
||||
f = F_MIN
|
||||
delta_f = F_MAX // 50
|
||||
delta_f = 1
|
||||
|
||||
pwm = PWM(Pin(27), f)
|
||||
p = PWM(Pin(5), f)
|
||||
print(p)
|
||||
|
||||
while True:
|
||||
pwm.freq(f)
|
||||
sleep(1 / f)
|
||||
sleep(0.1)
|
||||
print(pwm)
|
||||
p.freq(f)
|
||||
|
||||
sleep(10 / F_MIN)
|
||||
|
||||
f += delta_f
|
||||
if f > F_MAX or f < F_MIN:
|
||||
if f >= F_MAX or f <= F_MIN:
|
||||
delta_f = -delta_f
|
||||
print()
|
||||
if f > F_MAX:
|
||||
f = F_MAX
|
||||
elif f < F_MIN:
|
||||
f = F_MIN
|
||||
|
||||
See PWM wave on Pin(27) with an oscilloscope.
|
||||
See PWM wave at Pin(5) with an oscilloscope.
|
||||
|
||||
Output is::
|
||||
|
||||
PWM(Pin(27), freq=998, duty_u16=32768)
|
||||
PWM(Pin(27), freq=1202, duty_u16=32768)
|
||||
PWM(Pin(27), freq=1401, duty_u16=32768)
|
||||
PWM(Pin(27), freq=1598, duty_u16=32768)
|
||||
...
|
||||
PWM(Pin(27), freq=9398, duty_u16=32768)
|
||||
PWM(Pin(27), freq=9615, duty_u16=32768)
|
||||
PWM(Pin(27), freq=9804, duty_u16=32768)
|
||||
PWM(Pin(27), freq=10000, duty_u16=32768)
|
||||
|
||||
PWM(Pin(27), freq=10000, duty_u16=32768)
|
||||
PWM(Pin(27), freq=9804, duty_u16=32768)
|
||||
PWM(Pin(27), freq=9615, duty_u16=32768)
|
||||
PWM(Pin(27), freq=9398, duty_u16=32768)
|
||||
...
|
||||
PWM(Pin(27), freq=1598, duty_u16=32768)
|
||||
PWM(Pin(27), freq=1401, duty_u16=32768)
|
||||
PWM(Pin(27), freq=1202, duty_u16=32768)
|
||||
PWM(Pin(27), freq=998, duty_u16=32768)
|
||||
|
||||
|
||||
* Example of a **smooth duty change**::
|
||||
* Example of a smooth duty change::
|
||||
|
||||
from time import sleep
|
||||
from machine import Pin, PWM
|
||||
|
||||
DUTY_MAX = 65535
|
||||
DUTY_MAX = 2**16 - 1
|
||||
|
||||
duty_u16 = 0
|
||||
delta_d = 256
|
||||
delta_d = 16
|
||||
|
||||
pwm = PWM(Pin(27), freq=1000, duty_u16=duty_u16)
|
||||
p = PWM(Pin(5), 1000, duty_u16=duty_u16)
|
||||
print(p)
|
||||
|
||||
while True:
|
||||
pwm.duty_u16(duty_u16)
|
||||
sleep(2 / pwm.freq())
|
||||
print(pwm)
|
||||
p.duty_u16(duty_u16)
|
||||
|
||||
if duty_u16 >= DUTY_MAX:
|
||||
print()
|
||||
sleep(2)
|
||||
elif duty_u16 <= 0:
|
||||
print()
|
||||
sleep(2)
|
||||
sleep(1 / 1000)
|
||||
|
||||
duty_u16 += delta_d
|
||||
if duty_u16 >= DUTY_MAX:
|
||||
@@ -138,106 +99,9 @@ low all of the time.
|
||||
duty_u16 = 0
|
||||
delta_d = -delta_d
|
||||
|
||||
PWM wave on Pin(27) with an oscilloscope.
|
||||
See PWM wave at Pin(5) with an oscilloscope.
|
||||
|
||||
Output is::
|
||||
|
||||
PWM(Pin(27), freq=998, duty_u16=0)
|
||||
PWM(Pin(27), freq=998, duty_u16=256)
|
||||
PWM(Pin(27), freq=998, duty_u16=512)
|
||||
PWM(Pin(27), freq=998, duty_u16=768)
|
||||
PWM(Pin(27), freq=998, duty_u16=1024)
|
||||
...
|
||||
PWM(Pin(27), freq=998, duty_u16=64512)
|
||||
PWM(Pin(27), freq=998, duty_u16=64768)
|
||||
PWM(Pin(27), freq=998, duty_u16=65024)
|
||||
PWM(Pin(27), freq=998, duty_u16=65280)
|
||||
PWM(Pin(27), freq=998, duty_u16=65535)
|
||||
|
||||
PWM(Pin(27), freq=998, duty_u16=65279)
|
||||
PWM(Pin(27), freq=998, duty_u16=65023)
|
||||
PWM(Pin(27), freq=998, duty_u16=64767)
|
||||
PWM(Pin(27), freq=998, duty_u16=64511)
|
||||
...
|
||||
PWM(Pin(27), freq=998, duty_u16=1023)
|
||||
PWM(Pin(27), freq=998, duty_u16=767)
|
||||
PWM(Pin(27), freq=998, duty_u16=511)
|
||||
PWM(Pin(27), freq=998, duty_u16=255)
|
||||
PWM(Pin(27), freq=998, duty_u16=0)
|
||||
|
||||
|
||||
* Example of a **smooth duty change and PWM output inversion**::
|
||||
|
||||
from utime import sleep
|
||||
from machine import Pin, PWM
|
||||
|
||||
try:
|
||||
DUTY_MAX = 65535
|
||||
|
||||
duty_u16 = 0
|
||||
delta_d = 65536 // 32
|
||||
|
||||
pwm = PWM(Pin(27))
|
||||
pwmi = PWM(Pin(32), invert=1)
|
||||
|
||||
while True:
|
||||
pwm.duty_u16(duty_u16)
|
||||
pwmi.duty_u16(duty_u16)
|
||||
|
||||
duty_u16 += delta_d
|
||||
if duty_u16 >= DUTY_MAX:
|
||||
duty_u16 = DUTY_MAX
|
||||
delta_d = -delta_d
|
||||
elif duty_u16 <= 0:
|
||||
duty_u16 = 0
|
||||
delta_d = -delta_d
|
||||
|
||||
sleep(.01)
|
||||
print(pwm)
|
||||
print(pwmi)
|
||||
|
||||
finally:
|
||||
try:
|
||||
pwm.deinit()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
pwmi.deinit()
|
||||
except:
|
||||
pass
|
||||
|
||||
Output is::
|
||||
|
||||
PWM(Pin(27), freq=5000, duty_u16=0)
|
||||
PWM(Pin(32), freq=5000, duty_u16=32768, invert=1)
|
||||
PWM(Pin(27), freq=5000, duty_u16=2048)
|
||||
PWM(Pin(32), freq=5000, duty_u16=2048, invert=1)
|
||||
PWM(Pin(27), freq=5000, duty_u16=4096)
|
||||
PWM(Pin(32), freq=5000, duty_u16=4096, invert=1)
|
||||
PWM(Pin(27), freq=5000, duty_u16=6144)
|
||||
PWM(Pin(32), freq=5000, duty_u16=6144, invert=1)
|
||||
PWM(Pin(27), freq=5000, duty_u16=8192)
|
||||
PWM(Pin(32), freq=5000, duty_u16=8192, invert=1)
|
||||
...
|
||||
|
||||
|
||||
See PWM waves on Pin(27) and Pin(32) with an oscilloscope.
|
||||
|
||||
Note: New PWM parameters take effect in the next PWM cycle.
|
||||
|
||||
pwm = PWM(2, duty=512)
|
||||
print(pwm)
|
||||
>>> PWM(Pin(2), freq=5000, duty=1023) # the duty is not relevant
|
||||
pwm.init(freq=2, duty=64)
|
||||
print(pwm)
|
||||
>>> PWM(Pin(2), freq=2, duty=16) # the duty is not relevant
|
||||
time.sleep(1 / 2) # wait one PWM period
|
||||
print(pwm)
|
||||
>>> PWM(Pin(2), freq=2, duty=64) # the duty is actual
|
||||
|
||||
Note: machine.freq(20_000_000) reduces the highest PWM frequency to 10 MHz.
|
||||
|
||||
Note: the Pin.OUT mode does not need to be specified. The channel is initialized
|
||||
Note: the Pin.OUT mode does not need to be specified. The channel is initialized
|
||||
to PWM mode internally once for each Pin that is passed to the PWM constructor.
|
||||
|
||||
The following code is wrong::
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
Factory reset
|
||||
=============
|
||||
|
||||
If something unexpected happens and your ESP32-based board no longer boots
|
||||
MicroPython, then you may have to factory reset it. For more details, see
|
||||
:ref:`soft_bricking`.
|
||||
|
||||
Factory resetting the MicroPython esp32 port involves fully erasing the flash
|
||||
and resetting the flash memory, so you will need to re-flash the MicroPython
|
||||
firmware afterwards and copy any Python files to the filesystem again.
|
||||
|
||||
1. You will need the Espressif `esptool`_ installed on your system. This is the
|
||||
same tool that you may have used to initially install MicroPython on your
|
||||
board (see :ref:`installation instructions <esp32_flashing>`).
|
||||
2. Find the serial port name of your board, and then use esptool to erase the
|
||||
entire flash contents::
|
||||
|
||||
esptool.py -p PORTNAME erase_flash
|
||||
|
||||
3. Use esptool to flash the MicroPython file to your board again. If needed,
|
||||
this file and flashing instructions can be found on the `MicroPython
|
||||
downloads page`_.
|
||||
|
||||
.. _esptool: https://github.com/espressif/esptool
|
||||
.. _MicroPython downloads page: https://micropython.org/download/?port=esp32
|
||||
@@ -74,7 +74,40 @@ as possible after use.
|
||||
Boot process
|
||||
------------
|
||||
|
||||
See :doc:`/reference/reset_boot`.
|
||||
On boot, MicroPython EPS8266 port executes ``_boot.py`` script from internal
|
||||
frozen modules. It mounts filesystem in FlashROM, or if it's not available,
|
||||
performs first-time setup of the module and creates the filesystem. This
|
||||
part of the boot process is considered fixed, and not available for customization
|
||||
for end users (even if you build from source, please refrain from changes to
|
||||
it; customization of early boot process is available only to advanced users
|
||||
and developers, who can diagnose themselves any issues arising from
|
||||
modifying the standard process).
|
||||
|
||||
Once the filesystem is mounted, ``boot.py`` is executed from it. The standard
|
||||
version of this file is created during first-time module set up and has
|
||||
commands to start a WebREPL daemon (disabled by default, configurable
|
||||
with ``webrepl_setup`` module), etc. This
|
||||
file is customizable by end users (for example, you may want to set some
|
||||
parameters or add other services which should be run on
|
||||
a module start-up). But keep in mind that incorrect modifications to boot.py
|
||||
may still lead to boot loops or lock ups, requiring to reflash a module
|
||||
from scratch. (In particular, it's recommended that you use either
|
||||
``webrepl_setup`` module or manual editing to configure WebREPL, but not
|
||||
both).
|
||||
|
||||
As a final step of boot procedure, ``main.py`` is executed from filesystem,
|
||||
if exists. This file is a hook to start up a user application each time
|
||||
on boot (instead of going to REPL). For small test applications, you may
|
||||
name them directly as ``main.py``, and upload to module, but instead it's
|
||||
recommended to keep your application(s) in separate files, and have just
|
||||
the following in ``main.py``::
|
||||
|
||||
import my_app
|
||||
my_app.main()
|
||||
|
||||
This will allow to keep the structure of your application clear, as well as
|
||||
allow to install multiple applications on a board, and switch among them.
|
||||
|
||||
|
||||
Known Issues
|
||||
------------
|
||||
|
||||
@@ -49,11 +49,11 @@ The :mod:`esp` module::
|
||||
Networking
|
||||
----------
|
||||
|
||||
The :class:`network.WLAN` class in the :mod:`network` module::
|
||||
The :mod:`network` module::
|
||||
|
||||
import network
|
||||
|
||||
wlan = network.WLAN(network.WLAN.IF_STA) # create station interface
|
||||
wlan = network.WLAN(network.STA_IF) # create station interface
|
||||
wlan.active(True) # activate the interface
|
||||
wlan.scan() # scan for access points
|
||||
wlan.isconnected() # check if the station is connected to an AP
|
||||
@@ -61,7 +61,7 @@ The :class:`network.WLAN` class in the :mod:`network` module::
|
||||
wlan.config('mac') # get the interface's MAC address
|
||||
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
|
||||
|
||||
ap = network.WLAN(network.WLAN.IF_AP) # create access-point interface
|
||||
ap = network.WLAN(network.AP_IF) # create access-point interface
|
||||
ap.active(True) # activate the interface
|
||||
ap.config(ssid='ESP-AP') # set the SSID of the access point
|
||||
|
||||
@@ -69,7 +69,7 @@ A useful function for connecting to your local WiFi network is::
|
||||
|
||||
def do_connect():
|
||||
import network
|
||||
wlan = network.WLAN(network.WLAN.IF_STA)
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
if not wlan.isconnected():
|
||||
print('connecting to network...')
|
||||
@@ -108,9 +108,6 @@ with timer ID of -1::
|
||||
|
||||
The period is in milliseconds.
|
||||
|
||||
By default, timer callbacks are scheduled as soft interrupts on this port.
|
||||
Specify ``hard=True`` to run them in hard interrupt context instead.
|
||||
|
||||
Pins and GPIO
|
||||
-------------
|
||||
|
||||
@@ -166,10 +163,10 @@ sys.stdin.read() if it's needed to read characters from the UART(0)
|
||||
while it's also used for the REPL (or detach, read, then reattach).
|
||||
When detached the UART(0) can be used for other purposes.
|
||||
|
||||
If there are no objects in any of the dupterm slots when the REPL is started (on
|
||||
:doc:`hard or soft reset </reference/reset_boot>`) then UART(0) is automatically
|
||||
attached. Without this, the only way to recover a board without a REPL would be
|
||||
to completely erase and reflash (which would install the default boot.py which
|
||||
If there are no objects in any of the dupterm slots when the REPL is
|
||||
started (on hard or soft reset) then UART(0) is automatically attached.
|
||||
Without this, the only way to recover a board without a REPL would be to
|
||||
completely erase and reflash (which would install the default boot.py which
|
||||
attaches the REPL).
|
||||
|
||||
To detach the REPL from UART0, use::
|
||||
@@ -287,9 +284,7 @@ See :ref:`machine.RTC <machine.RTC>` ::
|
||||
from machine import RTC
|
||||
|
||||
rtc = RTC()
|
||||
rtc.datetime((2017, 8, 23, 0, 1, 12, 48, 0)) # set a specific date and
|
||||
# time, eg. 2017/8/23 1:12:48
|
||||
# the day-of-week value is ignored
|
||||
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
|
||||
rtc.datetime() # get date and time
|
||||
|
||||
# synchronize with ntp
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
Network basics
|
||||
==============
|
||||
|
||||
The :class:`network.WLAN` class in the :mod:`network` module is used to
|
||||
configure the WiFi connection. There are two WiFi interfaces, one for
|
||||
the station (when the ESP8266 connects to a router) and one for the
|
||||
access point (for other devices to connect to the ESP8266). Create
|
||||
The network module is used to configure the WiFi connection. There are two WiFi
|
||||
interfaces, one for the station (when the ESP8266 connects to a router) and one
|
||||
for the access point (for other devices to connect to the ESP8266). Create
|
||||
instances of these objects using::
|
||||
|
||||
>>> import network
|
||||
>>> sta_if = network.WLAN(network.WLAN.IF_STA)
|
||||
>>> ap_if = network.WLAN(network.WLAN.IF_AP)
|
||||
>>> sta_if = network.WLAN(network.STA_IF)
|
||||
>>> ap_if = network.WLAN(network.AP_IF)
|
||||
|
||||
You can check if the interfaces are active by::
|
||||
|
||||
@@ -58,7 +57,7 @@ connect to your WiFi network::
|
||||
|
||||
def do_connect():
|
||||
import network
|
||||
sta_if = network.WLAN(network.WLAN.IF_STA)
|
||||
sta_if = network.WLAN(network.STA_IF)
|
||||
if not sta_if.isconnected():
|
||||
print('connecting to network...')
|
||||
sta_if.active(True)
|
||||
|
||||
@@ -38,7 +38,7 @@ browser. The latest versions of Firefox and Chrome are supported.
|
||||
|
||||
For your convenience, WebREPL client is hosted at
|
||||
`<http://micropython.org/webrepl>`__. Alternatively, you can install it
|
||||
locally from the GitHub repository
|
||||
locally from the the GitHub repository
|
||||
`<https://github.com/micropython/webrepl>`__.
|
||||
|
||||
Before connecting to WebREPL, you should set a password and enable it via
|
||||
|
||||
@@ -19,10 +19,6 @@ Classes
|
||||
array are given by *iterable*. If it is not provided, an empty
|
||||
array is created.
|
||||
|
||||
In addition to the methods below, array objects also implement the buffer
|
||||
protocol. This means the contents of the entire array can be accessed as raw
|
||||
bytes via a `memoryview` or other interfaces which use this protocol.
|
||||
|
||||
.. method:: append(val)
|
||||
|
||||
Append new element *val* to the end of array, growing it.
|
||||
|
||||
@@ -36,9 +36,3 @@ Functions
|
||||
Encode binary data in base64 format, as in `RFC 3548
|
||||
<https://tools.ietf.org/html/rfc3548.html>`_. Returns the encoded data
|
||||
followed by a newline character if newline is true, as a bytes object.
|
||||
|
||||
.. function:: crc32(data, [value])
|
||||
|
||||
Compute CRC-32, the 32-bit checksum of *data*, starting with an initial CRC
|
||||
of *value*. The default initial CRC is zero. The algorithm is consistent
|
||||
with the ZIP file checksum.
|
||||
|
||||
@@ -665,7 +665,7 @@ L2CAP connection-oriented-channels
|
||||
|
||||
Connect to a listening peer on the specified *psm* with local MTU set to *mtu*.
|
||||
|
||||
On successful connection, the ``_IRQ_L2CAP_CONNECT`` event will be
|
||||
On successful connection, the the ``_IRQ_L2CAP_CONNECT`` event will be
|
||||
raised, allowing the client to obtain the CID and the local and remote (peer) MTU.
|
||||
|
||||
An unsuccessful connection will raise the ``_IRQ_L2CAP_DISCONNECT`` event
|
||||
@@ -764,5 +764,4 @@ Constructor
|
||||
The **value** can be either:
|
||||
|
||||
- A 16-bit integer. e.g. ``0x2908``.
|
||||
- An object with the buffer protocol and that is 2, 4 or 16 bytes long, e.g. ``b'\x08\x29'``.
|
||||
- A 128-bit UUID string. e.g. ``'6E400001-B5A3-F393-E0A9-E50E24DCCA9E'``.
|
||||
|
||||
@@ -151,10 +151,10 @@ Constants
|
||||
|
||||
.. data:: INCL
|
||||
|
||||
A flag for :meth:`btree.keys`, :meth:`btree.values`, :meth:`btree.items` methods to specify that
|
||||
A flag for `keys()`, `values()`, `items()` methods to specify that
|
||||
scanning should be inclusive of the end key.
|
||||
|
||||
.. data:: DESC
|
||||
|
||||
A flag for :meth:`btree.keys`, :meth:`btree.values`, :meth:`btree.items` methods to specify that
|
||||
A flag for `keys()`, `values()`, `items()` methods to specify that
|
||||
scanning should be in descending direction of keys.
|
||||
|
||||
@@ -19,8 +19,6 @@ Functions and types
|
||||
|
||||
.. class:: bytearray()
|
||||
|
||||
|see_cpython| `python:bytearray`.
|
||||
|
||||
.. class:: bytes()
|
||||
|
||||
|see_cpython| `python:bytes`.
|
||||
@@ -106,8 +104,6 @@ Functions and types
|
||||
|
||||
.. class:: memoryview()
|
||||
|
||||
|see_cpython| `python:memoryview`.
|
||||
|
||||
.. function:: min()
|
||||
|
||||
.. function:: next()
|
||||
@@ -174,10 +170,6 @@ Exceptions
|
||||
|
||||
.. exception:: KeyboardInterrupt
|
||||
|
||||
|see_cpython| `python:KeyboardInterrupt`.
|
||||
|
||||
See also in the context of :ref:`soft_bricking`.
|
||||
|
||||
.. exception:: KeyError
|
||||
|
||||
.. exception:: MemoryError
|
||||
@@ -198,12 +190,6 @@ Exceptions
|
||||
|
||||
|see_cpython| `python:SystemExit`.
|
||||
|
||||
On non-embedded ports (i.e. Windows and Unix), an unhandled ``SystemExit``
|
||||
exits the MicroPython process in a similar way to CPython.
|
||||
|
||||
On embedded ports, an unhandled ``SystemExit`` currently causes a
|
||||
:ref:`soft_reset` of MicroPython.
|
||||
|
||||
.. exception:: TypeError
|
||||
|
||||
|see_cpython| `python:TypeError`.
|
||||
|
||||
@@ -101,19 +101,3 @@ Classes
|
||||
a 2
|
||||
w 5
|
||||
b 3
|
||||
|
||||
.. method:: OrderedDict.popitem()
|
||||
|
||||
Remove and return a (key, value) pair from the dictionary.
|
||||
Pairs are returned in LIFO order.
|
||||
|
||||
.. admonition:: Difference to CPython
|
||||
:class: attention
|
||||
|
||||
``OrderedDict.popitem()`` does not support the ``last=False`` argument and
|
||||
will always remove and return the last item if present.
|
||||
|
||||
A workaround for this is to use ``pop(<first_key>)`` to remove the first item::
|
||||
|
||||
first_key = next(iter(d))
|
||||
d.pop(first_key)
|
||||
|
||||
@@ -18,40 +18,23 @@ Functions
|
||||
Configure whether or not a touch will wake the device from sleep.
|
||||
*wake* should be a boolean value.
|
||||
|
||||
.. note:: This is only available for boards that have touch sensor support.
|
||||
|
||||
.. function:: wake_on_ulp(wake)
|
||||
|
||||
Configure whether or not the Ultra-Low-Power co-processor can wake the
|
||||
device from sleep. *wake* should be a boolean value.
|
||||
|
||||
.. note:: This is only available for boards that have ULP coprocessor support.
|
||||
|
||||
.. function:: wake_on_ext0(pin, level)
|
||||
|
||||
Configure how EXT0 wakes the device from sleep. *pin* can be ``None``
|
||||
or a valid Pin object. *level* should be ``esp32.WAKEUP_ALL_LOW`` or
|
||||
``esp32.WAKEUP_ANY_HIGH``.
|
||||
|
||||
.. note:: This is only available for boards that have ext0 support.
|
||||
|
||||
.. function:: wake_on_ext1(pins, level)
|
||||
|
||||
Configure how EXT1 wakes the device from sleep. *pins* can be ``None``
|
||||
or a tuple/list of valid Pin objects. *level* should be ``esp32.WAKEUP_ALL_LOW``
|
||||
or ``esp32.WAKEUP_ANY_HIGH``.
|
||||
|
||||
.. note:: This is only available for boards that have ext1 support.
|
||||
|
||||
.. function:: wake_on_gpio(pins, level)
|
||||
|
||||
Configure how GPIO wakes the device from sleep. *pins* can be ``None``
|
||||
or a tuple/list of valid Pin objects. *level* should be ``esp32.WAKEUP_ALL_LOW``
|
||||
or ``esp32.WAKEUP_ANY_HIGH``.
|
||||
|
||||
.. note:: Some boards don't support waking on GPIO from deep sleep,
|
||||
on those boards, the pins set here can only be used to wake from light sleep.
|
||||
|
||||
.. function:: gpio_deep_sleep_hold(enable)
|
||||
|
||||
Configure whether non-RTC GPIO pin configuration is retained during
|
||||
@@ -97,29 +80,6 @@ Functions
|
||||
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()`.
|
||||
|
||||
.. function:: idf_task_info()
|
||||
|
||||
Returns information about running ESP-IDF/FreeRTOS tasks, which include
|
||||
MicroPython threads. This data is useful to gain insight into how much time
|
||||
tasks spend running or if they are blocked for significant parts of time,
|
||||
and to determine if allocated stacks are fully utilized or might be reduced.
|
||||
|
||||
``CONFIG_FREERTOS_USE_TRACE_FACILITY=y`` must be set in the board
|
||||
configuration to make this method available. Additionally configuring
|
||||
``CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y`` and
|
||||
``CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y`` is recommended to be able to
|
||||
retrieve the total and per-task runtime and the core ID respectively.
|
||||
|
||||
The return value is a 2-tuple where the first value is the total runtime,
|
||||
and the second a list of tasks. Each task is a 7-tuple containing: the task
|
||||
ID, name, current state, priority, runtime, stack high water mark, and the
|
||||
ID of the core it is running on. Runtime and core ID will be None when the
|
||||
respective FreeRTOS configuration option is not enabled.
|
||||
|
||||
.. note:: For an easier to use output based on this function you can use the
|
||||
`utop library <https://github.com/micropython/micropython-lib/tree/master/micropython/utop>`_,
|
||||
which implements a live overview similar to the Unix ``top`` command.
|
||||
|
||||
|
||||
Flash partitions
|
||||
----------------
|
||||
@@ -204,151 +164,6 @@ Constants
|
||||
|
||||
Used in `idf_heap_info`.
|
||||
|
||||
|
||||
.. _esp32.PCNT:
|
||||
|
||||
PCNT
|
||||
----
|
||||
|
||||
This class provides access to the ESP32 hardware support for pulse counting.
|
||||
There are 8 pulse counter units, with id 0..7.
|
||||
|
||||
See the :ref:`machine.Counter <machine.Counter>` and
|
||||
:ref:`machine.Encoder <machine.Encoder>` classes for simpler and portable
|
||||
abstractions of common pulse counting applications. These classes are
|
||||
implemented as thin Python shims around :class:`PCNT`.
|
||||
|
||||
.. class:: PCNT(id, *, ...)
|
||||
|
||||
Returns the singleton PCNT instance for the given unit ``id``.
|
||||
|
||||
Keyword arguments are passed to the ``init()`` method as described
|
||||
below.
|
||||
|
||||
.. method:: PCNT.init(*, ...)
|
||||
|
||||
(Re-)initialise a pulse counter unit. Supported keyword arguments are:
|
||||
|
||||
- ``channel``: see description below
|
||||
- ``pin``: the input Pin to monitor for pulses
|
||||
- ``rising``: an action to take on a rising edge - one of
|
||||
``PCNT.INCREMENT``, ``PCNT.DECREMENT`` or ``PCNT.IGNORE`` (the default)
|
||||
- ``falling``: an action to take on a falling edge (takes the save values
|
||||
as the ``rising`` argument).
|
||||
- ``mode_pin``: ESP32 pulse counters support monitoring a second pin and
|
||||
altering the behaviour of the counter based on its level - set this
|
||||
keyword to any input Pin
|
||||
- ``mode_low``: set to either ``PCNT.HOLD`` or ``PCNT.REVERSE`` to
|
||||
either suspend counting or reverse the direction of the counter (i.e.,
|
||||
``PCNT.INCREMENT`` behaves as ``PCNT.DECREMENT`` and vice versa)
|
||||
when ``mode_pin`` is low
|
||||
- ``mode_high``: as ``mode_low`` but for the behaviour when ``mode_pin``
|
||||
is high
|
||||
- ``filter``: set to a value 1..1023, in ticks of the 80MHz clock, to
|
||||
enable the pulse width filter
|
||||
- ``min``: set to the minimum level of the counter value when
|
||||
decrementing (-32768..-1) or 0 to disable
|
||||
- ``max``: set to the maximum level of the counter value when
|
||||
incrementing (1..32767) or 0 to disable
|
||||
- ``threshold0``: sets the counter value for the
|
||||
``PCNT.IRQ_THRESHOLD0`` event (see ``irq`` method)
|
||||
- ``threshold1``: sets the counter value for the
|
||||
``PCNT.IRQ_THRESHOLD1`` event (see ``irq`` method)
|
||||
- ``value``: can be set to ``0`` to reset the counter value
|
||||
|
||||
The hardware initialisation is done in stages and so some of the keyword
|
||||
arguments can be used in groups or in isolation to partially reconfigure a
|
||||
unit:
|
||||
|
||||
- the ``pin`` keyword (optionally combined with ``mode_pin``) can be used
|
||||
to change just the bound pin(s)
|
||||
- ``rising``, ``falling``, ``mode_low`` and ``mode_high`` can be used
|
||||
(singly or together) to change the counting logic - omitted keywords
|
||||
use their default (``PCNT.IGNORE`` or ``PCNT.NORMAL``)
|
||||
- ``filter`` can be used to change only the pulse width filter (with 0
|
||||
disabling it)
|
||||
- each of ``min``, ``max``, ``threshold0`` and ``threshold1`` can
|
||||
be used to change these limit/event values individually; however,
|
||||
setting any will reset the counter to zero (i.e., they imply
|
||||
``value=0``)
|
||||
|
||||
Each pulse counter unit supports two channels, 0 and 1, each able to
|
||||
monitor different pins with different counting logic but updating the same
|
||||
counter value. Use ``channel=1`` with the ``pin``, ``rising``, ``falling``,
|
||||
``mode_pin``, ``mode_low`` and ``mode_high`` keywords to configure the
|
||||
second channel.
|
||||
|
||||
The second channel can be used to configure 4X quadrature decoding with a
|
||||
single counter unit::
|
||||
|
||||
pin_a = Pin(2, Pin.INPUT, pull=Pin.PULL_UP)
|
||||
pin_b = Pin(3, Pin.INPUT, pull=Pin.PULL_UP)
|
||||
rotary = PCNT(0, min=-32000, max=32000)
|
||||
rotary.init(channel=0, pin=pin_a, falling=PCNT.INCREMENT, rising=PCNT.DECREMENT, mode_pin=pin_b, mode_low=PCNT.REVERSE)
|
||||
rotary.init(channel=1, pin=pin_b, falling=PCNT.DECREMENT, rising=PCNT.INCREMENT, mode_pin=pin_a, mode_low=PCNT.REVERSE)
|
||||
rotary.start()
|
||||
|
||||
.. method:: PCNT.value([value])
|
||||
|
||||
Call this method with no arguments to return the current counter value.
|
||||
|
||||
If the optional *value* argument is set to ``0`` then the counter is
|
||||
reset (but the previous value is returned). Read and reset is not atomic and
|
||||
so it is possible for a pulse to be missed. Any value other than ``0`` will
|
||||
raise an error.
|
||||
|
||||
.. method:: PCNT.irq(handler=None, trigger=PCNT.IRQ_ZERO)
|
||||
|
||||
ESP32 pulse counters support interrupts on these counter events:
|
||||
|
||||
- ``PCNT.IRQ_ZERO``: the counter has reset to zero
|
||||
- ``PCNT.IRQ_MIN``: the counter has hit the ``min`` value
|
||||
- ``PCNT.IRQ_MAX``: the counter has hit the ``max`` value
|
||||
- ``PCNT.IRQ_THRESHOLD0``: the counter has hit the ``threshold0`` value
|
||||
- ``PCNT.IRQ_THRESHOLD1``: the counter has hit the ``threshold1`` value
|
||||
|
||||
``trigger`` should be a bit-mask of the desired events OR'ed together. The
|
||||
``handler`` function should take a single argument which is the
|
||||
:class:`PCNT` instance that raised the event.
|
||||
|
||||
This method returns a callback object. The callback object can be used to
|
||||
access the bit-mask of events that are outstanding on the PCNT unit.::
|
||||
|
||||
def pcnt_irq(pcnt):
|
||||
flags = pcnt.irq().flags()
|
||||
if flags & PCNT.IRQ_ZERO:
|
||||
# reset
|
||||
if flags & PCNT.IRQ_MAX:
|
||||
# overflow...
|
||||
... etc
|
||||
|
||||
pcnt.irq(handler=pcnt_irq, trigger=PCNT.IRQ_ZERO | PCNT.IRQ_MAX | ...)
|
||||
|
||||
**Note:** Accessing ``irq.flags()`` will clear the flags, so only call it
|
||||
once per invocation of the handler.
|
||||
|
||||
The handler is called with the MicroPython scheduler and so will run at a
|
||||
point after the interrupt. If another interrupt occurs before the handler
|
||||
has been called then the events will be coalesced together into a single
|
||||
call and the bit mask will indicate all events that have occurred.
|
||||
|
||||
To avoid race conditions between a handler being called and retrieving the
|
||||
current counter value, the ``value()`` method will force execution of any
|
||||
pending events before returning the current counter value (and potentially
|
||||
resetting the value).
|
||||
|
||||
Only one handler can be in place per-unit. Set ``handler`` to ``None`` to
|
||||
disable the event interrupt.
|
||||
|
||||
.. Note::
|
||||
ESP32 pulse counters reset to *zero* when reaching the minimum or maximum
|
||||
value. Thus the ``IRQ_ZERO`` event will also trigger when either of these
|
||||
events occurs.
|
||||
|
||||
See the :ref:`machine.Counter <machine.Counter>` and
|
||||
:ref:`machine.Encoder <machine.Encoder>` classes for simpler abstractions of
|
||||
common pulse counting applications.
|
||||
|
||||
.. _esp32.RMT:
|
||||
|
||||
RMT
|
||||
@@ -362,24 +177,29 @@ used to transmit or receive many other types of digital signals::
|
||||
import esp32
|
||||
from machine import Pin
|
||||
|
||||
r = esp32.RMT(pin=Pin(18), resolution_hz=10000000)
|
||||
r # RMT(pin=18, source_freq=80000000, resolution_hz=10000000, idle_level=0)
|
||||
r = esp32.RMT(0, pin=Pin(18), clock_div=8)
|
||||
r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8, idle_level=0)
|
||||
|
||||
# To apply a carrier frequency to the high output
|
||||
r = esp32.RMT(pin=Pin(18), resolution_hz=10000000, tx_carrier=(38000, 50, 1))
|
||||
r = esp32.RMT(0, pin=Pin(18), clock_div=8, tx_carrier=(38000, 50, 1))
|
||||
|
||||
# The channel resolution is 100ns (1/resolution_hz)
|
||||
# The channel resolution is 100ns (1/(source_freq/clock_div)).
|
||||
r.write_pulses((1, 20, 2, 40), 0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns
|
||||
|
||||
The input to the RMT module is an 80MHz clock (in the future it may be able to
|
||||
configure the input clock but, for now, it's fixed). ``resolution_hz`` determines
|
||||
the resolution of the RMT channel. The numbers specified in ``write_pulses`` are
|
||||
multiplied by the resolution to
|
||||
configure the input clock but, for now, it's fixed). ``clock_div`` *divides*
|
||||
the clock input which determines the resolution of the RMT channel. The
|
||||
numbers specified in ``write_pulses`` are multiplied by the resolution to
|
||||
define the pulses.
|
||||
|
||||
So, in the example above, the resolution is resolution is (1/10Mhz) = 100ns.
|
||||
Since the ``start`` level is 0 and toggles with each number, the bitstream is
|
||||
``0101`` with durations of [100ns, 2000ns, 100ns, 4000ns].
|
||||
``clock_div`` is an 8-bit divider (0-255) and each pulse can be defined by
|
||||
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
|
||||
resolution is (1/(80Mhz/8)) 100ns. Since the ``start`` level is 0 and toggles
|
||||
with each number, the bitstream is ``0101`` with durations of [100ns, 2000ns,
|
||||
100ns, 4000ns].
|
||||
|
||||
For more details see Espressif's `ESP-IDF RMT documentation.
|
||||
<https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/rmt.html>`_.
|
||||
@@ -390,24 +210,13 @@ For more details see Espressif's `ESP-IDF RMT documentation.
|
||||
*beta feature* and the interface may change in the future.
|
||||
|
||||
|
||||
.. class:: RMT(channel, *, pin=None, resolution_hz=10000000, clock_div=None, idle_level=False, num_symbols=48|64, tx_carrier=None)
|
||||
.. class:: RMT(channel, *, pin=None, clock_div=8, idle_level=False, tx_carrier=None)
|
||||
|
||||
This class provides access to one of the eight RMT channels. *channel* is
|
||||
optional and a dummy parameter for backward compatibility. *pin* is required
|
||||
and configures which Pin is bound to the RMT channel.
|
||||
*resolution_hz* defines the resolution/unit of the samples.
|
||||
For example, 1,000,000 means the unit is microsecond. The pulse widths can
|
||||
assume values up to *RMT.PULSE_MAX*, so the resolution should be selected
|
||||
accordingly to the signal to be transmitted.
|
||||
*clock_div* (deprecated) is equivalent to *resolution_hz*, but expressed as
|
||||
a clock divider that divides the source clock (80MHz) to the RMT
|
||||
channel allowing the resolution to be specified. Either *clock_div* and
|
||||
*resolution_hz* may be supplied, but not both.
|
||||
*num_symbols* specifies the
|
||||
RMT buffer allocated for this channel (minimum 48 or 64, depending on chip), from a small pool of
|
||||
symbols (192 to 512, depending on chip) that are shared by all channels. This buffer does not limit the
|
||||
size of the pulse train that you can send, but bigger buffers reduce the
|
||||
CPU load and the potential of glitches/imprecise pulse lengths. *idle_level* specifies
|
||||
required and identifies which RMT channel (0-7) will be configured. *pin*,
|
||||
also required, configures which Pin is bound to the RMT channel. *clock_div*
|
||||
is an 8-bit clock divider that divides the source clock (80MHz) to the RMT
|
||||
channel allowing the resolution to be specified. *idle_level* specifies
|
||||
what level the output will be when no transmission is in progress and can
|
||||
be any value that converts to a boolean, with ``True`` representing high
|
||||
voltage and ``False`` representing low.
|
||||
@@ -425,52 +234,21 @@ For more details see Espressif's `ESP-IDF RMT documentation.
|
||||
.. method:: RMT.clock_div()
|
||||
|
||||
Return the clock divider. Note that the channel resolution is
|
||||
``1 / (source_freq / clock_div)``. (Method deprecated. The value may
|
||||
not be faithful if resolution was supplied as *resolution_hz*.)
|
||||
``1 / (source_freq / clock_div)``.
|
||||
|
||||
.. method:: RMT.wait_done(*, timeout=0)
|
||||
|
||||
Returns ``True`` if the channel is idle or ``False`` if a sequence of
|
||||
pulses started with `RMT.write_pulses` is being transmitted. If the
|
||||
*timeout* keyword argument is given then block for up to this many
|
||||
milliseconds for transmission to complete. Timeout of -1 blocks until
|
||||
transmission is complete (and blocks forever if loop is enabled).
|
||||
milliseconds for transmission to complete.
|
||||
|
||||
.. method:: RMT.loop(enable_loop)
|
||||
|
||||
Configure looping on the channel. *enable_loop* is bool, set to ``True`` to
|
||||
enable looping on the *next* call to `RMT.write_pulses`. If called with
|
||||
``False`` while a looping sequence is currently being transmitted then the
|
||||
transmission will stop. (Method deprecated by `RMT.loop_count`.)
|
||||
|
||||
.. method:: RMT.loop_count(n)
|
||||
|
||||
Configure looping on the channel. *n* is int. Affects the *next* call to
|
||||
`RMT.write_pulses`. Set to ``0`` to disable looping, ``-1`` to enable
|
||||
infinite looping, or a positive number to loop for a given number of times.
|
||||
If *n* is changed, the current transmission is stopped.
|
||||
|
||||
Note: looping for a finite number of times is not supported by all flavors
|
||||
of ESP32.
|
||||
|
||||
.. method:: RMT.active([boolean])
|
||||
|
||||
If called without parameters, returns *True* if there is an ongoing transmission.
|
||||
|
||||
If called with parameter *False*, stops the ongoing transmission.
|
||||
This is useful to stop an infinite transmission loop.
|
||||
The current loop is finished and transmission stops.
|
||||
The object is not invalidated, and the RMT channel is again enabled when a new
|
||||
transmission is started.
|
||||
|
||||
Calling with parameter *True* does not restart transmission. A new transmission
|
||||
should always be initiated by *write_pulses()*.
|
||||
|
||||
.. method:: RMT.deinit()
|
||||
|
||||
Release all RMT resources and invalidate the object. All subsequent method
|
||||
calls will raise OSError. Useful to free RMT resources without having to wait
|
||||
for the object to be garbage-collected.
|
||||
current loop iteration will be completed and then transmission will stop.
|
||||
|
||||
.. method:: RMT.write_pulses(duration, data=True)
|
||||
|
||||
@@ -500,28 +278,17 @@ For more details see Espressif's `ESP-IDF RMT documentation.
|
||||
new sequence of pulses. Looping sequences longer than 126 pulses is not
|
||||
supported by the hardware.
|
||||
|
||||
.. staticmethod:: RMT.bitstream_rmt([value])
|
||||
|
||||
Configure RMT usage in the `machine.bitstream` implementation.
|
||||
|
||||
If *value* is ``True``, bitstream tries to use RMT if possible. If *value*
|
||||
is ``False``, bitstream sticks to the bit-banging implementation.
|
||||
|
||||
If no parameter is supplied, it returns the current state. The default state
|
||||
is ``True``.
|
||||
|
||||
.. staticmethod:: RMT.bitstream_channel([value])
|
||||
|
||||
*This function is deprecated and will be replaced by `RMT.bitstream_rmt()`.*
|
||||
Select which RMT channel is used by the `machine.bitstream` implementation.
|
||||
*value* can be ``None`` or a valid RMT channel number. The default RMT
|
||||
channel is the highest numbered one.
|
||||
|
||||
Passing in no argument will return ``1`` if RMT was enabled for the `machine.bitstream`
|
||||
feature, and ``None`` otherwise.
|
||||
Passing in ``None`` disables the use of RMT and instead selects a bit-banging
|
||||
implementation for `machine.bitstream`.
|
||||
|
||||
Passing any non-negative integer argument is equivalent to calling ``RMT.bitstream_rmt(True)``.
|
||||
|
||||
.. note:: In previous versions of MicroPython it was necessary to use this function to assign
|
||||
a specific RMT channel number for the bitstream, but the channel number is now assigned
|
||||
dynamically.
|
||||
Passing in no argument will not change the channel. This function returns
|
||||
the current channel number.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
@@ -56,7 +56,7 @@ A simple example would be:
|
||||
import espnow
|
||||
|
||||
# A WLAN interface must be active to send()/recv()
|
||||
sta = network.WLAN(network.WLAN.IF_STA) # Or network.WLAN.IF_AP
|
||||
sta = network.WLAN(network.STA_IF) # Or network.AP_IF
|
||||
sta.active(True)
|
||||
sta.disconnect() # For ESP8266
|
||||
|
||||
@@ -76,7 +76,7 @@ A simple example would be:
|
||||
import espnow
|
||||
|
||||
# A WLAN interface must be active to send()/recv()
|
||||
sta = network.WLAN(network.WLAN.IF_STA)
|
||||
sta = network.WLAN(network.STA_IF)
|
||||
sta.active(True)
|
||||
sta.disconnect() # Because ESP8266 auto-connects to last Access Point
|
||||
|
||||
@@ -164,15 +164,11 @@ Configuration
|
||||
wait forever. The timeout can also be provided as arg to
|
||||
`recv()`/`irecv()`/`recvinto()`.
|
||||
|
||||
*rate*: (ESP32 only) Set the transmission data rate for ESPNow packets.
|
||||
The default setting is `espnow.RATE_1M`. It's recommended to use one of
|
||||
the other ``espnow.RATE_nnn`` constants to set this, but it's also
|
||||
possible to pass an integer corresponding to the `enum wifi_phy_rate_t
|
||||
<https://docs.espressif.com/projects/esp-idf/en/v5.5.1/esp32/
|
||||
api-reference/network/esp_wifi.html#_CPPv415wifi_phy_rate_t>`_. This
|
||||
parameter is actually *write-only* due to ESP-IDF not providing any
|
||||
means for querying the radio interface's rate parameter.
|
||||
See also `espnow-long-range`. This API currently doesn't work on ESP32-C6.
|
||||
*rate*: (ESP32 only, IDF>=4.3.0 only) Set the transmission speed for
|
||||
ESPNow packets. Must be set to a number from the allowed numeric values
|
||||
in `enum wifi_phy_rate_t
|
||||
<https://docs.espressif.com/projects/esp-idf/en/v4.4.1/esp32/
|
||||
api-reference/network/esp_wifi.html#_CPPv415wifi_phy_rate_t>`_.
|
||||
|
||||
.. data:: Returns:
|
||||
|
||||
@@ -186,14 +182,14 @@ Configuration
|
||||
Sending and Receiving Data
|
||||
--------------------------
|
||||
|
||||
A wifi interface (``network.WLAN.IF_STA`` or ``network.WLAN.IF_AP``) must be
|
||||
A wifi interface (``network.STA_IF`` or ``network.AP_IF``) must be
|
||||
`active()<network.WLAN.active>` before messages can be sent or received,
|
||||
but it is not necessary to connect or configure the WLAN interface.
|
||||
For example::
|
||||
|
||||
import network
|
||||
|
||||
sta = network.WLAN(network.WLAN.IF_STA)
|
||||
sta = network.WLAN(network.STA_IF)
|
||||
sta.active(True)
|
||||
sta.disconnect() # For ESP8266
|
||||
|
||||
@@ -445,14 +441,12 @@ must first register the sender and use the same encryption keys as the sender
|
||||
|
||||
- *channel*: The wifi channel (2.4GHz) to communicate with this peer.
|
||||
Must be an integer from 0 to 14. If channel is set to 0 the current
|
||||
channel of the wifi device will be used, if channel is set to another
|
||||
value then this must match the channel currently configured on the
|
||||
interface (see :func:`WLAN.config`). (default=0)
|
||||
channel of the wifi device will be used. (default=0)
|
||||
|
||||
- *ifidx*: (ESP32 only) Index of the wifi interface which will be
|
||||
used to send data to this peer. Must be an integer set to
|
||||
``network.WLAN.IF_STA`` (=0) or ``network.WLAN.IF_AP`` (=1).
|
||||
(default=0/``network.WLAN.IF_STA``). See `ESPNow and Wifi Operation`_
|
||||
``network.STA_IF`` (=0) or ``network.AP_IF`` (=1).
|
||||
(default=0/``network.STA_IF``). See `ESPNow and Wifi Operation`_
|
||||
below for more information.
|
||||
|
||||
- *encrypt*: (ESP32 only) If set to ``True`` data exchanged with
|
||||
@@ -476,9 +470,6 @@ must first register the sender and use the same encryption keys as the sender
|
||||
registered.
|
||||
- ``OSError(num, "ESP_ERR_ESPNOW_FULL")`` if too many peers are
|
||||
already registered.
|
||||
- ``OSError(num, "ESP_ERR_ESPNOW_CHAN")`` if a channel value was
|
||||
set that doesn't match the channel currently configured for this
|
||||
interface.
|
||||
- ``ValueError()`` on invalid keyword args or values.
|
||||
|
||||
.. method:: ESPNow.del_peer(mac)
|
||||
@@ -576,45 +567,6 @@ Constants
|
||||
espnow.MAX_TOTAL_PEER_NUM(=20)
|
||||
espnow.MAX_ENCRYPT_PEER_NUM(=6)
|
||||
|
||||
The following constants correspond to different transmit data rates on ESP32
|
||||
only. Lower data rates are generally more reliable over long distances:
|
||||
|
||||
.. data:: espnow.RATE_LORA_250K
|
||||
espnow.RATE_LORA_500K
|
||||
|
||||
See `espnow-long-range`.
|
||||
|
||||
.. data:: espnow.RATE_1M
|
||||
espnow.RATE_2M
|
||||
espnow.RATE_5M
|
||||
espnow.RATE_6M
|
||||
espnow.RATE_11M
|
||||
espnow.RATE_12M
|
||||
espnow.RATE_24M
|
||||
espnow.RATE_54M
|
||||
|
||||
Unless using the two proprietary long range data rates, only the sender must
|
||||
configure the data rate.
|
||||
|
||||
.. _espnow-long-range:
|
||||
|
||||
Long Range Mode
|
||||
---------------
|
||||
|
||||
(ESP32 Only, except ESP32-C2)
|
||||
|
||||
To use the `espnow.RATE_LORA_250K` and `espnow.RATE_LORA_500K` data rates,
|
||||
first set the `WLAN` interface object to long-range mode, i.e.::
|
||||
|
||||
import network, espnow
|
||||
sta = network.WLAN(network.WLAN.IF_STA)
|
||||
sta.active(True)
|
||||
sta.config(channel=6, protocol=WLAN.PROTOCOL_LR) # Set on sender & receiver
|
||||
e = espnow.ESPNow()
|
||||
e.config(rate=espnow.RATE_LORA_250K) # Needed on sender only
|
||||
|
||||
For more information about the limitations of long-range mode, see `WLAN.PROTOCOL_LR`.
|
||||
|
||||
Exceptions
|
||||
----------
|
||||
|
||||
@@ -636,7 +588,7 @@ api-reference/network/esp_now.html#api-reference>`_. For example::
|
||||
elif err.args[1] == 'ESP_ERR_ESPNOW_NOT_FOUND':
|
||||
e.add_peer(peer)
|
||||
elif err.args[1] == 'ESP_ERR_ESPNOW_IF':
|
||||
network.WLAN(network.WLAN.IF_STA).active(True)
|
||||
network.WLAN(network.STA_IF).active(True)
|
||||
else:
|
||||
raise err
|
||||
|
||||
@@ -693,7 +645,7 @@ A small async server example::
|
||||
import asyncio
|
||||
|
||||
# A WLAN interface must be active to send()/recv()
|
||||
network.WLAN(network.WLAN.IF_STA).active(True)
|
||||
network.WLAN(network.STA_IF).active(True)
|
||||
|
||||
e = aioespnow.AIOESPNow() # Returns AIOESPNow enhanced with async support
|
||||
e.active(True)
|
||||
@@ -795,8 +747,8 @@ ESPNow and Wifi Operation
|
||||
-------------------------
|
||||
|
||||
ESPNow messages may be sent and received on any `active()<network.WLAN.active>`
|
||||
`WLAN<network.WLAN()>` interface (``network.WLAN.IF_STA`` or ``network.WLAN.IF_AP``),
|
||||
even if that interface is also connected to a wifi network or configured as an access
|
||||
`WLAN<network.WLAN()>` interface (``network.STA_IF`` or ``network.AP_IF``), even
|
||||
if that interface is also connected to a wifi network or configured as an access
|
||||
point. When an ESP32 or ESP8266 device connects to a Wifi Access Point (see
|
||||
`ESP32 Quickref <../esp32/quickref.html#networking>`__) the following things
|
||||
happen which affect ESPNow communications:
|
||||
@@ -880,8 +832,8 @@ Other issues to take care with when using ESPNow with wifi are:
|
||||
import network, time
|
||||
|
||||
def wifi_reset(): # Reset wifi to AP_IF off, STA_IF on and disconnected
|
||||
sta = network.WLAN(network.WLAN.IF_STA); sta.active(False)
|
||||
ap = network.WLAN(network.WLAN.IF_AP); ap.active(False)
|
||||
sta = network.WLAN(network.STA_IF); sta.active(False)
|
||||
ap = network.WLAN(network.AP_IF); ap.active(False)
|
||||
sta.active(True)
|
||||
while not sta.active():
|
||||
time.sleep(0.1)
|
||||
|
||||
@@ -114,7 +114,7 @@ Drawing text
|
||||
|
||||
.. method:: FrameBuffer.text(s, x, y[, c])
|
||||
|
||||
Write text to the FrameBuffer using the coordinates as the upper-left
|
||||
Write text to the FrameBuffer using the the coordinates as the upper-left
|
||||
corner of the text. The color of the text can be defined by the optional
|
||||
argument but is otherwise a default value of 1. All characters have
|
||||
dimensions of 8x8 pixels and there is currently no way to change the font.
|
||||
@@ -137,18 +137,6 @@ Other methods
|
||||
is compared to the value from *palette*, not to the value directly from
|
||||
*fbuf*.)
|
||||
|
||||
*fbuf* can be another FrameBuffer instance, or a tuple or list of the form::
|
||||
|
||||
(buffer, width, height, format)
|
||||
|
||||
or::
|
||||
|
||||
(buffer, width, height, format, stride)
|
||||
|
||||
This matches the signature of the FrameBuffer constructor, and the elements
|
||||
of the tuple/list are the same as the arguments to the constructor except that
|
||||
the *buffer* here can be read-only.
|
||||
|
||||
The *palette* argument enables blitting between FrameBuffers with differing
|
||||
formats. Typical usage is to render a monochrome or grayscale glyph/icon to
|
||||
a color display. The *palette* is a FrameBuffer instance whose format is
|
||||
|
||||
@@ -69,7 +69,6 @@ library.
|
||||
heapq.rst
|
||||
io.rst
|
||||
json.rst
|
||||
marshal.rst
|
||||
math.rst
|
||||
os.rst
|
||||
platform.rst
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
.. currentmodule:: machine
|
||||
.. _machine.Counter:
|
||||
|
||||
class Counter -- pulse counter
|
||||
==============================
|
||||
|
||||
Counter implements pulse counting by monitoring an input signal and counting
|
||||
rising or falling edges.
|
||||
|
||||
Minimal example usage::
|
||||
|
||||
from machine import Pin, Counter
|
||||
|
||||
counter = Counter(0, Pin(0, Pin.IN)) # create Counter for pin 0 and begin counting
|
||||
value = counter.value() # retrieve current pulse count
|
||||
|
||||
Availability: **ESP32**
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: Counter(id, ...)
|
||||
|
||||
Returns the singleton Counter object for the the given *id*. Values of *id*
|
||||
depend on a particular port and its hardware. Values 0, 1, etc. are commonly
|
||||
used to select hardware block #0, #1, etc.
|
||||
|
||||
Additional arguments are passed to the :meth:`init` method described below,
|
||||
and will cause the Counter instance to be re-initialised and reset.
|
||||
|
||||
On ESP32, the *id* corresponds to a :ref:`PCNT unit <esp32.PCNT>`.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Counter.init(src, *, ...)
|
||||
|
||||
Initialise and reset the Counter with the given parameters:
|
||||
|
||||
- *src* specifies the input pin as a :ref:`machine.Pin <machine.Pin>` object.
|
||||
May be omitted on ports that have a predefined pin for a given hardware
|
||||
block.
|
||||
|
||||
Additional keyword-only parameters that may be supported by a port are:
|
||||
|
||||
- *edge* specifies the edge to count. Either ``Counter.RISING`` (the default)
|
||||
or ``Counter.FALLING``. *(Supported on ESP32)*
|
||||
|
||||
- *direction* specifies the direction to count. Either ``Counter.UP`` (the
|
||||
default) or ``Counter.DOWN``. *(Supported on ESP32)*
|
||||
|
||||
- *filter_ns* specifies a minimum period of time in nanoseconds that the
|
||||
source signal needs to be stable for a pulse to be counted. Implementations
|
||||
should use the longest filter supported by the hardware that is less than
|
||||
or equal to this value. The default is 0 (no filter). *(Supported on ESP32)*
|
||||
|
||||
.. method:: Counter.deinit()
|
||||
|
||||
Stops the Counter, disabling any interrupts and releasing hardware resources.
|
||||
A Soft Reset should deinitialize all Counter objects.
|
||||
|
||||
.. method:: Counter.value([value])
|
||||
|
||||
Get, and optionally set, the counter value as a signed integer.
|
||||
Implementations must aim to do the get and set atomically (i.e. without
|
||||
leading to skipped counts).
|
||||
|
||||
This counter value could exceed the range of a :term:`small integer`, which
|
||||
means that calling :meth:`Counter.value` could cause a heap allocation, but
|
||||
implementations should aim to ensure that internal state only uses small
|
||||
integers and therefore will not allocate until the user calls
|
||||
:meth:`Counter.value`.
|
||||
|
||||
For example, on ESP32, the internal state counts overflows of the hardware
|
||||
counter (every 32000 counts), which means that it will not exceed the small
|
||||
integer range until ``2**30 * 32000`` counts (slightly over 1 year at 1MHz).
|
||||
|
||||
In general, it is recommended that you should use ``Counter.value(0)`` to reset
|
||||
the counter (i.e. to measure the counts since the last call), and this will
|
||||
avoid this problem.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: Counter.RISING
|
||||
Counter.FALLING
|
||||
|
||||
Select the pulse edge.
|
||||
|
||||
.. data:: Counter.UP
|
||||
Counter.DOWN
|
||||
|
||||
Select the counting direction.
|
||||
@@ -1,68 +0,0 @@
|
||||
.. currentmodule:: machine
|
||||
.. _machine.DAC:
|
||||
|
||||
class DAC -- digital to analog conversion
|
||||
=========================================
|
||||
|
||||
The DAC is used to output an analog voltage based on a digital value.
|
||||
|
||||
The output voltage will be between 0 and 3.3V.
|
||||
|
||||
DAC is currently supported on ESP32 [#esp32_dac]_, SAMD and Renesas RA.
|
||||
|
||||
.. note::
|
||||
The STM32 port has similar functionality to ``machine.DAC``. See
|
||||
:ref:`pyb.DAC <pyb.DAC>` for details.
|
||||
|
||||
Example usage (ESP32)::
|
||||
|
||||
from machine import DAC
|
||||
|
||||
dac = DAC(pin) # create a DAC object acting on a pin
|
||||
dac.write(128) # write a value to the DAC
|
||||
dac.write(255) # output maximum value, 3.3V
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: DAC(id)
|
||||
|
||||
Construct a new DAC object.
|
||||
|
||||
``id`` is a pin object (ESP32 and Renesas RA) or an index to a DAC resource (SAMD).
|
||||
|
||||
.. note::
|
||||
On the ESP32, DAC functionality is available on pins 25 and 26. On the
|
||||
ESP32-S2, pins 17 and 18. See :ref:`ESP32 Quickref <esp32_quickref>`
|
||||
for more details.
|
||||
|
||||
.. note::
|
||||
SAMD21 has one DAC resource, SAMD51 has two. See :ref:`SAMD Quickref <samd_quickref>`
|
||||
for more details.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: DAC.write(value)
|
||||
|
||||
Output an analog voltage to the pin connected to the DAC.
|
||||
|
||||
``value`` is a representation of the desired output; a linear interpolation of
|
||||
0-3.3V, though the range differs depending on the port and micro, see below:
|
||||
|
||||
+--------------+------+--------+
|
||||
| *Port/micro* | Bits | Range |
|
||||
+==============+======+========+
|
||||
| ESP32 | 8 | 0-255 |
|
||||
+--------------+------+--------+
|
||||
| SAMD21 | 10 | 0-1023 |
|
||||
+--------------+------+--------+
|
||||
| SAMD51 | 12 | 0-4095 |
|
||||
+--------------+------+--------+
|
||||
| Renesas RA | 12 | 0-4095 |
|
||||
+--------------+------+--------+
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
||||
.. [#esp32_dac] The original ESP32 and ESP32-S2 *only*, since DAC hardware is
|
||||
not present on other microcontrollers in the family.
|
||||
@@ -1,72 +0,0 @@
|
||||
.. currentmodule:: machine
|
||||
.. _machine.Encoder:
|
||||
|
||||
class Encoder -- quadrature decoding
|
||||
====================================
|
||||
|
||||
Encoder implements decoding of quadrature signals as commonly output from
|
||||
rotary encoders, by counting either up or down depending on the order of two
|
||||
input pulses.
|
||||
|
||||
Minimal example usage::
|
||||
|
||||
from machine import Pin, Encoder
|
||||
|
||||
counter = Counter(0, Pin(0, Pin.IN), Pin(1, Pin.IN)) # create Encoder for pins 0, 1 and begin counting
|
||||
value = counter.value() # retrieve current count
|
||||
|
||||
Availability: **ESP32**
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: Encoder(id, ...)
|
||||
|
||||
Returns the singleton Encoder object for the the given *id*. Values of *id*
|
||||
depend on a particular port and its hardware. Values 0, 1, etc. are commonly
|
||||
used to select hardware block #0, #1, etc.
|
||||
|
||||
Additional arguments are passed to the :meth:`init` method described below,
|
||||
and will cause the Encoder instance to be re-initialised and reset.
|
||||
|
||||
On ESP32, the *id* corresponds to a :ref:`PCNT unit <esp32.PCNT>`.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Encoder.init(phase_a, phase_b, *, ...)
|
||||
|
||||
Initialise and reset the Encoder with the given parameters:
|
||||
|
||||
- *phase_a* specifies the first input pin as a
|
||||
:ref:`machine.Pin <machine.Pin>` object.
|
||||
|
||||
- *phase_b* specifies the second input pin as a
|
||||
:ref:`machine.Pin <machine.Pin>` object.
|
||||
|
||||
These pins may be omitted on ports that have predefined pins for a given
|
||||
hardware block.
|
||||
|
||||
Additional keyword-only parameters that may be supported by a port are:
|
||||
|
||||
- *filter_ns* specifies a minimum period of time in nanoseconds that the
|
||||
source signal needs to be stable for a pulse to be counted. Implementations
|
||||
should use the longest filter supported by the hardware that is less than
|
||||
or equal to this value. The default is 0 (no filter). *(Supported on ESP32)*
|
||||
|
||||
- *phases* specifies the number of signal edges to count and thus the
|
||||
granularity of the decoding. e.g. 4 phases corresponds to "4x quadrature
|
||||
decoding", and will result in four counts per pulse. Ports may support
|
||||
either 1, 2, or 4 phases and the default is 1 phase. *(Supported on ESP32)*
|
||||
|
||||
.. method:: Encoder.deinit()
|
||||
|
||||
Stops the Encoder, disabling any interrupts and releasing hardware resources.
|
||||
A Soft Reset should deinitialize all Encoder objects.
|
||||
|
||||
.. method:: Encoder.value([value])
|
||||
|
||||
Get, and optionally set, the encoder value as a signed integer.
|
||||
Implementations should aim to do the get and set atomically.
|
||||
|
||||
See :meth:`machine.Counter.value` for details about overflow of this value.
|
||||
@@ -1,174 +0,0 @@
|
||||
.. currentmodule:: machine
|
||||
.. _machine.I2CTarget:
|
||||
|
||||
class I2CTarget -- an I2C target device
|
||||
=======================================
|
||||
|
||||
An I2C target is a device which connects to an I2C bus and is controlled by an
|
||||
I2C controller. I2C targets can take many forms. The :class:`machine.I2CTarget`
|
||||
class implements an I2C target that can be configured as a memory/register device,
|
||||
or as an arbitrary I2C device by using callbacks (if supported by the port).
|
||||
|
||||
Example usage for the case of a memory device::
|
||||
|
||||
from machine import I2CTarget
|
||||
|
||||
# Create the backing memory for the I2C target.
|
||||
mem = bytearray(8)
|
||||
|
||||
# Create an I2C target. Depending on the port, extra parameters
|
||||
# may be required to select the peripheral and/or pins to use.
|
||||
i2c = I2CTarget(addr=67, mem=mem)
|
||||
|
||||
# At this point an I2C controller can read and write `mem`.
|
||||
...
|
||||
|
||||
# Deinitialise the I2C target.
|
||||
i2c.deinit()
|
||||
|
||||
Note that some ports require an ``id``, and maybe ``scl`` and ``sda`` pins, to be
|
||||
passed to the `I2CTarget` constructor, to select the hardware I2C instance and
|
||||
pins that it connects to.
|
||||
|
||||
When configured as a memory device, it's also possible to register to receive events.
|
||||
For example to be notified when the memory is read/written::
|
||||
|
||||
from machine import I2CTarget
|
||||
|
||||
# Define an IRQ handler, for I2C events.
|
||||
def irq_handler(i2c_target):
|
||||
flags = i2c_target.irq().flags()
|
||||
if flags & I2CTarget.IRQ_END_READ:
|
||||
print("controller read target at addr", i2c_target.memaddr)
|
||||
if flags & I2CTarget.IRQ_END_WRITE:
|
||||
print("controller wrote target at addr", i2c_target.memaddr)
|
||||
|
||||
# Create the I2C target and register to receive default events.
|
||||
mem = bytearray(8)
|
||||
i2c = I2CTarget(addr=67, mem=mem)
|
||||
i2c.irq(irq_handler)
|
||||
|
||||
More complicated I2C devices can be implemented using the full set of events. For
|
||||
example, to see the raw events as they are triggered::
|
||||
|
||||
from machine import I2CTarget
|
||||
|
||||
# Define an IRQ handler that prints the event id and responds to reads/writes.
|
||||
def irq_handler(i2c_target, buf=bytearray(1)):
|
||||
flags = i2c_target.irq().flags()
|
||||
print(flags)
|
||||
if flags & I2CTarget.IRQ_READ_REQ:
|
||||
i2c_target.write(buf)
|
||||
if flags & I2CTarget.IRQ_WRITE_REQ:
|
||||
i2c_target.readinto(buf)
|
||||
|
||||
# Create the I2C target and register to receive all events.
|
||||
i2c = I2CTarget(addr=67)
|
||||
all_triggers = (
|
||||
I2CTarget.IRQ_ADDR_MATCH_READ
|
||||
| I2CTarget.IRQ_ADDR_MATCH_WRITE
|
||||
| I2CTarget.IRQ_READ_REQ
|
||||
| I2CTarget.IRQ_WRITE_REQ
|
||||
| I2CTarget.IRQ_END_READ
|
||||
| I2CTarget.IRQ_END_WRITE
|
||||
)
|
||||
i2c.irq(irq_handler, trigger=all_triggers, hard=True)
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: I2CTarget(id, addr, *, addrsize=7, mem=None, mem_addrsize=8, scl=None, sda=None)
|
||||
|
||||
Construct and return a new I2CTarget object using the following parameters:
|
||||
|
||||
- *id* identifies a particular I2C peripheral. Allowed values depend on the
|
||||
particular port/board. Some ports have a default in which case this parameter
|
||||
can be omitted.
|
||||
- *addr* is the I2C address of the target.
|
||||
- *addrsize* is the number of bits in the I2C target address. Valid values
|
||||
are 7 and 10.
|
||||
- *mem* is an object with the buffer protocol that is writable. If not
|
||||
specified then there is no backing memory and data must be read/written
|
||||
using the :meth:`I2CTarget.readinto` and :meth:`I2CTarget.write` methods.
|
||||
- *mem_addrsize* is the number of bits in the memory address. Valid values
|
||||
are 0, 8, 16, 24 and 32.
|
||||
- *scl* is a pin object specifying the pin to use for SCL.
|
||||
- *sda* is a pin object specifying the pin to use for SDA.
|
||||
|
||||
Note that some ports/boards will have default values of *scl* and *sda*
|
||||
that can be changed in this constructor. Others will have fixed values
|
||||
of *scl* and *sda* that cannot be changed.
|
||||
|
||||
General Methods
|
||||
---------------
|
||||
|
||||
.. method:: I2CTarget.deinit()
|
||||
|
||||
Deinitialise the I2C target. After this method is called the hardware will no
|
||||
longer respond to requests on the I2C bus, and no other methods can be called.
|
||||
|
||||
.. method:: I2CTarget.readinto(buf)
|
||||
|
||||
Read into the given buffer any pending bytes written by the I2C controller.
|
||||
Returns the number of bytes read.
|
||||
|
||||
.. method:: I2CTarget.write(buf)
|
||||
|
||||
Write out the bytes from the given buffer, to be passed to the I2C controller
|
||||
after it sends a read request. Returns the number of bytes written. Most ports
|
||||
only accept one byte at a time to this method.
|
||||
|
||||
.. method:: I2CTarget.irq(handler=None, trigger=IRQ_END_READ|IRQ_END_WRITE, hard=False)
|
||||
|
||||
Configure an IRQ *handler* to be called when an event occurs. The possible events are
|
||||
given by the following constants, which can be or'd together and passed to the *trigger*
|
||||
argument:
|
||||
|
||||
- ``IRQ_ADDR_MATCH_READ`` indicates that the target was addressed by a
|
||||
controller for a read transaction.
|
||||
- ``IRQ_ADDR_MATCH_WRITE`` indicates that the target was addressed by a
|
||||
controller for a write transaction.
|
||||
- ``IRQ_READ_REQ`` indicates that the controller is requesting data, and this
|
||||
request must be satisfied by calling `I2CTarget.write` with the data to be
|
||||
passed back to the controller.
|
||||
- ``IRQ_WRITE_REQ`` indicates that the controller has written data, and the
|
||||
data must be read by calling `I2CTarget.readinto`.
|
||||
- ``IRQ_END_READ`` indicates that the controller has finished a read transaction.
|
||||
- ``IRQ_END_WRITE`` indicates that the controller has finished a write transaction.
|
||||
|
||||
Not all triggers are available on all ports. If a port has the constant then that
|
||||
event is available.
|
||||
|
||||
Note the following restrictions:
|
||||
|
||||
- ``IRQ_ADDR_MATCH_READ``, ``IRQ_ADDR_MATCH_WRITE``, ``IRQ_READ_REQ`` and
|
||||
``IRQ_WRITE_REQ`` must be handled by a hard IRQ callback (with the *hard* argument
|
||||
set to ``True``). This is because these events have very strict timing requirements
|
||||
and must usually be satisfied synchronously with the hardware event.
|
||||
|
||||
- ``IRQ_END_READ`` and ``IRQ_END_WRITE`` may be handled by either a soft or hard
|
||||
IRQ callback (although note that all events must be registered with the same handler,
|
||||
so if any events need a hard callback then all events must be hard).
|
||||
|
||||
- If a memory buffer has been supplied in the constructor then ``IRQ_END_WRITE``
|
||||
is not emitted for the transaction that writes the memory address. This is to
|
||||
allow ``IRQ_END_READ`` and ``IRQ_END_WRITE`` to function correctly as soft IRQ
|
||||
callbacks, where the IRQ handler may be called quite some time after the actual
|
||||
hardware event.
|
||||
|
||||
.. attribute:: I2CTarget.memaddr
|
||||
|
||||
The integer value of the most recent memory address that was selected by the I2C
|
||||
controller (only valid if ``mem`` was specified in the constructor).
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: I2CTarget.IRQ_ADDR_MATCH_READ
|
||||
I2CTarget.IRQ_ADDR_MATCH_WRITE
|
||||
I2CTarget.IRQ_READ_REQ
|
||||
I2CTarget.IRQ_WRITE_REQ
|
||||
I2CTarget.IRQ_END_READ
|
||||
I2CTarget.IRQ_END_WRITE
|
||||
|
||||
IRQ trigger sources.
|
||||
@@ -11,20 +11,20 @@ Example usage::
|
||||
from machine import PWM
|
||||
|
||||
pwm = PWM(pin, freq=50, duty_u16=8192) # create a PWM object on a pin
|
||||
# and set freq 50 Hz and duty 12.5%
|
||||
pwm.duty_u16(32768) # set duty to 50%
|
||||
# and set freq and duty
|
||||
pwm.duty_u16(32768) # set duty to 50%
|
||||
|
||||
# reinitialise with a period of 200us, duty of 5us
|
||||
pwm.init(freq=5000, duty_ns=5000)
|
||||
|
||||
pwm.duty_ns(3000) # set pulse width to 3us
|
||||
pwm.duty_ns(3000) # set pulse width to 3us
|
||||
|
||||
pwm.deinit()
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: PWM(dest, *, freq, duty_u16, duty_ns, invert=False)
|
||||
.. class:: PWM(dest, *, freq, duty_u16, duty_ns, invert)
|
||||
|
||||
Construct and return a new PWM object using the following parameters:
|
||||
|
||||
@@ -40,7 +40,7 @@ Constructors
|
||||
Setting *freq* may affect other PWM objects if the objects share the same
|
||||
underlying PWM generator (this is hardware specific).
|
||||
Only one of *duty_u16* and *duty_ns* should be specified at a time.
|
||||
*invert* is available only on the esp32, mimxrt, nrf, rp2, samd and zephyr ports.
|
||||
*invert* is not available at all ports.
|
||||
|
||||
Methods
|
||||
-------
|
||||
@@ -116,10 +116,10 @@ Limitations of PWM
|
||||
resolution of 8 bit, not 16-bit as may be expected. In this case, the lowest
|
||||
8 bits of *duty_u16* are insignificant. So::
|
||||
|
||||
pwm=PWM(Pin(13), freq=300_000, duty_u16=65536//2)
|
||||
pwm=PWM(Pin(13), freq=300_000, duty_u16=2**16//2)
|
||||
|
||||
and::
|
||||
|
||||
pwm=PWM(Pin(13), freq=300_000, duty_u16=65536//2 + 255)
|
||||
pwm=PWM(Pin(13), freq=300_000, duty_u16=2**16//2 + 255)
|
||||
|
||||
will generate PWM with the same 50% duty cycle.
|
||||
|
||||
@@ -209,13 +209,13 @@ The following methods are not part of the core Pin API and only implemented on c
|
||||
|
||||
Set pin to "0" output level.
|
||||
|
||||
Availability: mimxrt, nrf, renesas-ra, rp2, samd, stm32 ports.
|
||||
Availability: nrf, rp2, stm32 ports.
|
||||
|
||||
.. method:: Pin.high()
|
||||
|
||||
Set pin to "1" output level.
|
||||
|
||||
Availability: mimxrt, nrf, renesas-ra, rp2, samd, stm32 ports.
|
||||
Availability: nrf, rp2, stm32 ports.
|
||||
|
||||
.. method:: Pin.mode([mode])
|
||||
|
||||
@@ -242,7 +242,7 @@ The following methods are not part of the core Pin API and only implemented on c
|
||||
|
||||
Toggle output pin from "0" to "1" or vice-versa.
|
||||
|
||||
Availability: cc3200, esp32, esp8266, mimxrt, rp2, samd ports.
|
||||
Availability: mimxrt, samd, rp2 ports.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
@@ -42,21 +42,12 @@ Methods
|
||||
|
||||
Initialise the RTC. Datetime is a tuple of the form:
|
||||
|
||||
``(year, month, day, hour, minute, second, microsecond, tzinfo)``
|
||||
|
||||
All eight arguments must be present. The ``microsecond`` and ``tzinfo``
|
||||
values are currently ignored but might be used in the future.
|
||||
|
||||
Availability: CC3200, ESP32, MIMXRT, SAMD. The rtc.init() method on
|
||||
the stm32 and renesas-ra ports just (re-)starts the RTC and does not
|
||||
accept arguments.
|
||||
``(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])``
|
||||
|
||||
.. method:: RTC.now()
|
||||
|
||||
Get get the current datetime tuple.
|
||||
|
||||
Availability: WiPy.
|
||||
|
||||
.. method:: RTC.deinit()
|
||||
|
||||
Resets the RTC to the time of January 1, 2015 and starts running it again.
|
||||
@@ -71,13 +62,10 @@ Methods
|
||||
|
||||
Get the number of milliseconds left before the alarm expires.
|
||||
|
||||
.. method:: RTC.alarm_cancel(alarm_id=0)
|
||||
.. method:: RTC.cancel(alarm_id=0)
|
||||
|
||||
Cancel a running alarm.
|
||||
|
||||
The mimxrt port also exposes this function as ``RTC.cancel(alarm_id=0)``, but this is
|
||||
scheduled to be removed in MicroPython 2.0.
|
||||
|
||||
.. method:: RTC.irq(*, trigger, handler=None, wake=machine.IDLE)
|
||||
|
||||
Create an irq object triggered by a real time clock alarm.
|
||||
@@ -95,7 +83,7 @@ Methods
|
||||
a `bytes` object.
|
||||
|
||||
Data written to RTC user memory is persistent across restarts, including
|
||||
:ref:`soft_reset` and `machine.deepsleep()`.
|
||||
`machine.soft_reset()` and `machine.deepsleep()`.
|
||||
|
||||
The maximum length of RTC user memory is 2048 bytes by default on esp32,
|
||||
and 492 bytes on esp8266.
|
||||
|
||||
@@ -23,8 +23,7 @@ arguments that might need to be set in order to use either a non-standard slot
|
||||
or a non-standard pin assignment. The exact subset of arguments supported will
|
||||
vary from platform to platform.
|
||||
|
||||
.. class:: SDCard(slot=1, width=1, cd=None, wp=None, sck=None, miso=None, mosi=None,
|
||||
cs=None, cmd=None, data=None, freq=20000000)
|
||||
.. class:: SDCard(slot=1, width=1, cd=None, wp=None, sck=None, miso=None, mosi=None, cs=None, freq=20000000)
|
||||
|
||||
This class provides access to SD or MMC storage cards using either
|
||||
a dedicated SD/MMC interface hardware or through an SPI channel.
|
||||
@@ -38,8 +37,7 @@ vary from platform to platform.
|
||||
- *slot* selects which of the available interfaces to use. Leaving this
|
||||
unset will select the default interface.
|
||||
|
||||
- *width* selects the bus width for the SD/MMC interface. This many data
|
||||
pins must be connected to the SD card.
|
||||
- *width* selects the bus width for the SD/MMC interface.
|
||||
|
||||
- *cd* can be used to specify a card-detect pin.
|
||||
|
||||
@@ -53,14 +51,7 @@ vary from platform to platform.
|
||||
|
||||
- *cs* can be used to specify an SPI chip select pin.
|
||||
|
||||
The following additional parameters are only present on ESP32 port:
|
||||
|
||||
- *cmd* can be used to specify the SD CMD pin (ESP32-S3 only).
|
||||
|
||||
- *data* can be used to specify a list or tuple of SD data bus pins
|
||||
(ESP32-S3 only).
|
||||
|
||||
- *freq* selects the SD/MMC interface frequency in Hz.
|
||||
- *freq* selects the SD/MMC interface frequency in Hz (only supported on the ESP32).
|
||||
|
||||
Implementation-specific details
|
||||
-------------------------------
|
||||
@@ -76,130 +67,52 @@ The standard PyBoard has just one slot. No arguments are necessary or supported.
|
||||
ESP32
|
||||
`````
|
||||
|
||||
SD cards support access in both SD/MMC mode and the simpler (but slower) SPI
|
||||
mode.
|
||||
The ESP32 provides two channels of SD/MMC hardware and also supports
|
||||
access to SD Cards through either of the two SPI ports that are
|
||||
generally available to the user. As a result the *slot* argument can
|
||||
take a value between 0 and 3, inclusive. Slots 0 and 1 use the
|
||||
built-in SD/MMC hardware while slots 2 and 3 use the SPI ports. Slot 0
|
||||
supports 1, 4 or 8-bit wide access while slot 1 supports 1 or 4-bit
|
||||
access; the SPI slots only support 1-bit access.
|
||||
|
||||
SPI mode makes use of a `SPI` host peripheral, which cannot concurrently be used
|
||||
for other SPI interactions.
|
||||
.. note:: Slot 0 is used to communicate with on-board flash memory
|
||||
on most ESP32 modules and so will be unavailable to the
|
||||
user.
|
||||
|
||||
The ``slot`` argument determines which mode is used. Different values are
|
||||
supported on different chips:
|
||||
.. note:: Most ESP32 modules that provide an SD card slot using the
|
||||
dedicated hardware only wire up 1 data pin, so the default
|
||||
value for *width* is 1.
|
||||
|
||||
========== ======== ======== ============ ============
|
||||
Chip Slot 0 Slot 1 Slot 2 Slot 3
|
||||
========== ======== ======== ============ ============
|
||||
ESP32 SD/MMC SPI (id=1) SPI (id=0)
|
||||
ESP32-C3 SPI (id=0)
|
||||
ESP32-C6 SPI (id=0)
|
||||
ESP32-S2 SPI (id=1) SPI (id=0)
|
||||
ESP32-S3 SD/MMC SD/MMC SPI (id=1) SPI (id=0)
|
||||
========== ======== ======== ============ ============
|
||||
The pins used by the dedicated SD/MMC hardware are fixed. The pins
|
||||
used by the SPI hardware can be reassigned.
|
||||
|
||||
Different slots support different data bus widths (number of data pins):
|
||||
.. note:: If any of the SPI signals are remapped then all of the SPI
|
||||
signals will pass through a GPIO multiplexer unit which
|
||||
can limit the performance of high frequency signals. Since
|
||||
the normal operating speed for SD cards is 40MHz this can
|
||||
cause problems on some cards.
|
||||
|
||||
========== ========== =====================
|
||||
Slot Type Supported data widths
|
||||
========== ========== =====================
|
||||
0 SD/MMC 1, 4, 8
|
||||
1 SD/MMC 1, 4
|
||||
2 SPI 1
|
||||
3 SPI 1
|
||||
========== ========== =====================
|
||||
The default (and preferred) pin assignment are as follows:
|
||||
|
||||
.. note:: Most ESP32 modules that provide an SD card slot using the
|
||||
dedicated hardware only wire up 1 data pin, so the default
|
||||
value for ``width`` is 1.
|
||||
|
||||
Additional details depend on which ESP32 family chip is in use:
|
||||
|
||||
Original ESP32
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
In SD/MMC mode (slot 1), pin assignments in SD/MMC mode are fixed on the
|
||||
original ESP32. The SPI mode slots (2 & 3) allow pins to be set to different
|
||||
values in the constructor.
|
||||
|
||||
The default pin assignments are as follows:
|
||||
|
||||
====== ====== ====== ====== ============
|
||||
Slot 1 2 3 Can be set
|
||||
------ ------ ------ ------ ------------
|
||||
Signal Pin Pin Pin
|
||||
====== ====== ====== ====== ============
|
||||
CLK 14 No
|
||||
CMD 15 No
|
||||
D0 2 No
|
||||
D1 4 No
|
||||
D2 12 No
|
||||
D3 13 No
|
||||
sck 18 14 Yes
|
||||
cs 5 15 Yes
|
||||
miso 19 12 Yes
|
||||
mosi 23 13 Yes
|
||||
====== ====== ====== ====== ============
|
||||
|
||||
The ``cd`` and ``wp`` pins are not fixed in either mode and default to disabled, unless set.
|
||||
|
||||
ESP32-S3
|
||||
~~~~~~~~
|
||||
|
||||
The ESP32-S3 chip allows pins to be set to different values for both SD/MMC and
|
||||
SPI mode access.
|
||||
|
||||
If not set, default pin assignments are as follows:
|
||||
|
||||
======== ====== ====== ====== ======
|
||||
Slot 0 1 2 3
|
||||
-------- ------ ------ ------ ------
|
||||
Signal Pin Pin Pin Pin
|
||||
======== ====== ====== ====== ======
|
||||
CLK 14 14
|
||||
CMD 15 15
|
||||
D0 2 2
|
||||
D1 4 4
|
||||
D2 12 12
|
||||
D3 13 13
|
||||
D4 33*
|
||||
D5 34*
|
||||
D6 35*
|
||||
D7 36*
|
||||
sck 37* 14
|
||||
cs 34* 13
|
||||
miso 37* 2
|
||||
mosi 35* 15
|
||||
======== ====== ====== ====== ======
|
||||
|
||||
.. note:: Slots 0 and 1 cannot both be in use at the same time.
|
||||
|
||||
.. note:: Pins marked with an asterisk * in the table must be changed from the
|
||||
default if the ESP32-S3 board is configured for Octal SPI Flash or
|
||||
PSRAM.
|
||||
|
||||
To access a card in SD/MMC mode, set ``slot`` parameter value 0 or 1 and
|
||||
parameters ``sck`` (for CLK), ``cmd`` and ``data`` as needed to assign pins. If
|
||||
the ``data`` argument is passed then it should be a list or tuple of data pins
|
||||
or pin numbers with length equal to the ``width`` argument. For example::
|
||||
|
||||
sd = SDCard(slot=0, width=4, sck=8, cmd=9, data=(10, 11, 12, 13))
|
||||
|
||||
To access a card in SPI mode, set ``slot`` parameter value 2 or 3 and pass
|
||||
parameters ``sck``, ``cs``, ``miso``, ``mosi`` as needed to assign pins.
|
||||
|
||||
In either mode the ``cd`` and ``wp`` pins default to disabled, unless set in the
|
||||
constructor.
|
||||
|
||||
Other ESP32 chips
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Other ESP32 family chips do not have hardware SD/MMC host controllers and can
|
||||
only access SD cards in SPI mode.
|
||||
|
||||
To access a card in SPI mode, set ``slot`` parameter value 2 or 3 and pass
|
||||
parameters ``sck``, ``cs``, ``miso``, ``mosi`` to assign pins.
|
||||
|
||||
.. note:: ESP32-C3 and ESP32-C6 only have one available `SPI` bus, so the only
|
||||
valid ``slot`` parameter value is 2. Using this bus for the SD card
|
||||
will prevent also using it for :class:`machine.SPI`.
|
||||
====== ====== ====== ====== ======
|
||||
Slot 0 1 2 3
|
||||
------ ------ ------ ------ ------
|
||||
Signal Pin Pin Pin Pin
|
||||
====== ====== ====== ====== ======
|
||||
sck 6 14 18 14
|
||||
cmd 11 15
|
||||
cs 5 15
|
||||
miso 19 12
|
||||
mosi 23 13
|
||||
D0 7 2
|
||||
D1 8 4
|
||||
D2 9 12
|
||||
D3 10 13
|
||||
D4 16
|
||||
D5 17
|
||||
D6 5
|
||||
D7 18
|
||||
====== ====== ====== ====== ======
|
||||
|
||||
cc3200
|
||||
``````
|
||||
|
||||
@@ -4,52 +4,41 @@
|
||||
class Timer -- control hardware timers
|
||||
======================================
|
||||
|
||||
Timer class provides the ability to trigger a Python callback function after an
|
||||
expiry time, or periodically at a regular interval.
|
||||
Hardware timers deal with timing of periods and events. Timers are perhaps
|
||||
the most flexible and heterogeneous kind of hardware in MCUs and SoCs,
|
||||
differently greatly from a model to a model. MicroPython's Timer class
|
||||
defines a baseline operation of executing a callback with a given period
|
||||
(or once after some delay), and allow specific boards to define more
|
||||
non-standard behaviour (which thus won't be portable to other boards).
|
||||
|
||||
The available features and restrictions of Timer objects vary depending on the
|
||||
MicroPython board and port.
|
||||
See discussion of :ref:`important constraints <machine_callbacks>` on
|
||||
Timer callbacks.
|
||||
|
||||
.. note::
|
||||
|
||||
Memory can't be allocated inside irq handlers (an interrupt) and so
|
||||
exceptions raised within a handler don't give much information. See
|
||||
:func:`micropython.alloc_emergency_exception_buf` for how to get around this
|
||||
limitation.
|
||||
|
||||
If you are using a WiPy board please refer to :ref:`machine.TimerWiPy <machine.TimerWiPy>`
|
||||
instead of this class.
|
||||
|
||||
Timer Types
|
||||
-----------
|
||||
|
||||
There are two types of Timer in MicroPython, but not all ports support both:
|
||||
|
||||
- Virtual timers. These are managed in software, and are generally more
|
||||
flexible. Multiple virtual timers can be constructed and active at once. The
|
||||
``id`` of a virtual timer is ``-1``. Not all ports support virtual timers, but
|
||||
it's recommended to use them when available.
|
||||
- Hardware timers. Hardware timers have integer ``id`` values starting at ``0``.
|
||||
The number of available ``id`` values is determined by the hardware. Hardware
|
||||
timers may be more accurate for very fine sub-millisecond timing (especially
|
||||
when ``hard=True`` is supported and set, see :ref:`isr_rules`.) Most
|
||||
microcontroller ports support hardware timers, except Zephyr and RP2 which
|
||||
only support virtual timers.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: Timer(id, /, ...)
|
||||
|
||||
Construct a new Timer object with the given ``id``.
|
||||
|
||||
On ports which support virtual timers the ``id`` parameter is optional - the
|
||||
default value is ``-1`` which constructs a virtual timer.
|
||||
|
||||
On ports which support hardware timers, setting the ``id`` parameter to a
|
||||
non-negative integer determines which timer to use.
|
||||
|
||||
Construct a new timer object of the given ``id``. ``id`` of -1 constructs a
|
||||
virtual timer (if supported by a board).
|
||||
``id`` shall not be passed as a keyword argument.
|
||||
|
||||
Any additional parameters are handled the same as :func:`Timer.init()`.
|
||||
See ``init`` for parameters of initialisation.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Timer.init(*, mode=Timer.PERIODIC, freq=-1, period=-1, callback=None, hard=True)
|
||||
.. method:: Timer.init(*, mode=Timer.PERIODIC, freq=-1, period=-1, callback=None)
|
||||
|
||||
Initialise the timer. Example::
|
||||
|
||||
@@ -83,23 +72,10 @@ Methods
|
||||
|
||||
- ``callback`` - The callable to call upon expiration of the timer period.
|
||||
The callback must take one argument, which is passed the Timer object.
|
||||
|
||||
The ``callback`` argument shall be specified. Otherwise an exception
|
||||
will occur upon timer expiration:
|
||||
``TypeError: 'NoneType' object isn't callable``
|
||||
|
||||
- ``hard`` can be one of:
|
||||
|
||||
- ``True`` - The callback will be executed in hard interrupt context,
|
||||
which minimises delay and jitter but is subject to the limitations
|
||||
described in :ref:`isr_rules`. Not all ports support hard interrupts,
|
||||
see the port documentation for more information.
|
||||
- ``False`` - The callback will be scheduled as a soft interrupt,
|
||||
allowing it to allocate but possibly also introducing
|
||||
garbage-collection delays and jitter.
|
||||
|
||||
The default value of this parameter is port-specific for historical reasons.
|
||||
|
||||
.. method:: Timer.deinit()
|
||||
|
||||
Deinitialises the timer. Stops the timer, and disables the timer peripheral.
|
||||
|
||||
@@ -18,6 +18,16 @@ defines a baseline operation of executing a callback with a given period
|
||||
(or once after some delay), and allow specific boards to define more
|
||||
non-standard behaviour (which thus won't be portable to other boards).
|
||||
|
||||
See discussion of :ref:`important constraints <machine_callbacks>` on
|
||||
Timer callbacks.
|
||||
|
||||
.. note::
|
||||
|
||||
Memory can't be allocated inside irq handlers (an interrupt) and so
|
||||
exceptions raised within a handler don't give much information. See
|
||||
:func:`micropython.alloc_emergency_exception_buf` for how to get around this
|
||||
limitation.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
@@ -61,7 +71,7 @@ Methods
|
||||
|
||||
Otherwise, a TimerChannel object is initialized and returned.
|
||||
|
||||
The operating mode is the one configured to the Timer object that was used to
|
||||
The operating mode is is the one configured to the Timer object that was used to
|
||||
create the channel.
|
||||
|
||||
- ``channel`` if the width of the timer is 16-bit, then must be either ``TIMER.A``, ``TIMER.B``.
|
||||
@@ -124,9 +134,6 @@ Methods
|
||||
``TimerWiPy.ONE_SHOT``. In the case that mode is ``TimerWiPy.PWM`` then trigger must be equal to
|
||||
``TimerWiPy.MATCH``.
|
||||
|
||||
Note that callback handlers are hard interrupts, and the constraints described in :ref:`isr_rules`
|
||||
apply when they are executed.
|
||||
|
||||
Returns a callback object.
|
||||
|
||||
.. method:: timerchannel.freq([value])
|
||||
|
||||
@@ -83,7 +83,7 @@ Methods
|
||||
|
||||
- *pins* is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order).
|
||||
Any of the pins can be None if one wants the UART to operate with limited functionality.
|
||||
If the RTS pin is given the RX pin must be given as well. The same applies to CTS.
|
||||
If the RTS pin is given the the RX pin must be given as well. The same applies to CTS.
|
||||
When no pins are given, then the default set of TX and RX pins is taken, and hardware
|
||||
flow control will be disabled. If *pins* is ``None``, no pin assignment will be made.
|
||||
|
||||
@@ -224,8 +224,7 @@ Methods
|
||||
|
||||
|
||||
.. note::
|
||||
- The ESP32 port does not support the option hard=True. It uses Timer(0)
|
||||
for UART.IRQ_RXIDLE, so this timer cannot be used for other means.
|
||||
- The ESP32 port does not support the option hard=True.
|
||||
|
||||
- The rp2 port's UART.IRQ_TXIDLE is only triggered when the message
|
||||
is longer than 5 characters and the trigger happens when still 5 characters
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
class USBDevice -- USB Device driver
|
||||
====================================
|
||||
|
||||
.. note:: ``machine.USBDevice`` is currently only supported for esp32, rp2 and
|
||||
samd ports. Native USB support is also required, and not every board
|
||||
supports native USB.
|
||||
.. note:: ``machine.USBDevice`` is currently only supported on the rp2 and samd
|
||||
ports.
|
||||
|
||||
USBDevice provides a low-level Python API for implementing USB device functions using
|
||||
Python code.
|
||||
@@ -33,10 +32,10 @@ Managing a runtime USB interface can be tricky, especially if you are communicat
|
||||
with MicroPython over a built-in USB-CDC serial port that's part of the same USB
|
||||
device.
|
||||
|
||||
- A MicroPython :ref:`soft reset <soft_reset>` will always clear all runtime USB
|
||||
interfaces, which results in the entire USB device disconnecting from the
|
||||
host. If MicroPython is also providing a built-in USB-CDC serial port then
|
||||
this will re-appear after the soft reset.
|
||||
- A MicroPython soft reset will always clear all runtime USB interfaces, which
|
||||
results in the entire USB device disconnecting from the host. If MicroPython
|
||||
is also providing a built-in USB-CDC serial port then this will re-appear
|
||||
after the soft reset.
|
||||
|
||||
This means some functions (like ``mpremote run``) that target the USB-CDC
|
||||
serial port will immediately fail if a runtime USB interface is active,
|
||||
@@ -45,9 +44,9 @@ device.
|
||||
no more runtime USB interface.
|
||||
|
||||
- To configure a runtime USB device on every boot, it's recommended to place the
|
||||
configuration code in the :ref:`boot.py` file on the :ref:`device VFS
|
||||
configuration code in the ``boot.py`` file on the :ref:`device VFS
|
||||
<filesystem>`. On each reset this file is executed before the USB subsystem is
|
||||
initialised (and before :ref:`main.py`), so it allows the board to come up with the runtime
|
||||
initialised (and before ``main.py``), so it allows the board to come up with the runtime
|
||||
USB device immediately.
|
||||
|
||||
- For development or debugging, it may be convenient to connect a hardware
|
||||
|
||||
@@ -11,6 +11,14 @@ and unrestricted access to and control of hardware blocks on a system
|
||||
malfunction, lockups, crashes of your board, and in extreme cases, hardware
|
||||
damage.
|
||||
|
||||
.. _machine_callbacks:
|
||||
|
||||
A note of callbacks used by functions and class methods of :mod:`machine` module:
|
||||
all these callbacks should be considered as executing in an interrupt context.
|
||||
This is true for both physical devices with IDs >= 0 and "virtual" devices
|
||||
with negative IDs like -1 (these "virtual" devices are still thin shims on
|
||||
top of real hardware and real hardware interrupts). See :ref:`isr_rules`.
|
||||
|
||||
Memory access
|
||||
-------------
|
||||
|
||||
@@ -54,13 +62,14 @@ Reset related functions
|
||||
|
||||
.. function:: reset()
|
||||
|
||||
:ref:`Hard resets <hard_reset>` the device in a manner similar to pushing the
|
||||
external RESET button.
|
||||
Resets the device in a manner similar to pushing the external RESET
|
||||
button.
|
||||
|
||||
.. function:: soft_reset()
|
||||
|
||||
Performs a :ref:`soft reset <soft_reset>` of the interpreter, deleting all
|
||||
Python objects and resetting the Python heap.
|
||||
Performs a soft reset of the interpreter, deleting all Python objects and
|
||||
resetting the Python heap. It tries to retain the method by which the user
|
||||
is connected to the MicroPython REPL (eg serial, USB, Wifi).
|
||||
|
||||
.. function:: reset_cause()
|
||||
|
||||
@@ -252,17 +261,13 @@ Classes
|
||||
machine.Signal.rst
|
||||
machine.ADC.rst
|
||||
machine.ADCBlock.rst
|
||||
machine.DAC.rst
|
||||
machine.PWM.rst
|
||||
machine.UART.rst
|
||||
machine.SPI.rst
|
||||
machine.I2C.rst
|
||||
machine.I2CTarget.rst
|
||||
machine.I2S.rst
|
||||
machine.RTC.rst
|
||||
machine.Timer.rst
|
||||
machine.Counter.rst
|
||||
machine.Encoder.rst
|
||||
machine.WDT.rst
|
||||
machine.SD.rst
|
||||
machine.SDCard.rst
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
:mod:`marshal` -- Python object serialization
|
||||
=============================================
|
||||
|
||||
.. module:: marshal
|
||||
:synopsis: Convert Python objects to and from a binary format
|
||||
|
||||
|see_cpython_module| :mod:`python:marshal`.
|
||||
|
||||
This module implements conversion between Python objects and a binary format.
|
||||
The format is specific to MicroPython but does not depend on the machine
|
||||
architecture, so the data can be transferred and used on a different MicroPython
|
||||
instance, as long as the version of the binary data matches (it's currently
|
||||
versioned as the mpy file version, see :ref:`mpy_files`).
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: dumps(value, /)
|
||||
|
||||
Convert the given *value* to binary format and return a corresponding ``bytes``
|
||||
object.
|
||||
|
||||
Currently, code objects are the only supported values that can be converted.
|
||||
|
||||
.. function:: loads(data, /)
|
||||
|
||||
Convert the given bytes-like *data* to its corresponding Python object, and
|
||||
return it.
|
||||
@@ -6,7 +6,7 @@ class LAN -- control an Ethernet module
|
||||
|
||||
This class allows you to control the Ethernet interface. The PHY hardware type is board-specific.
|
||||
|
||||
Example usage, for a board with built-in LAN support::
|
||||
Example usage::
|
||||
|
||||
import network
|
||||
nic = network.LAN(0)
|
||||
@@ -32,7 +32,7 @@ Constructors
|
||||
- *phy_addr* specifies the address of the PHY interface. As with *phy_type*, the hardwired value has
|
||||
to be used for most boards and that value is the default.
|
||||
- *ref_clk_mode* specifies, whether the data clock is provided by the Ethernet controller or
|
||||
the PHY interface.
|
||||
the PYH interface.
|
||||
The default value is the one that matches the board. If set to ``LAN.OUT`` or ``Pin.OUT``
|
||||
or ``True``, the clock is driven by the Ethernet controller, if set to ``LAN.IN``
|
||||
or ``Pin.IN`` or ``False``, the clock is driven by the PHY interface.
|
||||
@@ -41,9 +41,6 @@ Constructors
|
||||
|
||||
nic = LAN(0, phy_type=LAN.PHY_LAN8720, phy_addr=1, ref_clk_mode=Pin.IN)
|
||||
|
||||
.. note:: On esp32 port the constructor requires different arguments. See
|
||||
:ref:`esp32 port reference <esp32_network_lan>`.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
||||
@@ -5,12 +5,7 @@ class PPP -- create network connections over serial PPP
|
||||
=======================================================
|
||||
|
||||
This class allows you to create a network connection over a serial port using
|
||||
the PPP protocol.
|
||||
|
||||
.. note:: Currently only the esp32 port has PPP support enabled in the default
|
||||
firmware build. PPP support can be enabled in custom builds of the
|
||||
stm32 and rp2 ports by enabling networking support and setting
|
||||
``MICROPY_PY_NETWORK_PPP_LWIP`` to 1.
|
||||
the PPP protocol. It is only available on selected ports and boards.
|
||||
|
||||
Example usage::
|
||||
|
||||
@@ -75,11 +70,8 @@ Methods
|
||||
|
||||
.. method:: PPP.config(config_parameters)
|
||||
|
||||
Sets or gets parameters of the PPP interface. The only parameter that can be
|
||||
retrieved and set is the underlying stream, using::
|
||||
|
||||
stream = PPP.config("stream")
|
||||
PPP.config(stream=stream)
|
||||
Sets or gets parameters of the PPP interface. There are currently no parameter that
|
||||
can be set or retrieved.
|
||||
|
||||
.. method:: PPP.ipconfig('param')
|
||||
PPP.ipconfig(param=value, ...)
|
||||
|
||||
@@ -9,9 +9,6 @@ the W5200 and W5500 chipsets. The particular chipset that is supported
|
||||
by the firmware is selected at compile-time via the MICROPY_PY_NETWORK_WIZNET5K
|
||||
option.
|
||||
|
||||
.. note:: The esp32 port also supports WIZnet W5500 chipsets, but this port
|
||||
uses the :ref:`network.LAN interface <esp32_spi_ethernet>`.
|
||||
|
||||
Example usage::
|
||||
|
||||
import network
|
||||
|
||||
@@ -8,7 +8,7 @@ This class provides a driver for WiFi network processors. Example usage::
|
||||
|
||||
import network
|
||||
# enable station interface and connect to WiFi access point
|
||||
nic = network.WLAN(network.WLAN.IF_STA)
|
||||
nic = network.WLAN(network.STA_IF)
|
||||
nic.active(True)
|
||||
nic.connect('your-ssid', 'your-key')
|
||||
# now use sockets as usual
|
||||
@@ -18,8 +18,8 @@ Constructors
|
||||
.. class:: WLAN(interface_id)
|
||||
|
||||
Create a WLAN network interface object. Supported interfaces are
|
||||
``network.WLAN.IF_STA`` (station aka client, connects to upstream WiFi access
|
||||
points) and ``network.WLAN.IF_AP`` (access point, allows other WiFi clients to
|
||||
``network.STA_IF`` (station aka client, connects to upstream WiFi access
|
||||
points) and ``network.AP_IF`` (access point, allows other WiFi clients to
|
||||
connect). Availability of the methods below depends on interface type.
|
||||
For example, only STA interface may `WLAN.connect()` to an access point.
|
||||
|
||||
@@ -75,7 +75,7 @@ Methods
|
||||
Return the current status of the wireless connection.
|
||||
|
||||
When called with no argument the return value describes the network link status.
|
||||
The possible statuses are defined as constants in the :mod:`network` module:
|
||||
The possible statuses are defined as constants:
|
||||
|
||||
* ``STAT_IDLE`` -- no connection and no activity,
|
||||
* ``STAT_CONNECTING`` -- connecting in progress,
|
||||
@@ -85,18 +85,7 @@ Methods
|
||||
* ``STAT_GOT_IP`` -- connection successful.
|
||||
|
||||
When called with one argument *param* should be a string naming the status
|
||||
parameter to retrieve, and different parameters are supported depending on the
|
||||
mode the WiFi is in.
|
||||
|
||||
In STA mode, passing ``'rssi'`` returns a signal strength indicator value, whose
|
||||
format varies depending on the port (this is available on all ports that support
|
||||
WiFi network interfaces, except for CC3200).
|
||||
|
||||
In AP mode, passing ``'stations'`` returns a list of connected WiFi stations
|
||||
(this is available on all ports that support WiFi network interfaces, except for
|
||||
CC3200). The format of the station information entries varies across ports,
|
||||
providing either the raw BSSID of the connected station, the IP address of the
|
||||
connected station, or both.
|
||||
parameter to retrieve. Supported parameters in WiFI STA mode are: ``'rssi'``.
|
||||
|
||||
.. method:: WLAN.isconnected()
|
||||
|
||||
@@ -137,7 +126,7 @@ Methods
|
||||
============= ===========
|
||||
mac MAC address (bytes)
|
||||
ssid WiFi access point name (string)
|
||||
channel WiFi channel (integer). Depending on the port this may only be supported on the AP interface.
|
||||
channel WiFi channel (integer)
|
||||
hidden Whether SSID is hidden (boolean)
|
||||
security Security protocol supported (enumeration, see module constants)
|
||||
key Access key (string)
|
||||
@@ -145,7 +134,6 @@ Methods
|
||||
reconnects Number of reconnect attempts to make (integer, 0=none, -1=unlimited)
|
||||
txpower Maximum transmit power in dBm (integer or float)
|
||||
pm WiFi Power Management setting (see below for allowed values)
|
||||
protocol (ESP32 Only.) WiFi Low level 802.11 protocol. See `WLAN.PROTOCOL_DEFAULTS`.
|
||||
============= ===========
|
||||
|
||||
Constants
|
||||
@@ -162,34 +150,3 @@ Constants
|
||||
* ``PM_POWERSAVE``: enable WiFi power management with additional power
|
||||
savings and reduced WiFi performance
|
||||
* ``PM_NONE``: disable wifi power management
|
||||
|
||||
|
||||
ESP32 Protocol Constants
|
||||
------------------------
|
||||
|
||||
The following ESP32-only constants relate to the ``WLAN.config(protocol=...)``
|
||||
network interface parameter:
|
||||
|
||||
.. data:: WLAN.PROTOCOL_DEFAULTS
|
||||
|
||||
A bitmap representing all of the default 802.11 Wi-Fi modes supported by
|
||||
the chip. Consult `ESP-IDF Wi-Fi Protocols`_ documentation for details.
|
||||
|
||||
.. data:: WLAN.PROTOCOL_LR
|
||||
|
||||
This value corresponds to the `Espressif proprietary "long-range" mode`_,
|
||||
which is not compatible with standard Wi-Fi devices. By setting this
|
||||
protocol it's possible for an ESP32 STA in long-range mode to connect to
|
||||
an ESP32 AP in long-range mode, or to use `ESP-NOW long range modes
|
||||
<espnow-long-range>`.
|
||||
|
||||
This mode can be bitwise ORed with some standard 802.11 protocol bits
|
||||
(including `WLAN.PROTOCOL_DEFAULTS`) in order to support a mix of standard
|
||||
Wi-Fi modes as well as LR mode, consult the `Espressif long-range
|
||||
documentation`_ for more details.
|
||||
|
||||
Long range mode is not supported on ESP32-C2.
|
||||
|
||||
.. _ESP-IDF Wi-Fi Protocols: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/wifi.html#wi-fi-protocol-mode
|
||||
.. _Espressif proprietary "long-range" mode:
|
||||
.. _Espressif long-range documentation: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/wifi.html#long-range-lr
|
||||
|
||||
@@ -55,9 +55,10 @@ Filesystem access
|
||||
directories and 0x8000 for regular files;
|
||||
- *inode* is an integer corresponding to the inode of the file, and may be 0
|
||||
for filesystems that don't have such a notion.
|
||||
- *size* is an integer that may be included depending on the filesystem type.
|
||||
For file entries, *size* represents the size of the file or -1 if unknown.
|
||||
Its meaning is currently undefined for directory entries.
|
||||
- Some platforms may return a 4-tuple that includes the entry's *size*. For
|
||||
file entries, *size* is an integer representing the size of the file
|
||||
or -1 if unknown. Its meaning is currently undefined for directory
|
||||
entries.
|
||||
|
||||
.. function:: listdir([dir])
|
||||
|
||||
@@ -132,37 +133,6 @@ Terminal redirection and duplication
|
||||
|
||||
The function returns the previous stream-like object in the given slot.
|
||||
|
||||
.. function:: dupterm_notify(obj_in, /)
|
||||
|
||||
Notify the MicroPython REPL that input is available on a stream-like object
|
||||
previously registered via `os.dupterm()`.
|
||||
|
||||
This function should be called by custom stream implementations (e.g., UART,
|
||||
Bluetooth, or other non-USB REPL streams) to inform the REPL that input is
|
||||
ready to be read. Proper use ensures that special characters such as
|
||||
Ctrl+C (used to trigger KeyboardInterrupt) are processed promptly by the
|
||||
REPL, enabling expected interruption behavior for user code.
|
||||
|
||||
The *obj_in* parameter is ignored by `os.dupterm_notify()`, but is required to allow calling
|
||||
dupterm_notify from an interrupt handler such as `UART.irq()`.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from machine import UART
|
||||
import os
|
||||
uart = UART(0)
|
||||
os.dupterm(uart, 0)
|
||||
uart.irq(os.dupterm_notify, machine.UART.IRQ_RX)
|
||||
|
||||
.. note::
|
||||
If the ``dupterm_notify()`` function is not called, input from the custom stream
|
||||
may not be detected or processed until the next REPL poll, potentially delaying
|
||||
KeyboardInterrupts or other control signals.
|
||||
This is especially important for UART, Bluetooth and other
|
||||
non-standard REPL connections, where automatic notification is not guaranteed.
|
||||
|
||||
Filesystem mounting
|
||||
-------------------
|
||||
|
||||
|
||||
@@ -36,11 +36,3 @@ Functions
|
||||
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.
|
||||
|
||||
.. function:: processor()
|
||||
|
||||
Returns a string with a detailed name of the processor, if one is available.
|
||||
If no name for the processor is known, it will return an empty string
|
||||
instead.
|
||||
|
||||
This is currently available only on RISC-V targets (both 32 and 64 bits).
|
||||
|
||||
@@ -67,17 +67,11 @@ Methods
|
||||
:meth:`~CAN.restart()` can be used to leave the bus-off state
|
||||
- *baudrate* if a baudrate other than 0 is provided, this function will try to automatically
|
||||
calculate the CAN nominal bit time (overriding *prescaler*, *bs1* and *bs2*) that satisfies
|
||||
both the *baudrate* (within .1%) and the desired *sample_point* (to the nearest 1%). For more precise
|
||||
control over the CAN timing, set the *prescaler*, *bs1* and *bs2* parameters directly.
|
||||
- *sample_point* specifies the position of the bit sample with respect to the whole nominal bit time,
|
||||
expressed as an integer percentage of the nominal bit time. The default *sample_point* is 75%.
|
||||
This parameter is ignored unless *baudrate* is set.
|
||||
both the baudrate and the desired *sample_point*.
|
||||
- *sample_point* given in a percentage of the nominal bit time, the *sample_point* specifies the position
|
||||
of the bit sample with respect to the whole nominal bit time. The default *sample_point* is 75%.
|
||||
- *num_filter_banks* for classic CAN, this is the number of banks that will be assigned to CAN(1),
|
||||
the rest of the 28 are assigned to CAN(2).
|
||||
|
||||
The remaining parameters are only present on boards with CAN FD support, and configure the optional CAN FD
|
||||
Bit Rate Switch (BRS) feature:
|
||||
|
||||
- *brs_prescaler* is the value by which the CAN FD input clock is divided to generate the
|
||||
data bit time quanta. The prescaler can be a value between 1 and 32 inclusive.
|
||||
- *brs_sjw* is the resynchronisation jump width in units of time quanta for data bits;
|
||||
@@ -88,11 +82,10 @@ Methods
|
||||
it can be a value between 1 and 16 inclusive
|
||||
- *brs_baudrate* if a baudrate other than 0 is provided, this function will try to automatically
|
||||
calculate the CAN data bit time (overriding *brs_prescaler*, *brs_bs1* and *brs_bs2*) that satisfies
|
||||
both the *brs_baudrate* (within .1%) and the desired *brs_sample_point* (to the nearest 1%). For more
|
||||
precise control over the BRS timing, set the *brs_prescaler*, *brs_bs1* and *brs_bs2* parameters directly.
|
||||
- *brs_sample_point* specifies the position of the bit sample with respect to the whole nominal bit time,
|
||||
expressed as an integer percentage of the nominal bit time. The default *brs_sample_point* is 75%.
|
||||
This parameter is ignored unless *brs_baudrate* is set.
|
||||
both the baudrate and the desired *brs_sample_point*.
|
||||
- *brs_sample_point* given in a percentage of the data bit time, the *brs_sample_point* specifies the position
|
||||
of the bit sample with respect to the whole data bit time. The default *brs_sample_point* is 75%.
|
||||
|
||||
|
||||
The time quanta tq is the basic unit of time for the CAN bus. tq is the CAN
|
||||
prescaler value divided by PCLK1 (the frequency of internal peripheral bus 1);
|
||||
|
||||
@@ -62,7 +62,7 @@ Constructors
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Timer.init(*, freq, prescaler, period, mode=Timer.UP, div=1, callback=None, deadtime=0, brk=Timer.BRK_OFF, hard=True)
|
||||
.. method:: Timer.init(*, freq, prescaler, period, mode=Timer.UP, div=1, callback=None, deadtime=0, brk=Timer.BRK_OFF)
|
||||
|
||||
Initialise the timer. Initialisation must be either by frequency (in Hz)
|
||||
or by prescaler and period::
|
||||
@@ -115,18 +115,6 @@ Methods
|
||||
``mode=Pin.ALT, alt=Pin.AFn_TIMx``. The pin's GPIO input features are
|
||||
available in alt mode - ``pull=`` , ``value()`` and ``irq()``.
|
||||
|
||||
- ``hard`` can be one of:
|
||||
|
||||
- ``True`` - The callback will be executed in hard interrupt
|
||||
context, which minimises delay and jitter but is subject to the
|
||||
limitations described in :ref:`isr_rules` including being unable
|
||||
to allocate on the heap.
|
||||
- ``False`` - The callback will be scheduled as a soft interrupt,
|
||||
allowing it to allocate but possibly also introducing
|
||||
garbage-collection delays and jitter.
|
||||
|
||||
The default value of this option is True.
|
||||
|
||||
You must either specify freq or both of period and prescaler.
|
||||
|
||||
.. method:: Timer.deinit()
|
||||
@@ -175,7 +163,7 @@ Methods
|
||||
- ``callback`` - as per TimerChannel.callback()
|
||||
|
||||
- ``pin`` None (the default) or a Pin object. If specified (and not None)
|
||||
this will cause the alternate function of the indicated pin
|
||||
this will cause the alternate function of the the indicated pin
|
||||
to be configured for this timer channel. An error will be raised if
|
||||
the pin doesn't support any alternate functions for this timer channel.
|
||||
|
||||
|
||||
@@ -147,10 +147,10 @@ Power related functions
|
||||
(internal oscillator) directly. The higher frequencies use the HSE to
|
||||
drive the PLL (phase locked loop), and then use the output of the PLL.
|
||||
|
||||
Note that if you change the frequency while the USB is enabled then the USB
|
||||
may become unreliable. It is best to change the frequency in :ref:`boot.py`,
|
||||
before the USB peripheral is started. Also note that sysclk frequencies below
|
||||
36MHz do not allow the USB to function correctly.
|
||||
Note that if you change the frequency while the USB is enabled then
|
||||
the USB may become unreliable. It is best to change the frequency
|
||||
in boot.py, before the USB peripheral is started. Also note that sysclk
|
||||
frequencies below 36MHz do not allow the USB to function correctly.
|
||||
|
||||
.. function:: wfi()
|
||||
|
||||
@@ -205,9 +205,8 @@ Miscellaneous functions
|
||||
|
||||
.. function:: main(filename)
|
||||
|
||||
Set the filename of the main script to run after :ref:`boot.py` is finished.
|
||||
If this function is not called then the default file :ref:`main.py` will be
|
||||
executed.
|
||||
Set the filename of the main script to run after boot.py is finished. If
|
||||
this function is not called then the default file main.py will be executed.
|
||||
|
||||
It only makes sense to call this function from within boot.py.
|
||||
|
||||
|
||||
@@ -154,8 +154,8 @@ Regex objects
|
||||
Compiled regular expression. Instances of this class are created using
|
||||
`re.compile()`.
|
||||
|
||||
.. method:: regex.match(string, [pos, [endpos]])
|
||||
regex.search(string, [pos, [endpos]])
|
||||
.. method:: regex.match(string)
|
||||
regex.search(string)
|
||||
regex.sub(replace, string, count=0, flags=0, /)
|
||||
|
||||
Similar to the module-level functions :meth:`match`, :meth:`search`
|
||||
@@ -163,16 +163,6 @@ Compiled regular expression. Instances of this class are created using
|
||||
Using methods is (much) more efficient if the same regex is applied to
|
||||
multiple strings.
|
||||
|
||||
The optional second parameter *pos* gives an index in the string where the
|
||||
search is to start; it defaults to ``0``. This is not completely equivalent
|
||||
to slicing the string; the ``'^'`` pattern character matches at the real
|
||||
beginning of the string and at positions just after a newline, but not
|
||||
necessarily at the index where the search is to start.
|
||||
|
||||
The optional parameter *endpos* limits how far the string will be searched;
|
||||
it will be as if the string is *endpos* characters long, so only the
|
||||
characters from *pos* to ``endpos - 1`` will be searched for a match.
|
||||
|
||||
.. method:: regex.split(string, max_split=-1, /)
|
||||
|
||||
Split a *string* using regex. If *max_split* is given, it specifies
|
||||
|
||||
@@ -58,11 +58,6 @@ Methods
|
||||
- *pull_thresh* is the threshold in bits before auto-pull or conditional
|
||||
re-pulling is triggered.
|
||||
|
||||
Note: pins used for *in_base* need to be configured manually for input (or
|
||||
otherwise) so that the PIO can see the desired signal (they could be input
|
||||
pins, output pins, or connected to a different peripheral). The *jmp_pin*
|
||||
can also be configured manually, but by default will be an input pin.
|
||||
|
||||
.. method:: StateMachine.active([value])
|
||||
|
||||
Gets or sets whether the state machine is currently running.
|
||||
|
||||
@@ -23,7 +23,7 @@ The ``rp2`` module includes functions for assembling PIO programs.
|
||||
|
||||
For running PIO programs, see :class:`rp2.StateMachine`.
|
||||
|
||||
.. function:: asm_pio(*, out_init=None, set_init=None, sideset_init=None, side_pindir=False, in_shiftdir=PIO.SHIFT_LEFT, out_shiftdir=PIO.SHIFT_LEFT, autopush=False, autopull=False, push_thresh=32, pull_thresh=32, fifo_join=PIO.JOIN_NONE)
|
||||
.. function:: asm_pio(*, out_init=None, set_init=None, sideset_init=None, in_shiftdir=0, out_shiftdir=0, autopush=False, autopull=False, push_thresh=32, pull_thresh=32, fifo_join=PIO.JOIN_NONE)
|
||||
|
||||
Assemble a PIO program.
|
||||
|
||||
@@ -35,10 +35,8 @@ For running PIO programs, see :class:`rp2.StateMachine`.
|
||||
- *out_init* configures the pins used for ``out()`` instructions.
|
||||
- *set_init* configures the pins used for ``set()`` instructions. There can
|
||||
be at most 5.
|
||||
- *sideset_init* configures the pins used for ``.side()`` modifiers. There
|
||||
can be at most 5.
|
||||
- *side_pindir* when set to ``True`` configures ``.side()`` modifiers to be
|
||||
used for pin directions, instead of pin values (the default, when ``False``).
|
||||
- *sideset_init* configures the pins used side-setting. There can be at
|
||||
most 5.
|
||||
|
||||
The following parameters are used by default, but can be overridden in
|
||||
`StateMachine.init()`:
|
||||
|
||||
@@ -227,28 +227,22 @@ Methods
|
||||
has the same "no short writes" policy for blocking sockets, and will return
|
||||
number of bytes sent on non-blocking sockets.
|
||||
|
||||
.. method:: socket.recv(bufsize, [flags])
|
||||
.. method:: socket.recv(bufsize)
|
||||
|
||||
Receive data from the socket. The return value is a bytes object representing the data
|
||||
received. The maximum amount of data to be received at once is specified by bufsize.
|
||||
|
||||
Most ports support the optional *flags* argument. Available *flags* are defined as constants
|
||||
in the socket module and have the same meaning as in CPython. ``MSG_PEEK`` and ``MSG_DONTWAIT``
|
||||
are supported on all ports which accept the *flags* argument.
|
||||
|
||||
.. method:: socket.sendto(bytes, address)
|
||||
|
||||
Send data to the socket. The socket should not be connected to a remote socket, since the
|
||||
destination socket is specified by *address*.
|
||||
|
||||
.. method:: socket.recvfrom(bufsize, [flags])
|
||||
.. method:: socket.recvfrom(bufsize)
|
||||
|
||||
Receive data from the socket. The return value is a pair *(bytes, address)* where *bytes* is a
|
||||
bytes object representing the data received and *address* is the address of the socket sending
|
||||
the data.
|
||||
|
||||
See the `recv` function for an explanation of the optional *flags* argument.
|
||||
|
||||
.. method:: socket.setsockopt(level, optname, value)
|
||||
|
||||
Set the value of the given socket option. The needed symbolic constants are defined in the
|
||||
|
||||
@@ -66,7 +66,7 @@ class SSLContext
|
||||
Set the available ciphers for sockets created with this context. *ciphers* should be
|
||||
a list of strings in the `IANA cipher suite format <https://wiki.mozilla.org/Security/Cipher_Suites>`_ .
|
||||
|
||||
.. method:: SSLContext.wrap_socket(sock, *, server_side=False, do_handshake_on_connect=True, server_hostname=None, client_id=None)
|
||||
.. 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, wrapping the underlying stream.
|
||||
@@ -89,9 +89,6 @@ class SSLContext
|
||||
server certificate. It also sets the name for Server Name Indication (SNI), allowing the server
|
||||
to present the proper certificate.
|
||||
|
||||
- *client_id* is a MicroPython-specific extension argument used only when implementing a DTLS
|
||||
Server. See :ref:`dtls` for details.
|
||||
|
||||
.. warning::
|
||||
|
||||
Some implementations of ``ssl`` module do NOT validate server certificates,
|
||||
@@ -120,65 +117,11 @@ Exceptions
|
||||
|
||||
This exception does NOT exist. Instead its base class, OSError, is used.
|
||||
|
||||
.. _dtls:
|
||||
|
||||
DTLS support
|
||||
------------
|
||||
|
||||
.. admonition:: Difference to CPython
|
||||
:class: attention
|
||||
|
||||
This is a MicroPython extension.
|
||||
|
||||
On most ports, this module supports DTLS in client and server mode via the
|
||||
`PROTOCOL_DTLS_CLIENT` and `PROTOCOL_DTLS_SERVER` constants that can be used as
|
||||
the ``protocol`` argument of `SSLContext`.
|
||||
|
||||
In this case the underlying socket is expected to behave as a datagram socket (i.e.
|
||||
like the socket opened with ``socket.socket`` with ``socket.AF_INET`` as ``af`` and
|
||||
``socket.SOCK_DGRAM`` as ``type``).
|
||||
|
||||
DTLS is only supported on ports that use mbedTLS, and it is enabled by default
|
||||
in most configurations but can be manually disabled by defining
|
||||
``MICROPY_PY_SSL_DTLS`` to 0.
|
||||
|
||||
DTLS server support
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
MicroPython's DTLS server support is configured with "Hello Verify" as required
|
||||
for DTLS 1.2. This is transparent for DTLS clients, but there are relevant
|
||||
considerations when implementing a DTLS server in MicroPython:
|
||||
|
||||
- The server should pass an additional argument *client_id* when calling
|
||||
`SSLContext.wrap_socket()`. This ID must be a `bytes` object (or similar) with
|
||||
a transport-specific identifier representing the client.
|
||||
|
||||
The simplest approach is to convert the tuple of ``(client_ip, client_port)``
|
||||
returned from ``socket.recv_from()`` into a byte string, i.e.::
|
||||
|
||||
_, client_addr = sock.recvfrom(1, socket.MSG_PEEK)
|
||||
sock.connect(client_addr) # Connect back to the client
|
||||
sock = ssl_ctx.wrap_socket(sock, server_side=True,
|
||||
client_id=repr(client_addr).encode())
|
||||
|
||||
- The first time a client connects, the server call to ``wrap_socket`` will fail
|
||||
with a `OSError` error "Hello Verify Required". This is because the DTLS
|
||||
"Hello Verify" cookie is not yet known by the client. If the same client
|
||||
connects a second time then ``wrap_socket`` will succeed.
|
||||
|
||||
- DTLS cookies for "Hello Verify" are associated with the `SSLContext` object,
|
||||
so the same `SSLContext` object should be used to wrap a subsequent connection
|
||||
from the same client. The cookie implementation includes a timeout and has
|
||||
constant memory use regardless of how many clients connect, so it's OK to
|
||||
reuse the same `SSLContext` object for the lifetime of the server.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: ssl.PROTOCOL_TLS_CLIENT
|
||||
ssl.PROTOCOL_TLS_SERVER
|
||||
ssl.PROTOCOL_DTLS_CLIENT (when DTLS support is enabled)
|
||||
ssl.PROTOCOL_DTLS_SERVER (when DTLS support is enabled)
|
||||
|
||||
Supported values for the *protocol* parameter.
|
||||
|
||||
|
||||
@@ -12,12 +12,9 @@ Functions
|
||||
.. function:: exit(retval=0, /)
|
||||
|
||||
Terminate current program with a given exit code. Underlyingly, this
|
||||
function raises a `SystemExit` exception. If an argument is given, its
|
||||
function raise as `SystemExit` exception. If an argument is given, its
|
||||
value given as an argument to `SystemExit`.
|
||||
|
||||
On embedded ports (i.e. all ports but Windows and Unix), an unhandled
|
||||
`SystemExit` currently causes a :ref:`soft_reset` of MicroPython.
|
||||
|
||||
.. function:: atexit(func)
|
||||
|
||||
Register *func* to be called upon termination. *func* must be a callable
|
||||
@@ -75,10 +72,6 @@ Constants
|
||||
* *version* - tuple (major, minor, micro, releaselevel), e.g. (1, 22, 0, '')
|
||||
* *_machine* - string describing the underlying machine
|
||||
* *_mpy* - supported mpy file-format version (optional attribute)
|
||||
* *_build* - string that can help identify the configuration that
|
||||
MicroPython was built with
|
||||
* *_thread* - optional string attribute, exists if the target has threading
|
||||
and is either "GIL" or "unsafe"
|
||||
|
||||
This object is the recommended way to distinguish MicroPython from other
|
||||
Python implementations (note that it still may not exist in the very
|
||||
@@ -87,24 +80,6 @@ Constants
|
||||
Starting with version 1.22.0-preview, the fourth node *releaselevel* in
|
||||
*implementation.version* is either an empty string or ``"preview"``.
|
||||
|
||||
The *_build* entry was added in version 1.25.0 and is a hyphen-separated
|
||||
set of elements. New elements may be appended in the future so it's best to
|
||||
access this field using ``sys.implementation._build.split("-")``. The
|
||||
elements that are currently used are:
|
||||
|
||||
* On the unix, webassembly and windows ports the first element is the variant
|
||||
name, for example ``'standard'``.
|
||||
* On microcontroller targets, the first element is the board name and the second
|
||||
element (if present) is the board variant, for example ``'RPI_PICO2-RISCV'``
|
||||
|
||||
The *_thread* entry was added in version 1.26.0 and if it exists then the
|
||||
target has the ``_thread`` module. If the target enables the GIL (global
|
||||
interpreter lock) then this attribute is ``"GIL"``. Otherwise the attribute
|
||||
is ``"unsafe"`` and the target has threading but does not enable the GIL,
|
||||
and mutable Python objects (such as `bytearray`, `list` and `dict`) that are
|
||||
shared amongst threads must be protected explicitly by locks such as
|
||||
``_thread.allocate_lock``.
|
||||
|
||||
.. admonition:: Difference to CPython
|
||||
:class: attention
|
||||
|
||||
|
||||
@@ -9,10 +9,9 @@
|
||||
The ``time`` module provides functions for getting the current time and date,
|
||||
measuring time intervals, and for delays.
|
||||
|
||||
**Time Epoch**: The unix, windows, webassembly, alif, mimxrt and rp2 ports
|
||||
use the standard for POSIX systems epoch of 1970-01-01 00:00:00 UTC.
|
||||
The other embedded ports use an epoch of 2000-01-01 00:00:00 UTC.
|
||||
Epoch year may be determined with ``gmtime(0)[0]``.
|
||||
**Time Epoch**: Unix port uses standard for POSIX systems epoch of
|
||||
1970-01-01 00:00:00 UTC. However, some embedded ports use epoch of
|
||||
2000-01-01 00:00:00 UTC. Epoch year may be determined with ``gmtime(0)[0]``.
|
||||
|
||||
**Maintaining actual calendar date/time**: This requires a
|
||||
Real Time Clock (RTC). On systems with underlying OS (including some
|
||||
@@ -58,11 +57,11 @@ Functions
|
||||
* weekday is 0-6 for Mon-Sun
|
||||
* yearday is 1-366
|
||||
|
||||
.. function:: mktime(date_time_tuple)
|
||||
.. function:: mktime()
|
||||
|
||||
This is inverse function of localtime. It's argument is a full 8-tuple
|
||||
which expresses a time as per localtime. It returns an integer which is
|
||||
the number of seconds since the time epoch.
|
||||
the number of seconds since Jan 1, 2000.
|
||||
|
||||
.. function:: sleep(seconds)
|
||||
|
||||
|
||||
@@ -34,14 +34,6 @@ represented by VFS classes.
|
||||
|
||||
Will raise ``OSError(EPERM)`` if *mount_point* is already mounted.
|
||||
|
||||
.. function:: mount()
|
||||
:noindex:
|
||||
|
||||
With no arguments to :func:`mount`, return a list of tuples representing
|
||||
all active mountpoints.
|
||||
|
||||
The returned list has the form *[(fsobj, mount_point), ...]*.
|
||||
|
||||
.. function:: umount(mount_point)
|
||||
|
||||
Unmount a filesystem. *mount_point* can be a string naming the mount location,
|
||||
|
||||
@@ -358,13 +358,13 @@ Run WM8960 on a MIMXRT10xx_DEV board in secondary mode (default)::
|
||||
sysclk_source=wm8960.SYSCLK_MCLK)
|
||||
|
||||
|
||||
Record with a SparkFun WM8960 breakout board with Teensy in secondary mode (default)::
|
||||
Record with a Sparkfun WM8960 breakout board with Teensy in secondary mode (default)::
|
||||
|
||||
# Micro_python WM8960 Codec driver
|
||||
#
|
||||
# The breakout board uses a fixed 24MHz MCLK. Therefore the internal
|
||||
# PLL must be used as sysclk, which is the master audio clock.
|
||||
# The SparkFun board has the WS pins for RX and TX connected on the
|
||||
# The Sparkfun board has the WS pins for RX and TX connected on the
|
||||
# board. Therefore adc_sync must be set to sync_adc, to configure
|
||||
# it's ADCLRC pin as input.
|
||||
#
|
||||
@@ -379,11 +379,11 @@ Record with a SparkFun WM8960 breakout board with Teensy in secondary mode (defa
|
||||
right_input=wm8960.INPUT_CLOSED)
|
||||
|
||||
|
||||
Play with a SparkFun WM8960 breakout board with Teensy in secondary mode (default)::
|
||||
Play with a Sparkfun WM8960 breakout board with Teensy in secondary mode (default)::
|
||||
|
||||
# The breakout board uses a fixed 24MHz MCLK. Therefore the internal
|
||||
# PLL must be used as sysclk, which is the master audio clock.
|
||||
# The SparkFun board has the WS pins for RX and TX connected on the
|
||||
# The Sparkfun board has the WS pins for RX and TX connected on the
|
||||
# board. Therefore adc_sync must be set to sync_adc, to configure
|
||||
# it's ADCLRC pin as input.
|
||||
|
||||
|
||||
@@ -22,10 +22,9 @@ Functions
|
||||
|
||||
Returns the thread id of the current thread, which is used to reference the thread.
|
||||
|
||||
.. function:: thread_analyze(cpu)
|
||||
.. function:: thread_analyze()
|
||||
|
||||
Runs the Zephyr debug thread analyzer on the current thread on the given cpu
|
||||
and prints stack size statistics in the format:
|
||||
Runs the Zephyr debug thread analyzer on the current thread and prints stack size statistics in the format:
|
||||
|
||||
"``thread_name``-20s: STACK: unused ``available_stack_space`` usage ``stack_space_used``
|
||||
/ ``stack_size`` (``percent_stack_space_used`` %); CPU: ``cpu_utilization`` %"
|
||||
@@ -36,9 +35,6 @@ Functions
|
||||
For more information, see documentation for Zephyr `thread analyzer
|
||||
<https://docs.zephyrproject.org/latest/guides/debug_tools/thread-analyzer.html#thread-analyzer>`_.
|
||||
|
||||
Note that the ``cpu`` argument is only used in Zephyr v4.0.0 and
|
||||
newer and ignored otherwise.
|
||||
|
||||
.. function:: shell_exec(cmd_in)
|
||||
|
||||
Executes the given command on an UART backend. This function can only be accessed if ``CONFIG_SHELL_BACKEND_SERIAL``
|
||||
|
||||
@@ -20,8 +20,7 @@ See Zephyr documentation for sensor usage here: `Sensors
|
||||
Sensors are defined in the Zephyr devicetree for each board. The quantities that a given sensor can
|
||||
measure are called a sensor channels. Sensors can have multiple channels to represent different axes
|
||||
of one property or different properties a sensor can measure. See `Channels`_ below for defined sensor
|
||||
channels. Each channel may have multiple attributes that can be changed and/or queried.
|
||||
See `Channel Attributes`_ below for defined sensor channel attributes.
|
||||
channels.
|
||||
|
||||
Constructor
|
||||
~~~~~~~~~~~
|
||||
@@ -60,36 +59,6 @@ Methods
|
||||
Returns only the integer value of the measurement sample.
|
||||
(Ex. value of ``(1, 500000)`` returns as ``1``)
|
||||
|
||||
.. method:: Sensor.attr_set(sensor_channel, channel_attribute, val1, [val2])
|
||||
|
||||
Set the given channel's attribute to the given value.
|
||||
``val1`` may be a float, in which case ``val2`` is not given, or
|
||||
``val1`` can be used for the value's
|
||||
integer part and ``val2`` for the value's fractional part in millionths.
|
||||
|
||||
Returns ``None`` if successful, or raises ``OSError``.
|
||||
|
||||
.. method:: Sensor.attr_get_float(sensor_channel, channel_attribute)
|
||||
|
||||
Returns the value of the sensor channel's attribute as a float.
|
||||
|
||||
Many sensors do not support this or any other of the ``attr_get`` methods.
|
||||
|
||||
.. method:: Sensor.attr_get_micros(sensor_channel, channel_attribute)
|
||||
|
||||
Returns the value of the sensor channel's attribute in millionths.
|
||||
(Ex. value of ``(1, 500000)`` returns as ``1500000``)
|
||||
|
||||
.. method:: Sensor.attr_get_millis(sensor_channel, channel_attribute)
|
||||
|
||||
Returns the value of the sensor channel's attribute in thousandths.
|
||||
(Ex. value of ``(1, 500000)`` returns as ``1500``)
|
||||
|
||||
.. method:: Sensor.attr_get_int(sensor_channel, channel_attribute)
|
||||
|
||||
Returns only the integer value of the channel's attribute.
|
||||
(Ex. value of ``(1, 500000)`` returns as ``1``)
|
||||
|
||||
Channels
|
||||
~~~~~~~~
|
||||
|
||||
@@ -105,11 +74,6 @@ Channels
|
||||
|
||||
Acceleration on the Z axis, in m/s^2.
|
||||
|
||||
.. data:: ACCEL_XYZ
|
||||
|
||||
Pseudo-channel representing all three accelerometer axes.
|
||||
Used for :meth:`Sensor.attr_set` and the ``Sensor.attr_get_xxx()`` methods.
|
||||
|
||||
.. data:: GYRO_X
|
||||
|
||||
Angular velocity around the X axis, in radians/s.
|
||||
@@ -122,11 +86,6 @@ Channels
|
||||
|
||||
Angular velocity around the Z axis, in radians/s.
|
||||
|
||||
.. data:: GYRO_XYZ
|
||||
|
||||
Pseudo-channel representing all three gyroscope axes.
|
||||
Used for :meth:`Sensor.attr_set` and the ``Sensor.attr_get_xxx()`` methods.
|
||||
|
||||
.. data:: MAGN_X
|
||||
|
||||
Magnetic field on the X axis, in Gauss.
|
||||
@@ -162,73 +121,3 @@ Channels
|
||||
.. data:: ALTITUDE
|
||||
|
||||
Altitude, in meters.
|
||||
|
||||
Channel Attributes
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. data:: ATTR_SAMPLING_FREQUENCY
|
||||
|
||||
Sensor sampling frequency, i.e. how many times a second the sensor takes a measurement.
|
||||
|
||||
.. data:: ATTR_LOWER_THRESH
|
||||
|
||||
Lower threshold for trigger.
|
||||
|
||||
.. data:: ATTR_UPPER_THRESH
|
||||
|
||||
Upper threshold for trigger.
|
||||
|
||||
.. data:: ATTR_SLOPE_TH
|
||||
|
||||
Threshold for any-motion (slope) trigger.
|
||||
|
||||
.. data:: ATTR_SLOPE_DUR
|
||||
|
||||
Duration for which the slope values needs to be outside the threshold for the trigger to fire.
|
||||
|
||||
.. data:: ATTR_HYSTERESIS
|
||||
|
||||
.. data:: ATTR_OVERSAMPLING
|
||||
|
||||
Oversampling factor.
|
||||
|
||||
.. data:: ATTR_FULL_SCALE
|
||||
|
||||
Sensor range, in SI units.
|
||||
|
||||
.. data:: ATTR_OFFSET
|
||||
|
||||
The sensor value returned will be altered by the amount indicated by offset: final_value = sensor_value + offset.
|
||||
|
||||
.. data:: ATTR_CALIB_TARGET
|
||||
|
||||
Calibration target. This will be used by the internal chip's algorithms to calibrate itself on a certain axis, or all of them.
|
||||
|
||||
.. data:: ATTR_CONFIGURATION
|
||||
|
||||
Configure the operating modes of a sensor.
|
||||
|
||||
.. data:: ATTR_CALIBRATION
|
||||
|
||||
Set a calibration value needed by a sensor.
|
||||
|
||||
.. data:: ATTR_FEATURE_MASK
|
||||
|
||||
Enable/disable sensor features.
|
||||
|
||||
.. data:: ATTR_ALERT
|
||||
|
||||
Alert threshold or alert enable/disable.
|
||||
|
||||
.. data:: ATTR_FF_DUR
|
||||
|
||||
Free-fall duration represented in milliseconds.
|
||||
If the sampling frequency is changed during runtime, this attribute should be set to adjust freefall duration to the new sampling frequency.
|
||||
|
||||
.. data:: ATTR_BATCH_DURATION
|
||||
|
||||
Hardware batch duration in ticks.
|
||||
|
||||
.. data:: ATTR_GAIN
|
||||
|
||||
.. data:: ATTR_RESOLUTION
|
||||
|
||||
@@ -5,10 +5,7 @@ Pinout for the i.MXRT machine modules
|
||||
|
||||
.. _mimxrt_uart_pinout:
|
||||
|
||||
The Teensy 4.0 and 4.1 board show pin numbers **nn** at the board's silkscreen.
|
||||
These are denoted in the tables below as **Dnn**. E.g. a silkscreen number **1** is
|
||||
shown as **D1**. Whenever a Pin has to be specified in a script, **Dnn** must
|
||||
be used, not **nn**.
|
||||
|
|
||||
|
||||
UART pin assignment
|
||||
-------------------
|
||||
@@ -20,8 +17,8 @@ tables below:
|
||||
================= =========== =========== =========== ===========
|
||||
Board / Pin UART0 UART1 UART2 UART3
|
||||
================= =========== =========== =========== ===========
|
||||
Teensy 4.0 - D0/D1 D7/D8 D14/D15
|
||||
Teensy 4.1 - D0/D1 D7/D8 D14/D15
|
||||
Teensy 4.0 - 0/1 7/8 14/15
|
||||
Teensy 4.1 - 0/1 7/8 14/15
|
||||
MIMXRT1010-EVK Debug USB D0/D1 D7/D6 -
|
||||
MIMXRT1015-EVK Debug USB D0/D1 D7/A1 -
|
||||
MIMXRT1020-EVK Debug USB D0/D1 D9/D6 D10/D13
|
||||
@@ -33,28 +30,26 @@ MIMXRT1170-EVK Debug USB D0/D1 D12/D11 D10/D13
|
||||
Adafruit Metro M7 - D0/D1 D7/D3 A1/A0
|
||||
Olimex RT1010Py - RxD/TxD D7/D8 D5/D6
|
||||
Seeed ARCH MIX - J3_19/J3_20 J4_16/J4_17 J4_06/J4_07
|
||||
Makerdiary RT1011 - D9/D10 D13/A0 D11/D12
|
||||
================= =========== =========== =========== ===========
|
||||
|
||||
|
|
||||
|
||||
================= =========== =========== ======= ======= =======
|
||||
Board / Pin UART4 UART5 UART6 UART7 UART8
|
||||
================= =========== =========== ======= ======= =======
|
||||
Teensy 4.0 D16/D17 D21/D20 D25/D24 D28/D29 -
|
||||
Teensy 4.1 D16/D17 D21/D20 D25/D24 D28/D29 D34/D35
|
||||
MIMXRT1010-EVK - - - - -
|
||||
MIMXRT1015-EVK - - - - -
|
||||
MIMXRT1020-EVK D15/D14 A1/A0 - - -
|
||||
MIMXRT1050-EVK A1/A0 - - - -
|
||||
MIMXRT1050-EVKB A1/A0 - - - -
|
||||
MIMXRT1060-EVK A1/A0 - - - -
|
||||
MIMXRT1064-EVK A1/A0 - - - -
|
||||
MIMXRT1170-EVK D15/D14 D25/D26 D33/D34 D35/D36 -
|
||||
Olimex RT1010Py - - - - -
|
||||
Seeed ARCH MIX J4_10/J4_11 J5_08/J5_12 - - -
|
||||
Makerdiary RT1011 A1/A2 - - - -
|
||||
================= =========== =========== ======= ======= =======
|
||||
================ =========== =========== ======= ======= =====
|
||||
Board / Pin UART4 UART5 UART6 UART7 UART8
|
||||
================ =========== =========== ======= ======= =====
|
||||
Teensy 4.0 16/17 21/20 25/24 28/29 -
|
||||
Teensy 4.1 16/17 21/20 25/24 28/29 34/35
|
||||
MIMXRT1010-EVK - - - - -
|
||||
MIMXRT1015-EVK - - - - -
|
||||
MIMXRT1020-EVK D15/D14 A1/A0 - - -
|
||||
MIMXRT1050-EVK A1/A0 - - - -
|
||||
MIMXRT1050-EVKB A1/A0 - - - -
|
||||
MIMXRT1060-EVK A1/A0 - - - -
|
||||
MIMXRT1064-EVK A1/A0 - - - -
|
||||
MIMXRT1170-EVK D15/D14 D25/D26 D33/D34 D35/D36 -
|
||||
Olimex RT1010Py - - - - -
|
||||
Seeed ARCH MIX J4_10/J4_11 J5_08/J5_12 - - -
|
||||
================ =========== =========== ======= ======= =====
|
||||
|
||||
.. _mimxrt_pwm_pinout:
|
||||
|
||||
@@ -105,46 +100,46 @@ Pins denoted with (*) are by default not wired at the board.
|
||||
==== ========== ==== ==========
|
||||
Pin Teensy 4.0 Pin Teensy 4.1
|
||||
==== ========== ==== ==========
|
||||
D0 F1/1/X D0 F1/1/X
|
||||
D1 F1/0/X D1 F1/0/X
|
||||
D2 F4/2/A D2 F4/2/A
|
||||
D3 F4/2/B D3 F4/2/B
|
||||
D4 F2/0/A D4 F2/0/A
|
||||
D5 F2/1/A D5 F2/1/A
|
||||
D6 F2/2/A D6 F2/2/A
|
||||
D7 F1/3/B D7 F1/3/B
|
||||
D8 F1/3/A D8 F1/3/A
|
||||
D9 F2/2/B D9 F2/2/B
|
||||
D10 Q1/0 D10 Q1/0
|
||||
D11 Q1/2 D11 Q1/2
|
||||
D12 Q1/1 D12 Q1/1
|
||||
D13 Q2/0 D13 Q2/0
|
||||
D14 Q3/2 D14 Q3/2
|
||||
D15 Q3/3 D15 Q3/3
|
||||
D18 Q3/1 D18 Q3/1
|
||||
D19 Q3/0 D19 Q3/0
|
||||
D22 F4/0/A D22 F4/0/A
|
||||
D23 F4/1/A D23 F4/1/A
|
||||
D24 F1/2/X D24 F1/2/X
|
||||
D25 F1/3/X D25 F1/3/X
|
||||
D28 F3/1/B D28 F3/1/B
|
||||
D29 F3/1/A D29 F3/1/A
|
||||
D33 F2/0/B D33 F2/0/B
|
||||
- - D36 F2/3/A
|
||||
- - D37 F2/3/B
|
||||
DAT1 F1/1/B D42 F1/1/B
|
||||
DAT0 F1/1/A D43 F1/1/A
|
||||
CLK F1/0/B D44 F1/0/B
|
||||
CMD F1/0/A D45 F1/0/A
|
||||
DAT2 F1/2/A D46 F1/2/A
|
||||
DAT3 F1/2/B D47 F1/2/B
|
||||
- - D48 F1/0/B
|
||||
- - D49 F1/2/A
|
||||
- - D50 F1/2/B
|
||||
- - D51 F3/3/B
|
||||
- - D52 F1/1/B
|
||||
- - D53 F1/1/A
|
||||
- - D54 F3/0/A
|
||||
0 F1/1/X 0 F1/1/X
|
||||
1 F1/0/X 1 F1/0/X
|
||||
2 F4/2/A 2 F4/2/A
|
||||
3 F4/2/B 3 F4/2/B
|
||||
4 F2/0/A 4 F2/0/A
|
||||
5 F2/1/A 5 F2/1/A
|
||||
6 F2/2/A 6 F2/2/A
|
||||
7 F1/3/B 7 F1/3/B
|
||||
8 F1/3/A 8 F1/3/A
|
||||
9 F2/2/B 9 F2/2/B
|
||||
10 Q1/0 10 Q1/0
|
||||
11 Q1/2 11 Q1/2
|
||||
12 Q1/1 12 Q1/1
|
||||
13 Q2/0 13 Q2/0
|
||||
14 Q3/2 14 Q3/2
|
||||
15 Q3/3 15 Q3/3
|
||||
18 Q3/1 18 Q3/1
|
||||
19 Q3/0 19 Q3/0
|
||||
22 F4/0/A 22 F4/0/A
|
||||
23 F4/1/A 23 F4/1/A
|
||||
24 F1/2/X 24 F1/2/X
|
||||
25 F1/3/X 25 F1/3/X
|
||||
28 F3/1/B 28 F3/1/B
|
||||
29 F3/1/A 29 F3/1/A
|
||||
33 F2/0/B 33 F2/0/B
|
||||
- - 36 F2/3/A
|
||||
- - 37 F2/3/B
|
||||
DAT1 F1/1/B 42 F1/1/B
|
||||
DAT0 F1/1/A 43 F1/1/A
|
||||
CLK F1/0/B 44 F1/0/B
|
||||
CMD F1/0/A 45 F1/0/A
|
||||
DAT2 F1/2/A 46 F1/2/A
|
||||
DAT3 F1/2/B 47 F1/2/B
|
||||
- - 48 F1/0/B
|
||||
- - 49 F1/2/A
|
||||
- - 50 F1/2/B
|
||||
- - 51 F3/3/B
|
||||
- - 52 F1/1/B
|
||||
- - 53 F1/1/A
|
||||
- - 54 F3/0/A
|
||||
==== ========== ==== ==========
|
||||
|
||||
|
|
||||
@@ -193,6 +188,7 @@ LED_BLUE F1/3/B
|
||||
========= ===============
|
||||
Pin Olimex RT1010PY
|
||||
========= ===============
|
||||
D0 -
|
||||
D1 F1/0/B
|
||||
D2 F1/0/A
|
||||
D3 F1/1/B
|
||||
@@ -201,10 +197,13 @@ D5 F1/2/B
|
||||
D6 F1/2/A
|
||||
D7 F1/3/B
|
||||
D8 F1/3/A
|
||||
D9 -
|
||||
D10 F1/0/B
|
||||
D11 F1/0/A
|
||||
D12 F1/1/B
|
||||
D13 F1/1/A
|
||||
D14 -
|
||||
A0 -
|
||||
A1 F1/2/B
|
||||
A2 F1/2/A
|
||||
A3 F1/3/B
|
||||
@@ -215,32 +214,6 @@ CS0 F1/1/X
|
||||
SCK F1/0/X
|
||||
========= ===============
|
||||
|
||||
|
|
||||
|
||||
========= =================
|
||||
Pin Makerdiary RT1011
|
||||
========= =================
|
||||
D1 F1/0/B
|
||||
D2 F1/0/A
|
||||
D3 F1/1/B
|
||||
D4 F1/1/A
|
||||
D5 F1/2/B
|
||||
D6 F1/2/A
|
||||
D7 F1/3/B
|
||||
D8 F1/3/A
|
||||
A3 F1/2/B
|
||||
A4 F1/2/A
|
||||
A5 F1/3/B
|
||||
A6 F1/3/A
|
||||
A9 F1/3/X
|
||||
A10 F1/2/X
|
||||
A11 F1/1/X
|
||||
SD1 F1/0/B
|
||||
SD2 F1/0/A
|
||||
LED F1/1/B
|
||||
DIO F1/0/X
|
||||
========= =================
|
||||
|
||||
Legend:
|
||||
|
||||
* Qm/n: QTMR module m, channel n
|
||||
@@ -333,11 +306,11 @@ The SPI signals have fixed assignments to GPIO pins.
|
||||
It depends on the board design, which SPI's signals are exposed to the user, as
|
||||
detailed in the table below. The signal order in the table is: CS0, CS1, MOSI, MISO, CLK.
|
||||
|
||||
================= ========================= ======================= =================
|
||||
================= ========================= ======================= ===============
|
||||
Board / Pin SPI0 SPI1 SPI2
|
||||
================= ========================= ======================= =================
|
||||
Teensy 4.0 D10/-/D11/D12/D13 D0/-/D26/D1/D27 -
|
||||
Teensy 4.1 D10/D37/D11/D12/D13 D0/-/D26/D1/D27 -/D29/D50/D54/D49
|
||||
================= ========================= ======================= ===============
|
||||
Teensy 4.0 10/-/11/12/13 0/-/26/1/27 -
|
||||
Teensy 4.1 10/37/11/12/13 0/-/26/1/27 -/29/50/54/49
|
||||
MIXMXRT1010-EVK D10/D7/D11/D12/D13 - -
|
||||
MIXMXRT1015-EVK D10/-/D11/D12/D13 - -
|
||||
MIXMXRT1020-EVK D10/-/D11/D12/D13 A3/D0/A5/A4/A0 -
|
||||
@@ -349,8 +322,7 @@ MIXMXRT1170-EVK D10/-/D11/D12/D13 D28/-/D25/D24/D26 -/-/D14/D
|
||||
Adafruit Metro M7 -/-/MOSI/MISO/SCK - -
|
||||
Olimex RT1010Py - CS0/-/SDO/SDI/SCK SDCARD with CS1
|
||||
Seeed ARCH MIX J4_12/-/J4_14/J4_13/J4_15 J3_09/J3_05/J3_08_J3_11
|
||||
Makerdiary RT1011 A5/A2/A4/A3/A6 A11/A1/A10/A9/CLK
|
||||
================= ========================= ======================= =================
|
||||
================= ========================= ======================= ===============
|
||||
|
||||
Pins denoted with (*) are by default not wired at the board. The CS0 and CS1 signals
|
||||
are enabled with the keyword option cs=0 or cs=1 of the SPI object constructor.
|
||||
@@ -370,8 +342,8 @@ detailed in the table below. The signal order in the table is: SDA, SCL.
|
||||
================= =========== =========== =========== ======= =======
|
||||
Board / Pin I2C 0 I2C 1 I2C 2 I2C 3 I2C 4
|
||||
================= =========== =========== =========== ======= =======
|
||||
Teensy 4.0 D18/D19 D17/D16 D25/D24 - -
|
||||
Teensy 4.1 D18/D19 D17/D16 D25/D24 - -
|
||||
Teensy 4.0 18/19 17/16 25/24 - -
|
||||
Teensy 4.1 18/19 17/16 25/24 - -
|
||||
MIXMXRT1010-EVK D14/D15 D0/D1 - - -
|
||||
MIXMXRT1015-EVK D14/D15 - - - -
|
||||
MIXMXRT1020-EVK D14/D15 A4/A5 D0/D1 - -
|
||||
@@ -383,7 +355,6 @@ MIXMXRT1170-EVK D14/D15 D1/D0 A4/A5 D26/D25 D19/D18
|
||||
Adafruit Metro M7 D14/D15 D0/D1
|
||||
Olimex RT1010Py - SDA1/SCL1 SDA2/SCL2 - -
|
||||
Seeed ARCH MIX J3_17/J3_16 J4_06/J4_07 J5_05/J5_04 - -
|
||||
Makerdiary RT1011 D1/D2 A7/A8
|
||||
================= =========== =========== =========== ======= =======
|
||||
|
||||
.. _mimxrt_i2s_pinout:
|
||||
@@ -399,16 +370,15 @@ Pin assignments for a few MIMXRT boards:
|
||||
================= == ===== ======== ======= ======= ======== ======= =======
|
||||
Board ID MCK SCK_TX WS_TX SD_TX SCK_RX WS_RX SD_RX
|
||||
================= == ===== ======== ======= ======= ======== ======= =======
|
||||
Teensy 4.0 1 D23 D26 D27 D7 D21 D20 D8
|
||||
Teensy 4.0 2 D33 D4 D3 D2 - - D5
|
||||
Teensy 4.1 1 D23 D26 D27 D7 D21 D20 D8
|
||||
Teensy 4.1 2 D33 D4 D3 D2 - - D5
|
||||
Teensy 4.0 1 23 26 27 7 21 20 8
|
||||
Teensy 4.0 2 33 4 3 2 - - 5
|
||||
Teensy 4.1 1 23 26 27 7 21 20 8
|
||||
Teensy 4.1 2 33 4 3 2 - - 5
|
||||
Seeed Arch MIX 1 J4_09 J4_14 J4_15 J14_13 J4_11 J4_10 J4_10
|
||||
Adafruit Metro M7 1 D8 D10 D9 D12 D14 D15 D13
|
||||
Olimex RT1010Py 1 D8 D6 D7 D4 D1 D2 D3
|
||||
Olimex RT1010Py 3 - D10 D9 D11 - - -
|
||||
MIMXRT_DEV 1 "MCK" "SCK_TX" "WS_TX" "SD_TX" "SCK_RX" "WS_RX" "SD_RX"
|
||||
Makerdiary RT1011 1 D8 SD1 D7 D4 D1 D2 D3
|
||||
================= == ===== ======== ======= ======= ======== ======= =======
|
||||
|
||||
Symbolic pin names are provided for the MIMXRT_10xx_DEV boards.
|
||||
|
||||
@@ -122,13 +122,10 @@ See :ref:`machine.UART <machine.UART>`. ::
|
||||
uart1 = UART(1, baudrate=115200)
|
||||
uart1.write('hello') # write 5 bytes
|
||||
uart1.read(5) # read up to 5 bytes
|
||||
uart1 = UART(baudrate=19200) # open UART 1 at 19200 baud
|
||||
|
||||
The i.MXRT has up to eight hardware UARTs, but not every board exposes all
|
||||
TX and RX pins for users. For the assignment of Pins to UART signals,
|
||||
refer to the :ref:`UART pinout <mimxrt_uart_pinout>`. If the UART ID is
|
||||
omitted, UART(1) is selected. Then, the keyword
|
||||
option for baudrate must be used to change it from the default value.
|
||||
refer to the :ref:`UART pinout <mimxrt_uart_pinout>`.
|
||||
|
||||
PWM (pulse width modulation)
|
||||
----------------------------
|
||||
@@ -196,7 +193,7 @@ PWM Constructor
|
||||
|
||||
- *freq* should be an integer which sets the frequency in Hz for the
|
||||
PWM cycle. The valid frequency range is 15 Hz resp. 18Hz resp. 24Hz up to > 1 MHz.
|
||||
- *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65535``.
|
||||
- *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65536``.
|
||||
The duty cycle of a X channel can only be changed, if the A and B channel
|
||||
of the respective submodule is not used. Otherwise the duty_16 value of the
|
||||
X channel is 32768 (50%).
|
||||
@@ -234,7 +231,7 @@ is created by dividing the pwm_clk signal by an integral factor, according to th
|
||||
|
||||
f = pwm_clk / (2**n * m)
|
||||
|
||||
with n being in the range of 0..7, and m in the range of 2..65535. pmw_clk is 125Mhz
|
||||
with n being in the range of 0..7, and m in the range of 2..65536. pmw_clk is 125Mhz
|
||||
for MIMXRT1010/1015/1020, 150 MHz for MIMXRT1050/1060/1064 and 160MHz for MIMXRT1170.
|
||||
The lowest frequency is pwm_clk/2**23 (15, 18, 20Hz). The highest frequency with
|
||||
U16 resolution is pwm_clk/2**16 (1907, 2288, 2441 Hz), the highest frequency
|
||||
@@ -258,7 +255,7 @@ Use the :ref:`machine.ADC <machine.ADC>` class::
|
||||
from machine import ADC
|
||||
|
||||
adc = ADC(Pin('A2')) # create ADC object on ADC pin
|
||||
adc.read_u16() # read value, 0-65535 across voltage range 0.0v - 3.3v
|
||||
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
|
||||
value returned by read_u16(). If you need a higher resolution or better accuracy, use
|
||||
@@ -308,15 +305,12 @@ rates (up to 30Mhz). Hardware SPI is accessed via the
|
||||
cs_pin(0)
|
||||
spi.write('Hello World')
|
||||
cs_pin(1)
|
||||
spi = SPI(baudrate=4_000_000) # Use SPI(0) at a baudrate of 4 MHz
|
||||
|
||||
For the assignment of Pins to SPI signals, refer to
|
||||
:ref:`Hardware SPI pinout <mimxrt_spi_pinout>`.
|
||||
The keyword option cs=n can be used to enable the cs pin 0 or 1 for an automatic cs signal. The
|
||||
default is cs=-1. Using cs=-1 the automatic cs signal is not created.
|
||||
In that case, cs has to be set by the script. Clearing that assignment requires a power cycle.
|
||||
If the SPI ID is omitted, SPI(0) is selected. Then, the keyword
|
||||
option for baudrate must be used to change it from the default value.
|
||||
|
||||
Notes:
|
||||
|
||||
@@ -361,10 +355,6 @@ has the same methods as software SPI above::
|
||||
|
||||
i2c = I2C(0, 400_000)
|
||||
i2c.writeto(0x76, b"Hello World")
|
||||
i2c = I2C(freq=100_000) # use I2C(0) at 100kHz
|
||||
|
||||
If the I2C ID is omitted, I2C(0) is selected. Then, the keyword
|
||||
option for freq must be used to change the freq from the default value.
|
||||
|
||||
I2S bus
|
||||
-------
|
||||
@@ -439,9 +429,7 @@ See :ref:`machine.RTC <machine.RTC>`::
|
||||
from machine import RTC
|
||||
|
||||
rtc = RTC()
|
||||
rtc.datetime((2017, 8, 23, 0, 1, 12, 48, 0)) # set a specific date and
|
||||
# time, eg. 2017/8/23 1:12:48
|
||||
# the day-of-week value is ignored
|
||||
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
|
||||
rtc.datetime() # get date and time
|
||||
rtc.now() # return date and time in CPython format.
|
||||
|
||||
|
||||
@@ -138,9 +138,7 @@ See :ref:`pyb.RTC <pyb.RTC>` ::
|
||||
from pyb import RTC
|
||||
|
||||
rtc = RTC()
|
||||
rtc.datetime((2017, 8, 23, 0, 1, 12, 48, 0)) # set a specific date and
|
||||
# time, eg. 2017/8/23 1:12:48
|
||||
# the day-of-week value is ignored
|
||||
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
|
||||
rtc.datetime() # get date and time
|
||||
|
||||
PWM (pulse width modulation)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user