Compare commits
1 Commits
v1.26-tonb
...
main-tonbe
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fdf5586f5 |
30
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
30
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -11,10 +11,19 @@ body:
|
||||
|
||||
* If you have a question \"How Do I ...?\", please post it on [GitHub Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead of here.
|
||||
* For missing or incorrect documentation, or feature requests, then please [choose a different issue type](https://github.com/micropython/micropython/issues/new/choose).
|
||||
|
||||
#### Existing issue?
|
||||
|
||||
* Please search for [existing issues](https://github.com/micropython/micropython/issues) matching this bug before reporting.
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Checks
|
||||
description: |
|
||||
Before submitting your bug report, please go over these check points:
|
||||
options:
|
||||
- label: |
|
||||
I agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone.
|
||||
required: true
|
||||
- label: |
|
||||
I've searched for [existing issues](https://github.com/micropython/micropython/issues) matching this bug, and didn't find any.
|
||||
required: true
|
||||
- type: input
|
||||
id: port-board-hw
|
||||
attributes:
|
||||
@@ -24,7 +33,7 @@ body:
|
||||
placeholder: |
|
||||
esp32 port, ESP32-Fantastic board.
|
||||
validations:
|
||||
required: true
|
||||
required: true
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
@@ -92,17 +101,6 @@ body:
|
||||
description: |
|
||||
Is there anything else that might help to resolve this issue?
|
||||
value: No, I've provided everything above.
|
||||
- type: dropdown
|
||||
id: code-of-conduct
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: |
|
||||
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
|
||||
options:
|
||||
- "Yes, I agree"
|
||||
multiple: true
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
|
||||
28
.github/ISSUE_TEMPLATE/documentation.yml
vendored
28
.github/ISSUE_TEMPLATE/documentation.yml
vendored
@@ -9,10 +9,19 @@ body:
|
||||
This form is for reporting issues with the documentation or examples provided with MicroPython.
|
||||
|
||||
If you have a general question \"How Do I ...?\", please post it on [GitHub Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead of here.
|
||||
|
||||
#### Existing issue?
|
||||
|
||||
* Please search for [existing issues](https://github.com/micropython/micropython/issues) before reporting a new one.
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Checks
|
||||
description: |
|
||||
Before submitting your bug report, please go over these check points:
|
||||
options:
|
||||
- label: |
|
||||
I agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone.
|
||||
required: true
|
||||
- label: |
|
||||
I've searched for [existing issues](https://github.com/micropython/micropython/issues) and didn't find any that matched.
|
||||
required: true
|
||||
- type: input
|
||||
id: page
|
||||
attributes:
|
||||
@@ -29,17 +38,6 @@ body:
|
||||
Please describe what was missing from the documentation and/or what was incorrect/incomplete.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: code-of-conduct
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: |
|
||||
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
|
||||
options:
|
||||
- "Yes, I agree"
|
||||
multiple: true
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
|
||||
43
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
43
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -15,10 +15,19 @@ body:
|
||||
|
||||
* If you have a question \"How Do I ...?\", please post it on GitHub Discussions or Discord instead of here.
|
||||
* Could this feature be implemented as a pure Python library? If so, please open the request on the [micropython-lib repository](https://github.com/micropython/micropython-lib/issues) instead.
|
||||
|
||||
#### Existing issue?
|
||||
|
||||
* Please search for [existing issues](https://github.com/micropython/micropython/issues) before opening a new one.
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Checks
|
||||
description: |
|
||||
Before submitting your feature request, please go over these check points:
|
||||
options:
|
||||
- label: |
|
||||
I agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone.
|
||||
required: true
|
||||
- label: |
|
||||
I've searched for [existing issues](https://github.com/micropython/micropython/issues) regarding this feature, and didn't find any.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: feature
|
||||
attributes:
|
||||
@@ -42,32 +51,14 @@ body:
|
||||
MicroPython aims to strike a balance between functionality and code size. Can this feature be optionally enabled?
|
||||
|
||||
If you believe the usefulness of this feature would outweigh the additional code size, please explain. (It's OK to say you're unsure here, we're happy to discuss this with you.)
|
||||
- type: dropdown
|
||||
- type: checkboxes
|
||||
id: implementation
|
||||
attributes:
|
||||
label: Implementation
|
||||
description: |
|
||||
What is your suggestion for implementing this feature?
|
||||
|
||||
(See also: [How to sponsor](https://github.com/sponsors/micropython#sponsors), [How to submit a Pull Request](https://github.com/micropython/micropython/wiki/ContributorGuidelines).)
|
||||
options:
|
||||
- I hope the MicroPython maintainers or community will implement this feature
|
||||
- I intend to implement this feature and would submit a Pull Request if desirable
|
||||
- I would like to sponsor development of this feature
|
||||
multiple: true
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: code-of-conduct
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: |
|
||||
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
|
||||
options:
|
||||
- "Yes, I agree"
|
||||
multiple: true
|
||||
validations:
|
||||
required: true
|
||||
- label: I intend to implement this feature and would submit a Pull Request if desirable.
|
||||
- label: I hope the MicroPython maintainers or community will implement this feature.
|
||||
- label: I would like to [Sponsor](https://github.com/sponsors/micropython#sponsors) development of this feature.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
|
||||
31
.github/ISSUE_TEMPLATE/security.yml
vendored
31
.github/ISSUE_TEMPLATE/security.yml
vendored
@@ -9,11 +9,21 @@ body:
|
||||
|
||||
1. For issues that are readily exploitable or have high impact, please email contact@micropython.org instead.
|
||||
1. If this is a question about security, please ask it in [Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead.
|
||||
|
||||
#### Existing issue?
|
||||
|
||||
* Please search for [existing issues](https://github.com/micropython/micropython/issues) before reporting a new one.
|
||||
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Checks
|
||||
description: |
|
||||
Before submitting your bug report, please go over these check points:
|
||||
options:
|
||||
- label: |
|
||||
I agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone.
|
||||
required: true
|
||||
- label: I wish to report a specific security issue that is **not readily exploitable and does not have high impact** for MicroPython developers or users.
|
||||
required: true
|
||||
- label: |
|
||||
I've searched for [existing issues](https://github.com/micropython/micropython/issues) and didn't find any that matched.
|
||||
required: true
|
||||
- type: input
|
||||
id: port-board-hw
|
||||
attributes:
|
||||
@@ -47,14 +57,3 @@ body:
|
||||
* How does the attacker exploit this issue?
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: code-of-conduct
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: |
|
||||
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
|
||||
options:
|
||||
- "Yes, I agree"
|
||||
multiple: true
|
||||
validations:
|
||||
required: true
|
||||
|
||||
33
.github/pull_request_template.md
vendored
33
.github/pull_request_template.md
vendored
@@ -1,33 +0,0 @@
|
||||
<!-- Thanks for submitting a Pull Request! We appreciate you spending the
|
||||
time to improve MicroPython. Please provide enough information so that
|
||||
others can review your Pull Request.
|
||||
|
||||
Before submitting, please read:
|
||||
https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md
|
||||
https://github.com/micropython/micropython/wiki/ContributorGuidelines
|
||||
|
||||
Please check any CI failures that appear after your Pull Request is opened.
|
||||
-->
|
||||
|
||||
### Summary
|
||||
|
||||
<!-- Explain the reason for making this change. What problem does the pull request
|
||||
solve, or what improvement does it add? Add links if relevant. -->
|
||||
|
||||
|
||||
### Testing
|
||||
|
||||
<!-- Explain what testing you did, and on which boards/ports. If there are
|
||||
boards or ports that you couldn't test, please mention this here as well.
|
||||
|
||||
If you leave this empty then your Pull Request may be closed. -->
|
||||
|
||||
|
||||
### Trade-offs and Alternatives
|
||||
|
||||
<!-- If the Pull Request has some negative impact (i.e. increased code size)
|
||||
then please explain why you think the trade-off improvement is worth it.
|
||||
If you can think of alternative ways to do this, please explain that here too.
|
||||
|
||||
Delete this heading if not relevant (i.e. small fixes) -->
|
||||
|
||||
3
.github/workflows/code_size.yml
vendored
3
.github/workflows/code_size.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Check code size
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/*.yml'
|
||||
@@ -23,7 +24,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
|
||||
2
.github/workflows/code_size_comment.yml
vendored
2
.github/workflows/code_size_comment.yml
vendored
@@ -11,7 +11,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: 'Download artifact'
|
||||
id: download-artifact
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: alif port
|
||||
name: qemu-arm port
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -11,23 +11,22 @@ on:
|
||||
- 'shared/**'
|
||||
- 'lib/**'
|
||||
- 'drivers/**'
|
||||
- 'ports/alif/**'
|
||||
- 'ports/qemu-arm/**'
|
||||
- 'tests/**'
|
||||
|
||||
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
|
||||
build_and_test:
|
||||
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 }}
|
||||
run: source tools/ci.sh && ci_qemu_arm_setup
|
||||
- name: Build and run test suite
|
||||
run: source tools/ci.sh && ci_qemu_arm_build
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: grep --before-context=100 --text "FAIL" ports/qemu-arm/build/console.out
|
||||
51
.github/workflows/ports_qemu.yml
vendored
51
.github/workflows/ports_qemu.yml
vendored
@@ -1,51 +0,0 @@
|
||||
name: qemu port
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/*.yml'
|
||||
- 'tools/**'
|
||||
- 'py/**'
|
||||
- 'extmod/**'
|
||||
- 'shared/**'
|
||||
- 'lib/**'
|
||||
- 'drivers/**'
|
||||
- 'ports/qemu/**'
|
||||
- 'tests/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
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: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
build_and_test_rv32:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: source tools/ci.sh && ci_qemu_setup_rv32
|
||||
- name: Build and run test suite
|
||||
run: source tools/ci.sh && ci_qemu_build_rv32
|
||||
- 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
|
||||
|
||||
131
.github/workflows/ports_unix.yml
vendored
131
.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
|
||||
@@ -218,7 +194,7 @@ jobs:
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
macos:
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-11.0
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
@@ -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
|
||||
@@ -261,68 +235,3 @@ jobs:
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
qemu_riscv64:
|
||||
# ubuntu-22.04 is needed for older libffi.
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install packages
|
||||
run: source tools/ci.sh && ci_unix_qemu_riscv64_setup
|
||||
- name: Build
|
||||
run: source tools/ci.sh && ci_unix_qemu_riscv64_build
|
||||
- name: Run main test suite
|
||||
run: source tools/ci.sh && ci_unix_qemu_riscv64_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
sanitize_address:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@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
|
||||
|
||||
39
.github/workflows/ports_windows.yml
vendored
39
.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,7 @@ 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 +50,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 +101,23 @@ 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'
|
||||
- name: Get Python path
|
||||
id: python_path
|
||||
shell: python
|
||||
run: |
|
||||
import os
|
||||
import sys
|
||||
output = f"python={os.fspath(sys.executable)}"
|
||||
print(output)
|
||||
with open(os.environ["GITHUB_OUTPUT"], "w") as f:
|
||||
f.write(output)
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.sys }}
|
||||
@@ -122,9 +126,9 @@ jobs:
|
||||
make
|
||||
mingw-w64-${{ matrix.env }}-gcc
|
||||
pkg-config
|
||||
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
|
||||
@@ -134,7 +138,8 @@ jobs:
|
||||
run: make -C ports/windows -j2 VARIANT=${{ matrix.variant }}
|
||||
- name: Run tests
|
||||
id: test
|
||||
run: make -C ports/windows test_full VARIANT=${{ matrix.variant }}
|
||||
# msys python breaks tests so we need to use "real" windows python
|
||||
run: MICROPY_CPYTHON3=$(cygpath "${{ steps.python_path.outputs.python }}") make -C ports/windows test_full VARIANT=${{ matrix.variant }}
|
||||
- name: Print failures
|
||||
if: failure() && steps.test.conclusion == 'failure'
|
||||
working-directory: tests
|
||||
|
||||
31
.github/workflows/ports_zephyr.yml
vendored
31
.github/workflows/ports_zephyr.yml
vendored
@@ -20,41 +20,10 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
# Only free up a few things so this step runs quickly.
|
||||
android: false
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: false
|
||||
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
|
||||
- name: Run main test suite
|
||||
run: source tools/ci.sh && ci_zephyr_run_tests
|
||||
- name: Print failures
|
||||
if: failure()
|
||||
run: tests/run-tests.py --print-failures
|
||||
|
||||
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 .
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -11,9 +11,8 @@ build/
|
||||
build-*/
|
||||
docs/genrst/
|
||||
|
||||
# Test failure outputs and intermediate artefacts
|
||||
# Test failure outputs
|
||||
tests/results/*
|
||||
tests/ports/unix/ffi_lib.so
|
||||
|
||||
# Python cache files
|
||||
__pycache__/
|
||||
|
||||
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -3,7 +3,7 @@
|
||||
url = https://github.com/micropython/axtls.git
|
||||
[submodule "lib/libffi"]
|
||||
path = lib/libffi
|
||||
url = https://github.com/libffi/libffi
|
||||
url = https://github.com/atgreen/libffi
|
||||
[submodule "lib/lwip"]
|
||||
path = lib/lwip
|
||||
url = https://github.com/lwip-tcpip/lwip.git
|
||||
@@ -68,9 +68,3 @@
|
||||
[submodule "lib/arduino-lib"]
|
||||
path = lib/arduino-lib
|
||||
url = https://github.com/arduino/arduino-lib-mpy.git
|
||||
[submodule "lib/alif_ensemble-cmsis-dfp"]
|
||||
path = lib/alif_ensemble-cmsis-dfp
|
||||
url = https://github.com/alifsemi/alif_ensemble-cmsis-dfp.git
|
||||
[submodule "lib/alif-security-toolkit"]
|
||||
path = lib/alif-security-toolkit
|
||||
url = https://github.com/micropython/alif-security-toolkit.git
|
||||
|
||||
@@ -12,14 +12,14 @@ repos:
|
||||
verbose: true
|
||||
stages: [commit-msg]
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
# Version should be kept in sync with .github/workflows/ruff.yml & also micropython-lib
|
||||
rev: v0.11.6
|
||||
# Version should be kept in sync with .github/workflows/ruff.yml
|
||||
rev: v0.1.3
|
||||
hooks:
|
||||
- id: ruff
|
||||
- id: ruff-format
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
# Version should be kept in sync with .github/workflows/codespell.yml
|
||||
rev: v2.4.1
|
||||
rev: v2.2.6
|
||||
hooks:
|
||||
- id: codespell
|
||||
name: Spellcheck for changed files (codespell)
|
||||
|
||||
@@ -206,21 +206,14 @@ adhere to the existing style and use `tools/codeformat.py` to check any changes.
|
||||
The main conventions, and things not enforceable via the auto-formatter, are
|
||||
described below.
|
||||
|
||||
As the MicroPython code base is over ten years old, not every source file
|
||||
conforms fully to these conventions. If making small changes to existing code,
|
||||
then it's usually acceptable to follow the existing code's style. New code or
|
||||
major changes should follow the conventions described here.
|
||||
|
||||
## White space
|
||||
|
||||
White space:
|
||||
- Expand tabs to 4 spaces.
|
||||
- Don't leave trailing whitespace at the end of a line.
|
||||
- For control blocks (if, for, while), put 1 space between the
|
||||
keyword and the opening parenthesis.
|
||||
- Put 1 space after a comma, and 1 space around operators.
|
||||
|
||||
## Braces
|
||||
|
||||
Braces:
|
||||
- Use braces for all blocks, even no-line and single-line pieces of
|
||||
code.
|
||||
- Put opening braces on the end of the line it belongs to, not on
|
||||
@@ -228,43 +221,18 @@ major changes should follow the conventions described here.
|
||||
- For else-statements, put the else on the same line as the previous
|
||||
closing brace.
|
||||
|
||||
## Header files
|
||||
|
||||
Header files:
|
||||
- Header files should be protected from multiple inclusion with #if
|
||||
directives. See an existing header for naming convention.
|
||||
|
||||
## Names
|
||||
|
||||
Names:
|
||||
- Use underscore_case, not camelCase for all names.
|
||||
- Use CAPS_WITH_UNDERSCORE for enums and macros.
|
||||
- When defining a type use underscore_case and put '_t' after it.
|
||||
|
||||
### Public names (declared in headers)
|
||||
|
||||
- MicroPython-specific names (especially any declared in `py/` and `extmod/`
|
||||
directories) should generally start with `mp_` or `MP_`.
|
||||
- Functions and variables declared in a header should generally share a longer
|
||||
common prefix. Usually the prefix matches the file name (i.e. items defined in
|
||||
`py/obj.c` are declared in `py/obj.h` and should be prefixed `mp_obj_`). There
|
||||
are exceptions, for example where one header file contains declarations
|
||||
implemented in multiple source files for expediency.
|
||||
|
||||
### Private names (specific to a single .c file)
|
||||
|
||||
- For static functions and variables exposed to Python (i.e. a static C function
|
||||
that is wrapped in `MP_DEFINE_CONST_FUN_...` and attached to a module), use
|
||||
the file-level shared common prefix, i.e. name them as if the function or
|
||||
variable was not static.
|
||||
- Other static definitions in source files (i.e. functions or variables defined
|
||||
in a .c file that are only used within that .c file) don't need any prefix
|
||||
(specifically: no `s_` or `_` prefix, and generally avoid adding the
|
||||
file-level common prefix).
|
||||
|
||||
## Integer types
|
||||
|
||||
MicroPython runs on 16, 32, and 64 bit machines, so it's important to use the
|
||||
correctly-sized (and signed) integer types. The general guidelines are:
|
||||
|
||||
Integer types: MicroPython runs on 16, 32, and 64 bit machines, so it's
|
||||
important to use the correctly-sized (and signed) integer types. The
|
||||
general guidelines are:
|
||||
- For most cases use mp_int_t for signed and mp_uint_t for unsigned
|
||||
integer values. These are guaranteed to be machine-word sized and
|
||||
therefore big enough to hold the value from a MicroPython small-int
|
||||
@@ -273,13 +241,11 @@ correctly-sized (and signed) integer types. The general guidelines are:
|
||||
- You can use int/uint, but remember that they may be 16-bits wide.
|
||||
- If in doubt, use mp_int_t/mp_uint_t.
|
||||
|
||||
## Comments
|
||||
|
||||
Comments:
|
||||
- Be concise and only write comments for things that are not obvious.
|
||||
- Use `// ` prefix, NOT `/* ... */`. No extra fluff.
|
||||
|
||||
## Memory allocation
|
||||
|
||||
Memory allocation:
|
||||
- Use m_new, m_renew, m_del (and friends) to allocate and free heap memory.
|
||||
These macros are defined in py/misc.h.
|
||||
|
||||
|
||||
4
LICENSE
4
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
|
||||
@@ -59,6 +59,7 @@ used during the build process and is not part of the compiled source code.
|
||||
/pico-sdk (BSD-3-clause)
|
||||
/re15 (BSD-3-clause)
|
||||
/stm32lib (BSD-3-clause)
|
||||
/tinytest (BSD-3-clause)
|
||||
/tinyusb (MIT)
|
||||
/uzlib (Zlib)
|
||||
/wiznet5k (MIT)
|
||||
@@ -72,7 +73,6 @@ used during the build process and is not part of the compiled source code.
|
||||
/ppp_set_auth.* (Apache-2.0)
|
||||
/rp2
|
||||
/mutex_extra.c (BSD-3-clause)
|
||||
/clocks_extra.c (BSD-3-clause)
|
||||
/stm32
|
||||
/usbd*.c (MCD-ST Liberty SW License Agreement V2)
|
||||
/stm32_it.* (MIT + BSD-3-clause)
|
||||
|
||||
10
README.md
10
README.md
@@ -19,7 +19,7 @@ Python 3.5 and some select features from later versions). The following core
|
||||
datatypes are provided: `str`(including basic Unicode support), `bytes`,
|
||||
`bytearray`, `tuple`, `list`, `dict`, `set`, `frozenset`, `array.array`,
|
||||
`collections.namedtuple`, classes and instances. Builtin modules include
|
||||
`os`, `sys`, `time`, `re`, and `struct`, etc. Some ports have support for
|
||||
`os`, `sys`, `time`, `re`, and `struct`, etc. Select ports have support for
|
||||
`_thread` module (multithreading), `socket` and `ssl` for networking, and
|
||||
`asyncio`. Note that only a subset of Python 3 functionality is implemented
|
||||
for the data types and modules.
|
||||
@@ -35,8 +35,8 @@ DAC, PWM, SPI, I2C, CAN, Bluetooth, and USB.
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
See the [online documentation](https://docs.micropython.org/) for the API
|
||||
reference and information about using MicroPython and information about how
|
||||
See the [online documentation](https://docs.micropython.org/) for API
|
||||
references and information about using MicroPython and information about how
|
||||
it is implemented.
|
||||
|
||||
We use [GitHub Discussions](https://github.com/micropython/micropython/discussions)
|
||||
@@ -108,13 +108,13 @@ track of the code size of the core runtime and VM.
|
||||
|
||||
In addition, the following ports are provided in this repository:
|
||||
- [cc3200](ports/cc3200) -- Texas Instruments CC3200 (including PyCom WiPy).
|
||||
- [esp32](ports/esp32) -- Espressif ESP32 SoC (including ESP32S2, ESP32S3, ESP32C3, ESP32C6).
|
||||
- [esp32](ports/esp32) -- Espressif ESP32 SoC (including ESP32S2, ESP32S3, ESP32C3).
|
||||
- [esp8266](ports/esp8266) -- Espressif ESP8266 SoC.
|
||||
- [mimxrt](ports/mimxrt) -- NXP m.iMX RT (including Teensy 4.x).
|
||||
- [nrf](ports/nrf) -- Nordic Semiconductor nRF51 and nRF52.
|
||||
- [pic16bit](ports/pic16bit) -- Microchip PIC 16-bit.
|
||||
- [powerpc](ports/powerpc) -- IBM PowerPC (including Microwatt)
|
||||
- [qemu](ports/qemu) -- QEMU-based emulated target (for testing)
|
||||
- [qemu-arm](ports/qemu-arm) -- QEMU-based emulated target, for testing)
|
||||
- [renesas-ra](ports/renesas-ra) -- Renesas RA family.
|
||||
- [rp2](ports/rp2) -- Raspberry Pi RP2040 (including Pico and Pico W).
|
||||
- [samd](ports/samd) -- Microchip (formerly Atmel) SAMD21 and SAMD51.
|
||||
|
||||
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",
|
||||
|
||||
@@ -59,7 +59,7 @@ A MicroPython user C module is a directory with the following files:
|
||||
SRC_USERMOD_LIB_C += $(EXAMPLE_MOD_DIR)/utils/algorithm.c
|
||||
|
||||
Similarly, use ``SRC_USERMOD_CXX`` and ``SRC_USERMOD_LIB_CXX`` for C++
|
||||
source files. If you want to include assembly files use ``SRC_USERMOD_LIB_ASM``.
|
||||
source files.
|
||||
|
||||
If you have custom compiler options (like ``-I`` to add directories to search
|
||||
for header files), these should be added to ``CFLAGS_USERMOD`` for C code
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -18,7 +18,7 @@ working with this board it may be useful to get an overview of the microcontroll
|
||||
general.rst
|
||||
tutorial/index.rst
|
||||
|
||||
Note that there are several varieties of ESP32 -- ESP32, ESP32C3, ESP32C6, ESP32S2, ESP32S3 --
|
||||
Note that there are several varieties of ESP32 -- ESP32, ESP32C3, ESP32S2, ESP32S3 --
|
||||
supported by MicroPython, with some differences in functionality between them.
|
||||
|
||||
Installing MicroPython
|
||||
@@ -61,13 +61,13 @@ The :mod:`esp32` module::
|
||||
import esp32
|
||||
|
||||
esp32.raw_temperature() # read the internal temperature of the MCU, in Fahrenheit
|
||||
esp32.ULP() # access to the Ultra-Low-Power Co-processor, not on ESP32C3/C6
|
||||
esp32.ULP() # access to the Ultra-Low-Power Co-processor, not on ESP32C3
|
||||
|
||||
Note that the temperature sensor in the ESP32 will typically read higher than
|
||||
ambient due to the IC getting warm while it runs. This effect can be minimised
|
||||
by reading the temperature sensor immediately after waking up from sleep.
|
||||
|
||||
ESP32C3, ESP32C6, ESP32S2, and ESP32S3 also have an internal temperature sensor available.
|
||||
ESP32C3, ESP32S2, and ESP32S3 also have an internal temperature sensor available.
|
||||
It is implemented a bit differently to the ESP32 and returns the temperature in
|
||||
Celsius::
|
||||
|
||||
@@ -79,35 +79,35 @@ 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.ifconfig() # get the interface's IP/netmask/gw/DNS 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()
|
||||
print('network config:', wlan.ipconfig('addr4'))
|
||||
pass
|
||||
print('network config:', wlan.ifconfig())
|
||||
|
||||
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
|
||||
@@ -121,56 +121,32 @@ 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
|
||||
|
||||
lan = network.LAN(mdc=PIN_MDC, ...) # Set the pin and mode configuration
|
||||
lan.active(True) # activate the interface
|
||||
lan.ipconfig('addr4') # get the interface's IPv4 addresses
|
||||
lan.ifconfig() # get the interface's IP/netmask/gw/DNS 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.
|
||||
|
||||
@@ -32,18 +32,6 @@ the prescaler of the MCPWM0 peripheral.
|
||||
mem32[MCPWM0] = 0x55 # change PWM_CLK_PRESCALE
|
||||
print(hex(mem32[MCPWM0])) # read PWM_CLK_CFG_REG
|
||||
|
||||
The specific addresses will be different on different ESP32
|
||||
models. For example, ESP32-S3 uses these values:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
DR_REG_DPORT_BASE = const(0x600C_0000)
|
||||
DPORT_PERIP_CLK_EN0_REG = const(DR_REG_DPORT_BASE + 0x0018)
|
||||
DPORT_PERIP_RST_EN0_REG = const(DR_REG_DPORT_BASE + 0x0020)
|
||||
DPORT_PWM0_CLK_EN = const(1 << 17)
|
||||
MCPWM0 = const(0x6001_E000 + 0x0004)
|
||||
...
|
||||
|
||||
Note that before a peripheral can be used its clock must be enabled and it must
|
||||
be taken out of reset. In the above example the following registers are used
|
||||
for this:
|
||||
|
||||
@@ -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,19 +49,19 @@ 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
|
||||
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.ifconfig() # get the interface's IP/netmask/gw/DNS 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,14 +69,14 @@ 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...')
|
||||
wlan.connect('ssid', 'key')
|
||||
while not wlan.isconnected():
|
||||
pass
|
||||
print('network config:', wlan.ipconfig('addr4'))
|
||||
print('network config:', wlan.ifconfig())
|
||||
|
||||
Once the network is established the :mod:`socket <socket>` module can be used
|
||||
to create and use TCP/UDP sockets as usual.
|
||||
@@ -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::
|
||||
|
||||
@@ -20,10 +19,10 @@ You can check if the interfaces are active by::
|
||||
|
||||
You can also check the network settings of the interface by::
|
||||
|
||||
>>> ap_if.ipconfig('addr4')
|
||||
('192.168.4.1', '255.255.255.0')
|
||||
>>> ap_if.ifconfig()
|
||||
('192.168.4.1', '255.255.255.0', '192.168.4.1', '8.8.8.8')
|
||||
|
||||
The returned values are: IP address and netmask.
|
||||
The returned values are: IP address, netmask, gateway, DNS.
|
||||
|
||||
Configuration of the WiFi
|
||||
-------------------------
|
||||
@@ -46,8 +45,8 @@ To check if the connection is established use::
|
||||
|
||||
Once established you can check the IP address::
|
||||
|
||||
>>> sta_if.ipconfig('addr4')
|
||||
('192.168.0.2', '255.255.255.0')
|
||||
>>> sta_if.ifconfig()
|
||||
('192.168.0.2', '255.255.255.0', '192.168.0.1', '8.8.8.8')
|
||||
|
||||
You can then disable the access-point interface if you no longer need it::
|
||||
|
||||
@@ -58,14 +57,14 @@ 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)
|
||||
sta_if.connect('<ssid>', '<key>')
|
||||
while not sta_if.isconnected():
|
||||
pass
|
||||
print('network config:', sta_if.ipconfig('addr4'))
|
||||
print('network config:', sta_if.ifconfig())
|
||||
|
||||
Sockets
|
||||
-------
|
||||
|
||||
@@ -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`.
|
||||
@@ -84,10 +82,6 @@ Functions and types
|
||||
In MicroPython, `byteorder` parameter must be positional (this is
|
||||
compatible with CPython).
|
||||
|
||||
.. note:: The optional ``signed`` kwarg from CPython is not supported.
|
||||
MicroPython currently converts negative integers as signed,
|
||||
and positive as unsigned. (:ref:`Details <cpydiff_types_int_to_bytes>`.)
|
||||
|
||||
.. function:: isinstance()
|
||||
|
||||
.. function:: issubclass()
|
||||
@@ -106,8 +100,6 @@ Functions and types
|
||||
|
||||
.. class:: memoryview()
|
||||
|
||||
|see_cpython| `python:memoryview`.
|
||||
|
||||
.. function:: min()
|
||||
|
||||
.. function:: next()
|
||||
@@ -174,10 +166,6 @@ Exceptions
|
||||
|
||||
.. exception:: KeyboardInterrupt
|
||||
|
||||
|see_cpython| `python:KeyboardInterrupt`.
|
||||
|
||||
See also in the context of :ref:`soft_bricking`.
|
||||
|
||||
.. exception:: KeyError
|
||||
|
||||
.. exception:: MemoryError
|
||||
@@ -198,12 +186,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])
|
||||
|
||||
@@ -238,12 +238,6 @@ The following methods are not part of the core Pin API and only implemented on c
|
||||
|
||||
Availability: cc3200 port.
|
||||
|
||||
.. method:: Pin.toggle()
|
||||
|
||||
Toggle output pin from "0" to "1" or vice-versa.
|
||||
|
||||
Availability: cc3200, esp32, esp8266, mimxrt, rp2, samd 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.
|
||||
|
||||
@@ -152,6 +152,31 @@ Methods
|
||||
Send a break condition on the bus. This drives the bus low for a duration
|
||||
longer than required for a normal transmission of a character.
|
||||
|
||||
.. method:: UART.irq(trigger, priority=1, handler=None, wake=machine.IDLE)
|
||||
|
||||
Create a callback to be triggered when data is received on the UART.
|
||||
|
||||
- *trigger* can only be ``UART.RX_ANY``
|
||||
- *priority* level of the interrupt. Can take values in the range 1-7.
|
||||
Higher values represent higher priorities.
|
||||
- *handler* an optional function to be called when new characters arrive.
|
||||
- *wake* can only be ``machine.IDLE``.
|
||||
|
||||
.. note::
|
||||
|
||||
The handler will be called whenever any of the following two conditions are met:
|
||||
|
||||
- 8 new characters have been received.
|
||||
- At least 1 new character is waiting in the Rx buffer and the Rx line has been
|
||||
silent for the duration of 1 complete frame.
|
||||
|
||||
This means that when the handler function is called there will be between 1 to 8
|
||||
characters waiting.
|
||||
|
||||
Returns an irq object.
|
||||
|
||||
Availability: WiPy.
|
||||
|
||||
.. method:: UART.flush()
|
||||
|
||||
Waits until all data has been sent. In case of a timeout, an exception is raised. The timeout
|
||||
@@ -160,7 +185,7 @@ Methods
|
||||
|
||||
.. note::
|
||||
|
||||
For the esp8266 and nrf ports the call returns while the last byte is sent.
|
||||
For the rp2, esp8266 and nrf ports the call returns while the last byte is sent.
|
||||
If required, a one character wait time has to be added in the calling script.
|
||||
|
||||
Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra
|
||||
@@ -172,92 +197,17 @@ Methods
|
||||
|
||||
.. note::
|
||||
|
||||
For the esp8266 and nrf ports the call may return ``True`` even if the last byte
|
||||
For the rp2, esp8266 and nrf ports the call may return ``True`` even if the last byte
|
||||
of a transfer is still being sent. If required, a one character wait time has to be
|
||||
added in the calling script.
|
||||
|
||||
Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra
|
||||
|
||||
.. method:: UART.irq(handler=None, trigger=0, hard=False)
|
||||
|
||||
Configure an interrupt handler to be called when a UART event occurs.
|
||||
|
||||
The arguments are:
|
||||
|
||||
- *handler* is an optional function to be called when the interrupt event
|
||||
triggers. The handler must take exactly one argument which is the
|
||||
``UART`` instance.
|
||||
|
||||
- *trigger* configures the event(s) which can generate an interrupt.
|
||||
Possible values are a mask of one or more of the following:
|
||||
|
||||
- ``UART.IRQ_RXIDLE`` interrupt after receiving at least one character
|
||||
and then the RX line goes idle.
|
||||
- ``UART.IRQ_RX`` interrupt after each received character.
|
||||
- ``UART.IRQ_TXIDLE`` interrupt after or while the last character(s) of
|
||||
a message are or have been sent.
|
||||
- ``UART.IRQ_BREAK`` interrupt when a break state is detected at RX
|
||||
|
||||
- *hard* if true a hardware interrupt is used. This reduces the delay
|
||||
between the pin change and the handler being called. Hard interrupt
|
||||
handlers may not allocate memory; see :ref:`isr_rules`.
|
||||
|
||||
Returns an irq object.
|
||||
|
||||
Due to limitations of the hardware not all trigger events are available on all ports.
|
||||
|
||||
.. table:: Availability of triggers
|
||||
:align: center
|
||||
|
||||
============== ========== ====== ========== =========
|
||||
Port / Trigger IRQ_RXIDLE IRQ_RX IRQ_TXIDLE IRQ_BREAK
|
||||
============== ========== ====== ========== =========
|
||||
CC3200 yes
|
||||
ESP32 yes yes yes
|
||||
MIMXRT yes yes
|
||||
NRF yes yes
|
||||
RENESAS-RA yes yes
|
||||
RP2 yes yes yes
|
||||
SAMD yes yes yes
|
||||
STM32 yes yes
|
||||
============== ========== ====== ========== =========
|
||||
|
||||
|
||||
.. 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 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
|
||||
are to be sent.
|
||||
|
||||
- The rp2 port's UART.IRQ_BREAK needs receiving valid characters for triggering
|
||||
again.
|
||||
|
||||
- The SAMD port's UART.IRQ_TXIDLE is triggered while the last character is sent.
|
||||
|
||||
- On STM32F4xx MCU's, using the trigger UART.IRQ_RXIDLE the handler will be called once
|
||||
after the first character and then after the end of the message, when the line is
|
||||
idle.
|
||||
|
||||
|
||||
Availability: cc3200, esp32, mimxrt, nrf, renesas-ra, rp2, samd, stm32.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: UART.RTS
|
||||
UART.CTS
|
||||
.. data:: UART.RX_ANY
|
||||
|
||||
Flow control options.
|
||||
IRQ trigger sources
|
||||
|
||||
Availability: esp32, mimxrt, renesas-ra, rp2, stm32.
|
||||
|
||||
.. data:: UART.IRQ_RXIDLE
|
||||
UART.IRQ_RX
|
||||
UART.IRQ_TXIDLE
|
||||
UART.IRQ_BREAK
|
||||
|
||||
IRQ trigger sources.
|
||||
|
||||
Availability: renesas-ra, stm32, esp32, rp2040, mimxrt, samd, cc3200.
|
||||
Availability: WiPy.
|
||||
|
||||
@@ -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
|
||||
@@ -216,13 +215,6 @@ Methods
|
||||
drivers. Placing a different string at any of these indexes overrides that
|
||||
string in the built-in driver.
|
||||
|
||||
.. method:: USBDevice.remote_wakeup(self)
|
||||
|
||||
Wake up host if we are in suspend mode and the REMOTE_WAKEUP feature
|
||||
is enabled by the host. This has to be enabled in the USB attributes,
|
||||
and on the host. Returns ``True`` if remote wakeup was enabled and
|
||||
active and the host was woken up.
|
||||
|
||||
.. method:: USBDevice.submit_xfer(self, ep, buffer /)
|
||||
|
||||
Submit a USB transfer on endpoint number ``ep``. ``buffer`` must be
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -126,20 +127,14 @@ Power related functions
|
||||
|
||||
.. function:: idle()
|
||||
|
||||
Gates the clock to the CPU, useful to reduce power consumption at any time
|
||||
during short or long periods. Peripherals continue working and execution
|
||||
resumes as soon as any interrupt is triggered, or at most one millisecond
|
||||
after the CPU was paused.
|
||||
|
||||
It is recommended to call this function inside any tight loop that is
|
||||
continuously checking for an external change (i.e. polling). This will reduce
|
||||
power consumption without significantly impacting performance. To reduce
|
||||
power consumption further then see the :func:`lightsleep`,
|
||||
:func:`time.sleep()` and :func:`time.sleep_ms()` functions.
|
||||
Gates the clock to the CPU, useful to reduce power consumption at any time during
|
||||
short or long periods. Peripherals continue working and execution resumes as soon
|
||||
as any interrupt is triggered (on many ports this includes system timer
|
||||
interrupt occurring at regular intervals on the order of millisecond).
|
||||
|
||||
.. function:: sleep()
|
||||
|
||||
.. note:: This function is deprecated, use :func:`lightsleep()` instead with no arguments.
|
||||
.. note:: This function is deprecated, use `lightsleep()` instead with no arguments.
|
||||
|
||||
.. function:: lightsleep([time_ms])
|
||||
deepsleep([time_ms])
|
||||
@@ -264,12 +259,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.
|
||||
@@ -125,11 +125,8 @@ Functions
|
||||
Return the natural logarithm of the gamma function of ``x``.
|
||||
|
||||
.. function:: log(x)
|
||||
log(x, base)
|
||||
|
||||
With one argument, return the natural logarithm of *x*.
|
||||
|
||||
With two arguments, return the logarithm of *x* to the given *base*.
|
||||
Return the natural logarithm of ``x``.
|
||||
|
||||
.. function:: log10(x)
|
||||
|
||||
|
||||
@@ -136,14 +136,6 @@ Functions
|
||||
the heap may be locked) and scheduling a function to call later will lift
|
||||
those restrictions.
|
||||
|
||||
On multi-threaded ports, the scheduled function's behaviour depends on
|
||||
whether the Global Interpreter Lock (GIL) is enabled for the specific port:
|
||||
|
||||
- If GIL is enabled, the function can preempt any thread and run in its
|
||||
context.
|
||||
- If GIL is disabled, the function will only preempt the main thread and run
|
||||
in its context.
|
||||
|
||||
Note: If `schedule()` is called from a preempting IRQ, when memory
|
||||
allocation is not allowed and the callback to be passed to `schedule()` is
|
||||
a bound method, passing this directly will fail. This is because creating a
|
||||
@@ -155,71 +147,3 @@ Functions
|
||||
|
||||
There is a finite queue to hold the scheduled functions and `schedule()`
|
||||
will raise a `RuntimeError` if the queue is full.
|
||||
|
||||
Classes
|
||||
-------
|
||||
|
||||
.. class:: RingIO(size)
|
||||
.. class:: RingIO(buffer)
|
||||
:noindex:
|
||||
|
||||
Provides a fixed-size ringbuffer for bytes with a stream interface. Can be
|
||||
considered like a fifo queue variant of `io.BytesIO`.
|
||||
|
||||
When created with integer size a suitable buffer will be allocated.
|
||||
Alternatively a `bytearray` or similar buffer protocol object can be provided
|
||||
to the constructor for in-place use.
|
||||
|
||||
The classic ringbuffer algorithm is used which allows for any size buffer
|
||||
to be used however one byte will be consumed for tracking. If initialised
|
||||
with an integer size this will be accounted for, for example ``RingIO(16)``
|
||||
will allocate a 17 byte buffer internally so it can hold 16 bytes of data.
|
||||
When passing in a pre-allocated buffer however one byte less than its
|
||||
original length will be available for storage, eg. ``RingIO(bytearray(16))``
|
||||
will only hold 15 bytes of data.
|
||||
|
||||
A RingIO instance can be IRQ / thread safe when used to pass data in a single
|
||||
direction eg. when written to in an IRQ and read from in a non-IRQ function
|
||||
(or vice versa). This does not hold if you try to eg. write to a single instance
|
||||
from both IRQ and non-IRQ code, this would often cause data corruption.
|
||||
|
||||
.. method:: RingIO.any()
|
||||
|
||||
Returns an integer counting the number of characters that can be read.
|
||||
|
||||
.. method:: RingIO.read([nbytes])
|
||||
|
||||
Read available characters. This is a non-blocking function. If ``nbytes``
|
||||
is specified then read at most that many bytes, otherwise read as much
|
||||
data as possible.
|
||||
|
||||
Return value: a bytes object containing the bytes read. Will be
|
||||
zero-length bytes object if no data is available.
|
||||
|
||||
.. method:: RingIO.readline([nbytes])
|
||||
|
||||
Read a line, ending in a newline character or return if one exists in
|
||||
the buffer, else return available bytes in buffer. If ``nbytes`` is
|
||||
specified then read at most that many bytes.
|
||||
|
||||
Return value: a bytes object containing the line read.
|
||||
|
||||
.. method:: RingIO.readinto(buf[, nbytes])
|
||||
|
||||
Read available bytes into the provided ``buf``. If ``nbytes`` is
|
||||
specified then read at most that many bytes. Otherwise, read at
|
||||
most ``len(buf)`` bytes.
|
||||
|
||||
Return value: Integer count of the number of bytes read into ``buf``.
|
||||
|
||||
.. method:: RingIO.write(buf)
|
||||
|
||||
Non-blocking write of bytes from ``buf`` into the ringbuffer, limited
|
||||
by the available space in the ringbuffer.
|
||||
|
||||
Return value: Integer count of bytes written.
|
||||
|
||||
.. method:: RingIO.close()
|
||||
|
||||
No-op provided as part of standard `stream` interface. Has no effect
|
||||
on data in the ringbuffer.
|
||||
|
||||
@@ -43,8 +43,7 @@ Constructors
|
||||
- *pin* is a machine.Pin instance.
|
||||
- *n* is the number of LEDs in the strip.
|
||||
- *bpp* is 3 for RGB LEDs, and 4 for RGBW LEDs.
|
||||
- *timing* is 0 for 400KHz, and 1 for 800kHz LEDs (most are 800kHz). You
|
||||
may also supply a timing tuple as accepted by `machine.bitstream()`.
|
||||
- *timing* is 0 for 400KHz, and 1 for 800kHz LEDs (most are 800kHz).
|
||||
|
||||
Pixel access methods
|
||||
--------------------
|
||||
|
||||
@@ -6,11 +6,11 @@ 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)
|
||||
print(nic.ipconfig("addr4"))
|
||||
print(nic.ifconfig())
|
||||
|
||||
# now use socket as usual
|
||||
...
|
||||
@@ -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
|
||||
-------
|
||||
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
.. currentmodule:: network
|
||||
.. _network.PPP:
|
||||
|
||||
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.
|
||||
|
||||
Example usage::
|
||||
|
||||
import network
|
||||
|
||||
ppp = network.PPP(uart)
|
||||
ppp.connect()
|
||||
|
||||
while not ppp.isconnected():
|
||||
pass
|
||||
|
||||
print(ppp.ipconfig("addr4"))
|
||||
|
||||
# use the socket module as usual, etc
|
||||
|
||||
ppp.disconnect()
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: PPP(stream)
|
||||
|
||||
Create a PPP driver object.
|
||||
|
||||
Arguments are:
|
||||
|
||||
- *stream* is any object that supports the stream protocol, but is most commonly a
|
||||
:class:`machine.UART` instance. This stream object must have an ``irq()`` method
|
||||
and an ``IRQ_RXIDLE`` constant, for use by `PPP.connect`.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: PPP.connect(security=SEC_NONE, user=None, key=None)
|
||||
|
||||
Initiate a PPP connection with the given parameters:
|
||||
|
||||
- *security* is the type of security, either ``PPP.SEC_NONE``, ``PPP.SEC_PAP``,
|
||||
or ``PPP.SEC_CHAP``.
|
||||
- *user* is an optional user name to use with the security mode.
|
||||
- *key* is an optional password to use with the security mode.
|
||||
|
||||
When this method is called the underlying stream has its interrupt configured to call
|
||||
`PPP.poll` via ``stream.irq(ppp.poll, stream.IRQ_RXIDLE)``. This makes sure the
|
||||
stream is polled, and data passed up the PPP stack, wheverver data becomes available
|
||||
on the stream.
|
||||
|
||||
The connection proceeds asynchronously, in the background.
|
||||
|
||||
.. method:: PPP.disconnect()
|
||||
|
||||
Terminate the connection. This must be called to cleanly close the PPP connection.
|
||||
|
||||
.. method:: PPP.isconnected()
|
||||
|
||||
Returns ``True`` if the PPP link is connected and up.
|
||||
Returns ``False`` otherwise.
|
||||
|
||||
.. method:: PPP.status()
|
||||
|
||||
Returns the PPP status.
|
||||
|
||||
.. 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)
|
||||
|
||||
.. method:: PPP.ipconfig('param')
|
||||
PPP.ipconfig(param=value, ...)
|
||||
|
||||
See `AbstractNIC.ipconfig`.
|
||||
|
||||
.. method:: PPP.ifconfig([(ip, subnet, gateway, dns)])
|
||||
|
||||
See `AbstractNIC.ifconfig`.
|
||||
|
||||
.. method:: PPP.poll()
|
||||
|
||||
Poll the underlying stream for data, and pass it up the PPP stack.
|
||||
This is called automatically if the stream is a UART with a RXIDLE interrupt,
|
||||
so it's not usually necessary to call it manually.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: PPP.SEC_NONE
|
||||
PPP.SEC_PAP
|
||||
PPP.SEC_CHAP
|
||||
|
||||
The type of connection security.
|
||||
@@ -9,14 +9,11 @@ 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
|
||||
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
|
||||
print(nic.ipconfig("addr4"))
|
||||
print(nic.ifconfig())
|
||||
|
||||
# now use socket as usual
|
||||
...
|
||||
@@ -54,7 +51,20 @@ Constructors
|
||||
Methods
|
||||
-------
|
||||
|
||||
This class implements most methods from `AbstractNIC <AbstractNIC>`, which are documented there. Additional methods are:
|
||||
.. method:: WIZNET5K.isconnected()
|
||||
|
||||
Returns ``True`` if the physical Ethernet link is connected and up.
|
||||
Returns ``False`` otherwise.
|
||||
|
||||
.. method:: WIZNET5K.ifconfig([(ip, subnet, gateway, dns)])
|
||||
|
||||
Get/set IP address, subnet mask, gateway and DNS.
|
||||
|
||||
When called with no arguments, this method returns a 4-tuple with the above information.
|
||||
|
||||
To set the above values, pass a 4-tuple with the required information. For example::
|
||||
|
||||
nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
|
||||
|
||||
.. method:: WIZNET5K.regs()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -118,7 +107,7 @@ Methods
|
||||
|
||||
Get or set general network interface parameters. These methods allow to work
|
||||
with additional parameters beyond standard IP configuration (as dealt with by
|
||||
`AbstractNIC.ipconfig()`). These include network-specific and hardware-specific
|
||||
`WLAN.ifconfig()`). These include network-specific and hardware-specific
|
||||
parameters. For setting parameters, keyword argument syntax should be used,
|
||||
multiple parameters can be set at once. For querying, parameters name should
|
||||
be quoted as a string, and only one parameter can be queries at time::
|
||||
@@ -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)
|
||||
|
||||
@@ -20,7 +20,7 @@ This class provides a driver for the WiFi network processor in the WiPy. Example
|
||||
wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
|
||||
while not wlan.isconnected():
|
||||
time.sleep_ms(50)
|
||||
print(wlan.ipconfig("addr4"))
|
||||
print(wlan.ifconfig())
|
||||
|
||||
# now use socket as usual
|
||||
...
|
||||
@@ -96,10 +96,16 @@ Methods
|
||||
In case of STA mode, returns ``True`` if connected to a WiFi access point and has a valid IP address.
|
||||
In AP mode returns ``True`` when a station is connected, ``False`` otherwise.
|
||||
|
||||
.. method:: WLANWiPy.ipconfig('param')
|
||||
WLANWiPy.ipconfig(param=value, ...)
|
||||
.. method:: WLANWiPy.ifconfig(if_id=0, config=['dhcp' or configtuple])
|
||||
|
||||
See :meth:`AbstractNIC.ipconfig <AbstractNIC.ipconfig>`. Supported parameters are: ``dhcp4``, ``addr4``, ``gw4``.
|
||||
With no parameters given returns a 4-tuple of *(ip, subnet_mask, gateway, DNS_server)*.
|
||||
|
||||
if ``'dhcp'`` is passed as a parameter then the DHCP client is enabled and the IP params
|
||||
are negotiated with the AP.
|
||||
|
||||
If the 4-tuple config is given then a static IP is configured. For instance::
|
||||
|
||||
wlan.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
|
||||
|
||||
.. method:: WLANWiPy.mode([mode])
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ For example::
|
||||
print("Waiting for connection...")
|
||||
while not nic.isconnected():
|
||||
time.sleep(1)
|
||||
print(nic.ipconfig("addr4"))
|
||||
print(nic.ifconfig())
|
||||
|
||||
# now use socket as usual
|
||||
import socket
|
||||
@@ -113,48 +113,8 @@ parameter should be `id`.
|
||||
connected to the AP. The list contains tuples of the form
|
||||
(MAC, RSSI).
|
||||
|
||||
.. method:: AbstractNIC.ipconfig('param')
|
||||
AbstractNIC.ipconfig(param=value, ...)
|
||||
|
||||
Get or set interface-specific IP-configuration interface parameters.
|
||||
Supported parameters are the following (availability of a particular
|
||||
parameter depends on the port and the specific network interface):
|
||||
|
||||
* ``dhcp4`` (``True/False``) obtain an IPv4 address, gateway and dns
|
||||
server via DHCP. This method does not block and wait for an address
|
||||
to be obtained. To check if an address was obtained, use the read-only
|
||||
property ``has_dhcp4``.
|
||||
* ``gw4`` Get/set the IPv4 default-gateway.
|
||||
* ``dhcp6`` (``True/False``) obtain a DNS server via stateless DHCPv6.
|
||||
Obtaining IP Addresses via DHCPv6 is currently not implemented.
|
||||
* ``autoconf6`` (``True/False``) obtain a stateless IPv6 address via
|
||||
the network prefix shared in router advertisements. To check if a
|
||||
stateless address was obtained, use the read-only
|
||||
property ``has_autoconf6``.
|
||||
* ``addr4`` (e.g. ``192.168.0.4/24``) obtain the current IPv4 address
|
||||
and network mask as ``(ip, subnet)``-tuple, regardless of how this
|
||||
address was obtained. This method can be used to set a static IPv4
|
||||
address either as ``(ip, subnet)``-tuple or in CIDR-notation.
|
||||
* ``addr6`` (e.g. ``fe80::1234:5678``) obtain a list of current IPv6
|
||||
addresses as ``(ip, state, preferred_lifetime, valid_lifetime)``-tuple.
|
||||
This include link-local, slaac and static addresses.
|
||||
``preferred_lifetime`` and ``valid_lifetime`` represent the remaining
|
||||
valid and preferred lifetime of each IPv6 address, in seconds.
|
||||
``state`` indicates the current state of the address:
|
||||
|
||||
* ``0x08`` - ``0x0f`` indicates the address is tentative, counting the
|
||||
number of probes sent.
|
||||
* ``0x10`` The address is deprecated (but still valid)
|
||||
* ``0x30`` The address is preferred (and valid)
|
||||
* ``0x40`` The address is duplicated and can not be used.
|
||||
|
||||
This method can be used to set a static IPv6
|
||||
address, by setting this parameter to the address, like ``fe80::1234:5678``.
|
||||
|
||||
.. method:: AbstractNIC.ifconfig([(ip, subnet, gateway, dns)])
|
||||
|
||||
.. note:: This function is deprecated, use `ipconfig()` instead.
|
||||
|
||||
Get/set IP-level network interface parameters: IP address, subnet mask,
|
||||
gateway and DNS server. When called with no arguments, this method returns
|
||||
a 4-tuple with the above information. To set the above values, pass a
|
||||
@@ -167,7 +127,7 @@ parameter should be `id`.
|
||||
|
||||
Get or set general network interface parameters. These methods allow to work
|
||||
with additional parameters beyond standard IP configuration (as dealt with by
|
||||
`ipconfig()`). These include network-specific and hardware-specific
|
||||
`ifconfig()`). These include network-specific and hardware-specific
|
||||
parameters. For setting parameters, the keyword argument
|
||||
syntax should be used, and multiple parameters can be set at once. For
|
||||
querying, a parameter name should be quoted as a string, and only one
|
||||
@@ -192,7 +152,6 @@ provide a way to control networking interfaces of various kinds.
|
||||
network.WLANWiPy.rst
|
||||
network.WIZNET5K.rst
|
||||
network.LAN.rst
|
||||
network.PPP.rst
|
||||
|
||||
Network functions
|
||||
=================
|
||||
@@ -236,20 +195,6 @@ The following are functions available in the network module.
|
||||
|
||||
The default hostname is typically the name of the board.
|
||||
|
||||
.. function:: ipconfig('param')
|
||||
ipconfig(param=value, ...)
|
||||
|
||||
Get or set global IP-configuration parameters.
|
||||
Supported parameters are the following (availability of a particular
|
||||
parameter depends on the port and the specific network interface):
|
||||
|
||||
* ``dns`` Get/set DNS server. This method can support both, IPv4 and
|
||||
IPv6 addresses.
|
||||
* ``prefer`` (``4/6``) Specify which address type to return, if a domain
|
||||
name has both A and AAAA records. Note, that this does not clear the
|
||||
local DNS cache, so that any previously obtained addresses might not
|
||||
change.
|
||||
|
||||
.. function:: phy_mode([mode])
|
||||
|
||||
Get or set the PHY mode.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -27,17 +27,6 @@ Constructors
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: PIO.gpio_base([base])
|
||||
|
||||
Query and optionally set the current GPIO base for this PIO instance.
|
||||
|
||||
If an argument is given then it must be a pin (or integer corresponding to a pin
|
||||
number), restricted to either GPIO0 or GPIO16. The GPIO base will then be set to
|
||||
that pin. Setting the GPIO base must be done before any programs are added or state
|
||||
machines created.
|
||||
|
||||
Returns the current GPIO base pin.
|
||||
|
||||
.. method:: PIO.add_program(program)
|
||||
|
||||
Add the *program* to the instruction memory of this PIO instance.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -450,10 +438,6 @@ The i.MXRT MCU supports battery backup of the RTC. By connecting a battery of
|
||||
current drawn from the battery is ~20µA, which is rather high. A CR2032 coin
|
||||
cell will last for about one year.
|
||||
|
||||
Note: In v1.23.0 the support for subseconds was removed. When reading the RTC, 0 will
|
||||
be returned as value for subsecond, When setting the RTC time, the subsecond
|
||||
field is ignored. The RTC itself does not provide a microsecond value.
|
||||
|
||||
SD card
|
||||
-------
|
||||
|
||||
@@ -544,7 +528,7 @@ Ethernet. Example usage::
|
||||
lan.active(True)
|
||||
|
||||
If there is a DHCP server in the LAN, the IP address is supplied by that server.
|
||||
Otherwise, the IP address can be set with lan.ipconfig(addr4="..."). The default address
|
||||
Otherwise, the IP address can be set with lan.ifconfig(). The default address
|
||||
is 192.168.0.1.
|
||||
|
||||
Teensy 4.1 does not have an Ethernet jack on the board, but PJRC offers an
|
||||
|
||||
@@ -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
|
||||
@@ -228,53 +227,24 @@ The full list of supported commands are:
|
||||
- ``cat <file..>`` to show the contents of a file or files on the device
|
||||
- ``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
|
||||
- ``cp [-r] <src...> <dest>`` to copy files
|
||||
- ``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.
|
||||
@@ -286,11 +256,6 @@ The full list of supported commands are:
|
||||
This will copy the file to the device then enter the REPL. The ``+`` prevents
|
||||
``"repl"`` being interpreted as a path.
|
||||
|
||||
The ``cp`` command supports the ``-r`` option to make a recursive copy. By
|
||||
default ``cp`` will skip copying files to the remote device if the SHA256 hash
|
||||
of the source and destination file matches. To force a copy regardless of the
|
||||
hash use the ``-f`` option.
|
||||
|
||||
**Note:** For convenience, all of the filesystem sub-commands are also
|
||||
:ref:`aliased as regular commands <mpremote_shortcuts>`, i.e. you can write
|
||||
``mpremote cp ...`` instead of ``mpremote fs cp ...``.
|
||||
@@ -376,29 +341,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 +429,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
|
||||
@@ -534,9 +469,9 @@ An example ``config.py`` might look like:
|
||||
for ap in wl.scan():
|
||||
print(ap)
|
||||
""",], # Print out nearby WiFi networks.
|
||||
"wl_ipconfig": [
|
||||
"wl_ifconfig": [
|
||||
"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.ifconfig())",
|
||||
""",], # 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 +541,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
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ If importing an .mpy file fails then try the following:
|
||||
sys_mpy = sys.implementation._mpy
|
||||
arch = [None, 'x86', 'x64',
|
||||
'armv6', 'armv6m', 'armv7m', 'armv7em', 'armv7emsp', 'armv7emdp',
|
||||
'xtensa', 'xtensawin', 'rv32imc'][sys_mpy >> 10]
|
||||
'xtensa', 'xtensawin'][sys_mpy >> 10]
|
||||
print('mpy version:', sys_mpy & 0xff)
|
||||
print('mpy sub-version:', sys_mpy >> 8 & 3)
|
||||
print('mpy flags:', end='')
|
||||
|
||||
@@ -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``.
|
||||
|
||||
@@ -120,8 +120,9 @@ Some more examples::
|
||||
# Same, but using . instead.
|
||||
$ pyboard.py --device /dev/ttyACM0 -f cp :main.py .
|
||||
|
||||
# Copy three files to the device, keeping their names.
|
||||
$ pyboard.py --device /dev/ttyACM0 -f cp main.py app.py foo.py :
|
||||
# Copy three files to the device, keeping their names
|
||||
# and paths (note: `lib` must exist on the device)
|
||||
$ pyboard.py --device /dev/ttyACM0 -f cp main.py app.py lib/foo.py :
|
||||
|
||||
# Remove a file from the device.
|
||||
$ pyboard.py --device /dev/ttyACM0 -f rm util.py
|
||||
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user