Compare commits
30 Commits
mbl-next
...
v1.24-tonb
| Author | SHA1 | Date | |
|---|---|---|---|
| e4422b860e | |||
| 0f26771a44 | |||
|
|
29275e2c58 | ||
|
|
732c2989c5 | ||
|
|
ef5c3c043c | ||
|
|
ba21be5215 | ||
|
|
8ba7af3a70 | ||
|
|
08513e1a32 | ||
|
|
ecfdd5d6f9 | ||
|
|
564ef28ad2 | ||
|
|
7118942a8c | ||
|
|
948863c0b8 | ||
|
|
33f50d4f20 | ||
|
|
eb0027b82f | ||
|
|
03bc561edb | ||
|
|
49b83ed44a | ||
|
|
4f4d683ea5 | ||
|
|
67f893852a | ||
|
|
20a6d82872 | ||
|
|
0c580f71ae | ||
|
|
4e78c611b4 | ||
|
|
159b54b7da | ||
|
|
c1a85bb6de | ||
|
|
72799f9973 | ||
|
|
164c549248 | ||
|
|
6f327684b7 | ||
|
|
a7d3bc2308 | ||
|
|
c0afff8f22 | ||
|
|
785c92df76 | ||
|
|
5c7ac55232 |
1
.github/workflows/code_size.yml
vendored
1
.github/workflows/code_size.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Check code size
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/*.yml'
|
||||
|
||||
2
.github/workflows/codespell.yml
vendored
2
.github/workflows/codespell.yml
vendored
@@ -8,6 +8,6 @@ jobs:
|
||||
steps:
|
||||
- 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
|
||||
|
||||
|
||||
4
.github/workflows/commit_formatting.yml
vendored
4
.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 }}
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100
|
||||
fetch-depth: '100'
|
||||
- uses: actions/setup-python@v5
|
||||
- name: Check commit message formatting
|
||||
run: source tools/ci.sh && ci_commit_formatting_run
|
||||
|
||||
4
.github/workflows/docs.yml
vendored
4
.github/workflows/docs.yml
vendored
@@ -5,8 +5,6 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- docs/**
|
||||
- py/**
|
||||
- tests/cpydiff/**
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -21,7 +19,5 @@ jobs:
|
||||
- uses: actions/setup-python@v5
|
||||
- name: Install Python packages
|
||||
run: pip install -r docs/requirements.txt
|
||||
- name: Build unix port
|
||||
run: source tools/ci.sh && ci_unix_build_helper
|
||||
- name: Build docs
|
||||
run: make -C docs/ html
|
||||
|
||||
2
.github/workflows/mpy_format.yml
vendored
2
.github/workflows/mpy_format.yml
vendored
@@ -15,7 +15,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-22.04 # use 22.04 to get python2
|
||||
runs-on: ubuntu-20.04 # use 20.04 to get python2
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
|
||||
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@v4
|
||||
- name: Install packages
|
||||
run: source tools/ci.sh && ci_alif_setup
|
||||
- name: Build ci_${{matrix.ci_func }}
|
||||
run: source tools/ci.sh && ci_${{ matrix.ci_func }}
|
||||
7
.github/workflows/ports_esp32.yml
vendored
7
.github/workflows/ports_esp32.yml
vendored
@@ -25,14 +25,13 @@ jobs:
|
||||
ci_func: # names are functions in ci.sh
|
||||
- esp32_build_cmod_spiram_s2
|
||||
- esp32_build_s3_c3
|
||||
- esp32_build_c2_c6
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- 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
|
||||
|
||||
2
.github/workflows/ports_mimxrt.yml
vendored
2
.github/workflows/ports_mimxrt.yml
vendored
@@ -19,7 +19,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
defaults:
|
||||
run:
|
||||
working-directory: 'micropython repo' # test build with space in path
|
||||
|
||||
2
.github/workflows/ports_nrf.yml
vendored
2
.github/workflows/ports_nrf.yml
vendored
@@ -19,7 +19,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
|
||||
11
.github/workflows/ports_qemu.yml
vendored
11
.github/workflows/ports_qemu.yml
vendored
@@ -20,20 +20,13 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build_and_test_arm:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ci_func: # names are functions in ci.sh
|
||||
- bigendian
|
||||
- sabrelite
|
||||
- thumb
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: source tools/ci.sh && ci_qemu_setup_arm
|
||||
- name: Build and run test suite ci_qemu_build_arm_${{ matrix.ci_func }}
|
||||
run: source tools/ci.sh && ci_qemu_build_arm_${{ matrix.ci_func }}
|
||||
- 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
|
||||
|
||||
2
.github/workflows/ports_renesas-ra.yml
vendored
2
.github/workflows/ports_renesas-ra.yml
vendored
@@ -19,7 +19,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build_renesas_ra_board:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
|
||||
2
.github/workflows/ports_stm32.yml
vendored
2
.github/workflows/ports_stm32.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
- stm32_pyb_build
|
||||
- stm32_nucleo_build
|
||||
- stm32_misc_build
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
|
||||
117
.github/workflows/ports_unix.yml
vendored
117
.github/workflows/ports_unix.yml
vendored
@@ -71,11 +71,6 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
# 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: source tools/ci.sh && ci_unix_coverage_setup
|
||||
- name: Build
|
||||
@@ -93,7 +88,7 @@ jobs:
|
||||
(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,7 +98,7 @@ 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@v4
|
||||
- name: Install packages
|
||||
@@ -121,7 +116,7 @@ jobs:
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
nanbox:
|
||||
runs-on: ubuntu-22.04 # use 22.04 to get python2, and libffi-dev:i386
|
||||
runs-on: ubuntu-20.04 # use 20.04 to get python2, and libffi-dev:i386
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
@@ -134,20 +129,6 @@ jobs:
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
longlong:
|
||||
runs-on: ubuntu-22.04 # use 22.04 to get python2, and libffi-dev:i386
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: source tools/ci.sh && ci_unix_32bit_setup
|
||||
- name: Build
|
||||
run: source tools/ci.sh && ci_unix_longlong_build
|
||||
- name: Run main test suite
|
||||
run: source tools/ci.sh && ci_unix_longlong_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
float:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -160,20 +141,8 @@ jobs:
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
gil_enabled:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: source tools/ci.sh && ci_unix_gil_enabled_build
|
||||
- name: Run main test suite
|
||||
run: source tools/ci.sh && ci_unix_gil_enabled_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@v4
|
||||
- name: Install packages
|
||||
@@ -187,7 +156,7 @@ jobs:
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
float_clang:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
@@ -200,15 +169,22 @@ jobs:
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
settrace:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build
|
||||
run: source tools/ci.sh && ci_unix_settrace_build
|
||||
- name: Run main test suite
|
||||
run: source tools/ci.sh && ci_unix_settrace_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
settrace_stackless:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
# 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: Build
|
||||
run: source tools/ci.sh && ci_unix_settrace_stackless_build
|
||||
- name: Run main test suite
|
||||
@@ -233,8 +209,7 @@ jobs:
|
||||
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@v4
|
||||
- name: Install packages
|
||||
@@ -248,8 +223,7 @@ jobs:
|
||||
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@v4
|
||||
- name: Install packages
|
||||
@@ -263,8 +237,7 @@ jobs:
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
qemu_riscv64:
|
||||
# ubuntu-22.04 is needed for older libffi.
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
@@ -276,53 +249,3 @@ jobs:
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
sanitize_address:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
# 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: source tools/ci.sh && ci_unix_coverage_setup
|
||||
- name: Build
|
||||
run: source tools/ci.sh && ci_unix_sanitize_address_build
|
||||
- name: Run main test suite
|
||||
run: source tools/ci.sh && ci_unix_sanitize_address_run_tests
|
||||
- name: Test merging .mpy files
|
||||
run: source tools/ci.sh && ci_unix_coverage_run_mpy_merge_tests
|
||||
- name: Build native mpy modules
|
||||
run: source tools/ci.sh && ci_native_mpy_modules_build
|
||||
- name: Test importing .mpy generated by mpy_ld.py
|
||||
run: source tools/ci.sh && ci_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@v4
|
||||
- uses: actions/setup-python@v5
|
||||
# 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: source tools/ci.sh && ci_unix_coverage_setup
|
||||
- name: Build
|
||||
run: source tools/ci.sh && ci_unix_sanitize_undefined_build
|
||||
- name: Run main test suite
|
||||
run: source tools/ci.sh && ci_unix_sanitize_undefined_run_tests
|
||||
- name: Test merging .mpy files
|
||||
run: source tools/ci.sh && ci_unix_coverage_run_mpy_merge_tests
|
||||
- name: Build native mpy modules
|
||||
run: source tools/ci.sh && ci_native_mpy_modules_build
|
||||
- name: Test importing .mpy generated by mpy_ld.py
|
||||
run: source tools/ci.sh && ci_unix_coverage_run_native_mpy_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
24
.github/workflows/ports_windows.yml
vendored
24
.github/workflows/ports_windows.yml
vendored
@@ -28,10 +28,13 @@ jobs:
|
||||
visualstudio: ['2017', '2019', '2022']
|
||||
include:
|
||||
- visualstudio: '2017'
|
||||
runner: windows-latest
|
||||
vs_version: '[15, 16)'
|
||||
- visualstudio: '2019'
|
||||
runner: windows-2019
|
||||
vs_version: '[16, 17)'
|
||||
- visualstudio: '2022'
|
||||
runner: windows-2022
|
||||
vs_version: '[17, 18)'
|
||||
# trim down the number of jobs in the matrix
|
||||
exclude:
|
||||
@@ -39,9 +42,9 @@ 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 2017
|
||||
if: matrix.visualstudio == '2017'
|
||||
@@ -49,15 +52,13 @@ jobs:
|
||||
choco install visualstudio2017buildtools
|
||||
choco install visualstudio2017-workload-vctools
|
||||
choco install windows-sdk-8.1
|
||||
- name: Install Visual Studio 2019
|
||||
if: matrix.visualstudio == '2019'
|
||||
run: |
|
||||
choco install visualstudio2019buildtools
|
||||
choco install visualstudio2019-workload-vctools
|
||||
choco install windows-sdk-8.1
|
||||
- uses: microsoft/setup-msbuild@v2
|
||||
with:
|
||||
vs-version: ${{ matrix.vs_version }}
|
||||
- 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 }}
|
||||
@@ -102,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@v5
|
||||
# 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 }}
|
||||
@@ -122,9 +118,9 @@ 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@v4
|
||||
- name: Build mpy-cross.exe
|
||||
run: make -C mpy-cross -j2
|
||||
|
||||
17
.github/workflows/ports_zephyr.yml
vendored
17
.github/workflows/ports_zephyr.yml
vendored
@@ -30,26 +30,9 @@ jobs:
|
||||
docker-images: false
|
||||
swap-storage: false
|
||||
- uses: actions/checkout@v4
|
||||
- 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@v4
|
||||
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
|
||||
- name: Install packages
|
||||
run: source tools/ci.sh && ci_zephyr_setup
|
||||
- name: Install Zephyr
|
||||
if: steps.cache_workspace.outputs.cache-hit != 'true'
|
||||
run: source tools/ci.sh && ci_zephyr_install
|
||||
- name: Build
|
||||
run: source tools/ci.sh && ci_zephyr_build
|
||||
|
||||
4
.github/workflows/ruff.yml
vendored
4
.github/workflows/ruff.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# ruff version should be kept in sync with .pre-commit-config.yaml & also micropython-lib
|
||||
- run: pipx install ruff==0.11.6
|
||||
# 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 .
|
||||
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -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
|
||||
|
||||
11
docs/conf.py
11
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 ------------------------------------------------
|
||||
|
||||
@@ -71,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
|
||||
@@ -247,7 +244,7 @@ latex_documents = [
|
||||
master_doc,
|
||||
"MicroPython.tex",
|
||||
"MicroPython Documentation",
|
||||
micropy_authors,
|
||||
"Damien P. George, Paul Sokolovsky, and contributors",
|
||||
"manual",
|
||||
),
|
||||
]
|
||||
@@ -284,7 +281,7 @@ man_pages = [
|
||||
"index",
|
||||
"micropython",
|
||||
"MicroPython Documentation",
|
||||
[micropy_authors],
|
||||
["Damien P. George, Paul Sokolovsky, and contributors"],
|
||||
1,
|
||||
),
|
||||
]
|
||||
@@ -303,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",
|
||||
|
||||
@@ -278,7 +278,7 @@ 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`.
|
||||
|
||||
|
||||
@@ -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
|
||||
----------------
|
||||
|
||||
|
||||
@@ -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,8 +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.
|
||||
The period is in milliseconds.
|
||||
|
||||
Virtual timers are not currently supported on this port.
|
||||
|
||||
@@ -387,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
|
||||
@@ -397,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%)
|
||||
@@ -406,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
|
||||
@@ -544,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
|
||||
----------------
|
||||
@@ -728,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)
|
||||
@@ -816,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
|
||||
|
||||
@@ -838,9 +684,6 @@ The RMT is ESP32-specific and allows generation of accurate digital pulses with
|
||||
# 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
|
||||
--------------
|
||||
|
||||
@@ -907,33 +750,20 @@ 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...')
|
||||
@@ -163,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::
|
||||
@@ -284,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`.
|
||||
|
||||
@@ -18,31 +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:: gpio_deep_sleep_hold(enable)
|
||||
|
||||
Configure whether non-RTC GPIO pin configuration is retained during
|
||||
@@ -88,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
|
||||
----------------
|
||||
@@ -195,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
|
||||
|
||||
@@ -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,13 +164,11 @@ Configuration
|
||||
wait forever. The timeout can also be provided as arg to
|
||||
`recv()`/`irecv()`/`recvinto()`.
|
||||
|
||||
*rate*: (ESP32 only) Set the transmission speed for
|
||||
*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/v5.2.3/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.
|
||||
<https://docs.espressif.com/projects/esp-idf/en/v4.4.1/esp32/
|
||||
api-reference/network/esp_wifi.html#_CPPv415wifi_phy_rate_t>`_.
|
||||
|
||||
.. data:: Returns:
|
||||
|
||||
@@ -184,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
|
||||
|
||||
@@ -443,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
|
||||
@@ -474,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)
|
||||
@@ -595,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
|
||||
|
||||
@@ -652,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)
|
||||
@@ -754,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:
|
||||
@@ -839,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,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_READ`` 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_READ``, ``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
|
||||
``````
|
||||
|
||||
@@ -71,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``.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -62,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()
|
||||
|
||||
@@ -264,12 +265,9 @@ Classes
|
||||
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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -163,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.
|
||||
|
||||
|
||||
@@ -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``
|
||||
|
||||
@@ -30,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 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 - - -
|
||||
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:
|
||||
|
||||
@@ -190,6 +188,7 @@ LED_BLUE F1/3/B
|
||||
========= ===============
|
||||
Pin Olimex RT1010PY
|
||||
========= ===============
|
||||
D0 -
|
||||
D1 F1/0/B
|
||||
D2 F1/0/A
|
||||
D3 F1/1/B
|
||||
@@ -198,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
|
||||
@@ -212,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
|
||||
@@ -346,7 +322,6 @@ 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
|
||||
@@ -380,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:
|
||||
@@ -405,7 +379,6 @@ 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)
|
||||
|
||||
@@ -10,8 +10,6 @@ execution of ``boot.py`` and ``main.py`` and gives default USB settings.
|
||||
If you have problems with the filesystem you can do a factory reset,
|
||||
which restores the filesystem to its original state.
|
||||
|
||||
For more information, see :doc:`/reference/reset_boot`.
|
||||
|
||||
Safe mode
|
||||
---------
|
||||
|
||||
|
||||
@@ -188,13 +188,6 @@ Glossary
|
||||
Most MicroPython boards make a REPL available over a UART, and this is
|
||||
typically accessible on a host PC via USB.
|
||||
|
||||
small integer
|
||||
MicroPython optimises the internal representation of integers such that
|
||||
"small" values do not take up space on the heap, and calculations with
|
||||
them do not require heap allocation. On most 32-bit ports, this
|
||||
corresponds to values in the interval ``-2**30 <= x < 2**30``, but this
|
||||
should be considered an implementation detail and not relied upon.
|
||||
|
||||
stream
|
||||
Also known as a "file-like object". A Python object which provides
|
||||
sequential read-write access to the underlying data. A stream object
|
||||
|
||||
@@ -21,7 +21,6 @@ implementation and the best practices to use them.
|
||||
|
||||
glossary.rst
|
||||
repl.rst
|
||||
reset_boot.rst
|
||||
mpremote.rst
|
||||
mpyfiles.rst
|
||||
isr_rules.rst
|
||||
|
||||
@@ -170,17 +170,11 @@ is partially updated. When the ISR tries to read the object, a crash results. Be
|
||||
on rare, random occasions they can be hard to diagnose. There are ways to circumvent this issue, described in
|
||||
:ref:`Critical Sections <Critical>` below.
|
||||
|
||||
It is important to be clear about what constitutes the modification of an object. Altering the contents of an array
|
||||
or bytearray is safe. This is because bytes or words are written as a single machine code instruction which is not
|
||||
interruptible: in the parlance of real time programming the write is atomic. The same is true of updating a
|
||||
dictionary item because items are machine words, being integers or pointers to objects. A user defined object might
|
||||
instantiate an array or bytearray. It is valid for both the main loop and the ISR to alter the contents of these.
|
||||
|
||||
The hazard arises when the structure of an object is altered, notably in the case of dictionaries. Adding or deleting
|
||||
keys can trigger a rehash. If a hard ISR runs while a rehash is in progress and attempts to access an item, a crash
|
||||
may occur. Internally globals are implemented as a dictionary. Consequently the main program should create all
|
||||
necessary globals before starting a process that generates hard interrupts. Application code should also avoid
|
||||
deleting globals.
|
||||
It is important to be clear about what constitutes the modification of an object. An alteration to a built-in type
|
||||
such as a dictionary is problematic. Altering the contents of an array or bytearray is not. This is because bytes
|
||||
or words are written as a single machine code instruction which is not interruptible: in the parlance of real time
|
||||
programming the write is atomic. A user defined object might instantiate an integer, array or bytearray. It is valid
|
||||
for both the main loop and the ISR to alter the contents of these.
|
||||
|
||||
MicroPython supports integers of arbitrary precision. Values between 2**30 -1 and -2**30 will be stored in
|
||||
a single machine word. Larger values are stored as Python objects. Consequently changes to long integers cannot
|
||||
@@ -209,7 +203,7 @@ issue a further interrupt. It then schedules a callback to process the data.
|
||||
|
||||
Scheduled callbacks should comply with the principles of interrupt handler design outlined below. This is to
|
||||
avoid problems resulting from I/O activity and the modification of shared data which can arise in any code
|
||||
which preempts the main program loop.
|
||||
which pre-empts the main program loop.
|
||||
|
||||
Execution time needs to be considered in relation to the frequency with which interrupts can occur. If an
|
||||
interrupt occurs while the previous callback is executing, a further instance of the callback will be queued
|
||||
|
||||
@@ -26,7 +26,7 @@ re-flashing the entire firmware. However, it can still be useful to
|
||||
selectively freeze some rarely-changing dependencies (such as third-party
|
||||
libraries).
|
||||
|
||||
The way to list the Python files to be frozen into the firmware is via
|
||||
The way to list the Python files to be be frozen into the firmware is via
|
||||
a "manifest", which is a Python file that will be interpreted by the build
|
||||
process. Typically you would write a manifest file as part of a board
|
||||
definition, but you can also write a stand-alone manifest file and use it with
|
||||
|
||||
@@ -78,7 +78,6 @@ The full list of supported commands are:
|
||||
- `mip <mpremote_command_mip>`
|
||||
- `mount <mpremote_command_mount>`
|
||||
- `unmount <mpremote_command_unmount>`
|
||||
- `romfs <mpremote_command_romfs>`
|
||||
- `rtc <mpremote_command_rtc>`
|
||||
- `sleep <mpremote_command_sleep>`
|
||||
- `reset <mpremote_command_reset>`
|
||||
@@ -108,7 +107,7 @@ The full list of supported commands are:
|
||||
**Note:** Instead of using the ``connect`` command, there are several
|
||||
:ref:`pre-defined shortcuts <mpremote_shortcuts>` for common device paths. For
|
||||
example the ``a0`` shortcut command is equivalent to
|
||||
``connect /dev/ttyACM0`` (Linux), or ``c1`` for ``COM1`` (Windows).
|
||||
``connect /dev/ttyACM0`` (Linux), or ``c0`` for ``COM0`` (Windows).
|
||||
|
||||
**Note:** The ``auto`` option will only detect USB serial ports, i.e. a serial
|
||||
port that has an associated USB VID/PID (i.e. CDC/ACM or FTDI-style
|
||||
@@ -229,52 +228,24 @@ The full list of supported commands are:
|
||||
- ``ls`` to list the current directory
|
||||
- ``ls <dirs...>`` to list the given directories
|
||||
- ``cp [-rf] <src...> <dest>`` to copy files
|
||||
- ``rm [-r] <src...>`` to remove files or folders on the device
|
||||
- ``rm <src...>`` to remove files on the device
|
||||
- ``mkdir <dirs...>`` to create directories on the device
|
||||
- ``rmdir <dirs...>`` to remove directories on the device
|
||||
- ``touch <file..>`` to create the files (if they don't already exist)
|
||||
- ``sha256sum <file..>`` to calculate the SHA256 sum of files
|
||||
- ``tree [-vsh] <dirs...>`` to print a tree of the given directories
|
||||
|
||||
The ``cp`` command uses a convention where a leading ``:`` represents a remote
|
||||
path. Without a leading ``:`` means a local path. This is based on the
|
||||
convention used by the `Secure Copy Protocol (scp) client
|
||||
<https://en.wikipedia.org/wiki/Secure_copy_protocol>`_.
|
||||
<https://en.wikipedia.org/wiki/Secure_copy_protocol>`_. All other commands
|
||||
implicitly assume the path is a remote path, but the ``:`` can be optionally
|
||||
used for clarity.
|
||||
|
||||
So for example, ``mpremote fs cp main.py :main.py`` copies ``main.py`` from
|
||||
the current local directory to the remote filesystem, whereas
|
||||
``mpremote fs cp :main.py main.py`` copies ``main.py`` from the device back
|
||||
to the current directory.
|
||||
|
||||
The ``mpremote rm -r`` command accepts both relative and absolute paths.
|
||||
Use ``:`` to refer to the current remote working directory (cwd) to allow a
|
||||
directory tree to be removed from the device's default path (eg ``/flash``, ``/``).
|
||||
Use ``-v/--verbose`` to see the files being removed.
|
||||
|
||||
For example:
|
||||
|
||||
- ``mpremote rm -r :libs`` will remove the ``libs`` directory and all its
|
||||
child items from the device.
|
||||
- ``mpremote rm -rv :/sd`` will remove all files from a mounted SDCard and result
|
||||
in a non-blocking warning. The mount will be retained.
|
||||
- ``mpremote rm -rv :/`` will remove all files on the device, including any
|
||||
located in mounted vfs such as ``/sd`` or ``/flash``. After removing all folders
|
||||
and files, this will also return an error to mimic unix ``rm -rf /`` behaviour.
|
||||
|
||||
.. warning::
|
||||
There is no supported way to undelete files removed by ``mpremote rm -r :``.
|
||||
Please use with caution.
|
||||
|
||||
The ``tree`` command will print a tree of the given directories.
|
||||
Using the ``--size/-s`` option will print the size of each file, or use
|
||||
``--human/-h`` to use a more human readable format.
|
||||
Note: Directory size is only printed when a non-zero size is reported by the device's filesystem.
|
||||
The ``-v`` option can be used to include the name of the serial device in
|
||||
the output.
|
||||
|
||||
All other commands implicitly assume the path is a remote path, but the ``:``
|
||||
can be optionally used for clarity.
|
||||
|
||||
All of the filesystem sub-commands take multiple path arguments, so if there
|
||||
is another command in the sequence, you must use ``+`` to terminate the
|
||||
arguments, e.g.
|
||||
@@ -376,29 +347,6 @@ The full list of supported commands are:
|
||||
This happens automatically when ``mpremote`` terminates, but it can be used
|
||||
in a sequence to unmount an earlier mount before subsequent command are run.
|
||||
|
||||
.. _mpremote_command_romfs:
|
||||
|
||||
- **romfs** -- manage ROMFS partitions on the device:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ mpremote romfs <sub-command>
|
||||
|
||||
``<sub-command>`` may be:
|
||||
|
||||
- ``romfs query`` to list all the available ROMFS partitions and their size
|
||||
- ``romfs [-o <output>] build <source>`` to create a ROMFS image from the given
|
||||
source directory; the default output file is the source appended by ``.romfs``
|
||||
- ``romfs [-p <partition>] deploy <source>`` to deploy a ROMFS image to the device;
|
||||
will also create a temporary ROMFS image if the source is a directory
|
||||
|
||||
The ``build`` and ``deploy`` sub-commands both support the ``-m``/``--mpy`` option
|
||||
to automatically compile ``.py`` files to ``.mpy`` when creating the ROMFS image.
|
||||
This option is enabled by default, but only works if the ``mpy_cross`` Python
|
||||
package has been installed (eg via ``pip install mpy_cross``). If the package is
|
||||
not installed then a warning is printed and ``.py`` files remain as is. Compiling
|
||||
of ``.py`` files can be disabled with the ``--no-mpy`` option.
|
||||
|
||||
.. _mpremote_command_rtc:
|
||||
|
||||
- **rtc** -- set/get the device clock (RTC):
|
||||
@@ -487,16 +435,9 @@ Shortcuts can be defined using the macro system. Built-in shortcuts are:
|
||||
|
||||
- ``cat``, ``edit``, ``ls``, ``cp``, ``rm``, ``mkdir``, ``rmdir``, ``touch``: Aliases for ``fs <sub-command>``
|
||||
|
||||
Additional shortcuts can be defined in the user configuration file ``mpremote/config.py``,
|
||||
located in the User Configuration Directory.
|
||||
The correct location for each OS is determined using the ``platformdirs`` module.
|
||||
|
||||
This is typically:
|
||||
- ``$XDG_CONFIG_HOME/mpremote/config.py``
|
||||
- ``$HOME/.config/mpremote/config.py``
|
||||
- ``$env:LOCALAPPDATA/mpremote/config.py``
|
||||
|
||||
The ``config.py``` file should define a dictionary named ``commands``. The keys of this dictionary are the shortcuts
|
||||
Additional shortcuts can be defined by in user-configuration files, which is
|
||||
located at ``.config/mpremote/config.py``. This file should define a
|
||||
dictionary named ``commands``. The keys of this dictionary are the shortcuts
|
||||
and the values are either a string or a list-of-strings:
|
||||
|
||||
.. code-block:: python3
|
||||
@@ -536,7 +477,7 @@ An example ``config.py`` might look like:
|
||||
""",], # Print out nearby WiFi networks.
|
||||
"wl_ipconfig": [
|
||||
"exec",
|
||||
"import network; sta_if = network.WLAN(network.WLAN.IF_STA); print(sta_if.ipconfig('addr4'))",
|
||||
"import network; sta_if = network.WLAN(network.STA_IF); print(sta_if.ipconfig('addr4'))",
|
||||
""",], # Print ip address of station interface.
|
||||
"test": ["mount", ".", "exec", "import test"], # Mount current directory and run test.py.
|
||||
"demo": ["run", "path/to/demo.py"], # Execute demo.py on the device.
|
||||
@@ -606,9 +547,9 @@ device at ``/dev/ttyACM1``, printing each result.
|
||||
|
||||
mpremote resume exec "print_state_info()" soft-reset
|
||||
|
||||
Connect to the device without triggering a :ref:`soft reset <soft_reset>` and
|
||||
execute the ``print_state_info()`` function (e.g. to find out information about
|
||||
the current program state), then trigger a soft reset.
|
||||
Connect to the device without triggering a soft reset and execute the
|
||||
``print_state_info()`` function (e.g. to find out information about the current
|
||||
program state), then trigger a soft reset.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ On the Unix port, ``mip`` can be used at the REPL as above, and also by using ``
|
||||
$ ./micropython -m mip install pkgname-or-url
|
||||
$ ./micropython -m mip install pkgname-or-url@version
|
||||
|
||||
The ``--target path``, ``--no-mpy``, and ``--index`` arguments can be set::
|
||||
The ``--target=path``, ``--no-mpy``, and ``--index`` arguments can be set::
|
||||
|
||||
$ ./micropython -m mip install --target third-party pkgname
|
||||
$ ./micropython -m mip install --target=third-party pkgname
|
||||
$ ./micropython -m mip install --no-mpy pkgname
|
||||
$ ./micropython -m mip install --index https://host/pi pkgname
|
||||
|
||||
@@ -96,18 +96,6 @@ The ``--target=path``, ``--no-mpy``, and ``--index`` arguments can be set::
|
||||
$ mpremote mip install --no-mpy pkgname
|
||||
$ mpremote mip install --index https://host/pi pkgname
|
||||
|
||||
:term:`mpremote` can also install packages from files stored on the host's local
|
||||
filesystem::
|
||||
|
||||
$ mpremote mip install path/to/pkg.py
|
||||
$ mpremote mip install path/to/app/package.json
|
||||
$ mpremote mip install \\path\\to\\pkg.py
|
||||
|
||||
This is especially useful for testing packages during development and for
|
||||
installing packages from local clones of GitHub repositories. Note that URLs in
|
||||
``package.json`` files must use forward slashes ("/") as directory separators,
|
||||
even on Windows, so that they are compatible with installing from the web.
|
||||
|
||||
Installing packages manually
|
||||
----------------------------
|
||||
|
||||
@@ -128,25 +116,12 @@ To write a "self-hosted" package that can be downloaded by ``mip`` or
|
||||
``mpremote``, you need a static webserver (or GitHub) to host either a
|
||||
single .py file, or a ``package.json`` file alongside your .py files.
|
||||
|
||||
An example ``mlx90640`` library hosted on GitHub could be installed with::
|
||||
|
||||
$ mpremote mip install github:org/micropython-mlx90640
|
||||
|
||||
The layout for the package on GitHub might look like::
|
||||
|
||||
https://github.com/org/micropython-mlx90640/
|
||||
package.json
|
||||
mlx90640/
|
||||
__init__.py
|
||||
utils.py
|
||||
|
||||
The ``package.json`` specifies the location of files to be installed and other
|
||||
dependencies::
|
||||
A typical ``package.json`` for an example ``mlx90640`` library looks like::
|
||||
|
||||
{
|
||||
"urls": [
|
||||
["mlx90640/__init__.py", "mlx90640/__init__.py"],
|
||||
["mlx90640/utils.py", "mlx90640/utils.py"]
|
||||
["mlx90640/__init__.py", "github:org/micropython-mlx90640/mlx90640/__init__.py"],
|
||||
["mlx90640/utils.py", "github:org/micropython-mlx90640/mlx90640/utils.py"]
|
||||
],
|
||||
"deps": [
|
||||
["collections-defaultdict", "latest"],
|
||||
@@ -157,20 +132,9 @@ dependencies::
|
||||
"version": "0.2"
|
||||
}
|
||||
|
||||
The ``urls`` list specifies the files to be installed according to::
|
||||
|
||||
"urls": [
|
||||
[destination_path, source_url]
|
||||
...
|
||||
|
||||
where ``destination_path`` is the location and name of the file to be installed
|
||||
on the device and ``source_url`` is the URL of the file to be installed. The
|
||||
source URL would usually be specified relative to the directory containing the
|
||||
``package.json`` file, but can also be an absolute URL, eg::
|
||||
|
||||
["mlx90640/utils.py", "github:org/micropython-mlx90640/mlx90640/utils.py"]
|
||||
|
||||
The package depends on ``collections-defaultdict`` and ``os-path`` which will
|
||||
This includes two files, hosted at a GitHub repo named
|
||||
``org/micropython-mlx90640``, which install into the ``mlx90640`` directory on
|
||||
the device. It depends on ``collections-defaultdict`` and ``os-path`` which will
|
||||
be installed automatically from the :term:`micropython-lib`. The third
|
||||
dependency installs the content as defined by the ``package.json`` file of the
|
||||
``main`` branch of the GitHub repo ``org/micropython-additions``.
|
||||
|
||||
@@ -143,12 +143,10 @@ the auto-indent feature, and changes the prompt from ``>>>`` to ``===``. For exa
|
||||
Paste Mode allows blank lines to be pasted. The pasted text is compiled as if
|
||||
it were a file. Pressing Ctrl-D exits paste mode and initiates the compilation.
|
||||
|
||||
.. _repl_soft_reset:
|
||||
|
||||
Soft reset
|
||||
----------
|
||||
|
||||
A :ref:`soft_reset` will reset the python interpreter, but tries not to reset the
|
||||
A soft reset will reset the python interpreter, but tries not to reset the
|
||||
method by which you're connected to the MicroPython board (USB-serial, or Wifi).
|
||||
|
||||
You can perform a soft reset from the REPL by pressing Ctrl-D, or from your python
|
||||
@@ -184,9 +182,6 @@ variables no longer exist:
|
||||
['__name__', 'pyb']
|
||||
>>>
|
||||
|
||||
For more information about reset types and the startup process, see
|
||||
:doc:`/reference/reset_boot`.
|
||||
|
||||
The special variable _ (underscore)
|
||||
-----------------------------------
|
||||
|
||||
@@ -201,8 +196,6 @@ So you can use the underscore to save the result in a variable. For example:
|
||||
15
|
||||
>>>
|
||||
|
||||
.. _raw_repl:
|
||||
|
||||
Raw mode and raw-paste mode
|
||||
---------------------------
|
||||
|
||||
@@ -213,7 +206,7 @@ echo turned off, and with optional flow control.
|
||||
Raw mode is entered using Ctrl-A. You then send your python code, followed by
|
||||
a Ctrl-D. The Ctrl-D will be acknowledged by 'OK' and then the python code will
|
||||
be compiled and executed. Any output (or errors) will be sent back. Entering
|
||||
Ctrl-B will leave raw mode and return the regular (aka friendly) REPL.
|
||||
Ctrl-B will leave raw mode and return the the regular (aka friendly) REPL.
|
||||
|
||||
Raw-paste mode is an additional mode within the raw REPL that includes flow control,
|
||||
and which compiles code as it receives it. This makes it more robust for high-speed
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
Reset and Boot Sequence
|
||||
=======================
|
||||
|
||||
A device running MicroPython follows a particular boot sequence to start up and
|
||||
initialise itself after a reset.
|
||||
|
||||
.. _hard_reset:
|
||||
|
||||
Hard reset
|
||||
----------
|
||||
|
||||
Booting from hard reset is what happens when a board is first powered up, a cold
|
||||
boot. This is a complete reset of the MCU hardware.
|
||||
|
||||
The MicroPython port code initialises all essential hardware (including embedded
|
||||
clocks and power regulators, internal serial UART, etc), and then starts the
|
||||
MicroPython environment. Existing :doc:`RTC </library/machine.RTC>`
|
||||
configuration may be retained after a hard reset, but all other hardware state
|
||||
is cleared.
|
||||
|
||||
The same hard reset boot sequence can be triggered by a number of events such as:
|
||||
|
||||
- Python code executing :func:`machine.reset()`.
|
||||
- User presses a physical Reset button on the board (where applicable).
|
||||
- Waking from deep sleep (on most ports).
|
||||
- MCU hardware watchdog reset.
|
||||
- MCU hardware brown out detector.
|
||||
|
||||
The details of hardware-specific reset triggers depend on the port and
|
||||
associated hardware. The :func:`machine.reset_cause()` function can be used to
|
||||
further determine the cause of a reset.
|
||||
|
||||
.. _soft_reset:
|
||||
|
||||
Soft Reset
|
||||
----------
|
||||
|
||||
When MicroPython is already running, it's possible to trigger a soft reset by
|
||||
:ref:`typing Ctrl-D in the REPL <repl_soft_reset>` or executing
|
||||
:func:`machine.soft_reset()`.
|
||||
|
||||
A soft reset clears the Python interpreter, frees all Python memory, and starts
|
||||
the MicroPython environment again.
|
||||
|
||||
State which is cleared by a soft reset includes:
|
||||
|
||||
- All Python variables, objects, imported modules, etc.
|
||||
- Most peripherals configured using the :doc:`machine module
|
||||
</library/machine>`. There are very limited exceptions, for example
|
||||
:doc:`machine.Pin </library/machine.Pin>` modes (i.e. if a pin is input or
|
||||
output, high or low) are not reset on most ports. More advanced configuration
|
||||
such as :func:`Pin.irq()` is always reset.
|
||||
- Bluetooth.
|
||||
- Network sockets. Open TCP sockets are closed cleanly with respect to the other party.
|
||||
- Open files. The filesystem is left in a valid state.
|
||||
|
||||
Some system state remains the same after a soft reset, including:
|
||||
|
||||
- Any existing network connections (Ethernet, Wi-Fi, etc) remain active at the
|
||||
IP Network layer. Querying the :doc:`network interface from code
|
||||
</library/network>` may indicate the network interface is still active with a
|
||||
configured IP address, etc.
|
||||
- An active :doc:`REPL <repl>` appears continuous before and after soft reset,
|
||||
except in some unusual cases:
|
||||
|
||||
* If the :ref:`machine.USBDevice <machine.USBDevice>` class has been used to
|
||||
create a custom USB interface then any built-in USB serial device will
|
||||
appear to disconnect and reconnect as the custom USB interface must be
|
||||
cleared during reset.
|
||||
* A serial UART REPL will restore its default hardware configuration (baud
|
||||
rate, etc).
|
||||
|
||||
- CPU clock speed is usually not changed by a soft reset.
|
||||
- :doc:`RTC </library/machine.RTC>` configuration (i.e. setting of the current
|
||||
time) is not changed by soft reset.
|
||||
|
||||
.. _boot_sequence:
|
||||
|
||||
Boot Sequence
|
||||
-------------
|
||||
|
||||
When MicroPython boots following either a hard or soft reset, it follows this
|
||||
boot sequence in order:
|
||||
|
||||
_boot.py
|
||||
^^^^^^^^
|
||||
|
||||
This is an internal script :doc:`frozen into the MicroPython firmware
|
||||
<manifest>`. It is provided by MicroPython on many ports to do essential
|
||||
initialisation.
|
||||
|
||||
For example, on most ports ``_boot.py`` will detect the first boot of a new
|
||||
device and format the :doc:`internal flash filesystem <filesystem>` ready for
|
||||
use.
|
||||
|
||||
Unless you're creating a custom MicroPython build or adding a new port then you
|
||||
probably don't need to worry about ``_boot.py``. It's best not to change the
|
||||
contents unless you really know what you're doing.
|
||||
|
||||
.. _boot.py:
|
||||
|
||||
boot.py
|
||||
^^^^^^^
|
||||
|
||||
A file named ``boot.py`` can be copied to the board's internal :ref:`filesystem
|
||||
<filesystem>` using :doc:`mpremote <mpremote>`.
|
||||
|
||||
If ``boot.py`` is found then it is executed. You can add code in ``boot.py`` to
|
||||
perform custom one-off initialisation (for example, to configure the board's
|
||||
hardware).
|
||||
|
||||
A common practice is to configure a board's network connection in ``boot.py`` so
|
||||
that it's always available after reset for use with the :doc:`REPL <repl>`,
|
||||
:doc:`mpremote <mpremote>`, etc.
|
||||
|
||||
.. warning:: boot.py should always exit and not run indefinitely.
|
||||
|
||||
Depending on the port, some hardware initialisation is delayed until after
|
||||
``boot.py`` exits. This includes initialising USB on the stm32 port and all
|
||||
ports which support :ref:`machine.USBDevice <machine.USBDevice>`. On these
|
||||
ports, output printed from ``boot.py`` may not be visible on the built-in USB
|
||||
serial port until after ``boot.py`` finishes running.
|
||||
|
||||
The purpose of this late initialisation is so that it's possible to
|
||||
pre-configure particular hardware in ``boot.py``, and then have it start with
|
||||
the correct configuration.
|
||||
|
||||
.. note:: It is sometimes simpler to not have a ``boot.py`` file and place any
|
||||
initialisation code at the top of ``main.py`` instead.
|
||||
|
||||
.. _main.py:
|
||||
|
||||
main.py
|
||||
^^^^^^^
|
||||
|
||||
Similar to ``boot.py``, a file named ``main.py`` can be copied to the board's
|
||||
internal :ref:`filesystem <filesystem>`. If found then it is executed next in the
|
||||
startup process.
|
||||
|
||||
``main.py`` is for any Python code that you want to run each time your device
|
||||
starts.
|
||||
|
||||
Some tips for ``main.py`` usage:
|
||||
|
||||
- ``main.py`` doesn't have to exit, feel free to put an infinite ``while
|
||||
True`` loop in there.
|
||||
- For complex Python applications then you don't need to put all your
|
||||
code in ``main.py``. ``main.py`` can be a simple entry point that
|
||||
imports your application and starts execution::
|
||||
|
||||
import my_app
|
||||
my_app.main()
|
||||
|
||||
This can help keep the structure of your application clear. It also makes
|
||||
it easy to install multiple applications on a board and switch among them.
|
||||
- It's good practice when writing robust apps to wrap code in ``main.py`` with an
|
||||
exception handler to take appropriate action if the code crashes. For example::
|
||||
|
||||
import machine, sys
|
||||
import my_app
|
||||
try:
|
||||
my_app.main()
|
||||
except Exception as e:
|
||||
print("Fatal error in main:")
|
||||
sys.print_exception(e)
|
||||
|
||||
# Following a normal Exception or main() exiting, reset the board.
|
||||
# Following a non-Exception error such as KeyboardInterrupt (Ctrl-C),
|
||||
# this code will drop to a REPL. Place machine.reset() in a finally
|
||||
# block to always reset, instead.
|
||||
machine.reset()
|
||||
|
||||
Otherwise MicroPython will drop to the REPL following any crash or if main
|
||||
exits (see below).
|
||||
|
||||
- Any global variables that were set in ``boot.py`` will still be set in the
|
||||
global context of ``main.py``.
|
||||
|
||||
- To fully optimise flash usage and memory consumption, you can copy
|
||||
:doc:`pre-compiled <mpyfiles>` ``main.mpy`` and/or ``boot.mpy`` files to the
|
||||
filesystem, or even :doc:`freeze <manifest>` them into the firmware build
|
||||
instead.
|
||||
- ``main.py`` execution is skipped when a soft reset is initiated from :ref:`raw
|
||||
REPL mode <raw_repl>` (for example, when :doc:`mpremote <mpremote>` or another
|
||||
program is interacting directly with MicroPython).
|
||||
|
||||
Interactive Interpreter (REPL)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If ``main.py`` is not found, or if ``main.py`` exits, then :doc:`repl`
|
||||
will start immediately.
|
||||
|
||||
.. note:: Even if ``main.py`` contains an infinite loop, typing Ctrl-C on the
|
||||
REPL serial port will inject a `KeyboardInterrupt`. If no exception
|
||||
handler catches it then ``main.py`` will exit and the REPL will start.
|
||||
|
||||
Any global variables that were set in ``boot.py`` and ``main.py`` will still be
|
||||
set in the global context of the REPL.
|
||||
|
||||
The REPL continues executing until Python code triggers a hard or soft reset.
|
||||
|
||||
.. _soft_bricking:
|
||||
|
||||
Soft Bricking (failure to boot)
|
||||
---------------------------------
|
||||
|
||||
It is rare but possible for MicroPython to become unresponsive during startup, a
|
||||
state sometimes called "soft bricked". For example:
|
||||
|
||||
- If ``boot.py`` execution gets stuck and the native USB serial port
|
||||
never initialises.
|
||||
- If Python code reconfigures the REPL interface, making it inaccessible.
|
||||
|
||||
Rest assured, recovery is possible!
|
||||
|
||||
KeyboardInterrupt
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
In many cases, opening the REPL serial port and typing ``Ctrl-C`` will inject
|
||||
`KeyboardInterrupt` and may cause the running script to exit and a REPL to
|
||||
start. From the REPL, you can use :func:`os.remove()` to remove the misbehaving
|
||||
Python file::
|
||||
|
||||
import os
|
||||
os.remove('main.py')
|
||||
|
||||
To confirm which files are still present in the internal filesystem::
|
||||
|
||||
import os
|
||||
os.listdir()
|
||||
|
||||
Safe Mode and Factory Reset
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you're unable to easily access the REPL then you may need to perform one of
|
||||
two processes:
|
||||
|
||||
1. "Safe mode" boot, which skips ``boot.py`` and ``main.py`` and immediately
|
||||
starts a REPL, allowing you to clean up. This is only supported on some ports.
|
||||
2. Factory Reset to erase the entire contents of the flash filesystem. This may
|
||||
also be necessary if the internal flash filesystem has become corrupted
|
||||
somehow.
|
||||
|
||||
The specific process(es) are different on each port:
|
||||
|
||||
- :doc:`pyboard and stm32 port instructions </pyboard/tutorial/reset>`
|
||||
- :doc:`esp32 port instructions </esp32/tutorial/reset>`
|
||||
- :doc:`renesas-ra port instructions </renesas-ra/tutorial/reset>`
|
||||
- :doc:`rp2 port instructions </rp2/tutorial/reset>`
|
||||
- :doc:`wipy port instructions </wipy/tutorial/reset>`
|
||||
|
||||
For ports without specific instructions linked above, the factory reset process
|
||||
involves erasing the board's entire flash and then flashing MicroPython again
|
||||
from scratch. Usually this will involve the same tool(s) that were originally
|
||||
used to install MicroPython. Consult the installation docs for your board, or
|
||||
ask on the `GitHub Discussions`_ if you're not sure.
|
||||
|
||||
.. warning:: Re-flashing the MicroPython firmware without erasing the entire
|
||||
flash first will usually not recover from soft bricking, as a
|
||||
firmware update usually preserves the contents of the filesystem.
|
||||
|
||||
.. _GitHub Discussions: https://github.com/orgs/micropython/discussions
|
||||
@@ -57,8 +57,6 @@ and used in various methods.
|
||||
|
||||
This is covered in further detail :ref:`Controlling garbage collection <controlling_gc>` below.
|
||||
|
||||
.. _speed_buffers:
|
||||
|
||||
Buffers
|
||||
~~~~~~~
|
||||
|
||||
@@ -71,13 +69,6 @@ example, objects which support stream interface (e.g., file or UART) provide ``r
|
||||
method which allocates new buffer for read data, but also a ``readinto()`` method
|
||||
to read data into an existing buffer.
|
||||
|
||||
Some useful classes for creating reusable buffer objects:
|
||||
|
||||
- :class:`bytearray`
|
||||
- :mod:`array` (:ref:`discussed below<speed_arrays>`)
|
||||
- :class:`io.StringIO` and :class:`io.BytesIO`
|
||||
- :class:`micropython.RingIO`
|
||||
|
||||
Floating point
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
@@ -89,20 +80,15 @@ point to sections of the code where performance is not paramount. For example,
|
||||
capture ADC readings as integers values to an array in one quick go, and only then
|
||||
convert them to floating-point numbers for signal processing.
|
||||
|
||||
.. _speed_arrays:
|
||||
|
||||
Arrays
|
||||
~~~~~~
|
||||
|
||||
Consider the use of the various types of array classes as an alternative to lists.
|
||||
The :mod:`array` module supports various element types with 8-bit elements supported
|
||||
The `array` module supports various element types with 8-bit elements supported
|
||||
by Python's built in `bytes` and `bytearray` classes. These data structures all store
|
||||
elements in contiguous memory locations. Once again to avoid memory allocation in critical
|
||||
code these should be pre-allocated and passed as arguments or as bound objects.
|
||||
|
||||
Memoryviews
|
||||
~~~~~~~~~~~
|
||||
|
||||
When passing slices of objects such as `bytearray` instances, Python creates
|
||||
a copy which involves allocation of the size proportional to the size of slice.
|
||||
This can be alleviated using a `memoryview` object. The `memoryview` itself
|
||||
@@ -132,23 +118,6 @@ of buffer and fills in entire buffer. What if you need to put data in the
|
||||
middle of existing buffer? Just create a memoryview into the needed section
|
||||
of buffer and pass it to ``readinto()``.
|
||||
|
||||
Strings vs Bytes
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
MicroPython uses :ref:`string interning <qstr>` to save space when there are
|
||||
multiple identical strings. Each time a new string is allocated at runtime (for
|
||||
example, when two other strings are concatenated), MicroPython checks whether
|
||||
the new string can be interned to save RAM.
|
||||
|
||||
If you have code which performs performance-critical string operations then
|
||||
consider using :class:`bytes` objects and literals (i.e. ``b"abc"``). This skips
|
||||
the interning check, and can be several times faster than performing the same
|
||||
operations with string objects.
|
||||
|
||||
.. note:: The fastest performance will always be achieved by avoiding new object
|
||||
creation entirely, for example with a reusable :ref:`buffer as described
|
||||
above<speed_buffers>`.
|
||||
|
||||
Identifying the slowest section of code
|
||||
---------------------------------------
|
||||
|
||||
@@ -219,7 +188,7 @@ process known as garbage collection reclaims the memory used by these redundant
|
||||
objects and the allocation is then tried again - a process which can take several
|
||||
milliseconds.
|
||||
|
||||
There may be benefits in preempting this by periodically issuing `gc.collect()`.
|
||||
There may be benefits in pre-empting this by periodically issuing `gc.collect()`.
|
||||
Firstly doing a collection before it is actually required is quicker - typically on the
|
||||
order of 1ms if done frequently. Secondly you can determine the point in code
|
||||
where this time is used rather than have a longer delay occur at random points,
|
||||
@@ -246,13 +215,6 @@ There are certain limitations in the current implementation of the native code e
|
||||
* Context managers are not supported (the ``with`` statement).
|
||||
* Generators are not supported.
|
||||
* If ``raise`` is used an argument must be supplied.
|
||||
* The background scheduler (see `micropython.schedule`) is not run during
|
||||
execution of native code.
|
||||
* On targets with thrteading and the GIL, the GIL is not released during
|
||||
execution of native code.
|
||||
|
||||
To mitigate the last two points, long running native functions should call
|
||||
``time.sleep(0)`` periodically, which will run the scheduler and bounce the GIL.
|
||||
|
||||
The trade-off for the improved performance (roughly twice as fast as bytecode) is an
|
||||
increase in compiled code size.
|
||||
|
||||
@@ -206,9 +206,8 @@ 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
|
||||
# time, eg 2017/8/23 1:12:48
|
||||
rtc.datetime() # get date and time
|
||||
|
||||
Following functions are not supported at the present::
|
||||
|
||||
@@ -28,8 +28,6 @@ As the factory setting, following 2 files are created in the file system:
|
||||
* boot.py : executed first when the system starts
|
||||
* main.py : executed after boot.py completes
|
||||
|
||||
See :doc:`/reference/reset_boot` for more information.
|
||||
|
||||
Write a program in the internal file system
|
||||
-------------------------------------------
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@ If that isn't working you can perform a hard reset (turn-it-off-and-on-again)
|
||||
by pressing the RESET button. This will end your session, disconnecting
|
||||
whatever program (PuTTY, screen, etc) that you used to connect to the board.
|
||||
|
||||
For more details, see :doc:`/reference/reset_boot`.
|
||||
|
||||
boot mode
|
||||
---------
|
||||
|
||||
@@ -31,9 +29,7 @@ There are 3 boot modes:
|
||||
* safe boot mode
|
||||
* factory filesystem boot mode
|
||||
|
||||
boot.py and main.py are executed on "normal boot mode". See :ref:`boot_sequence`.
|
||||
|
||||
The other modes can be used to recover from :ref:`soft_bricking`:
|
||||
boot.py and main.py are executed on "normal boot mode".
|
||||
|
||||
boot.py and main.py are *NOT* executed on "safe boot mode".
|
||||
|
||||
@@ -50,4 +46,16 @@ on the board:
|
||||
|
||||
You have created the main.py which executes LED1 blinking in the previous part.
|
||||
If you change the boot mode to safe boot mode, the MicroPython starts without
|
||||
the execution of main.py.
|
||||
the execution of main.py. Then you can remove the main.py by following
|
||||
command or change the boot mode to factory file system boot mode.::
|
||||
|
||||
import os
|
||||
os.remove('main.py')
|
||||
|
||||
or change the boot mode to factory file system boot mode.
|
||||
|
||||
You can confirm that the initialized file system that there are only boot.py and main.py files.::
|
||||
|
||||
import os
|
||||
os.listdir()
|
||||
|
||||
|
||||
@@ -55,57 +55,6 @@ The :mod:`rp2` module::
|
||||
|
||||
import rp2
|
||||
|
||||
Networking
|
||||
----------
|
||||
|
||||
WLAN
|
||||
^^^^
|
||||
|
||||
.. note::
|
||||
This section applies only to devices that include WiFi support, such as the `Pico W`_ and `Pico 2 W`_.
|
||||
|
||||
The :class:`network.WLAN` class in 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.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
|
||||
|
||||
ap = network.WLAN(network.WLAN.IF_AP) # create access-point interface
|
||||
ap.config(ssid='RP2-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()
|
||||
wlan.active(True)
|
||||
if not wlan.isconnected():
|
||||
print('connecting to network...')
|
||||
wlan.connect('ssid', 'key')
|
||||
while not wlan.isconnected():
|
||||
machine.idle()
|
||||
print('network config:', wlan.ipconfig('addr4'))
|
||||
|
||||
Once the network is established the :mod:`socket <socket>` module can be used
|
||||
to create and use TCP/UDP sockets as usual, and the ``requests`` module for
|
||||
convenient HTTP requests.
|
||||
|
||||
After a call to ``wlan.connect()``, the device will by default retry to connect
|
||||
**forever**, even when the authentication failed or no AP is in range.
|
||||
``wlan.status()`` will return ``network.STAT_CONNECTING`` in this state until a
|
||||
connection succeeds or the interface gets disabled.
|
||||
|
||||
.. _Pico W: https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#picow-technical-specification
|
||||
.. _Pico 2 W: https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#pico2w-technical-specification
|
||||
|
||||
Delay and timing
|
||||
----------------
|
||||
|
||||
@@ -135,12 +84,6 @@ Use the :mod:`machine.Timer` class::
|
||||
tim = Timer(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
|
||||
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))
|
||||
|
||||
By default, timer callbacks run as soft IRQs so they can allocate but
|
||||
are prone to GC jitter and delays. Pass ``hard=True`` to the ``Timer()``
|
||||
constructor or ``init()`` method to run the callback in hard-IRQ context
|
||||
instead. This reduces delay and jitter, but see :ref:`isr_rules` for the
|
||||
restrictions that apply to hard-IRQ handlers.
|
||||
|
||||
|
||||
.. _rp2_Pins_and_GPIO:
|
||||
|
||||
@@ -367,9 +310,8 @@ 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
|
||||
rtc.datetime((2017, 8, 23, 2, 12, 48, 0, 0)) # set a specific date and
|
||||
# time, eg. 2017/8/23 1:12:48
|
||||
# the day-of-week value is ignored
|
||||
rtc.datetime() # get date and time
|
||||
|
||||
WDT (Watchdog timer)
|
||||
|
||||
@@ -8,5 +8,4 @@ Let's get started!
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
reset.rst
|
||||
pio.rst
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
Factory reset
|
||||
=============
|
||||
|
||||
If something unexpected happens and your RP2xxx-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 rp2 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. Follow the instructions on the Raspberry Pi website for `resetting flash
|
||||
memory`_.
|
||||
2. Copy the MicroPython .uf2 firmware file to your board. If needed, this file
|
||||
can be found on the `MicroPython downloads page`_.
|
||||
|
||||
.. _resetting flash memory: https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#resetting-flash-memory
|
||||
.. _MicroPython downloads page: https://micropython.org/download/?port=rp2
|
||||
@@ -41,11 +41,9 @@ Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
|
||||
35 PB03 FLASH_MISO 3 11 - 5/1 6/1 -
|
||||
54 PB22 FLASH_MOSI 6 - - 5/2 7/0 -
|
||||
55 PB23 FLASH_SCK 7 - - 5/3 7/1 -
|
||||
11 PA11 RX 11 19 0/3 2/3 1/1 0/3
|
||||
10 PA10 TX 10 18 0/2 2/2 1/0 0/2
|
||||
12 PA12 MISO 12 - 2/0 4/0 2/0 0/6
|
||||
42 PA12 MOSI 10 - - 4/2 5/0 0/4
|
||||
43 PA13 SCK 11 - - 4/3 5/1 0/5
|
||||
42 PB10 MOSI 10 - - 4/2 5/0 0/4
|
||||
43 PB11 SCK 11 - - 4/3 5/1 0/5
|
||||
23 PA23 SCL 7 - 3/1 5/1 4/1 0/5
|
||||
22 PA22 SDA 6 - 3/0 5/0 4/0 0/4
|
||||
30 PA30 SWCLK 10 - - 1/2 1/0 -
|
||||
@@ -129,7 +127,7 @@ Examples for Adafruit ItsyBitsy M0 Express:
|
||||
- SPI 1 at pins D11/D12/D13
|
||||
- SPI 2 at pins D0/D4/D1
|
||||
- SPI 3 at pins D11/D12/D13
|
||||
- SPI 2 at Pin MOSI/MISO/SCK This is the default SPI device at the MOSI/MISO/SCK labelled pins.
|
||||
- SPI 4 at Pin MOSI/MISO/SCK This is the default SPI device at the MOSI/MISO/SCK labelled pins.
|
||||
|
||||
or other combinations.
|
||||
|
||||
@@ -171,8 +169,6 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
|
||||
22 PA22 D13 6 - - 3/0 5/1 4/0 1/6 0/2
|
||||
34 PB02 DOTSTAR_CLK 2 14 - - 5/0 6/0 2/2 -
|
||||
35 PB03 DOTSTAR_DATA 9 15 - - 5/1 6/1 - -
|
||||
16 PA16 RX 0 - - 1/0 3/1 2/0 1/0 0/4
|
||||
17 PA17 TX 1 - - 1/1 3/0 2/1 1/1 0/5
|
||||
55 PB23 MISO 7 - - 1/3 5/3 7/1 - -
|
||||
0 PA00 MOSI 0 - - - 1/0 2/0 - -
|
||||
43 PB11 QSPI_CS 12 - - - 4/3 5/1 0/5 1/1
|
||||
@@ -239,7 +235,7 @@ The I2C devices and signals must be chosen according to the following rules:
|
||||
- The SDA signal must be at a Pin with pad numbers 0.
|
||||
- The SCL signal must be at a Pin with pad numbers 1.
|
||||
|
||||
Examples for Adafruit ItsyBitsy M4 Express:
|
||||
Examples for Adafruit ItsyBitsy M0 Express:
|
||||
|
||||
- I2C 0 at pins A3/A4
|
||||
- I2C 1 at pins D0/D1
|
||||
@@ -257,7 +253,7 @@ The SPI devices and signals must be chosen according to the following rules:
|
||||
- The following pad number pairs are suitable for MOSI/SCK: 0/1 and 3/1.
|
||||
- The MISO signal must be at a Pin with a different pad number than MOSI or SCK.
|
||||
|
||||
Examples for Adafruit ItsyBitsy M4 Express:
|
||||
Examples for Adafruit ItsyBitsy M0 Express:
|
||||
|
||||
- SPI 1 at Pin MOSI/MISO/SCK This is the default SPI device at the MOSI/MISO/SCK labelled pins.
|
||||
- SPI 3 at pins D13/D11/D12
|
||||
@@ -300,8 +296,6 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
|
||||
21 PA21 D11 5 - - 5/3 3/3 7/1 1/5 0/1
|
||||
22 PA22 D12 6 - - 3/0 5/1 4/0 1/6 0/2
|
||||
23 PA23 D13 7 - - 3/1 5/0 4/1 1/7 0/3
|
||||
49 PB17 RX 1 - - 5/1 - 6/1 3/1 0/5
|
||||
48 PB16 TX 0 - - 5/0 - 6/0 3/0 0/4
|
||||
54 PB22 MISO 22 - - 1/2 5/2 7/0 - -
|
||||
55 PB23 MOSI 7 - - 1/3 5/3 7/1 - -
|
||||
35 PB03 NEOPIXEL 9 15 - - 5/1 6/1 - -
|
||||
@@ -387,8 +381,6 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
|
||||
8 PA08 FLASH_MOSI - 8 2 0/0 2/1 0/0 0/0 1/4
|
||||
42 PB10 FLASH_SCK 10 - - - 4/2 5/0 0/4 1/0
|
||||
10 PA10 FLASH_WP 10 10 - 0/2 2/2 1/0 0/2 1/6
|
||||
23 PA23 RX 7 - - 3/1 5/0 4/1 1/7 0/3
|
||||
22 PA22 TX 6 - - 3/0 5/1 4/0 1/6 0/2
|
||||
14 PA14 MISO 14 - - 2/2 4/2 3/0 2/0 1/2
|
||||
12 PA12 MOSI 12 - - 2/0 4/1 2/0 0/6 1/2
|
||||
54 PB22 NEOPIXEL 22 - - 1/2 5/2 7/0 - -
|
||||
@@ -437,13 +429,6 @@ Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
|
||||
5 PA05 A9_D9 5 5 - 0/1 0/1 -
|
||||
6 PA06 A10_D10 6 6 - 0/2 1/0 -
|
||||
18 PA18 RX_LED 2 - 1/2 3/2 3/0 0/2
|
||||
41 PB09 RX 9 3 - 4/1 4/1 -
|
||||
40 PB08 TX 8 2 - 4/0 4/0 -
|
||||
8 PA08 SDA - 16 0/0 2/0 0/0 1/2
|
||||
9 PA09 SCL 9 17 0/1 2/1 0/1 1/3
|
||||
6 PA06 MOSI 6 6 - 0/2 1/0 -
|
||||
5 PA05 MISO 5 5 - 0/1 0/1 -
|
||||
7 PA07 SCK 7 7 - 0/3 1/1 -
|
||||
30 PA30 SWCLK 10 - - 1/2 1/0 -
|
||||
31 PA31 SWDIO 11 - - 1/3 1/1 -
|
||||
19 PA19 TX_LED 3 - 1/3 3/3 3/1 0/3
|
||||
@@ -518,8 +503,6 @@ Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
|
||||
43 PB11 SCK 11 - - 4/3 5/1 0/5
|
||||
23 PA23 SCL 7 - 3/1 5/1 4/1 0/5
|
||||
22 PA22 SDA 6 - 3/0 5/0 4/0 0/4
|
||||
11 PA11 RX 11 19 0/3 2/3 1/1 0/3
|
||||
10 PA10 TX 10 18 0/2 2/2 1/0 0/2
|
||||
30 PA30 SWCLK 10 - - 1/2 1/0 -
|
||||
31 PA31 SWDIO 11 - - 1/3 1/1 -
|
||||
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
|
||||
@@ -535,9 +518,9 @@ Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
|
||||
|
||||
The default devices at the board are:
|
||||
|
||||
- UART 2 at pins PA11/PA10, labelled RX/TX
|
||||
- UART 5 at pins PB23/PB22, labelled RX/TX
|
||||
- I2C 3 at pins PA22/PA23, labelled SDA/SCL
|
||||
- SPI 4 at pins PB10/PA12/PB11, labelled MOSI, MISO and SCK
|
||||
- SPI 4 at pins PA10/PA12/PA11, labelled MOSI, MISO and SCK
|
||||
- DAC output on pin PA02, labelled A0
|
||||
|
||||
Adafruit Trinket M0 pin assignment table
|
||||
@@ -553,13 +536,6 @@ Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
|
||||
6 PA06 D4 6 6 - 0/2 1/0 -
|
||||
1 PA01 DOTSTAR_CLK 1 - - 1/1 2/1 -
|
||||
0 PA00 DOTSTAR_DATA 0 - - 1/0 2/0 -
|
||||
7 PA07 RX 7 7 - 0/3 1/1 -
|
||||
6 PA06 TX 6 6 - 0/2 1/0 -
|
||||
8 PA08 SDA - 16 0/0 2/0 0/0 1/2
|
||||
9 PA09 SCL 9 17 0/1 2/1 0/1 1/3
|
||||
6 PA06 MOSI 6 6 - 0/2 1/0 -
|
||||
9 PA09 MISO 9 17 0/1 2/1 0/1 1/3
|
||||
7 PA07 SCK 7 7 - 0/3 1/1 -
|
||||
10 PA10 LED 10 18 0/2 2/2 1/0 0/2
|
||||
30 PA30 SWCLK 10 - - 1/2 1/0 -
|
||||
31 PA31 SWDIO 11 - - 1/3 1/1 -
|
||||
@@ -591,184 +567,6 @@ The default devices at the board are:
|
||||
- SPI 0 at pins PA06/PA09/PA08, labelled D4, D2 and D0
|
||||
- DAC output on pin PA02, labelled D1
|
||||
|
||||
Adafruit QT PY pin assignment table
|
||||
-----------------------------------
|
||||
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
2 PA02 A0 2 0 - - - -
|
||||
3 PA03 A1 3 1 - - - -
|
||||
4 PA04 A2 4 4 - 0/0 0/0 -
|
||||
5 PA05 A3 5 5 - 0/1 0/1 -
|
||||
7 PA07 RX 7 7 - 0/3 1/1 -
|
||||
6 PA06 TX 6 6 - 0/2 1/0 -
|
||||
8 PA08 FLASH_CS - 16 0/0 2/0 0/0 1/2
|
||||
19 PA19 FLASH_MISO 3 - 1/3 3/3 3/1 0/3
|
||||
22 PA22 FLASH_MOSI 6 - 3/0 5/0 4/0 0/4
|
||||
23 PA23 FLASH_SCK 7 - 3/1 5/1 4/1 0/5
|
||||
9 PA09 MISO 9 17 0/1 2/1 0/1 1/3
|
||||
10 PA10 MOSI 10 18 0/2 2/2 1/0 0/2
|
||||
18 PA18 NEOPIX 2 - 1/2 3/2 3/0 0/2
|
||||
15 PA15 NEO_PWR 15 - 2/3 4/3 3/1 0/5
|
||||
11 PA11 SCK 11 19 0/3 2/3 1/1 0/3
|
||||
17 PA17 SCL 1 - 1/1 3/1 2/1 0/7
|
||||
16 PA16 SDA 0 - 1/0 3/0 2/0 0/6
|
||||
30 PA30 SWCLK 10 - - 1/2 1/0 -
|
||||
31 PA31 SWDIO 11 - - 1/3 1/1 -
|
||||
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
|
||||
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
|
||||
For the definition of the table columns see the explanation at the table for
|
||||
Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
|
||||
|
||||
The default devices at the board are:
|
||||
|
||||
- UART 0 at pins PA07/PA06, labelled RX/TX
|
||||
- I2C 1 at pins PA16/PA17, labelled SDA/SCL
|
||||
- SPI 0 at pins PA09/PA10/PA11, labelled MISO, MOSI and SCK
|
||||
- DAC output on pin PA02, labelled A0
|
||||
|
||||
Adafruit NeoKey Trinkey pin assignment table
|
||||
--------------------------------------------
|
||||
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
15 PA15 NEOPIXEL 15 - 2/3 4/3 3/1 0/5
|
||||
30 PA30 SWCLK 10 - - 1/2 1/0 -
|
||||
31 PA31 SWDIO 11 - - 1/3 1/1 -
|
||||
18 PA18 SWITCH 2 - 1/2 3/2 3/0 0/2
|
||||
7 PA07 TOUCH 7 7 - 0/3 1/1 -
|
||||
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
|
||||
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
|
||||
For the definition of the table columns see the explanation at the table for
|
||||
Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
|
||||
|
||||
The board does not provide access to UART, I2C, SPI or DAC.
|
||||
|
||||
SparkFun Redboard Turbo assignment table
|
||||
----------------------------------------
|
||||
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
2 PA02 A0 2 0 - - - -
|
||||
40 PB08 A1 8 2 - 4/0 4/0 -
|
||||
41 PB09 A2 9 3 - 4/1 4/1 -
|
||||
4 PA04 A3 4 4 - 0/0 0/0 -
|
||||
5 PA05 A4 5 5 - 0/1 0/1 -
|
||||
34 PB02 A5 2 10 - 5/0 6/0 -
|
||||
11 PA11 D0 11 19 0/3 2/3 1/1 0/3
|
||||
10 PA10 D1 10 18 0/2 2/2 1/0 0/2
|
||||
14 PA14 D2 14 - 2/2 4/2 3/0 0/4
|
||||
9 PA09 D3 9 17 0/1 2/1 0/1 1/3
|
||||
8 PA08 D4 - 16 0/0 2/0 0/0 1/2
|
||||
15 PA15 D5 15 - 2/3 4/3 3/1 0/5
|
||||
20 PA20 D6 4 - 5/2 3/2 7/0 0/4
|
||||
21 PA21 D7 5 - 5/3 3/3 7/1 0/7
|
||||
6 PA06 D8 6 6 - 0/2 1/0 -
|
||||
7 PA07 D9 7 7 - 0/3 1/1 -
|
||||
11 PA11 RX 11 19 0/3 2/3 1/1 0/3
|
||||
10 PA10 TX 10 18 0/2 2/2 1/0 0/2
|
||||
3 PA03 AREF 3 1 - - - -
|
||||
18 PA18 D10 2 - 1/2 3/2 3/0 0/2
|
||||
16 PA16 D11 0 - 1/0 3/0 2/0 0/6
|
||||
19 PA19 D12 3 - 1/3 3/3 3/1 0/3
|
||||
17 PA17 D13 1 - 1/1 3/1 2/1 0/7
|
||||
13 PA13 FLASH_CS 13 - 2/1 4/1 2/0 0/7
|
||||
35 PB03 FLASH_MISO 3 11 - 5/1 6/1 -
|
||||
54 PB22 FLASH_MOSI 6 - - 5/2 7/0 -
|
||||
55 PB23 FLASH_SCK 7 - - 5/3 7/1 -
|
||||
31 PA31 LED_RX 11 - - 1/3 1/1 -
|
||||
27 PA27 LED_TX 15 - - - - -
|
||||
12 PA12 MISO 12 - 2/0 4/0 2/0 0/6
|
||||
42 PB10 MOSI 10 - - 4/2 5/0 0/4
|
||||
30 PA30 NEOPIXEL 10 - - 1/2 1/0 -
|
||||
43 PB11 SCK 11 - - 4/3 5/1 0/5
|
||||
23 PA23 SCL 7 - 3/1 5/1 4/1 0/5
|
||||
22 PA22 SDA 6 - 3/0 5/0 4/0 0/4
|
||||
30 PA30 SWCLK 10 - - 1/2 1/0 -
|
||||
31 PA31 SWDIO 11 - - 1/3 1/1 -
|
||||
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
|
||||
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
|
||||
0 PA00 0 - - 1/0 2/0 -
|
||||
1 PA01 1 - - 1/1 2/1 -
|
||||
28 PA28 8 - - - - -
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
|
||||
For the definition of the table columns see the explanation at the table for
|
||||
Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
|
||||
|
||||
The default devices at the board are:
|
||||
|
||||
- UART 0 at pins PA11/PA10, labelled RX/TX
|
||||
- I2C 3 at pins PA22/PA23, labelled SDA/SCL
|
||||
- SPI 4 at pins PB10/PA12/PB11, labelled MISO, MOSI and SCK
|
||||
- DAC output on pin PA02, labelled A0
|
||||
|
||||
|
||||
SparkFun SAMD21 Dev Breakout assignment table
|
||||
---------------------------------------------
|
||||
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
2 PA02 A0 2 0 - - - -
|
||||
40 PB08 A1 8 2 - 4/0 4/0 -
|
||||
41 PB09 A2 9 3 - 4/1 4/1 -
|
||||
4 PA04 A3 4 4 - 0/0 0/0 -
|
||||
5 PA05 A4 5 5 - 0/1 0/1 -
|
||||
34 PB02 A5 2 10 - 5/0 6/0 -
|
||||
11 PA11 D0 11 19 0/3 2/3 1/1 0/3
|
||||
10 PA10 D1 10 18 0/2 2/2 1/0 0/2
|
||||
14 PA14 D2 14 - 2/2 4/2 3/0 0/4
|
||||
9 PA09 D3 9 17 0/1 2/1 0/1 1/3
|
||||
8 PA08 D4 - 16 0/0 2/0 0/0 1/2
|
||||
15 PA15 D5 15 - 2/3 4/3 3/1 0/5
|
||||
20 PA20 D6 4 - 5/2 3/2 7/0 0/4
|
||||
21 PA21 D7 5 - 5/3 3/3 7/1 0/7
|
||||
6 PA06 D8 6 6 - 0/2 1/0 -
|
||||
7 PA07 D9 7 7 - 0/3 1/1 -
|
||||
11 PA11 RX 11 19 0/3 2/3 1/1 0/3
|
||||
10 PA10 TX 10 18 0/2 2/2 1/0 0/2
|
||||
3 PA03 AREF 3 1 - - - -
|
||||
18 PA18 D10 2 - 1/2 3/2 3/0 0/2
|
||||
16 PA16 D11 0 - 1/0 3/0 2/0 0/6
|
||||
19 PA19 D12 3 - 1/3 3/3 3/1 0/3
|
||||
17 PA17 D13 1 - 1/1 3/1 2/1 0/7
|
||||
54 PB22 D30 6 - - 5/2 7/0 -
|
||||
55 PB23 D31 7 - - 5/3 7/1 -
|
||||
13 PA13 D38 13 - 2/1 4/1 2/0 0/7
|
||||
35 PB03 LED_RX 3 11 - 5/1 6/1 -
|
||||
27 PA27 LED_TX 15 - - - - -
|
||||
12 PA12 MISO 12 - 2/0 4/0 2/0 0/6
|
||||
42 PB10 MOSI 10 - - 4/2 5/0 0/4
|
||||
43 PB11 SCK 11 - - 4/3 5/1 0/5
|
||||
23 PA23 SCL 7 - 3/1 5/1 4/1 0/5
|
||||
22 PA22 SDA 6 - 3/0 5/0 4/0 0/4
|
||||
30 PA30 SWCLK 10 - - 1/2 1/0 -
|
||||
31 PA31 SWDIO 11 - - 1/3 1/1 -
|
||||
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
|
||||
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
|
||||
0 PA00 0 - - 1/0 2/0 -
|
||||
1 PA01 1 - - 1/1 2/1 -
|
||||
28 PA28 8 - - - - -
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
|
||||
For the definition of the table columns see the explanation at the table for
|
||||
Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
|
||||
|
||||
The default devices at the board are:
|
||||
|
||||
- UART 0 at pins PA11/PA10, labelled RX/TX
|
||||
- I2C 3 at pins PA22/PA23, labelled SDA/SCL
|
||||
- SPI 4 at pins PB10/PA12/PB11, labelled MISO, MOSI and SCK
|
||||
- DAC output on pin PA02, labelled A0
|
||||
|
||||
SAMD21 Xplained PRO pin assignment table
|
||||
----------------------------------------
|
||||
|
||||
@@ -858,10 +656,8 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
|
||||
34 PB02 DOTSTAR_CLK 2 14 - - 5/0 6/0 2/2 -
|
||||
35 PB03 DOTSTAR_DATA 9 15 - - 5/1 6/1 - -
|
||||
15 PA15 LED 15 - - 2/3 4/3 3/1 2/1 1/3
|
||||
16 PA16 RX 0 - - 1/0 3/1 2/0 1/0 0/4
|
||||
17 PA17 TX 1 - - 1/1 3/0 2/1 1/1 0/5
|
||||
55 PB23 MOSI 7 - - 1/3 5/3 7/1 - -
|
||||
54 PB22 MISO 22 - - 1/2 5/2 7/0 - -
|
||||
55 PB23 MISO 7 - - 1/3 5/3 7/1 - -
|
||||
54 PB22 MOSI 22 - - 1/2 5/2 7/0 - -
|
||||
43 PB11 QSPI_CS 12 - - - 4/3 5/1 0/5 1/1
|
||||
8 PA08 QSPI_D0 - 8 2 0/0 2/1 0/0 0/0 1/4
|
||||
9 PA09 QSPI_D1 9 9 3 0/1 2/0 0/1 0/1 1/5
|
||||
@@ -1010,7 +806,7 @@ Default pin assignments:
|
||||
|
||||
There seems to be no default pin assignment for this board.
|
||||
|
||||
SparkFun SAMD51 Thing Plus pin assignment table
|
||||
Sparkfun SAMD51 Thing Plus pin assignment table
|
||||
------------------------------------------------
|
||||
|
||||
=== ==== ============ ==== ==== ==== ====== ====== ===== ===== =====
|
||||
@@ -1037,8 +833,6 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
|
||||
11 PA11 FLASH_MISO 11 11 - 0/3 2/3 1/1 0/3 1/7
|
||||
8 PA08 FLASH_MOSI - 8 2 0/0 2/1 0/0 0/0 1/4
|
||||
9 PA09 FLASH_SCK 9 9 3 0/1 2/0 0/1 0/1 1/5
|
||||
13 PA13 RX 13 - - 2/1 4/0 2/1 0/7 1/3
|
||||
12 PA12 TX 12 - - 2/0 4/1 2/0 0/6 1/2
|
||||
43 PB11 MISO 12 - - - 4/3 5/1 0/5 1/1
|
||||
44 PB12 MOSI 12 - - 4/0 - 4/0 3/0 0/0
|
||||
55 PB23 RXD 7 - - 1/3 5/3 7/1 - -
|
||||
@@ -1077,192 +871,10 @@ Adafruit ItsyBitsy M4 Express :ref:`samd51_pinout_table`.
|
||||
The default devices at the board are:
|
||||
|
||||
- UART 2 at pins PA13/PA12, labelled RXD/TXD
|
||||
- I2C 3 at pins PA22/PA23, labelled SDA/SCL
|
||||
- I2C 5 at pins PA22/PA23, labelled SDA/SCL
|
||||
- SPI 4 at pins PB12/PB11/PB13, labelled MOSI, MISO and SCK
|
||||
- DAC output on pins PA02 and PA05, labelled A0 and A4
|
||||
|
||||
Generic SAMD21x18 pin assignment table
|
||||
--------------------------------------
|
||||
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
Pin GPIO Name/Package IRQ ADC Serial Serial TCC/TC TCC/TC
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
0 PA00 EGJ 0 - - 1/0 2/0 -
|
||||
1 PA01 EGJ 1 - - 1/1 2/1 -
|
||||
2 PA02 EGJ 2 0 - - - -
|
||||
3 PA03 EGJ 3 1 - - - -
|
||||
4 PA04 EGJ 4 4 - 0/0 0/0 -
|
||||
5 PA05 EGJ 5 5 - 0/1 0/1 -
|
||||
6 PA06 EGJ 6 6 - 0/2 1/0 -
|
||||
7 PA07 EGJ 7 7 - 0/3 1/1 -
|
||||
8 PA08 EGJ - 16 0/0 2/0 0/0 1/2
|
||||
9 PA09 EGJ 9 17 0/1 2/1 0/1 1/3
|
||||
10 PA10 EGJ 10 18 0/2 2/2 1/0 0/2
|
||||
11 PA11 EGJ 11 19 0/3 2/3 1/1 0/3
|
||||
12 PA12 GJ 12 - 2/0 4/0 2/0 0/6
|
||||
13 PA13 GJ 13 - 2/1 4/1 2/0 0/7
|
||||
14 PA14 EGJ 14 - 2/2 4/2 3/0 0/4
|
||||
15 PA15 EGJ 15 - 2/3 4/3 3/1 0/5
|
||||
16 PA16 EGJ 0 - 1/0 3/0 2/0 0/6
|
||||
17 PA17 EGJ 1 - 1/1 3/1 2/1 0/7
|
||||
18 PA18 EGJ 2 - 1/2 3/2 3/0 0/2
|
||||
19 PA19 EGJ 3 - 1/3 3/3 3/1 0/3
|
||||
20 PA20 GJ 4 - 5/2 3/2 7/0 0/4
|
||||
21 PA21 GJ 5 - 5/3 3/3 7/1 0/7
|
||||
22 PA22 EGJ 6 - 3/0 5/0 4/0 0/4
|
||||
23 PA23 EGJ 7 - 3/1 5/1 4/1 0/5
|
||||
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
|
||||
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
|
||||
27 PA27 EGJ 15 - - - - -
|
||||
28 PA28 EGJ 8 - - - - -
|
||||
30 PA30 SWCLK 10 - - 1/2 1/0 -
|
||||
31 PA31 SWDIO 11 - - 1/3 1/1 -
|
||||
32 PB00 J 0 8 - 5/2 7/0 -
|
||||
33 PB01 J 1 9 - 5/3 7/1 -
|
||||
34 PB02 GJ 2 10 - 5/0 6/0 -
|
||||
35 PB03 GJ 3 11 - 5/1 6/1 -
|
||||
36 PB04 J 4 12 - - - -
|
||||
37 PB05 J 5 13 - - - -
|
||||
38 PB06 J 6 14 - - - -
|
||||
39 PB07 J 7 15 - - - -
|
||||
40 PB08 GJ 8 2 - 4/0 4/0 -
|
||||
41 PB09 GJ 9 3 - 4/1 4/1 -
|
||||
42 PB10 GJ 10 - - 4/2 5/0 0/4
|
||||
43 PB11 GJ 11 - - 4/3 5/1 0/5
|
||||
44 PB12 J 12 - 4/0 - 4/0 0/6
|
||||
45 PB13 J 13 - 4/1 - 4/1 0/7
|
||||
46 PB14 J 14 - 4/2 - 5/0 -
|
||||
47 PB15 J 15 - 4/3 - 5/1 -
|
||||
48 PB16 J 0 - 5/0 - 6/0 0/4
|
||||
49 PB17 J 1 - 5/1 - 6/1 0/5
|
||||
54 PB22 GJ 6 - - 5/2 7/0 -
|
||||
55 PB23 GJ 7 - - 5/3 7/1 -
|
||||
62 PB30 J 14 - - 5/0 0/0 1/2
|
||||
63 PB31 J 15 - - 5/1 0/1 1/3
|
||||
=== ==== ============ ==== ==== ====== ====== ====== ======
|
||||
|
||||
For the definition of the table columns see the explanation at the table for
|
||||
Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
|
||||
|
||||
The Package column indicates the package letter providing this pin. An entry
|
||||
EGJ tells for instance, that the pin is available for SAMD21E18, SAMD21G18 and
|
||||
SAMD21J18.
|
||||
|
||||
|
||||
Generic SAMD51x19 and SAM51x20 pin assignment table
|
||||
---------------------------------------------------
|
||||
|
||||
For the definition of the table columns see the explanation at the table for
|
||||
Adafruit ItsyBitsy M4 Express :ref:`samd51_pinout_table`.
|
||||
|
||||
=== ==== ============ ==== ==== ==== ====== ====== ===== ===== =====
|
||||
Pin GPIO Name/Package IRQ ADC ADC Serial Serial TC PWM PWM
|
||||
=== ==== ============ ==== ==== ==== ====== ====== ===== ===== =====
|
||||
8 PA08 QSPI_D0 - 8 2 0/0 2/1 0/0 0/0 1/4
|
||||
9 PA09 QSPI_D1 9 9 3 0/1 2/0 0/1 0/1 1/5
|
||||
10 PA10 QSPI_D2 10 10 - 0/2 2/2 1/0 0/2 1/6
|
||||
11 PA11 QSPI_D3 11 11 - 0/3 2/3 1/1 0/3 1/7
|
||||
42 PB10 QSPI_SCK 10 - - - 4/2 5/0 0/4 1/0
|
||||
23 PA23 USB_SOF 7 - - 3/1 5/0 4/1 1/7 0/3
|
||||
24 PA24 USB_DM 8 - - 3/2 5/2 5/0 2/2 -
|
||||
25 PA25 USB_DP 9 - - 3/3 5/3 5/1 - -
|
||||
0 PA00 GJP 0 - - - 1/0 2/0 - -
|
||||
1 PA01 GJP 1 - - - 1/1 2/1 - -
|
||||
2 PA02 GJP 2 0 - - - - - -
|
||||
3 PA03 GJP 3 10 - - - - - -
|
||||
4 PA04 GJP 4 4 - - 0/0 0/0 - -
|
||||
5 PA05 GJP 5 5 - - 0/1 0/1 - -
|
||||
6 PA06 GJP 6 6 - - 0/2 1/0 - -
|
||||
7 PA07 GJP 7 7 - - 0/3 1/1 - -
|
||||
12 PA12 GJP 12 - - 2/0 4/1 2/0 0/6 1/2
|
||||
13 PA13 GJP 13 - - 2/1 4/0 2/1 0/7 1/3
|
||||
14 PA14 GJP 14 - - 2/2 4/2 3/0 2/0 1/2
|
||||
15 PA15 GJP 15 - - 2/3 4/3 3/1 2/1 1/3
|
||||
16 PA16 GJP 0 - - 1/0 3/1 2/0 1/0 0/4
|
||||
17 PA17 GJP 1 - - 1/1 3/0 2/1 1/1 0/5
|
||||
18 PA18 GJP 2 - - 1/2 3/2 3/0 1/2 0/6
|
||||
19 PA19 GJP 3 - - 1/3 3/3 3/1 1/3 0/7
|
||||
20 PA20 GJP 4 - - 5/2 3/2 7/0 1/4 0/0
|
||||
21 PA21 GJP 5 - - 5/3 3/3 7/1 1/5 0/1
|
||||
22 PA22 GJP 6 - - 3/0 5/1 4/0 1/6 0/2
|
||||
27 PA27 GJP 11 - - - - - - -
|
||||
30 PA30 SWCLK 14 - - 7/2 1/2 6/0 2/0 -
|
||||
31 PA31 SWDIO 15 - - 7/3 1/3 6/1 2/1 -
|
||||
32 PB00 JP 0 12 - - 5/2 7/0 - -
|
||||
33 PB01 JP 1 13 - - 5/3 7/1 - -
|
||||
34 PB02 GJP 2 14 - - 5/0 6/0 2/2 -
|
||||
35 PB03 GJP 3 15 - - 5/1 6/1 - -
|
||||
36 PB04 JP 4 - 6 - - - - -
|
||||
37 PB05 JP 5 - 7 - - - - -
|
||||
38 PB06 JP 6 - 8 - - - - -
|
||||
39 PB07 JP 7 - 9 - - - - -
|
||||
40 PB08 GJP 8 2 0 - 4/0 4/0 - -
|
||||
41 PB09 GJP 9 3 1 - 4/1 4/1 - -
|
||||
44 PB12 JP 12 - - 4/0 - 4/0 3/0 0/0
|
||||
45 PB13 JP 13 - - 4/1 - 4/1 3/1 0/1
|
||||
46 PB14 JP 14 - - 4/2 - 5/0 4/0 0/2
|
||||
47 PB15 JP 15 - - 4/3 - 5/1 4/1 0/3
|
||||
48 PB16 JP 0 - - 5/0 - 6/0 3/0 0/4
|
||||
49 PB17 JP 1 - - 5/1 - 6/1 3/1 0/5
|
||||
50 PB18 P 2 - - 5/2 7/2 - 1/0 -
|
||||
51 PB19 P 3 - - 5/3 7/3 - 1/1 -
|
||||
52 PB20 P 4 - - 3/0 7/1 - 1/2 -
|
||||
53 PB21 P 5 - - 3/1 7/0 - 1/3 -
|
||||
54 PB22 GJP 6 - - 1/2 5/2 7/0 - -
|
||||
55 PB23 GJP 7 - - 1/3 5/3 7/1 - -
|
||||
56 PB24 P 8 - - 0/0 2/1 - - -
|
||||
57 PB25 P 9 - - 0/1 2/0 - - -
|
||||
58 PB26 P 12 - - 2/0 4/1 - 1/2 -
|
||||
59 PB27 P 13 - - 2/1 4/0 - 1/3 -
|
||||
60 PB28 P 14 - - 2/2 4/2 - 1/4 -
|
||||
61 PB29 P 15 - - 2/3 4/3 - 1/5 -
|
||||
62 PB30 JP 14 - - 7/0 5/1 0/0 4/0 0/6
|
||||
63 PB31 JP 15 - - 7/1 5/0 0/1 4/1 0/7
|
||||
64 PC00 P 0 - 10 - - - - -
|
||||
65 PC01 P 1 - 11 - - - - -
|
||||
66 PC02 P 2 - 4 - - - - -
|
||||
67 PC03 P 3 - 5 - - - - -
|
||||
68 PC04 P 4 - - 6/0 - - 0/0 -
|
||||
69 PC05 P 5 - - 6/1 - - - -
|
||||
70 PC06 P 6 - - 6/2 - - - -
|
||||
71 PC07 P 9 - - 6/3 - - - -
|
||||
74 PC10 P 10 - - 6/2 7/2 - 0/0 1/4
|
||||
75 PC11 P 11 - - 6/3 7/3 - 0/1 1/5
|
||||
76 PC12 P 12 - - 7/0 6/1 - 0/2 1/6
|
||||
77 PC13 P 13 - - 7/1 6/0 - 0/3 1/7
|
||||
78 PC14 P 14 - - 7/2 6/2 - 0/4 1/0
|
||||
79 PC15 P 15 - - 7/3 6/3 - 0/5 1/1
|
||||
80 PC16 P 0 - - 6/0 0/1 - 0/0 -
|
||||
81 PC17 P 1 - - 6/1 0/0 - 0/1 -
|
||||
82 PC18 P 2 - - 6/2 0/2 - 0/2 -
|
||||
83 PC19 P 3 - - 6/3 0/3 - 0/3 -
|
||||
84 PC20 P 4 - - - - - 0/4 -
|
||||
85 PC21 P 5 - - - - - 0/5 -
|
||||
86 PC22 P 6 - - 1/0 3/1 - 0/5 -
|
||||
87 PC23 P 7 - - 1/1 3/0 - 0/7 -
|
||||
88 PC24 P 8 - - 0/2 2/2 - - -
|
||||
89 PC25 P 9 - - 0/3 2/3 - - -
|
||||
90 PC26 P 10 - - - - - - -
|
||||
91 PC27 P 11 - - 1/0 - - - -
|
||||
92 PC28 P 12 - - 1/1 - - - -
|
||||
94 PC30 P 14 - 12 - - - - -
|
||||
95 PC31 P 15 - 13 - - - - -
|
||||
96 PD00 P 0 - 14 - - - - -
|
||||
97 PD01 P 1 - 15 - - - - -
|
||||
104 PD08 P 3 - - 7/0 6/1 - 0/1 -
|
||||
105 PD09 P 4 - - 7/1 6/0 - 0/2 -
|
||||
106 PD10 P 5 - - 7/2 6/2 - 0/3 -
|
||||
107 PD11 P 6 - - 7/3 6/3 - 0/4 -
|
||||
108 PD12 P 7 - - - - - 0/5 -
|
||||
116 PD20 P 10 - - 1/2 3/2 - 1/0 -
|
||||
117 PD21 P 11 - - 1/3 3/3 - 1/1 -
|
||||
=== ==== ============ ==== ==== ==== ====== ====== ===== ===== =====
|
||||
|
||||
|
||||
The Package column indicates the package letter providing this pin. An entry
|
||||
GJP tells for instance, that the pin is available for SAMD51G19, SAMD51J19/-J20 and
|
||||
SAMD51P19/-P20.
|
||||
|
||||
Scripts for creating the pin assignment tables
|
||||
----------------------------------------------
|
||||
|
||||
@@ -1309,22 +921,22 @@ The tables shown above were created with small a Python script running on the ta
|
||||
else:
|
||||
return "zzzzzzz%03d" % i[0]
|
||||
|
||||
def pinnum(p):
|
||||
return (ord(p[1]) - ord("A")) * 32 + int(p[2:])
|
||||
|
||||
def table(num = 127, sort=True):
|
||||
def table(num=127, sort=True):
|
||||
pintbl = []
|
||||
pinlist = []
|
||||
for name in Pin.board.__dict__.keys():
|
||||
p = Pin(name)
|
||||
pi = pininfo(p)
|
||||
pintbl.append((pinnum(pi[0]), name, pi))
|
||||
pinlist.append(p)
|
||||
for pc in Pin.cpu.__dict__.keys():
|
||||
p = Pin(pc)
|
||||
pi = pininfo(p)
|
||||
if not p in pinlist:
|
||||
pintbl.append((pinnum(pi[0]), "", pi))
|
||||
inv_bd = {v: k for k, v in Pin.board.__dict__.items()}
|
||||
for i in range(num):
|
||||
try:
|
||||
p = Pin(i)
|
||||
pi = pininfo(p)
|
||||
if p in inv_bd.keys():
|
||||
name = inv_bd[p]
|
||||
else:
|
||||
name = ""
|
||||
pintbl.append((i, name, pininfo(i)))
|
||||
except:
|
||||
pass
|
||||
# print("not defined")
|
||||
|
||||
if sort:
|
||||
pintbl.sort(key=tblkey)
|
||||
for item in pintbl:
|
||||
|
||||
@@ -163,15 +163,10 @@ See :ref:`machine.UART <machine.UART>`. ::
|
||||
uart3.write('hello') # write 5 bytes
|
||||
uart3.read(5) # read up to 5 bytes
|
||||
|
||||
uart = UART() # Use the default values for id, rx and tx.
|
||||
uart = UART(baudrate=9600) # Use the default UART and set the baudrate
|
||||
|
||||
The SAMD21/SAMD51 MCUs have up to eight hardware so called SERCOM devices, which can be used as UART,
|
||||
SPI or I2C device, but not every MCU variant and board exposes all
|
||||
TX and RX pins for users. For the assignment of Pins to devices and UART signals,
|
||||
refer to the :ref:`SAMD pinout <samd_pinout>`. If the id, rx or tx pins are not specified,
|
||||
the default values are used. The first positional argument (if given) is assumed to be the UART id.
|
||||
If the baudrate is changed and the UART id is omitted, it must be set using the baudrate keyword.
|
||||
refer to the :ref:`SAMD pinout <samd_pinout>`.
|
||||
|
||||
PWM (pulse width modulation)
|
||||
----------------------------
|
||||
@@ -220,7 +215,7 @@ PWM Constructor
|
||||
|
||||
- *freq* should be an integer which sets the frequency in Hz for the
|
||||
PWM cycle. The valid frequency range is 1 Hz to 24 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``.
|
||||
- *duty_ns* sets the pulse width in nanoseconds. The limitation for X channels
|
||||
apply as well.
|
||||
- *invert*\=True|False. Setting a bit inverts the respective output.
|
||||
@@ -251,7 +246,7 @@ Use the :ref:`machine.ADC <machine.ADC>` class::
|
||||
from machine import ADC
|
||||
|
||||
adc0 = ADC(Pin('A0')) # create ADC object on ADC pin, average=16
|
||||
adc0.read_u16() # read value, 0-65535 across voltage range 0.0v - 3.3v
|
||||
adc0.read_u16() # read value, 0-65536 across voltage range 0.0v - 3.3v
|
||||
adc1 = ADC(Pin('A1'), average=1) # create ADC object on ADC pin, average=1
|
||||
|
||||
The resolution of the ADC is 12 bit with 12 bit accuracy, irrespective of the
|
||||
@@ -378,18 +373,8 @@ signal pins for users. Hardware SPI is accessed via the
|
||||
spi = SPI(1, sck=Pin("SCK"), mosi=Pin("MOSI"), miso=Pin("MISO"), baudrate=10000000)
|
||||
spi.write('Hello World')
|
||||
|
||||
For the assignment of Pins to SPI devices and signals, refer to
|
||||
:ref:`SAMD pinout <samd_pinout>`. If the id, miso, mosi or sck pins are not specified,
|
||||
the default values are used. So it is possible to create the SPI object as::
|
||||
|
||||
from machine import SPI
|
||||
spi = SPI() # Use the default device and default baudrate
|
||||
spi = SPI(baudrate=12_000_000) # Use the default device and change the baudrate
|
||||
|
||||
If the MISO signal shall be omitted, it must be defined as miso=None.
|
||||
The first positional argument (if given) is assumed to be the SPI id.
|
||||
If the baudrate is changed while the SPI id is omitted, it must be
|
||||
set using the baudrate keyword.
|
||||
If miso is not specified, it is not used. For the assignment of Pins to SPI devices and signals, refer to
|
||||
:ref:`SAMD pinout <samd_pinout>`.
|
||||
|
||||
Note: Even if the highest reliable baud rate at the moment is about 24 Mhz,
|
||||
setting a baud rate will not always result in exactly that frequency, especially
|
||||
@@ -422,7 +407,6 @@ The SAMD21/SAMD51 MCUs have up to eight hardware so called SERCOM devices,
|
||||
which can be used as UART, SPI or I2C device, but not every MCU variant
|
||||
and board exposes all signal pins for users.
|
||||
For the assignment of Pins to devices and I2C signals, refer to :ref:`SAMD pinout <samd_pinout>`.
|
||||
If the id, scl or sda pins are not specified, the default values are used.
|
||||
|
||||
Hardware I2C is accessed via the :ref:`machine.I2C <machine.I2C>` class and
|
||||
has the same methods as software SPI above::
|
||||
@@ -432,13 +416,6 @@ has the same methods as software SPI above::
|
||||
i2c = I2C(2, scl=Pin("SCL"), sda=Pin("SDA"), freq=400_000)
|
||||
i2c.writeto(0x76, b"Hello World")
|
||||
|
||||
i2c2 = I2C() # Use the default values for id, scl and sda.
|
||||
i2c2 = I2C(freq=100_000) # Use the default device and set freq.
|
||||
|
||||
The first positional argument (if given) is assumed to be the I2C id.
|
||||
If the freq is changed and the I2C id is omitted, it must be set using
|
||||
the freq keyword.
|
||||
|
||||
OneWire driver
|
||||
--------------
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ There are soft resets and hard resets.
|
||||
import machine
|
||||
machine.reset()
|
||||
|
||||
For more information, see :doc:`/reference/reset_boot`.
|
||||
|
||||
Safe boot
|
||||
---------
|
||||
|
||||
|
||||
@@ -56,21 +56,6 @@ Use the :ref:`machine.Pin <machine.Pin>` class::
|
||||
switch = Pin(("gpioc", 6), Pin.IN) # create input pin for a switch
|
||||
switch.irq(lambda t: print("SW2 changed")) # enable an interrupt when switch state is changed
|
||||
|
||||
PWM
|
||||
---
|
||||
|
||||
Use the :ref:`machine.PWM <machine.PWM>` class::
|
||||
|
||||
from machine import PWM
|
||||
|
||||
pwm = PWM(("pwm0", 0), freq=3921568, duty_ns=200, invert=True) # create pwm on PWM0
|
||||
print(pwm) # print pwm
|
||||
|
||||
print(pwm.duty_ns()) # print pwm duty cycle in nanoseconds
|
||||
pwm.duty_ns(255) # set new pwm duty cycle in nanoseconds
|
||||
|
||||
pwm.deinit()
|
||||
|
||||
Hardware I2C bus
|
||||
----------------
|
||||
|
||||
@@ -153,8 +138,6 @@ Use the :ref:`zephyr.FlashArea <zephyr.FlashArea>` class to support filesystem::
|
||||
f.write('Hello world') # write to the file
|
||||
print(open('/flash/hello.txt').read()) # print contents of the file
|
||||
|
||||
The FlashAreas' IDs that are available are listed in the FlashArea module, as ID_*.
|
||||
|
||||
Sensor
|
||||
------
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ With your serial program open (PuTTY, screen, picocom, etc) you may see a
|
||||
blank screen with a flashing cursor. Press Enter (or reset the board) and
|
||||
you should be presented with the following text::
|
||||
|
||||
*** Booting Zephyr OS build v4.0.0 ***
|
||||
*** Booting Zephyr OS build v3.7.0 ***
|
||||
MicroPython v1.24.0-preview.179.g5b85b24bd on 2024-08-05; zephyr-frdm_k64f with mk64f12
|
||||
Type "help()" for more information.
|
||||
>>>
|
||||
|
||||
@@ -37,16 +37,14 @@ enum {
|
||||
MP_QSPI_IOCTL_DEINIT,
|
||||
MP_QSPI_IOCTL_BUS_ACQUIRE,
|
||||
MP_QSPI_IOCTL_BUS_RELEASE,
|
||||
MP_QSPI_IOCTL_MEMORY_MODIFIED,
|
||||
};
|
||||
|
||||
typedef struct _mp_qspi_proto_t {
|
||||
int (*ioctl)(void *self, uint32_t cmd, uintptr_t arg);
|
||||
int (*ioctl)(void *self, uint32_t cmd);
|
||||
int (*write_cmd_data)(void *self, uint8_t cmd, size_t len, uint32_t data);
|
||||
int (*write_cmd_addr_data)(void *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src);
|
||||
int (*read_cmd)(void *self, uint8_t cmd, size_t len, uint32_t *dest);
|
||||
int (*read_cmd_qaddr_qdata)(void *self, uint8_t cmd, uint32_t addr, uint8_t num_dummy, size_t len, uint8_t *dest);
|
||||
int (*direct_read)(void *self, uint32_t addr, size_t len, uint8_t *dest); // can be NULL if direct read not supported
|
||||
int (*read_cmd_qaddr_qdata)(void *self, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest);
|
||||
} mp_qspi_proto_t;
|
||||
|
||||
typedef struct _mp_soft_qspi_obj_t {
|
||||
|
||||
@@ -56,9 +56,8 @@ static void nibble_write(mp_soft_qspi_obj_t *self, uint8_t v) {
|
||||
mp_hal_pin_write(self->io3, (v >> 3) & 1);
|
||||
}
|
||||
|
||||
static int mp_soft_qspi_ioctl(void *self_in, uint32_t cmd, uintptr_t arg) {
|
||||
static int mp_soft_qspi_ioctl(void *self_in, uint32_t cmd) {
|
||||
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
|
||||
(void)arg;
|
||||
|
||||
switch (cmd) {
|
||||
case MP_QSPI_IOCTL_INIT:
|
||||
@@ -189,13 +188,13 @@ static int mp_soft_qspi_read_cmd(void *self_in, uint8_t cmd, size_t len, uint32_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, uint8_t num_dummy, size_t len, uint8_t *dest) {
|
||||
static int mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest) {
|
||||
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
|
||||
uint8_t cmd_buf[16] = {cmd};
|
||||
uint8_t cmd_buf[7] = {cmd};
|
||||
uint8_t addr_len = mp_spi_set_addr_buff(&cmd_buf[1], addr);
|
||||
CS_LOW(self);
|
||||
mp_soft_qspi_transfer(self, 1, cmd_buf, NULL);
|
||||
mp_soft_qspi_qwrite(self, addr_len + 1 + num_dummy, &cmd_buf[1]); // 3/4 addr bytes, 1 extra byte (0), N dummy bytes (2*N dummy cycles)
|
||||
mp_soft_qspi_qwrite(self, addr_len + 3, &cmd_buf[1]); // 3/4 addr bytes, 1 extra byte (0), 2 dummy bytes (4 dummy cycles)
|
||||
mp_soft_qspi_qread(self, len, dest);
|
||||
CS_HIGH(self);
|
||||
return 0;
|
||||
|
||||
17
drivers/cyw43/README.md
Normal file
17
drivers/cyw43/README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
CYW43xx WiFi SoC driver
|
||||
=======================
|
||||
|
||||
This is a driver for the CYW43xx WiFi SoC.
|
||||
|
||||
There are four layers to the driver:
|
||||
|
||||
1. SDIO bus interface, provided by the host device/system.
|
||||
|
||||
2. Low-level CYW43xx interface, managing the bus, control messages, Ethernet
|
||||
frames and asynchronous events. Includes download of SoC firmware. The
|
||||
header file `cyw43_ll.h` defines the interface to this layer.
|
||||
|
||||
3. Mid-level CYW43xx control, to control and set WiFi parameters and manage
|
||||
events. See `cyw43_ctrl.c`.
|
||||
|
||||
4. TCP/IP bindings to lwIP. See `cyw43_lwip.c`.
|
||||
304
drivers/cyw43/cywbt.c
Normal file
304
drivers/cyw43/cywbt.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019-2020 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/mpbthci.h"
|
||||
|
||||
#if MICROPY_PY_NETWORK_CYW43
|
||||
|
||||
#include "lib/cyw43-driver/src/cyw43_config.h"
|
||||
#include "lib/cyw43-driver/firmware/cyw43_btfw_4343A1.h"
|
||||
|
||||
// Provided by the port, and also possibly shared with the stack.
|
||||
extern uint8_t mp_bluetooth_hci_cmd_buf[4 + 256];
|
||||
|
||||
/******************************************************************************/
|
||||
// CYW BT HCI low-level driver
|
||||
|
||||
#ifdef CYW43_PIN_BT_CTS
|
||||
// This code is not portable and currently only builds on stm32 port.
|
||||
|
||||
#include "pin_static_af.h"
|
||||
#include "uart.h"
|
||||
|
||||
// Provided by the port.
|
||||
extern machine_uart_obj_t mp_bluetooth_hci_uart_obj;
|
||||
|
||||
static void cywbt_wait_cts_low(void) {
|
||||
mp_hal_pin_config(CYW43_PIN_BT_CTS, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0);
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
if (mp_hal_pin_read(CYW43_PIN_BT_CTS) == 0) {
|
||||
break;
|
||||
}
|
||||
mp_hal_delay_ms(1);
|
||||
}
|
||||
mp_hal_pin_config_alt(CYW43_PIN_BT_CTS, MP_HAL_PIN_MODE_ALT,
|
||||
MP_HAL_PIN_PULL_UP, AF_FN_UART, mp_bluetooth_hci_uart_obj.uart_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cywbt_hci_cmd_raw(size_t len, uint8_t *buf) {
|
||||
mp_bluetooth_hci_uart_write((void *)buf, len);
|
||||
for (int c, i = 0; i < 6; ++i) {
|
||||
while ((c = mp_bluetooth_hci_uart_readchar()) == -1) {
|
||||
mp_event_wait_indefinite();
|
||||
}
|
||||
buf[i] = c;
|
||||
}
|
||||
|
||||
// expect a command complete event (event 0x0e)
|
||||
if (buf[0] != 0x04 || buf[1] != 0x0e) {
|
||||
printf("unknown response: %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
if buf[3:6] != cmd[:3]:
|
||||
print('response doesn\'t match cmd:', cmd, ev)
|
||||
return b''
|
||||
*/
|
||||
|
||||
int sz = buf[2] - 3;
|
||||
for (int c, i = 0; i < sz; ++i) {
|
||||
while ((c = mp_bluetooth_hci_uart_readchar()) == -1) {
|
||||
mp_event_wait_indefinite();
|
||||
}
|
||||
buf[i] = c;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cywbt_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *param_buf) {
|
||||
uint8_t *buf = mp_bluetooth_hci_cmd_buf;
|
||||
buf[0] = 0x01;
|
||||
buf[1] = ocf;
|
||||
buf[2] = ogf << 2 | ocf >> 8;
|
||||
buf[3] = param_len;
|
||||
if (param_len) {
|
||||
memcpy(buf + 4, param_buf, param_len);
|
||||
}
|
||||
return cywbt_hci_cmd_raw(4 + param_len, buf);
|
||||
}
|
||||
|
||||
static void put_le16(uint8_t *buf, uint16_t val) {
|
||||
buf[0] = val;
|
||||
buf[1] = val >> 8;
|
||||
}
|
||||
|
||||
static void put_le32(uint8_t *buf, uint32_t val) {
|
||||
buf[0] = val;
|
||||
buf[1] = val >> 8;
|
||||
buf[2] = val >> 16;
|
||||
buf[3] = val >> 24;
|
||||
}
|
||||
|
||||
static int cywbt_set_baudrate(uint32_t baudrate) {
|
||||
uint8_t buf[6];
|
||||
put_le16(buf, 0);
|
||||
put_le32(buf + 2, baudrate);
|
||||
return cywbt_hci_cmd(0x3f, 0x18, 6, buf);
|
||||
}
|
||||
|
||||
// download firmware
|
||||
static int cywbt_download_firmware(const uint8_t *firmware) {
|
||||
cywbt_hci_cmd(0x3f, 0x2e, 0, NULL);
|
||||
|
||||
bool last_packet = false;
|
||||
while (!last_packet) {
|
||||
uint8_t *buf = mp_bluetooth_hci_cmd_buf;
|
||||
memcpy(buf + 1, firmware, 3);
|
||||
firmware += 3;
|
||||
last_packet = buf[1] == 0x4e;
|
||||
if (buf[2] != 0xfc) {
|
||||
printf("fail1 %02x\n", buf[2]);
|
||||
break;
|
||||
}
|
||||
uint8_t len = buf[3];
|
||||
|
||||
memcpy(buf + 4, firmware, len);
|
||||
firmware += len;
|
||||
|
||||
buf[0] = 1;
|
||||
cywbt_hci_cmd_raw(4 + len, buf);
|
||||
if (buf[0] != 0) {
|
||||
printf("fail3 %02x\n", buf[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// RF switch must select high path during BT patch boot
|
||||
#if MICROPY_HW_ENABLE_RF_SWITCH
|
||||
mp_hal_pin_config(CYW43_PIN_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0);
|
||||
#endif
|
||||
mp_hal_delay_ms(10); // give some time for CTS to go high
|
||||
#ifdef CYW43_PIN_BT_CTS
|
||||
cywbt_wait_cts_low();
|
||||
#endif
|
||||
#if MICROPY_HW_ENABLE_RF_SWITCH
|
||||
// Select chip antenna (could also select external)
|
||||
mp_hal_pin_config(CYW43_PIN_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_DOWN, 0);
|
||||
#endif
|
||||
|
||||
mp_bluetooth_hci_uart_set_baudrate(115200);
|
||||
cywbt_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY);
|
||||
mp_bluetooth_hci_uart_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mp_bluetooth_hci_controller_init(void) {
|
||||
// This is called immediately after the UART is initialised during stack initialisation.
|
||||
|
||||
mp_hal_pin_output(CYW43_PIN_BT_REG_ON);
|
||||
mp_hal_pin_low(CYW43_PIN_BT_REG_ON);
|
||||
#ifdef CYW43_PIN_BT_HOST_WAKE
|
||||
mp_hal_pin_input(CYW43_PIN_BT_HOST_WAKE);
|
||||
#endif
|
||||
#ifdef CYW43_PIN_BT_DEV_WAKE
|
||||
mp_hal_pin_output(CYW43_PIN_BT_DEV_WAKE);
|
||||
mp_hal_pin_low(CYW43_PIN_BT_DEV_WAKE);
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_RF_SWITCH
|
||||
// TODO don't select antenna if wifi is enabled
|
||||
mp_hal_pin_config(CYW43_PIN_WL_GPIO_4, MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0); // RF-switch power
|
||||
mp_hal_pin_high(CYW43_PIN_WL_GPIO_4); // Turn the RF-switch on
|
||||
#endif
|
||||
|
||||
uint8_t buf[256];
|
||||
|
||||
mp_hal_pin_low(CYW43_PIN_BT_REG_ON);
|
||||
mp_bluetooth_hci_uart_set_baudrate(115200);
|
||||
mp_hal_delay_ms(100);
|
||||
mp_hal_pin_high(CYW43_PIN_BT_REG_ON);
|
||||
#ifdef CYW43_PIN_BT_CTS
|
||||
cywbt_wait_cts_low();
|
||||
#else
|
||||
mp_hal_delay_ms(100);
|
||||
#endif
|
||||
|
||||
// Reset
|
||||
cywbt_hci_cmd(0x03, 0x0003, 0, NULL);
|
||||
|
||||
#ifdef MICROPY_HW_BLE_UART_BAUDRATE_DOWNLOAD_FIRMWARE
|
||||
// Change baudrate
|
||||
cywbt_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_DOWNLOAD_FIRMWARE);
|
||||
mp_bluetooth_hci_uart_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_DOWNLOAD_FIRMWARE);
|
||||
#endif
|
||||
|
||||
cywbt_download_firmware((const uint8_t *)&cyw43_btfw_4343A1[0]);
|
||||
|
||||
// Reset
|
||||
cywbt_hci_cmd(0x03, 0x0003, 0, NULL);
|
||||
|
||||
// Set BD_ADDR (sent as little endian)
|
||||
uint8_t bdaddr[6];
|
||||
mp_hal_get_mac(MP_HAL_MAC_BDADDR, bdaddr);
|
||||
buf[0] = bdaddr[5];
|
||||
buf[1] = bdaddr[4];
|
||||
buf[2] = bdaddr[3];
|
||||
buf[3] = bdaddr[2];
|
||||
buf[4] = bdaddr[1];
|
||||
buf[5] = bdaddr[0];
|
||||
cywbt_hci_cmd(0x3f, 0x0001, 6, buf);
|
||||
|
||||
// Set local name
|
||||
// memset(buf, 0, 248);
|
||||
// memcpy(buf, "PYBD-BLE", 8);
|
||||
// cywbt_hci_cmd(0x03, 0x0013, 248, buf);
|
||||
|
||||
// Configure sleep mode
|
||||
cywbt_hci_cmd(0x3f, 0x27, 12, (const uint8_t *)"\x01\x02\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00");
|
||||
|
||||
// HCI_Write_LE_Host_Support
|
||||
cywbt_hci_cmd(3, 109, 2, (const uint8_t *)"\x01\x00");
|
||||
|
||||
#ifdef CYW43_PIN_BT_DEV_WAKE
|
||||
mp_hal_pin_high(CYW43_PIN_BT_DEV_WAKE); // let sleep
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mp_bluetooth_hci_controller_deinit(void) {
|
||||
mp_hal_pin_low(CYW43_PIN_BT_REG_ON);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CYW43_PIN_BT_DEV_WAKE
|
||||
static uint32_t bt_sleep_ticks;
|
||||
#endif
|
||||
|
||||
int mp_bluetooth_hci_controller_sleep_maybe(void) {
|
||||
#ifdef CYW43_PIN_BT_DEV_WAKE
|
||||
if (mp_hal_pin_read(CYW43_PIN_BT_DEV_WAKE) == 0) {
|
||||
if (mp_hal_ticks_ms() - bt_sleep_ticks > 500) {
|
||||
mp_hal_pin_high(CYW43_PIN_BT_DEV_WAKE); // let sleep
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool mp_bluetooth_hci_controller_woken(void) {
|
||||
#ifdef CYW43_PIN_BT_HOST_WAKE
|
||||
bool host_wake = mp_hal_pin_read(CYW43_PIN_BT_HOST_WAKE);
|
||||
/*
|
||||
// this is just for info/tracing purposes
|
||||
static bool last_host_wake = false;
|
||||
if (host_wake != last_host_wake) {
|
||||
printf("HOST_WAKE change %d -> %d\n", last_host_wake, host_wake);
|
||||
last_host_wake = host_wake;
|
||||
}
|
||||
*/
|
||||
return host_wake;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
int mp_bluetooth_hci_controller_wakeup(void) {
|
||||
#ifdef CYW43_PIN_BT_DEV_WAKE
|
||||
bt_sleep_ticks = mp_hal_ticks_ms();
|
||||
|
||||
if (mp_hal_pin_read(CYW43_PIN_BT_DEV_WAKE) == 1) {
|
||||
mp_hal_pin_low(CYW43_PIN_BT_DEV_WAKE); // wake up
|
||||
// Use delay_us rather than delay_ms to prevent running the scheduler (which
|
||||
// might result in more BLE operations).
|
||||
mp_hal_delay_us(5000); // can't go lower than this
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -72,7 +72,7 @@ int esp_hosted_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *param_
|
||||
// Receive HCI event packet, initially reading 3 bytes (HCI Event, Event code, Plen).
|
||||
for (mp_uint_t start = mp_hal_ticks_ms(), size = 3, i = 0; i < size;) {
|
||||
while (!mp_bluetooth_hci_uart_any()) {
|
||||
mp_event_wait_ms(1);
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
// Timeout.
|
||||
if ((mp_hal_ticks_ms() - start) > HCI_COMMAND_TIMEOUT) {
|
||||
error_printf("timeout waiting for HCI packet\n");
|
||||
@@ -126,7 +126,7 @@ int mp_bluetooth_hci_controller_init(void) {
|
||||
if (mp_bluetooth_hci_uart_any()) {
|
||||
mp_bluetooth_hci_uart_readchar();
|
||||
}
|
||||
mp_event_wait_ms(1);
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
}
|
||||
|
||||
#ifdef MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user