30 Commits

Author SHA1 Message Date
e4422b860e rp2: Fix stacks for multicore operation
Unfortunately, no way to override this from board config.
2025-03-23 19:11:24 +01:00
0f26771a44 rp2: Modify linker script to run MP3 decoder from RAM 2025-03-04 22:57:09 +01:00
Mike Bell
29275e2c58 rp2/rp2_flash: Workaround multicore lockout not being reset.
With regression test.

See upstream bug https://github.com/raspberrypi/pico-sdk/issues/2201

Tested-by: Angus Gratton <angus@redyak.com.au>
Signed-off-by: Mike Bell <mdb036@gmail.com>
2025-03-04 20:12:18 +01:00
Damien George
732c2989c5 lib/pico-sdk: Update to version 2.1.1.
Release notes: https://github.com/raspberrypi/pico-sdk/releases/tag/2.1.1

Signed-off-by: Damien George <damien@micropython.org>
2025-03-04 19:49:20 +01:00
Peter Harper
ef5c3c043c rp2/mphalport: Add mp_hal_is_pin_reserved() function.
As cyw43 pins might be dynamic, add a function that returns if a pin is
reserved.  This is used by `MICROPY_HW_PIN_RESERVED` to prevent the pin IRQ
from being reset across a soft-reset.

Signed-off-by: Peter Harper <peter.harper@raspberrypi.com>
2025-03-04 19:41:59 +01:00
Peter Harper
ba21be5215 rp2/cyw43_configport: Define cyw43 pins.
The cyw43 pins used to be hardcoded and `CYW43_PIN_WL_HOST_WAKE` and
`CYW43_PIN_WL_REG_ON` were in the `pico_w.h` board header.

This has been changed so the board header just defines the "default
version of the pins, e.g. `CYW43_DEFAULT_PIN_WL_HOST_WAKE`,
`CYW43_DEFAULT_PIN_WL_REG_ON` etc.

Set the pin values in `cyw43_configport.`h so `cyw43-driver` sees them and
allow them to be changed at runtime (dynamic) if required.

Signed-off-by: Peter Harper <peter.harper@raspberrypi.com>
2025-03-04 19:40:17 +01:00
Phil Howard
8ba7af3a70 rp2/CMakeLists.txt: Add components required by bootrom.h.
Signed-off-by: Peter Harper <peter.harper@raspberrypi.com>
2025-03-04 19:38:19 +01:00
Peter Harper
08513e1a32 lib/pico-sdk: Update to version 2.1.0.
Brings in support for Pico 2 W, among other things.

Signed-off-by: Peter Harper <peter.harper@raspberrypi.com>
2025-03-04 19:38:19 +01:00
Damien George
ecfdd5d6f9 all: Bump version to 1.24.1.
Signed-off-by: Damien George <damien@micropython.org>
2024-11-29 23:53:11 +11:00
Angus Gratton
564ef28ad2 py/objfloat: Workaround non-constant NAN definition on Windows MSVC.
Recent MSVC versions have changed the definition of NAN to a non-constant
expression!  This is a bug, C standard says it should be a constant.

Good explanation and workaround at: https://stackoverflow.com/a/79199887

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-11-28 23:56:21 +11:00
robert-hh
7118942a8c nrf/drivers/ticker: Reset slow ticker callback count on soft reboot.
The micro:bit board (and probably other boards using the music or display
module) locked up on soft reboot.  Reason was a buffer overflow caused by
an index counter, which was not reset on soft_reboot.

That's fixed in this commit.  Tested with a micro:bit board, performing a
series of soft reboots.

Signed-off-by: robert-hh <robert@hammelrath.com>
2024-11-28 23:08:33 +11:00
Corran Webster
948863c0b8 extmod/modframebuf: Fix 0 radius bug in FrameBuffer.ellipse.
This fixes a bug in FrameBuffer.ellipse where it goes into an infinite loop
if both radii are 0.

This fixes the bug with a simple pre-check to see if both radii are 0, and
in that case sets a single pixel at the center. This is consistent with the
behaviour of the method when called with just one of the radii set to 0,
where it will draw a horizontal or vertical line of 1 pixel width.

The pixel is set with setpixel_checked so it should handle out-of-bounds
drawing correctly.

This fix also includes three new tests: one for the default behaviour, one
for drawing out-of-bounds, and one for when the sector mask is 0.

Fixes issue #16053.

Signed-off-by: Corran Webster <cwebster@unital.dev>
2024-11-28 23:08:29 +11:00
Angus Gratton
33f50d4f20 esp32: Fix machine.TouchPad startup on ESP32-S2 and S3.
Closes #13178.

TouchPad confirmed working on both chips, and fixes the the ESP32-S3
reading constant max value. Was unable to reproduce the bug on ESP32-S2 but
this may be due to my test setup, and it still works with the fix.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-11-28 23:08:26 +11:00
Angus Gratton
eb0027b82f esp32: Use hardware version for touchpad macro defines.
ESP32 has hardware V1 and S2/S3 has V2, and future chips
may have different versions.

This should still compile to the same binary before and after.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-11-28 23:08:22 +11:00
Angus Gratton
03bc561edb esp32: Fix setting WLAN channel in AP mode.
- Previously the call to esp_wifi_set_channel() would be immediately
  overridden by calling esp_wifi_config(...) with the previous channel set.

- AP interface doesn't seem to need more than esp_wifi_config(...) to work.
  It will automatically configure 40MHz bandwidth and place the secondary
  channel using similar logic to what was being explicitly calculated here.

- However, calling esp_wifi_set_channel() on the STA interface is necessary
  if using this interface with ESP-NOW (without connecting to an AP). So
  the esp_wifi_set_channel() call is kept in for this purpose. Without
  this, tests/multi_espnow/70_channel.py fails.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-11-28 23:08:18 +11:00
Angus Gratton
49b83ed44a extmod/network_cyw43: Allow configuring active AP interface.
Configuring the AP for cyw43 writes to some buffers that are only sent to
the modem when the interface is brought up. This means you can't configure
the AP after calling active(True), the new settings seem to be accepted but
the radio doesn't change.

This is different to the WLAN behaviour on other ports. The esp8266 port
requires calling active(True) on the AP before configuring, even.

Fix this by bouncing the AP interface after a config change, if it's
active. Configuring with active(False) still works the same as before.

Adds a static variable to track interface active state, rather than relying
on the LWIP interface state. This is because the interface state is updated
by a driver callback and there's a race: if code calls active(True) and
then config(a=b) then the driver doesn't know it's active yet and the
changes aren't correctly applied.

It is possible this pattern will cause the AP to come up briefly with the
default "PICOabcd" SSID before being reconfigured, however (due to the
aforementioned race condition) it seems like this may not happen at all
before the new config is applied.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-11-20 14:44:53 +11:00
Damien George
4f4d683ea5 extmod/network_cyw43: Fix uninitialised variable in status('stations').
The `num_stas` was uninitialised and if it happened to take the value 0
then no results were returned.  It now has the correct maximum value.

Signed-off-by: Damien George <damien@micropython.org>
2024-11-20 14:27:16 +11:00
Angus Gratton
67f893852a extmod/network_cyw43: Fix isconnected() result on AP interface.
This function is documented to return True if any stations are connected to
the AP. Without this fix it returns True whenever the driver has brought
the AP interface up.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-11-20 14:27:11 +11:00
Damien George
20a6d82872 extmod/vfs_blockdev: Support bool return from Python read/write blocks.
Commit f4ab9d9247 inadvertently broke some
Python block devices, for example esp32 and stm32 SDCard classes.  Those
classes return a bool from their `readblocks` and `writeblocks` methods
instead of an integer errno code.  With that change, both `False` and
`True` return values are now be interpreted as non-zero and hence the block
device call fails.

The fix in this commit is to allow a bool and explicitly convert `True` to
0 and `False` to `-MP_EIO`.

Signed-off-by: Damien George <damien@micropython.org>
2024-11-18 23:27:13 +11:00
Damien George
0c580f71ae esp32/modsocket: Fix getaddrinfo hints to set AI_CANONNAME.
Because the `ai_canonname` field is subsequently used.

ESP32_GENERIC_S3 (at least) crashes with IDF 5.2.3 without this set.

Signed-off-by: Damien George <damien@micropython.org>
2024-11-18 23:27:13 +11:00
Damien George
4e78c611b4 tools/mpremote: Support trailing slash on dest for non-recursive copy.
This fixes a regression in db59e55fe7: prior
to that commit `mpremote` supported trailing slashes on the destination of
a normal (non-recursive) copy.

Add back support for that, with the semantics that a trailing slash
requires the destination to be an existing directory.

Also add a test for this.

Signed-off-by: Damien George <damien@micropython.org>
2024-11-18 23:27:13 +11:00
Damien George
159b54b7da tools/mpremote: Add test for forced copy.
Signed-off-by: Damien George <damien@micropython.org>
2024-11-18 23:27:13 +11:00
Damien George
c1a85bb6de tools/mpremote: Make sure stdout and stderr output appear in order.
mpremote error messages now go to stderr, so make sure stdout is flushed
before printing them.

Also update the test runner to capture error messages.

Signed-off-by: Damien George <damien@micropython.org>
2024-11-18 23:27:13 +11:00
Angus Gratton
72799f9973 esp32: Workaround native code execution crash on ESP32-S2.
Seemingly ESP-IDF incorrectly marks RTC FAST memory region
as MALLOC_CAP_EXEC on ESP32-S2 when it isn't. This memory is
the lowest priority, so it only is returned if D/IRAM is exhausted.

Apply this workaround to treat the allocation as failed if it gives us
non-executable RAM back, rather than crashing.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-11-18 23:27:13 +11:00
Angus Gratton
164c549248 esp32/machine_pwm: Restore PWM support for ESP-IDF v5.0.x and v5.1.x.
The cleanup in 548babf8 relies on some functions not available in older
ESP-IDF. Temporarily restore them, until we drop support for ESP-IDF <5.2.

PWM functionality should end up the same regardless of ESP-IDF version, and
also no different from MicroPython V1.23.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-11-18 23:27:13 +11:00
Damien George
6f327684b7 extmod/modlwip: Fix IGMP address type when IPv6 is enabled.
This was missed in 628abf8f25.  The the bug
was that, when IPv6 is enabled, the `sizeof(ip_addr_t)` is much larger than
IPv4 size, which is what's needed for IGMP addressing.

Fixes issue #16100.

Signed-off-by: Damien George <damien@micropython.org>
2024-11-18 23:27:13 +11:00
Jan Sturm
a7d3bc2308 py/objdeque: Fix buffer overflow in deque_subscr.
In `deque_subscr()`, if `index_val` equals `self->alloc`, the index
correction `index_val -= self->alloc` does not execute, leading to an
out-of-bounds access in `self->items[index_val]`.

The fix in this commit ensures that the index correction is applied
whenever `index_val >= self->alloc`, preventing access beyond the allocated
buffer size.

Signed-off-by: Jan Sturm <jansturm92@googlemail.com>
2024-11-18 23:27:13 +11:00
Alessandro Gatti
c0afff8f22 pic16bit: Make it build with recent XC16 versions.
The PIC16 port didn't catch up with the other ports, so it required a bit
of work to make it build with the latest version of XC16.

Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2024-11-18 23:27:13 +11:00
Andrew Leech
785c92df76 esp32/machine_pwm: Use IDF functions to calculate resolution correctly.
This commit fixes PWM configuration across C3, C6, S2 and S3 chips, which
was broken by 6d799378ba.  Without this fix
the PWM frequency is limited to a maximum of 2446Hz (on S2 at least).

Signed-off-by: Andrew Leech <andrew@alelec.net>
2024-11-18 23:27:13 +11:00
Glenn Moloney
5c7ac55232 tools/mpremote: Fix UnboundLocalError in Transport.fs_writefile().
The variable `written` was being used before it was defined in the
`fs_writefile()` method of the Transport class.  This was causing an
`UnboundLocalError` to be raised when the `progress_callback` was not
provided.

Fixes issue #16084.

Signed-off-by: Glenn Moloney <glenn.moloney@gmail.com>
2024-11-18 23:27:13 +11:00
1625 changed files with 10395 additions and 54997 deletions

View File

@@ -1,6 +1,7 @@
name: Check code size
on:
push:
pull_request:
paths:
- '.github/workflows/*.yml'

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,33 +0,0 @@
name: alif port
on:
push:
pull_request:
paths:
- '.github/workflows/*.yml'
- 'tools/**'
- 'py/**'
- 'extmod/**'
- 'shared/**'
- 'lib/**'
- 'drivers/**'
- 'ports/alif/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build_alif:
strategy:
fail-fast: false
matrix:
ci_func: # names are functions in ci.sh
- alif_ae3_build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install packages
run: source tools/ci.sh && ci_alif_setup
- name: Build ci_${{matrix.ci_func }}
run: source tools/ci.sh && ci_${{ matrix.ci_func }}

View File

@@ -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

View File

@@ -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

View File

@@ -19,7 +19,7 @@ concurrency:
jobs:
build:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: Install packages

View File

@@ -20,20 +20,13 @@ concurrency:
jobs:
build_and_test_arm:
strategy:
fail-fast: false
matrix:
ci_func: # names are functions in ci.sh
- bigendian
- sabrelite
- thumb
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install packages
run: source tools/ci.sh && ci_qemu_setup_arm
- name: Build and run test suite ci_qemu_build_arm_${{ matrix.ci_func }}
run: source tools/ci.sh && ci_qemu_build_arm_${{ matrix.ci_func }}
- name: Build and run test suite
run: source tools/ci.sh && ci_qemu_build_arm
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures

View File

@@ -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

View File

@@ -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

View File

@@ -71,11 +71,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
# Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
# Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
with:
python-version: '3.11'
- name: Install packages
run: source tools/ci.sh && ci_unix_coverage_setup
- name: Build
@@ -93,7 +88,7 @@ jobs:
(cd ports/unix && gcov -o build-coverage/py ../../py/*.c || true)
(cd ports/unix && gcov -o build-coverage/extmod ../../extmod/*.c || true)
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
verbose: true
@@ -103,7 +98,7 @@ jobs:
run: tests/run-tests.py --print-failures
coverage_32bit:
runs-on: ubuntu-22.04 # use 22.04 to get libffi-dev:i386
runs-on: ubuntu-20.04 # use 20.04 to get libffi-dev:i386
steps:
- uses: actions/checkout@v4
- name: Install packages
@@ -121,7 +116,7 @@ jobs:
run: tests/run-tests.py --print-failures
nanbox:
runs-on: ubuntu-22.04 # use 22.04 to get python2, and libffi-dev:i386
runs-on: ubuntu-20.04 # use 20.04 to get python2, and libffi-dev:i386
steps:
- uses: actions/checkout@v4
- name: Install packages
@@ -134,20 +129,6 @@ jobs:
if: failure()
run: tests/run-tests.py --print-failures
longlong:
runs-on: ubuntu-22.04 # use 22.04 to get python2, and libffi-dev:i386
steps:
- uses: actions/checkout@v4
- name: Install packages
run: source tools/ci.sh && ci_unix_32bit_setup
- name: Build
run: source tools/ci.sh && ci_unix_longlong_build
- name: Run main test suite
run: source tools/ci.sh && ci_unix_longlong_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
float:
runs-on: ubuntu-latest
steps:
@@ -160,20 +141,8 @@ jobs:
if: failure()
run: tests/run-tests.py --print-failures
gil_enabled:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: source tools/ci.sh && ci_unix_gil_enabled_build
- name: Run main test suite
run: source tools/ci.sh && ci_unix_gil_enabled_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
stackless_clang:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: Install packages
@@ -187,7 +156,7 @@ jobs:
run: tests/run-tests.py --print-failures
float_clang:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: Install packages
@@ -200,15 +169,22 @@ jobs:
if: failure()
run: tests/run-tests.py --print-failures
settrace:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: source tools/ci.sh && ci_unix_settrace_build
- name: Run main test suite
run: source tools/ci.sh && ci_unix_settrace_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
settrace_stackless:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
# Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
# Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
with:
python-version: '3.11'
- name: Build
run: source tools/ci.sh && ci_unix_settrace_stackless_build
- name: Run main test suite
@@ -233,8 +209,7 @@ jobs:
run: tests/run-tests.py --print-failures
qemu_mips:
# ubuntu-22.04 is needed for older libffi.
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install packages
@@ -248,8 +223,7 @@ jobs:
run: tests/run-tests.py --print-failures
qemu_arm:
# ubuntu-22.04 is needed for older libffi.
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install packages
@@ -263,8 +237,7 @@ jobs:
run: tests/run-tests.py --print-failures
qemu_riscv64:
# ubuntu-22.04 is needed for older libffi.
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install packages
@@ -276,53 +249,3 @@ jobs:
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
sanitize_address:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
# Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
# Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
with:
python-version: '3.11'
- name: Install packages
run: source tools/ci.sh && ci_unix_coverage_setup
- name: Build
run: source tools/ci.sh && ci_unix_sanitize_address_build
- name: Run main test suite
run: source tools/ci.sh && ci_unix_sanitize_address_run_tests
- name: Test merging .mpy files
run: source tools/ci.sh && ci_unix_coverage_run_mpy_merge_tests
- name: Build native mpy modules
run: source tools/ci.sh && ci_native_mpy_modules_build
- name: Test importing .mpy generated by mpy_ld.py
run: source tools/ci.sh && ci_unix_coverage_run_native_mpy_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
sanitize_undefined:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
# Python 3.12 is the default for ubuntu-24.04, but that has compatibility issues with settrace tests.
# Can remove this step when ubuntu-latest uses a more recent Python 3.x as the default.
with:
python-version: '3.11'
- name: Install packages
run: source tools/ci.sh && ci_unix_coverage_setup
- name: Build
run: source tools/ci.sh && ci_unix_sanitize_undefined_build
- name: Run main test suite
run: source tools/ci.sh && ci_unix_sanitize_undefined_run_tests
- name: Test merging .mpy files
run: source tools/ci.sh && ci_unix_coverage_run_mpy_merge_tests
- name: Build native mpy modules
run: source tools/ci.sh && ci_native_mpy_modules_build
- name: Test importing .mpy generated by mpy_ld.py
run: source tools/ci.sh && ci_unix_coverage_run_native_mpy_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures

View File

@@ -28,10 +28,13 @@ jobs:
visualstudio: ['2017', '2019', '2022']
include:
- visualstudio: '2017'
runner: windows-latest
vs_version: '[15, 16)'
- visualstudio: '2019'
runner: windows-2019
vs_version: '[16, 17)'
- visualstudio: '2022'
runner: windows-2022
vs_version: '[17, 18)'
# trim down the number of jobs in the matrix
exclude:
@@ -39,9 +42,9 @@ jobs:
configuration: Debug
- visualstudio: '2019'
configuration: Debug
runs-on: windows-latest
env:
CI_BUILD_CONFIGURATION: ${{ matrix.configuration }}
runs-on: ${{ matrix.runner }}
steps:
- name: Install Visual Studio 2017
if: matrix.visualstudio == '2017'
@@ -49,15 +52,13 @@ jobs:
choco install visualstudio2017buildtools
choco install visualstudio2017-workload-vctools
choco install windows-sdk-8.1
- name: Install Visual Studio 2019
if: matrix.visualstudio == '2019'
run: |
choco install visualstudio2019buildtools
choco install visualstudio2019-workload-vctools
choco install windows-sdk-8.1
- uses: microsoft/setup-msbuild@v2
with:
vs-version: ${{ matrix.vs_version }}
- uses: actions/setup-python@v5
if: matrix.runner == 'windows-2019'
with:
python-version: '3.9'
- uses: actions/checkout@v4
- name: Build mpy-cross.exe
run: msbuild mpy-cross\mpy-cross.vcxproj -maxcpucount -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }}
@@ -102,18 +103,13 @@ jobs:
env: i686
- sys: mingw64
env: x86_64
runs-on: windows-latest
runs-on: windows-2022
env:
CHERE_INVOKING: enabled_from_arguments
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/setup-python@v5
# note: can go back to installing mingw-w64-${{ matrix.env }}-python after
# MSYS2 updates to Python >3.12 (due to settrace compatibility issue)
with:
python-version: '3.11'
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.sys }}
@@ -122,9 +118,9 @@ jobs:
make
mingw-w64-${{ matrix.env }}-gcc
pkg-config
mingw-w64-${{ matrix.env }}-python3
git
diffutils
path-type: inherit # Remove when setup-python is removed
- uses: actions/checkout@v4
- name: Build mpy-cross.exe
run: make -C mpy-cross -j2

View File

@@ -30,26 +30,9 @@ jobs:
docker-images: false
swap-storage: false
- uses: actions/checkout@v4
- id: versions
name: Read Zephyr version
run: source tools/ci.sh && echo "ZEPHYR=$ZEPHYR_VERSION" | tee "$GITHUB_OUTPUT"
- name: Cached Zephyr Workspace
id: cache_workspace
uses: actions/cache@v4
with:
# note that the Zephyr CI docker image is 15GB. At time of writing
# GitHub caches are limited to 10GB total for a project. So we only
# cache the "workspace"
path: ./zephyrproject
key: zephyr-workspace-${{ steps.versions.outputs.ZEPHYR }}
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: zephyr
- name: Install packages
run: source tools/ci.sh && ci_zephyr_setup
- name: Install Zephyr
if: steps.cache_workspace.outputs.cache-hit != 'true'
run: source tools/ci.sh && ci_zephyr_install
- name: Build
run: source tools/ci.sh && ci_zephyr_build

View File

@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ruff version should be kept in sync with .pre-commit-config.yaml & also micropython-lib
- run: pipx install ruff==0.11.6
# ruff version should be kept in sync with .pre-commit-config.yaml
- run: pip install --user ruff==0.1.3
- run: ruff check --output-format=github .
- run: ruff format --diff .

6
.gitmodules vendored
View File

@@ -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

View File

@@ -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)

View File

@@ -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.

View File

@@ -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

View File

@@ -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",

View File

@@ -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`.

View File

@@ -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
----------------

View File

@@ -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):

View File

@@ -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.

View File

@@ -79,34 +79,34 @@ Networking
WLAN
^^^^
The :class:`network.WLAN` class in the :mod:`network` module::
The :mod:`network` module::
import network
wlan = network.WLAN() # create station interface (the default, see below for an access point interface)
wlan.active(True) # activate the interface
wlan.scan() # scan for access points
wlan.isconnected() # check if the station is connected to an AP
wlan = network.WLAN(network.STA_IF) # create station interface
wlan.active(True) # activate the interface
wlan.scan() # scan for access points
wlan.isconnected() # check if the station is connected to an AP
wlan.connect('ssid', 'key') # connect to an AP
wlan.config('mac') # get the interface's MAC address
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
wlan.config('mac') # get the interface's MAC address
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
ap = network.WLAN(network.WLAN.IF_AP) # create access-point interface
ap.config(ssid='ESP-AP') # set the SSID of the access point
ap.config(max_clients=10) # set how many clients can connect to the network
ap.active(True) # activate the interface
ap = network.WLAN(network.AP_IF) # create access-point interface
ap.config(ssid='ESP-AP') # set the SSID of the access point
ap.config(max_clients=10) # set how many clients can connect to the network
ap.active(True) # activate the interface
A useful function for connecting to your local WiFi network is::
def do_connect():
import machine, network
wlan = network.WLAN()
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('ssid', 'key')
while not wlan.isconnected():
machine.idle()
pass
print('network config:', wlan.ipconfig('addr4'))
Once the network is established the :mod:`socket <socket>` module can be used
@@ -121,20 +121,10 @@ calling ``wlan.config(reconnects=n)``, where n are the number of desired reconne
attempts (0 means it won't retry, -1 will restore the default behaviour of trying
to reconnect forever).
.. _esp32_network_lan:
LAN
^^^
Built-in MAC (original ESP32)
"""""""""""""""""""""""""""""
The original ESP32 SoC has a built-in Ethernet MAC. Using this MAC requires an
external Ethernet PHY to be wired to the chip's EMAC pins. Most of the EMAC pin
assignments are fixed, consult the ESP32 datasheet for details.
If the PHY is connected, the internal Ethernet MAC can be configured via
the :class:`network.LAN` constructor::
To use the wired interfaces one has to specify the pins and mode ::
import network
@@ -143,34 +133,20 @@ the :class:`network.LAN` constructor::
lan.ipconfig('addr4') # get the interface's IPv4 addresses
Required keyword arguments for the constructor:
The keyword arguments for the constructor defining the PHY type and interface are:
- ``mdc`` and ``mdio`` - :class:`machine.Pin` objects (or integers) specifying
the MDC and MDIO pins.
- ``phy_type`` - Select the PHY device type. Supported devices are
``PHY_GENERIC``,
``PHY_LAN8710``, ``PHY_LAN8720``, ``PHY_IP101``, ``PHY_RTL8201``,
``PHY_DP83848``, ``PHY_KSZ8041`` and ``PHY_KSZ8081``. These values are all
constants defined in the ``network`` module.
- ``phy_addr`` - The address number of the PHY device. Must be an integer in the
range 0x00 to 0x1f, inclusive. Common values are ``0`` and ``1``.
- mdc=pin-object # set the mdc and mdio pins.
- mdio=pin-object
- reset=pin-object # set the reset pin of the PHY device.
- power=pin-object # set the pin which switches the power of the PHY device.
- phy_type=<type> # Select the PHY device type. Supported devices are PHY_LAN8710,
PHY_LAN8720, PH_IP101, PHY_RTL8201, PHY_DP83848 and PHY_KSZ8041
- phy_addr=number # The address number of the PHY device.
- ref_clk_mode=mode # Defines, whether the ref_clk at the ESP32 is an input
or output. Suitable values are Pin.IN and Pin.OUT.
- ref_clk=pin-object # defines the Pin used for ref_clk.
All of the above keyword arguments must be present to configure the interface.
Optional keyword arguments:
- ``reset`` - :class:`machine.Pin` object (or integer) specifying the PHY reset pin.
- ``power`` - :class:`machine.Pin` object (or integer) specifying a pin which
switches the power of the PHY device.
- ``ref_clk`` - :class:`machine.Pin` object (or integer) specifying the pin used
for the EMAC ``ref_clk`` signal. If not specified, the board default is used
(typically GPIO 0, but may be different if a particular board has Ethernet.)
- ``ref_clk_mode`` - Defines whether the EMAC ``ref_clk`` pin of the ESP32
should be an input or an output. Suitable values are ``machine.Pin.IN`` and
``machine.Pin.OUT``. If not specified, the board default is used
(typically input, but may be different if a particular board has Ethernet.)
These are working configurations for LAN interfaces of some popular ESP32 boards::
These are working configurations for LAN interfaces of popular boards::
# Olimex ESP32-GATEWAY: power controlled by Pin(5)
# Olimex ESP32 PoE and ESP32-PoE ISO: power controlled by Pin(12)
@@ -195,66 +171,6 @@ These are working configurations for LAN interfaces of some popular ESP32 boards
lan = network.LAN(id=0, mdc=Pin(23), mdio=Pin(18), power=Pin(5),
phy_type=network.PHY_IP101, phy_addr=1)
.. _esp32_spi_ethernet:
SPI Ethernet Interface
""""""""""""""""""""""
All ESP32 SoCs support external SPI Ethernet interface chips. These are Ethernet
interfaces that connect via a SPI bus, rather than an Ethernet RMII interface.
.. note:: The only exception is the ESP32 ``d2wd`` variant, where this feature is disabled
to save code size.
SPI Ethernet uses the same :class:`network.LAN` constructor, with a different
set of keyword arguments::
import machine, network
spi = machine.SPI(1, sck=SCK_PIN, mosi=MOSI_PIN, miso=MISO_PIN)
lan = network.LAN(spi=spi, cs=CS_PIN, ...) # Set the pin and mode configuration
lan.active(True) # activate the interface
lan.ipconfig('addr4') # get the interface's IPv4 addresses
Required keyword arguments for the constructor:
- ``spi`` - Should be a :class:`machine.SPI` object configured for this
connection. Note that any clock speed configured on the SPI object is ignored,
the SPI Ethernet clock speed is configured at compile time.
- ``cs`` - :class:`machine.Pin` object (or integer) specifying the CS pin
connected to the interface.
- ``int`` - :class:`machine.Pin` object (or integer) specifying the INT pin
connected to the interface.
- ``phy_type`` - Select the SPI Ethernet interface type. Supported devices are
``PHY_KSZ8851SNL``, ``PHY_DM9051``, ``PHY_W5500``. These values are all
constants defined in the ``network`` module.
- ``phy_addr`` - The address number of the PHY device. Must be an integer in the
range 0x00 to 0x1f, inclusive. This is usually ``0`` for SPI Ethernet devices.
All of the above keyword arguments must be present to configure the interface.
Optional keyword arguments for the constructor:
- ``reset`` - :class:`machine.Pin` object (or integer) specifying the SPI Ethernet
interface reset pin.
- ``power`` - :class:`machine.Pin` object (or integer) specifying a pin which
switches the power of the SPI Ethernet interface.
Here is a sample configuration for a WIZNet W5500 chip connected to pins on
an ESP32-S3 development board::
import machine, network
from machine import Pin, SPI
spi = SPI(1, sck=Pin(12), mosi=Pin(13), miso=Pin(14))
lan = network.LAN(spi=spi, phy_type=network.PHY_W5500, phy_addr=0,
cs=Pin(10), int=Pin(11))
.. note:: WIZnet W5500 Ethernet is also supported on some other MicroPython
ports, but using a :ref:`different software interface
<network.WIZNET5K>`.
Delay and timing
----------------
@@ -271,10 +187,8 @@ Use the :mod:`time <time>` module::
Timers
------
The ESP32 port has one, two or four hardware timers, depending on the ESP32 device type.
There is 1 timer for ESP32C2, 2 timers for ESP32C4, ESP32C6 and ESP32H4, and
4 timers otherwise. Use the :ref:`machine.Timer <machine.Timer>` class
with a timer ID of 0, 0 and 1, or from 0 to 3 (inclusive)::
The ESP32 port has four hardware timers. Use the :ref:`machine.Timer <machine.Timer>` class
with a timer ID from 0 to 3 (inclusive)::
from machine import Timer
@@ -284,8 +198,7 @@ with a timer ID of 0, 0 and 1, or from 0 to 3 (inclusive)::
tim1 = Timer(1)
tim1.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(1))
The period is in milliseconds. When using UART.IRQ_RXIDLE, timer 0 is needed for
the IRQ_RXIDLE mechanism and must not be used otherwise.
The period is in milliseconds.
Virtual timers are not currently supported on this port.
@@ -387,7 +300,7 @@ for more details.
Use the :ref:`machine.PWM <machine.PWM>` class::
from machine import Pin, PWM, lightsleep
from machine import Pin, PWM
pwm0 = PWM(Pin(0), freq=5000, duty_u16=32768) # create PWM object from a pin
freq = pwm0.freq() # get current frequency
@@ -397,7 +310,7 @@ Use the :ref:`machine.PWM <machine.PWM>` class::
pwm0.duty(256) # set duty cycle from 0 to 1023 as a ratio duty/1023, (now 25%)
duty_u16 = pwm0.duty_u16() # get current duty cycle, range 0-65535
pwm0.duty_u16(65536*3//4) # set duty cycle from 0 to 65535 as a ratio duty_u16/65535, (now 75%)
pwm0.duty_u16(2**16*3//4) # set duty cycle from 0 to 65535 as a ratio duty_u16/65535, (now 75%)
duty_ns = pwm0.duty_ns() # get current pulse width in ns
pwm0.duty_ns(250_000) # set pulse width in nanoseconds from 0 to 1_000_000_000/freq, (now 25%)
@@ -406,35 +319,19 @@ Use the :ref:`machine.PWM <machine.PWM>` class::
pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go
print(pwm2) # view PWM settings
pwm2.deinit() # turn off PWM on the pin
pwm0 = PWM(Pin(0), duty_u16=16384) # The output is at a high level 25% of the time.
pwm2 = PWM(Pin(2), duty_u16=16384, invert=1) # The output is at a low level 25% of the time.
pwm4 = PWM(Pin(4), lightsleep=True) # Allow PWM during light sleep mode
lightsleep(10*1000) # pwm0, pwm2 goes off, pwm4 stays on during 10s light sleep
# pwm0, pwm2, pwm4 on after 10s light sleep
ESP chips have different hardware peripherals:
======================================================= ======== ========= ==========
Hardware specification ESP32 ESP32-S2, ESP32-C2,
ESP32-S3, ESP32-C3,
ESP32-P4 ESP32-C5,
ESP32-C6,
ESP32-H2
------------------------------------------------------- -------- --------- ----------
Number of groups (speed modes) 2 1 1
Number of timers per group 4 4 4
Number of channels per group 8 8 6
------------------------------------------------------- -------- --------- ----------
Different PWM frequencies = (groups * timers) 8 4 4
Total PWM channels (Pins, duties) = (groups * channels) 16 8 6
======================================================= ======== ========= ==========
In light sleep, the ESP32 PWM can only operate in low speed mode, so only 4 timers and
8 channels are available.
===================================================== ======== ======== ========
Hardware specification ESP32 ESP32-S2 ESP32-C3
----------------------------------------------------- -------- -------- --------
Number of groups (speed modes) 2 1 1
Number of timers per group 4 4 4
Number of channels per group 8 8 6
----------------------------------------------------- -------- -------- --------
Different PWM frequencies (groups * timers) 8 4 4
Total PWM channels (Pins, duties) (groups * channels) 16 8 6
===================================================== ======== ======== ========
A maximum number of PWM channels (Pins) are available on the ESP32 - 16 channels,
but only 8 different PWM frequencies are available, the remaining 8 channels must
@@ -544,63 +441,14 @@ Legacy methods:
Equivalent to ``ADC.block().init(bits=bits)``.
The only chip that can switch resolution to a lower one is the normal esp32.
The C2 & S3 are stuck at 12 bits, while the S2 is at 13 bits.
For compatibility, the ``ADC`` object also provides constants matching the
supported ADC resolutions, per chip:
supported ADC resolutions:
ESP32:
- ``ADC.WIDTH_9BIT`` = 9
- ``ADC.WIDTH_10BIT`` = 10
- ``ADC.WIDTH_11BIT`` = 11
- ``ADC.WIDTH_12BIT`` = 12
ESP32 C3 & S3:
- ``ADC.WIDTH_12BIT`` = 12
ESP32 S2:
- ``ADC.WIDTH_13BIT`` = 13
.. method:: ADC.deinit()
Provided to deinit the adc driver.
Pulse Counter (pin pulse/edge counting)
---------------------------------------
The ESP32 provides up to 8 pulse counter peripherals depending on the hardware,
with id 0..7. These can be configured to count rising and/or falling edges on
any input pin.
Use the :ref:`esp32.PCNT <esp32.PCNT>` class::
from machine import Pin
from esp32 import PCNT
counter = PCNT(0, pin=Pin(2), rising=PCNT.INCREMENT) # create counter
counter.start() # start counter
count = counter.value() # read count, -32768..32767
counter.value(0) # reset counter
count = counter.value(0) # read and reset
The PCNT hardware supports monitoring multiple pins in a single unit to
implement quadrature decoding or up/down signal counters.
See the :ref:`machine.Counter <machine.Counter>` and
:ref:`machine.Encoder <machine.Encoder>` classes for simpler abstractions of
common pulse counting applications::
from machine import Pin, Counter
counter = Counter(0, Pin(2)) # create a counter as above and start it
count = counter.value() # read the count as an arbitrary precision signed integer
encoder = Encoder(0, Pin(12), Pin(14)) # create an encoder and begin counting
count = encoder.value() # read the count as an arbitrary precision signed integer
Note that the id passed to these ``Counter()`` and ``Encoder()`` objects must be
a PCNT id.
Software SPI bus
----------------
@@ -728,9 +576,7 @@ See :ref:`machine.RTC <machine.RTC>` ::
from machine import RTC
rtc = RTC()
rtc.datetime((2017, 8, 23, 0, 1, 12, 48, 0)) # set a specific date and
# time, eg. 2017/8/23 1:12:48
# the day-of-week value is ignored
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
rtc.datetime() # get date and time
WDT (Watchdog timer)
@@ -816,7 +662,7 @@ See :ref:`machine.SDCard <machine.SDCard>`. ::
import machine, os, vfs
# On original ESP32, slot 2 uses pins sck=18, cs=5, miso=19, mosi=23
# Slot 2 uses pins sck=18, cs=5, miso=19, mosi=23
sd = machine.SDCard(slot=2)
vfs.mount(sd, '/sd') # mount
@@ -838,9 +684,6 @@ The RMT is ESP32-specific and allows generation of accurate digital pulses with
# The channel resolution is 100ns (1/(source_freq/clock_div)).
r.write_pulses((1, 20, 2, 40), 0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns
The ESP32-C2 family does not include any RMT peripheral, so this class is
unavailable on those SoCs.
OneWire driver
--------------
@@ -907,33 +750,20 @@ APA102 (DotStar) uses a different driver as it has an additional clock pin.
Capacitive touch
----------------
ESP32, ESP32-S2 and ESP32-S3 support capacitive touch via the ``TouchPad`` class
in the ``machine`` module::
Use the ``TouchPad`` class in the ``machine`` module::
from machine import TouchPad, Pin
t = TouchPad(Pin(14))
t.read() # Returns a smaller number when touched
``TouchPad.read`` returns a value proportional to the capacitance between the
pin and the board's Ground connection. On ESP32 the number becomes smaller when
the pin (or connected touch pad) is touched, on ESP32-S2 and ESP32-S3 the number
becomes larger when the pin is touched.
``TouchPad.read`` returns a value relative to the capacitive variation. Small numbers (typically in
the *tens*) are common when a pin is touched, larger numbers (above *one thousand*) when
no touch is present. However the values are *relative* and can vary depending on the board
and surrounding composition so some calibration may be required.
In all cases, a touch causes a significant change in the return value. Note the
returned values are *relative* and can vary depending on the board and
surrounding environment so some calibration (i.e. comparison to a baseline or
rolling average) may be required.
========= ==============================================
Chip Touch-enabled pins
--------- ----------------------------------------------
ESP32 0, 2, 4, 12, 13, 14, 15, 27, 32, 33
ESP32-S2 1 to 14 inclusive
ESP32-S3 1 to 14 inclusive
========= ==============================================
Trying to assign to any other pins will result in a ``ValueError``.
There are ten capacitive touch-enabled pins that can be used on the ESP32: 0, 2, 4, 12, 13
14, 15, 27, 32, 33. Trying to assign to any other pins will result in a ``ValueError``.
Note that TouchPads can be used to wake an ESP32 from sleep::

View File

@@ -21,4 +21,3 @@ to `<https://www.python.org>`__.
intro.rst
pwm.rst
peripheral_access.rst
reset.rst

View File

@@ -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.

View File

@@ -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::

View File

@@ -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

View File

@@ -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
------------

View File

@@ -49,11 +49,11 @@ The :mod:`esp` module::
Networking
----------
The :class:`network.WLAN` class in the :mod:`network` module::
The :mod:`network` module::
import network
wlan = network.WLAN(network.WLAN.IF_STA) # create station interface
wlan = network.WLAN(network.STA_IF) # create station interface
wlan.active(True) # activate the interface
wlan.scan() # scan for access points
wlan.isconnected() # check if the station is connected to an AP
@@ -61,7 +61,7 @@ The :class:`network.WLAN` class in the :mod:`network` module::
wlan.config('mac') # get the interface's MAC address
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
ap = network.WLAN(network.WLAN.IF_AP) # create access-point interface
ap = network.WLAN(network.AP_IF) # create access-point interface
ap.active(True) # activate the interface
ap.config(ssid='ESP-AP') # set the SSID of the access point
@@ -69,7 +69,7 @@ A useful function for connecting to your local WiFi network is::
def do_connect():
import network
wlan = network.WLAN(network.WLAN.IF_STA)
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
@@ -163,10 +163,10 @@ sys.stdin.read() if it's needed to read characters from the UART(0)
while it's also used for the REPL (or detach, read, then reattach).
When detached the UART(0) can be used for other purposes.
If there are no objects in any of the dupterm slots when the REPL is started (on
:doc:`hard or soft reset </reference/reset_boot>`) then UART(0) is automatically
attached. Without this, the only way to recover a board without a REPL would be
to completely erase and reflash (which would install the default boot.py which
If there are no objects in any of the dupterm slots when the REPL is
started (on hard or soft reset) then UART(0) is automatically attached.
Without this, the only way to recover a board without a REPL would be to
completely erase and reflash (which would install the default boot.py which
attaches the REPL).
To detach the REPL from UART0, use::
@@ -284,9 +284,7 @@ See :ref:`machine.RTC <machine.RTC>` ::
from machine import RTC
rtc = RTC()
rtc.datetime((2017, 8, 23, 0, 1, 12, 48, 0)) # set a specific date and
# time, eg. 2017/8/23 1:12:48
# the day-of-week value is ignored
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
rtc.datetime() # get date and time
# synchronize with ntp

View File

@@ -1,15 +1,14 @@
Network basics
==============
The :class:`network.WLAN` class in the :mod:`network` module is used to
configure the WiFi connection. There are two WiFi interfaces, one for
the station (when the ESP8266 connects to a router) and one for the
access point (for other devices to connect to the ESP8266). Create
The network module is used to configure the WiFi connection. There are two WiFi
interfaces, one for the station (when the ESP8266 connects to a router) and one
for the access point (for other devices to connect to the ESP8266). Create
instances of these objects using::
>>> import network
>>> sta_if = network.WLAN(network.WLAN.IF_STA)
>>> ap_if = network.WLAN(network.WLAN.IF_AP)
>>> sta_if = network.WLAN(network.STA_IF)
>>> ap_if = network.WLAN(network.AP_IF)
You can check if the interfaces are active by::
@@ -58,7 +57,7 @@ connect to your WiFi network::
def do_connect():
import network
sta_if = network.WLAN(network.WLAN.IF_STA)
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print('connecting to network...')
sta_if.active(True)

View File

@@ -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

View File

@@ -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.

View File

@@ -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.

View File

@@ -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'``.

View File

@@ -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.

View File

@@ -19,8 +19,6 @@ Functions and types
.. class:: bytearray()
|see_cpython| `python:bytearray`.
.. class:: bytes()
|see_cpython| `python:bytes`.
@@ -106,8 +104,6 @@ Functions and types
.. class:: memoryview()
|see_cpython| `python:memoryview`.
.. function:: min()
.. function:: next()
@@ -174,10 +170,6 @@ Exceptions
.. exception:: KeyboardInterrupt
|see_cpython| `python:KeyboardInterrupt`.
See also in the context of :ref:`soft_bricking`.
.. exception:: KeyError
.. exception:: MemoryError
@@ -198,12 +190,6 @@ Exceptions
|see_cpython| `python:SystemExit`.
On non-embedded ports (i.e. Windows and Unix), an unhandled ``SystemExit``
exits the MicroPython process in a similar way to CPython.
On embedded ports, an unhandled ``SystemExit`` currently causes a
:ref:`soft_reset` of MicroPython.
.. exception:: TypeError
|see_cpython| `python:TypeError`.

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -69,7 +69,6 @@ library.
heapq.rst
io.rst
json.rst
marshal.rst
math.rst
os.rst
platform.rst

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -209,13 +209,13 @@ The following methods are not part of the core Pin API and only implemented on c
Set pin to "0" output level.
Availability: mimxrt, nrf, renesas-ra, rp2, samd, stm32 ports.
Availability: nrf, rp2, stm32 ports.
.. method:: Pin.high()
Set pin to "1" output level.
Availability: mimxrt, nrf, renesas-ra, rp2, samd, stm32 ports.
Availability: nrf, rp2, stm32 ports.
.. method:: Pin.mode([mode])
@@ -242,7 +242,7 @@ The following methods are not part of the core Pin API and only implemented on c
Toggle output pin from "0" to "1" or vice-versa.
Availability: cc3200, esp32, esp8266, mimxrt, rp2, samd ports.
Availability: mimxrt, samd, rp2 ports.
Constants
---------

View File

@@ -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.

View File

@@ -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
``````

View File

@@ -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``.

View File

@@ -83,7 +83,7 @@ Methods
- *pins* is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order).
Any of the pins can be None if one wants the UART to operate with limited functionality.
If the RTS pin is given the RX pin must be given as well. The same applies to CTS.
If the RTS pin is given the the RX pin must be given as well. The same applies to CTS.
When no pins are given, then the default set of TX and RX pins is taken, and hardware
flow control will be disabled. If *pins* is ``None``, no pin assignment will be made.
@@ -224,8 +224,7 @@ Methods
.. note::
- The ESP32 port does not support the option hard=True. It uses Timer(0)
for UART.IRQ_RXIDLE, so this timer cannot be used for other means.
- The ESP32 port does not support the option hard=True.
- The rp2 port's UART.IRQ_TXIDLE is only triggered when the message
is longer than 5 characters and the trigger happens when still 5 characters

View File

@@ -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

View File

@@ -62,13 +62,14 @@ Reset related functions
.. function:: reset()
:ref:`Hard resets <hard_reset>` the device in a manner similar to pushing the
external RESET button.
Resets the device in a manner similar to pushing the external RESET
button.
.. function:: soft_reset()
Performs a :ref:`soft reset <soft_reset>` of the interpreter, deleting all
Python objects and resetting the Python heap.
Performs a soft reset of the interpreter, deleting all Python objects and
resetting the Python heap. It tries to retain the method by which the user
is connected to the MicroPython REPL (eg serial, USB, Wifi).
.. function:: reset_cause()
@@ -264,12 +265,9 @@ Classes
machine.UART.rst
machine.SPI.rst
machine.I2C.rst
machine.I2CTarget.rst
machine.I2S.rst
machine.RTC.rst
machine.Timer.rst
machine.Counter.rst
machine.Encoder.rst
machine.WDT.rst
machine.SD.rst
machine.SDCard.rst

View File

@@ -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.

View File

@@ -6,7 +6,7 @@ class LAN -- control an Ethernet module
This class allows you to control the Ethernet interface. The PHY hardware type is board-specific.
Example usage, for a board with built-in LAN support::
Example usage::
import network
nic = network.LAN(0)
@@ -32,7 +32,7 @@ Constructors
- *phy_addr* specifies the address of the PHY interface. As with *phy_type*, the hardwired value has
to be used for most boards and that value is the default.
- *ref_clk_mode* specifies, whether the data clock is provided by the Ethernet controller or
the PHY interface.
the PYH interface.
The default value is the one that matches the board. If set to ``LAN.OUT`` or ``Pin.OUT``
or ``True``, the clock is driven by the Ethernet controller, if set to ``LAN.IN``
or ``Pin.IN`` or ``False``, the clock is driven by the PHY interface.
@@ -41,9 +41,6 @@ Constructors
nic = LAN(0, phy_type=LAN.PHY_LAN8720, phy_addr=1, ref_clk_mode=Pin.IN)
.. note:: On esp32 port the constructor requires different arguments. See
:ref:`esp32 port reference <esp32_network_lan>`.
Methods
-------

View File

@@ -5,12 +5,7 @@ class PPP -- create network connections over serial PPP
=======================================================
This class allows you to create a network connection over a serial port using
the PPP protocol.
.. note:: Currently only the esp32 port has PPP support enabled in the default
firmware build. PPP support can be enabled in custom builds of the
stm32 and rp2 ports by enabling networking support and setting
``MICROPY_PY_NETWORK_PPP_LWIP`` to 1.
the PPP protocol. It is only available on selected ports and boards.
Example usage::
@@ -75,11 +70,8 @@ Methods
.. method:: PPP.config(config_parameters)
Sets or gets parameters of the PPP interface. The only parameter that can be
retrieved and set is the underlying stream, using::
stream = PPP.config("stream")
PPP.config(stream=stream)
Sets or gets parameters of the PPP interface. There are currently no parameter that
can be set or retrieved.
.. method:: PPP.ipconfig('param')
PPP.ipconfig(param=value, ...)

View File

@@ -9,9 +9,6 @@ the W5200 and W5500 chipsets. The particular chipset that is supported
by the firmware is selected at compile-time via the MICROPY_PY_NETWORK_WIZNET5K
option.
.. note:: The esp32 port also supports WIZnet W5500 chipsets, but this port
uses the :ref:`network.LAN interface <esp32_spi_ethernet>`.
Example usage::
import network

View File

@@ -8,7 +8,7 @@ This class provides a driver for WiFi network processors. Example usage::
import network
# enable station interface and connect to WiFi access point
nic = network.WLAN(network.WLAN.IF_STA)
nic = network.WLAN(network.STA_IF)
nic.active(True)
nic.connect('your-ssid', 'your-key')
# now use sockets as usual
@@ -18,8 +18,8 @@ Constructors
.. class:: WLAN(interface_id)
Create a WLAN network interface object. Supported interfaces are
``network.WLAN.IF_STA`` (station aka client, connects to upstream WiFi access
points) and ``network.WLAN.IF_AP`` (access point, allows other WiFi clients to
``network.STA_IF`` (station aka client, connects to upstream WiFi access
points) and ``network.AP_IF`` (access point, allows other WiFi clients to
connect). Availability of the methods below depends on interface type.
For example, only STA interface may `WLAN.connect()` to an access point.
@@ -75,7 +75,7 @@ Methods
Return the current status of the wireless connection.
When called with no argument the return value describes the network link status.
The possible statuses are defined as constants in the :mod:`network` module:
The possible statuses are defined as constants:
* ``STAT_IDLE`` -- no connection and no activity,
* ``STAT_CONNECTING`` -- connecting in progress,
@@ -85,18 +85,7 @@ Methods
* ``STAT_GOT_IP`` -- connection successful.
When called with one argument *param* should be a string naming the status
parameter to retrieve, and different parameters are supported depending on the
mode the WiFi is in.
In STA mode, passing ``'rssi'`` returns a signal strength indicator value, whose
format varies depending on the port (this is available on all ports that support
WiFi network interfaces, except for CC3200).
In AP mode, passing ``'stations'`` returns a list of connected WiFi stations
(this is available on all ports that support WiFi network interfaces, except for
CC3200). The format of the station information entries varies across ports,
providing either the raw BSSID of the connected station, the IP address of the
connected station, or both.
parameter to retrieve. Supported parameters in WiFI STA mode are: ``'rssi'``.
.. method:: WLAN.isconnected()
@@ -137,7 +126,7 @@ Methods
============= ===========
mac MAC address (bytes)
ssid WiFi access point name (string)
channel WiFi channel (integer). Depending on the port this may only be supported on the AP interface.
channel WiFi channel (integer)
hidden Whether SSID is hidden (boolean)
security Security protocol supported (enumeration, see module constants)
key Access key (string)

View File

@@ -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);

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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()`:

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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)

View File

@@ -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,

View File

@@ -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.

View File

@@ -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``

View File

@@ -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.

View File

@@ -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.

View File

@@ -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)

View File

@@ -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
---------

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -78,7 +78,6 @@ The full list of supported commands are:
- `mip <mpremote_command_mip>`
- `mount <mpremote_command_mount>`
- `unmount <mpremote_command_unmount>`
- `romfs <mpremote_command_romfs>`
- `rtc <mpremote_command_rtc>`
- `sleep <mpremote_command_sleep>`
- `reset <mpremote_command_reset>`
@@ -108,7 +107,7 @@ The full list of supported commands are:
**Note:** Instead of using the ``connect`` command, there are several
:ref:`pre-defined shortcuts <mpremote_shortcuts>` for common device paths. For
example the ``a0`` shortcut command is equivalent to
``connect /dev/ttyACM0`` (Linux), or ``c1`` for ``COM1`` (Windows).
``connect /dev/ttyACM0`` (Linux), or ``c0`` for ``COM0`` (Windows).
**Note:** The ``auto`` option will only detect USB serial ports, i.e. a serial
port that has an associated USB VID/PID (i.e. CDC/ACM or FTDI-style
@@ -229,52 +228,24 @@ The full list of supported commands are:
- ``ls`` to list the current directory
- ``ls <dirs...>`` to list the given directories
- ``cp [-rf] <src...> <dest>`` to copy files
- ``rm [-r] <src...>`` to remove files or folders on the device
- ``rm <src...>`` to remove files on the device
- ``mkdir <dirs...>`` to create directories on the device
- ``rmdir <dirs...>`` to remove directories on the device
- ``touch <file..>`` to create the files (if they don't already exist)
- ``sha256sum <file..>`` to calculate the SHA256 sum of files
- ``tree [-vsh] <dirs...>`` to print a tree of the given directories
The ``cp`` command uses a convention where a leading ``:`` represents a remote
path. Without a leading ``:`` means a local path. This is based on the
convention used by the `Secure Copy Protocol (scp) client
<https://en.wikipedia.org/wiki/Secure_copy_protocol>`_.
<https://en.wikipedia.org/wiki/Secure_copy_protocol>`_. All other commands
implicitly assume the path is a remote path, but the ``:`` can be optionally
used for clarity.
So for example, ``mpremote fs cp main.py :main.py`` copies ``main.py`` from
the current local directory to the remote filesystem, whereas
``mpremote fs cp :main.py main.py`` copies ``main.py`` from the device back
to the current directory.
The ``mpremote rm -r`` command accepts both relative and absolute paths.
Use ``:`` to refer to the current remote working directory (cwd) to allow a
directory tree to be removed from the device's default path (eg ``/flash``, ``/``).
Use ``-v/--verbose`` to see the files being removed.
For example:
- ``mpremote rm -r :libs`` will remove the ``libs`` directory and all its
child items from the device.
- ``mpremote rm -rv :/sd`` will remove all files from a mounted SDCard and result
in a non-blocking warning. The mount will be retained.
- ``mpremote rm -rv :/`` will remove all files on the device, including any
located in mounted vfs such as ``/sd`` or ``/flash``. After removing all folders
and files, this will also return an error to mimic unix ``rm -rf /`` behaviour.
.. warning::
There is no supported way to undelete files removed by ``mpremote rm -r :``.
Please use with caution.
The ``tree`` command will print a tree of the given directories.
Using the ``--size/-s`` option will print the size of each file, or use
``--human/-h`` to use a more human readable format.
Note: Directory size is only printed when a non-zero size is reported by the device's filesystem.
The ``-v`` option can be used to include the name of the serial device in
the output.
All other commands implicitly assume the path is a remote path, but the ``:``
can be optionally used for clarity.
All of the filesystem sub-commands take multiple path arguments, so if there
is another command in the sequence, you must use ``+`` to terminate the
arguments, e.g.
@@ -376,29 +347,6 @@ The full list of supported commands are:
This happens automatically when ``mpremote`` terminates, but it can be used
in a sequence to unmount an earlier mount before subsequent command are run.
.. _mpremote_command_romfs:
- **romfs** -- manage ROMFS partitions on the device:
.. code-block:: bash
$ mpremote romfs <sub-command>
``<sub-command>`` may be:
- ``romfs query`` to list all the available ROMFS partitions and their size
- ``romfs [-o <output>] build <source>`` to create a ROMFS image from the given
source directory; the default output file is the source appended by ``.romfs``
- ``romfs [-p <partition>] deploy <source>`` to deploy a ROMFS image to the device;
will also create a temporary ROMFS image if the source is a directory
The ``build`` and ``deploy`` sub-commands both support the ``-m``/``--mpy`` option
to automatically compile ``.py`` files to ``.mpy`` when creating the ROMFS image.
This option is enabled by default, but only works if the ``mpy_cross`` Python
package has been installed (eg via ``pip install mpy_cross``). If the package is
not installed then a warning is printed and ``.py`` files remain as is. Compiling
of ``.py`` files can be disabled with the ``--no-mpy`` option.
.. _mpremote_command_rtc:
- **rtc** -- set/get the device clock (RTC):
@@ -487,16 +435,9 @@ Shortcuts can be defined using the macro system. Built-in shortcuts are:
- ``cat``, ``edit``, ``ls``, ``cp``, ``rm``, ``mkdir``, ``rmdir``, ``touch``: Aliases for ``fs <sub-command>``
Additional shortcuts can be defined in the user configuration file ``mpremote/config.py``,
located in the User Configuration Directory.
The correct location for each OS is determined using the ``platformdirs`` module.
This is typically:
- ``$XDG_CONFIG_HOME/mpremote/config.py``
- ``$HOME/.config/mpremote/config.py``
- ``$env:LOCALAPPDATA/mpremote/config.py``
The ``config.py``` file should define a dictionary named ``commands``. The keys of this dictionary are the shortcuts
Additional shortcuts can be defined by in user-configuration files, which is
located at ``.config/mpremote/config.py``. This file should define a
dictionary named ``commands``. The keys of this dictionary are the shortcuts
and the values are either a string or a list-of-strings:
.. code-block:: python3
@@ -536,7 +477,7 @@ An example ``config.py`` might look like:
""",], # Print out nearby WiFi networks.
"wl_ipconfig": [
"exec",
"import network; sta_if = network.WLAN(network.WLAN.IF_STA); print(sta_if.ipconfig('addr4'))",
"import network; sta_if = network.WLAN(network.STA_IF); print(sta_if.ipconfig('addr4'))",
""",], # Print ip address of station interface.
"test": ["mount", ".", "exec", "import test"], # Mount current directory and run test.py.
"demo": ["run", "path/to/demo.py"], # Execute demo.py on the device.
@@ -606,9 +547,9 @@ device at ``/dev/ttyACM1``, printing each result.
mpremote resume exec "print_state_info()" soft-reset
Connect to the device without triggering a :ref:`soft reset <soft_reset>` and
execute the ``print_state_info()`` function (e.g. to find out information about
the current program state), then trigger a soft reset.
Connect to the device without triggering a soft reset and execute the
``print_state_info()`` function (e.g. to find out information about the current
program state), then trigger a soft reset.
.. code-block:: bash

View File

@@ -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``.

View File

@@ -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

View File

@@ -1,262 +0,0 @@
Reset and Boot Sequence
=======================
A device running MicroPython follows a particular boot sequence to start up and
initialise itself after a reset.
.. _hard_reset:
Hard reset
----------
Booting from hard reset is what happens when a board is first powered up, a cold
boot. This is a complete reset of the MCU hardware.
The MicroPython port code initialises all essential hardware (including embedded
clocks and power regulators, internal serial UART, etc), and then starts the
MicroPython environment. Existing :doc:`RTC </library/machine.RTC>`
configuration may be retained after a hard reset, but all other hardware state
is cleared.
The same hard reset boot sequence can be triggered by a number of events such as:
- Python code executing :func:`machine.reset()`.
- User presses a physical Reset button on the board (where applicable).
- Waking from deep sleep (on most ports).
- MCU hardware watchdog reset.
- MCU hardware brown out detector.
The details of hardware-specific reset triggers depend on the port and
associated hardware. The :func:`machine.reset_cause()` function can be used to
further determine the cause of a reset.
.. _soft_reset:
Soft Reset
----------
When MicroPython is already running, it's possible to trigger a soft reset by
:ref:`typing Ctrl-D in the REPL <repl_soft_reset>` or executing
:func:`machine.soft_reset()`.
A soft reset clears the Python interpreter, frees all Python memory, and starts
the MicroPython environment again.
State which is cleared by a soft reset includes:
- All Python variables, objects, imported modules, etc.
- Most peripherals configured using the :doc:`machine module
</library/machine>`. There are very limited exceptions, for example
:doc:`machine.Pin </library/machine.Pin>` modes (i.e. if a pin is input or
output, high or low) are not reset on most ports. More advanced configuration
such as :func:`Pin.irq()` is always reset.
- Bluetooth.
- Network sockets. Open TCP sockets are closed cleanly with respect to the other party.
- Open files. The filesystem is left in a valid state.
Some system state remains the same after a soft reset, including:
- Any existing network connections (Ethernet, Wi-Fi, etc) remain active at the
IP Network layer. Querying the :doc:`network interface from code
</library/network>` may indicate the network interface is still active with a
configured IP address, etc.
- An active :doc:`REPL <repl>` appears continuous before and after soft reset,
except in some unusual cases:
* If the :ref:`machine.USBDevice <machine.USBDevice>` class has been used to
create a custom USB interface then any built-in USB serial device will
appear to disconnect and reconnect as the custom USB interface must be
cleared during reset.
* A serial UART REPL will restore its default hardware configuration (baud
rate, etc).
- CPU clock speed is usually not changed by a soft reset.
- :doc:`RTC </library/machine.RTC>` configuration (i.e. setting of the current
time) is not changed by soft reset.
.. _boot_sequence:
Boot Sequence
-------------
When MicroPython boots following either a hard or soft reset, it follows this
boot sequence in order:
_boot.py
^^^^^^^^
This is an internal script :doc:`frozen into the MicroPython firmware
<manifest>`. It is provided by MicroPython on many ports to do essential
initialisation.
For example, on most ports ``_boot.py`` will detect the first boot of a new
device and format the :doc:`internal flash filesystem <filesystem>` ready for
use.
Unless you're creating a custom MicroPython build or adding a new port then you
probably don't need to worry about ``_boot.py``. It's best not to change the
contents unless you really know what you're doing.
.. _boot.py:
boot.py
^^^^^^^
A file named ``boot.py`` can be copied to the board's internal :ref:`filesystem
<filesystem>` using :doc:`mpremote <mpremote>`.
If ``boot.py`` is found then it is executed. You can add code in ``boot.py`` to
perform custom one-off initialisation (for example, to configure the board's
hardware).
A common practice is to configure a board's network connection in ``boot.py`` so
that it's always available after reset for use with the :doc:`REPL <repl>`,
:doc:`mpremote <mpremote>`, etc.
.. warning:: boot.py should always exit and not run indefinitely.
Depending on the port, some hardware initialisation is delayed until after
``boot.py`` exits. This includes initialising USB on the stm32 port and all
ports which support :ref:`machine.USBDevice <machine.USBDevice>`. On these
ports, output printed from ``boot.py`` may not be visible on the built-in USB
serial port until after ``boot.py`` finishes running.
The purpose of this late initialisation is so that it's possible to
pre-configure particular hardware in ``boot.py``, and then have it start with
the correct configuration.
.. note:: It is sometimes simpler to not have a ``boot.py`` file and place any
initialisation code at the top of ``main.py`` instead.
.. _main.py:
main.py
^^^^^^^
Similar to ``boot.py``, a file named ``main.py`` can be copied to the board's
internal :ref:`filesystem <filesystem>`. If found then it is executed next in the
startup process.
``main.py`` is for any Python code that you want to run each time your device
starts.
Some tips for ``main.py`` usage:
- ``main.py`` doesn't have to exit, feel free to put an infinite ``while
True`` loop in there.
- For complex Python applications then you don't need to put all your
code in ``main.py``. ``main.py`` can be a simple entry point that
imports your application and starts execution::
import my_app
my_app.main()
This can help keep the structure of your application clear. It also makes
it easy to install multiple applications on a board and switch among them.
- It's good practice when writing robust apps to wrap code in ``main.py`` with an
exception handler to take appropriate action if the code crashes. For example::
import machine, sys
import my_app
try:
my_app.main()
except Exception as e:
print("Fatal error in main:")
sys.print_exception(e)
# Following a normal Exception or main() exiting, reset the board.
# Following a non-Exception error such as KeyboardInterrupt (Ctrl-C),
# this code will drop to a REPL. Place machine.reset() in a finally
# block to always reset, instead.
machine.reset()
Otherwise MicroPython will drop to the REPL following any crash or if main
exits (see below).
- Any global variables that were set in ``boot.py`` will still be set in the
global context of ``main.py``.
- To fully optimise flash usage and memory consumption, you can copy
:doc:`pre-compiled <mpyfiles>` ``main.mpy`` and/or ``boot.mpy`` files to the
filesystem, or even :doc:`freeze <manifest>` them into the firmware build
instead.
- ``main.py`` execution is skipped when a soft reset is initiated from :ref:`raw
REPL mode <raw_repl>` (for example, when :doc:`mpremote <mpremote>` or another
program is interacting directly with MicroPython).
Interactive Interpreter (REPL)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If ``main.py`` is not found, or if ``main.py`` exits, then :doc:`repl`
will start immediately.
.. note:: Even if ``main.py`` contains an infinite loop, typing Ctrl-C on the
REPL serial port will inject a `KeyboardInterrupt`. If no exception
handler catches it then ``main.py`` will exit and the REPL will start.
Any global variables that were set in ``boot.py`` and ``main.py`` will still be
set in the global context of the REPL.
The REPL continues executing until Python code triggers a hard or soft reset.
.. _soft_bricking:
Soft Bricking (failure to boot)
---------------------------------
It is rare but possible for MicroPython to become unresponsive during startup, a
state sometimes called "soft bricked". For example:
- If ``boot.py`` execution gets stuck and the native USB serial port
never initialises.
- If Python code reconfigures the REPL interface, making it inaccessible.
Rest assured, recovery is possible!
KeyboardInterrupt
^^^^^^^^^^^^^^^^^
In many cases, opening the REPL serial port and typing ``Ctrl-C`` will inject
`KeyboardInterrupt` and may cause the running script to exit and a REPL to
start. From the REPL, you can use :func:`os.remove()` to remove the misbehaving
Python file::
import os
os.remove('main.py')
To confirm which files are still present in the internal filesystem::
import os
os.listdir()
Safe Mode and Factory Reset
^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you're unable to easily access the REPL then you may need to perform one of
two processes:
1. "Safe mode" boot, which skips ``boot.py`` and ``main.py`` and immediately
starts a REPL, allowing you to clean up. This is only supported on some ports.
2. Factory Reset to erase the entire contents of the flash filesystem. This may
also be necessary if the internal flash filesystem has become corrupted
somehow.
The specific process(es) are different on each port:
- :doc:`pyboard and stm32 port instructions </pyboard/tutorial/reset>`
- :doc:`esp32 port instructions </esp32/tutorial/reset>`
- :doc:`renesas-ra port instructions </renesas-ra/tutorial/reset>`
- :doc:`rp2 port instructions </rp2/tutorial/reset>`
- :doc:`wipy port instructions </wipy/tutorial/reset>`
For ports without specific instructions linked above, the factory reset process
involves erasing the board's entire flash and then flashing MicroPython again
from scratch. Usually this will involve the same tool(s) that were originally
used to install MicroPython. Consult the installation docs for your board, or
ask on the `GitHub Discussions`_ if you're not sure.
.. warning:: Re-flashing the MicroPython firmware without erasing the entire
flash first will usually not recover from soft bricking, as a
firmware update usually preserves the contents of the filesystem.
.. _GitHub Discussions: https://github.com/orgs/micropython/discussions

View File

@@ -57,8 +57,6 @@ and used in various methods.
This is covered in further detail :ref:`Controlling garbage collection <controlling_gc>` below.
.. _speed_buffers:
Buffers
~~~~~~~
@@ -71,13 +69,6 @@ example, objects which support stream interface (e.g., file or UART) provide ``r
method which allocates new buffer for read data, but also a ``readinto()`` method
to read data into an existing buffer.
Some useful classes for creating reusable buffer objects:
- :class:`bytearray`
- :mod:`array` (:ref:`discussed below<speed_arrays>`)
- :class:`io.StringIO` and :class:`io.BytesIO`
- :class:`micropython.RingIO`
Floating point
~~~~~~~~~~~~~~
@@ -89,20 +80,15 @@ point to sections of the code where performance is not paramount. For example,
capture ADC readings as integers values to an array in one quick go, and only then
convert them to floating-point numbers for signal processing.
.. _speed_arrays:
Arrays
~~~~~~
Consider the use of the various types of array classes as an alternative to lists.
The :mod:`array` module supports various element types with 8-bit elements supported
The `array` module supports various element types with 8-bit elements supported
by Python's built in `bytes` and `bytearray` classes. These data structures all store
elements in contiguous memory locations. Once again to avoid memory allocation in critical
code these should be pre-allocated and passed as arguments or as bound objects.
Memoryviews
~~~~~~~~~~~
When passing slices of objects such as `bytearray` instances, Python creates
a copy which involves allocation of the size proportional to the size of slice.
This can be alleviated using a `memoryview` object. The `memoryview` itself
@@ -132,23 +118,6 @@ of buffer and fills in entire buffer. What if you need to put data in the
middle of existing buffer? Just create a memoryview into the needed section
of buffer and pass it to ``readinto()``.
Strings vs Bytes
~~~~~~~~~~~~~~~~
MicroPython uses :ref:`string interning <qstr>` to save space when there are
multiple identical strings. Each time a new string is allocated at runtime (for
example, when two other strings are concatenated), MicroPython checks whether
the new string can be interned to save RAM.
If you have code which performs performance-critical string operations then
consider using :class:`bytes` objects and literals (i.e. ``b"abc"``). This skips
the interning check, and can be several times faster than performing the same
operations with string objects.
.. note:: The fastest performance will always be achieved by avoiding new object
creation entirely, for example with a reusable :ref:`buffer as described
above<speed_buffers>`.
Identifying the slowest section of code
---------------------------------------
@@ -219,7 +188,7 @@ process known as garbage collection reclaims the memory used by these redundant
objects and the allocation is then tried again - a process which can take several
milliseconds.
There may be benefits in preempting this by periodically issuing `gc.collect()`.
There may be benefits in pre-empting this by periodically issuing `gc.collect()`.
Firstly doing a collection before it is actually required is quicker - typically on the
order of 1ms if done frequently. Secondly you can determine the point in code
where this time is used rather than have a longer delay occur at random points,
@@ -246,13 +215,6 @@ There are certain limitations in the current implementation of the native code e
* Context managers are not supported (the ``with`` statement).
* Generators are not supported.
* If ``raise`` is used an argument must be supplied.
* The background scheduler (see `micropython.schedule`) is not run during
execution of native code.
* On targets with thrteading and the GIL, the GIL is not released during
execution of native code.
To mitigate the last two points, long running native functions should call
``time.sleep(0)`` periodically, which will run the scheduler and bounce the GIL.
The trade-off for the improved performance (roughly twice as fast as bytecode) is an
increase in compiled code size.

View File

@@ -206,9 +206,8 @@ See :ref:`machine.RTC <machine.RTC>` ::
from machine import RTC
rtc = RTC()
rtc.datetime((2017, 8, 23, 0, 1, 12, 48, 0)) # set a specific date and
# time, eg. 2017/8/23 1:12:48
# the day-of-week value is ignored
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
# time, eg 2017/8/23 1:12:48
rtc.datetime() # get date and time
Following functions are not supported at the present::

View File

@@ -28,8 +28,6 @@ As the factory setting, following 2 files are created in the file system:
* boot.py : executed first when the system starts
* main.py : executed after boot.py completes
See :doc:`/reference/reset_boot` for more information.
Write a program in the internal file system
-------------------------------------------

View File

@@ -20,8 +20,6 @@ If that isn't working you can perform a hard reset (turn-it-off-and-on-again)
by pressing the RESET button. This will end your session, disconnecting
whatever program (PuTTY, screen, etc) that you used to connect to the board.
For more details, see :doc:`/reference/reset_boot`.
boot mode
---------
@@ -31,9 +29,7 @@ There are 3 boot modes:
* safe boot mode
* factory filesystem boot mode
boot.py and main.py are executed on "normal boot mode". See :ref:`boot_sequence`.
The other modes can be used to recover from :ref:`soft_bricking`:
boot.py and main.py are executed on "normal boot mode".
boot.py and main.py are *NOT* executed on "safe boot mode".
@@ -50,4 +46,16 @@ on the board:
You have created the main.py which executes LED1 blinking in the previous part.
If you change the boot mode to safe boot mode, the MicroPython starts without
the execution of main.py.
the execution of main.py. Then you can remove the main.py by following
command or change the boot mode to factory file system boot mode.::
import os
os.remove('main.py')
or change the boot mode to factory file system boot mode.
You can confirm that the initialized file system that there are only boot.py and main.py files.::
import os
os.listdir()

View File

@@ -55,57 +55,6 @@ The :mod:`rp2` module::
import rp2
Networking
----------
WLAN
^^^^
.. note::
This section applies only to devices that include WiFi support, such as the `Pico W`_ and `Pico 2 W`_.
The :class:`network.WLAN` class in the :mod:`network` module::
import network
wlan = network.WLAN() # create station interface (the default, see below for an access point interface)
wlan.active(True) # activate the interface
wlan.scan() # scan for access points
wlan.isconnected() # check if the station is connected to an AP
wlan.connect('ssid', 'key') # connect to an AP
wlan.config('mac') # get the interface's MAC address
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
ap = network.WLAN(network.WLAN.IF_AP) # create access-point interface
ap.config(ssid='RP2-AP') # set the SSID of the access point
ap.config(max_clients=10) # set how many clients can connect to the network
ap.active(True) # activate the interface
A useful function for connecting to your local WiFi network is::
def do_connect():
import machine, network
wlan = network.WLAN()
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('ssid', 'key')
while not wlan.isconnected():
machine.idle()
print('network config:', wlan.ipconfig('addr4'))
Once the network is established the :mod:`socket <socket>` module can be used
to create and use TCP/UDP sockets as usual, and the ``requests`` module for
convenient HTTP requests.
After a call to ``wlan.connect()``, the device will by default retry to connect
**forever**, even when the authentication failed or no AP is in range.
``wlan.status()`` will return ``network.STAT_CONNECTING`` in this state until a
connection succeeds or the interface gets disabled.
.. _Pico W: https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#picow-technical-specification
.. _Pico 2 W: https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#pico2w-technical-specification
Delay and timing
----------------
@@ -135,12 +84,6 @@ Use the :mod:`machine.Timer` class::
tim = Timer(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))
By default, timer callbacks run as soft IRQs so they can allocate but
are prone to GC jitter and delays. Pass ``hard=True`` to the ``Timer()``
constructor or ``init()`` method to run the callback in hard-IRQ context
instead. This reduces delay and jitter, but see :ref:`isr_rules` for the
restrictions that apply to hard-IRQ handlers.
.. _rp2_Pins_and_GPIO:
@@ -367,9 +310,8 @@ See :ref:`machine.RTC <machine.RTC>` ::
from machine import RTC
rtc = RTC()
rtc.datetime((2017, 8, 23, 0, 1, 12, 48, 0)) # set a specific date and
rtc.datetime((2017, 8, 23, 2, 12, 48, 0, 0)) # set a specific date and
# time, eg. 2017/8/23 1:12:48
# the day-of-week value is ignored
rtc.datetime() # get date and time
WDT (Watchdog timer)

View File

@@ -8,5 +8,4 @@ Let's get started!
.. toctree::
:maxdepth: 1
reset.rst
pio.rst

View File

@@ -1,18 +0,0 @@
Factory reset
=============
If something unexpected happens and your RP2xxx-based board no longer boots
MicroPython, then you may have to factory reset it. For more details, see
:ref:`soft_bricking`.
Factory resetting the MicroPython rp2 port involves fully erasing the flash and
resetting the flash memory, so you will need to re-flash the MicroPython
firmware afterwards and copy any Python files to the filesystem again.
1. Follow the instructions on the Raspberry Pi website for `resetting flash
memory`_.
2. Copy the MicroPython .uf2 firmware file to your board. If needed, this file
can be found on the `MicroPython downloads page`_.
.. _resetting flash memory: https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#resetting-flash-memory
.. _MicroPython downloads page: https://micropython.org/download/?port=rp2

View File

@@ -41,11 +41,9 @@ Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
35 PB03 FLASH_MISO 3 11 - 5/1 6/1 -
54 PB22 FLASH_MOSI 6 - - 5/2 7/0 -
55 PB23 FLASH_SCK 7 - - 5/3 7/1 -
11 PA11 RX 11 19 0/3 2/3 1/1 0/3
10 PA10 TX 10 18 0/2 2/2 1/0 0/2
12 PA12 MISO 12 - 2/0 4/0 2/0 0/6
42 PA12 MOSI 10 - - 4/2 5/0 0/4
43 PA13 SCK 11 - - 4/3 5/1 0/5
42 PB10 MOSI 10 - - 4/2 5/0 0/4
43 PB11 SCK 11 - - 4/3 5/1 0/5
23 PA23 SCL 7 - 3/1 5/1 4/1 0/5
22 PA22 SDA 6 - 3/0 5/0 4/0 0/4
30 PA30 SWCLK 10 - - 1/2 1/0 -
@@ -129,7 +127,7 @@ Examples for Adafruit ItsyBitsy M0 Express:
- SPI 1 at pins D11/D12/D13
- SPI 2 at pins D0/D4/D1
- SPI 3 at pins D11/D12/D13
- SPI 2 at Pin MOSI/MISO/SCK This is the default SPI device at the MOSI/MISO/SCK labelled pins.
- SPI 4 at Pin MOSI/MISO/SCK This is the default SPI device at the MOSI/MISO/SCK labelled pins.
or other combinations.
@@ -171,8 +169,6 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
22 PA22 D13 6 - - 3/0 5/1 4/0 1/6 0/2
34 PB02 DOTSTAR_CLK 2 14 - - 5/0 6/0 2/2 -
35 PB03 DOTSTAR_DATA 9 15 - - 5/1 6/1 - -
16 PA16 RX 0 - - 1/0 3/1 2/0 1/0 0/4
17 PA17 TX 1 - - 1/1 3/0 2/1 1/1 0/5
55 PB23 MISO 7 - - 1/3 5/3 7/1 - -
0 PA00 MOSI 0 - - - 1/0 2/0 - -
43 PB11 QSPI_CS 12 - - - 4/3 5/1 0/5 1/1
@@ -239,7 +235,7 @@ The I2C devices and signals must be chosen according to the following rules:
- The SDA signal must be at a Pin with pad numbers 0.
- The SCL signal must be at a Pin with pad numbers 1.
Examples for Adafruit ItsyBitsy M4 Express:
Examples for Adafruit ItsyBitsy M0 Express:
- I2C 0 at pins A3/A4
- I2C 1 at pins D0/D1
@@ -257,7 +253,7 @@ The SPI devices and signals must be chosen according to the following rules:
- The following pad number pairs are suitable for MOSI/SCK: 0/1 and 3/1.
- The MISO signal must be at a Pin with a different pad number than MOSI or SCK.
Examples for Adafruit ItsyBitsy M4 Express:
Examples for Adafruit ItsyBitsy M0 Express:
- SPI 1 at Pin MOSI/MISO/SCK This is the default SPI device at the MOSI/MISO/SCK labelled pins.
- SPI 3 at pins D13/D11/D12
@@ -300,8 +296,6 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
21 PA21 D11 5 - - 5/3 3/3 7/1 1/5 0/1
22 PA22 D12 6 - - 3/0 5/1 4/0 1/6 0/2
23 PA23 D13 7 - - 3/1 5/0 4/1 1/7 0/3
49 PB17 RX 1 - - 5/1 - 6/1 3/1 0/5
48 PB16 TX 0 - - 5/0 - 6/0 3/0 0/4
54 PB22 MISO 22 - - 1/2 5/2 7/0 - -
55 PB23 MOSI 7 - - 1/3 5/3 7/1 - -
35 PB03 NEOPIXEL 9 15 - - 5/1 6/1 - -
@@ -387,8 +381,6 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
8 PA08 FLASH_MOSI - 8 2 0/0 2/1 0/0 0/0 1/4
42 PB10 FLASH_SCK 10 - - - 4/2 5/0 0/4 1/0
10 PA10 FLASH_WP 10 10 - 0/2 2/2 1/0 0/2 1/6
23 PA23 RX 7 - - 3/1 5/0 4/1 1/7 0/3
22 PA22 TX 6 - - 3/0 5/1 4/0 1/6 0/2
14 PA14 MISO 14 - - 2/2 4/2 3/0 2/0 1/2
12 PA12 MOSI 12 - - 2/0 4/1 2/0 0/6 1/2
54 PB22 NEOPIXEL 22 - - 1/2 5/2 7/0 - -
@@ -437,13 +429,6 @@ Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
5 PA05 A9_D9 5 5 - 0/1 0/1 -
6 PA06 A10_D10 6 6 - 0/2 1/0 -
18 PA18 RX_LED 2 - 1/2 3/2 3/0 0/2
41 PB09 RX 9 3 - 4/1 4/1 -
40 PB08 TX 8 2 - 4/0 4/0 -
8 PA08 SDA - 16 0/0 2/0 0/0 1/2
9 PA09 SCL 9 17 0/1 2/1 0/1 1/3
6 PA06 MOSI 6 6 - 0/2 1/0 -
5 PA05 MISO 5 5 - 0/1 0/1 -
7 PA07 SCK 7 7 - 0/3 1/1 -
30 PA30 SWCLK 10 - - 1/2 1/0 -
31 PA31 SWDIO 11 - - 1/3 1/1 -
19 PA19 TX_LED 3 - 1/3 3/3 3/1 0/3
@@ -518,8 +503,6 @@ Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
43 PB11 SCK 11 - - 4/3 5/1 0/5
23 PA23 SCL 7 - 3/1 5/1 4/1 0/5
22 PA22 SDA 6 - 3/0 5/0 4/0 0/4
11 PA11 RX 11 19 0/3 2/3 1/1 0/3
10 PA10 TX 10 18 0/2 2/2 1/0 0/2
30 PA30 SWCLK 10 - - 1/2 1/0 -
31 PA31 SWDIO 11 - - 1/3 1/1 -
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
@@ -535,9 +518,9 @@ Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
The default devices at the board are:
- UART 2 at pins PA11/PA10, labelled RX/TX
- UART 5 at pins PB23/PB22, labelled RX/TX
- I2C 3 at pins PA22/PA23, labelled SDA/SCL
- SPI 4 at pins PB10/PA12/PB11, labelled MOSI, MISO and SCK
- SPI 4 at pins PA10/PA12/PA11, labelled MOSI, MISO and SCK
- DAC output on pin PA02, labelled A0
Adafruit Trinket M0 pin assignment table
@@ -553,13 +536,6 @@ Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
6 PA06 D4 6 6 - 0/2 1/0 -
1 PA01 DOTSTAR_CLK 1 - - 1/1 2/1 -
0 PA00 DOTSTAR_DATA 0 - - 1/0 2/0 -
7 PA07 RX 7 7 - 0/3 1/1 -
6 PA06 TX 6 6 - 0/2 1/0 -
8 PA08 SDA - 16 0/0 2/0 0/0 1/2
9 PA09 SCL 9 17 0/1 2/1 0/1 1/3
6 PA06 MOSI 6 6 - 0/2 1/0 -
9 PA09 MISO 9 17 0/1 2/1 0/1 1/3
7 PA07 SCK 7 7 - 0/3 1/1 -
10 PA10 LED 10 18 0/2 2/2 1/0 0/2
30 PA30 SWCLK 10 - - 1/2 1/0 -
31 PA31 SWDIO 11 - - 1/3 1/1 -
@@ -591,184 +567,6 @@ The default devices at the board are:
- SPI 0 at pins PA06/PA09/PA08, labelled D4, D2 and D0
- DAC output on pin PA02, labelled D1
Adafruit QT PY pin assignment table
-----------------------------------
=== ==== ============ ==== ==== ====== ====== ====== ======
Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
=== ==== ============ ==== ==== ====== ====== ====== ======
2 PA02 A0 2 0 - - - -
3 PA03 A1 3 1 - - - -
4 PA04 A2 4 4 - 0/0 0/0 -
5 PA05 A3 5 5 - 0/1 0/1 -
7 PA07 RX 7 7 - 0/3 1/1 -
6 PA06 TX 6 6 - 0/2 1/0 -
8 PA08 FLASH_CS - 16 0/0 2/0 0/0 1/2
19 PA19 FLASH_MISO 3 - 1/3 3/3 3/1 0/3
22 PA22 FLASH_MOSI 6 - 3/0 5/0 4/0 0/4
23 PA23 FLASH_SCK 7 - 3/1 5/1 4/1 0/5
9 PA09 MISO 9 17 0/1 2/1 0/1 1/3
10 PA10 MOSI 10 18 0/2 2/2 1/0 0/2
18 PA18 NEOPIX 2 - 1/2 3/2 3/0 0/2
15 PA15 NEO_PWR 15 - 2/3 4/3 3/1 0/5
11 PA11 SCK 11 19 0/3 2/3 1/1 0/3
17 PA17 SCL 1 - 1/1 3/1 2/1 0/7
16 PA16 SDA 0 - 1/0 3/0 2/0 0/6
30 PA30 SWCLK 10 - - 1/2 1/0 -
31 PA31 SWDIO 11 - - 1/3 1/1 -
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
=== ==== ============ ==== ==== ====== ====== ====== ======
For the definition of the table columns see the explanation at the table for
Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
The default devices at the board are:
- UART 0 at pins PA07/PA06, labelled RX/TX
- I2C 1 at pins PA16/PA17, labelled SDA/SCL
- SPI 0 at pins PA09/PA10/PA11, labelled MISO, MOSI and SCK
- DAC output on pin PA02, labelled A0
Adafruit NeoKey Trinkey pin assignment table
--------------------------------------------
=== ==== ============ ==== ==== ====== ====== ====== ======
Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
=== ==== ============ ==== ==== ====== ====== ====== ======
15 PA15 NEOPIXEL 15 - 2/3 4/3 3/1 0/5
30 PA30 SWCLK 10 - - 1/2 1/0 -
31 PA31 SWDIO 11 - - 1/3 1/1 -
18 PA18 SWITCH 2 - 1/2 3/2 3/0 0/2
7 PA07 TOUCH 7 7 - 0/3 1/1 -
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
=== ==== ============ ==== ==== ====== ====== ====== ======
For the definition of the table columns see the explanation at the table for
Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
The board does not provide access to UART, I2C, SPI or DAC.
SparkFun Redboard Turbo assignment table
----------------------------------------
=== ==== ============ ==== ==== ====== ====== ====== ======
Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
=== ==== ============ ==== ==== ====== ====== ====== ======
2 PA02 A0 2 0 - - - -
40 PB08 A1 8 2 - 4/0 4/0 -
41 PB09 A2 9 3 - 4/1 4/1 -
4 PA04 A3 4 4 - 0/0 0/0 -
5 PA05 A4 5 5 - 0/1 0/1 -
34 PB02 A5 2 10 - 5/0 6/0 -
11 PA11 D0 11 19 0/3 2/3 1/1 0/3
10 PA10 D1 10 18 0/2 2/2 1/0 0/2
14 PA14 D2 14 - 2/2 4/2 3/0 0/4
9 PA09 D3 9 17 0/1 2/1 0/1 1/3
8 PA08 D4 - 16 0/0 2/0 0/0 1/2
15 PA15 D5 15 - 2/3 4/3 3/1 0/5
20 PA20 D6 4 - 5/2 3/2 7/0 0/4
21 PA21 D7 5 - 5/3 3/3 7/1 0/7
6 PA06 D8 6 6 - 0/2 1/0 -
7 PA07 D9 7 7 - 0/3 1/1 -
11 PA11 RX 11 19 0/3 2/3 1/1 0/3
10 PA10 TX 10 18 0/2 2/2 1/0 0/2
3 PA03 AREF 3 1 - - - -
18 PA18 D10 2 - 1/2 3/2 3/0 0/2
16 PA16 D11 0 - 1/0 3/0 2/0 0/6
19 PA19 D12 3 - 1/3 3/3 3/1 0/3
17 PA17 D13 1 - 1/1 3/1 2/1 0/7
13 PA13 FLASH_CS 13 - 2/1 4/1 2/0 0/7
35 PB03 FLASH_MISO 3 11 - 5/1 6/1 -
54 PB22 FLASH_MOSI 6 - - 5/2 7/0 -
55 PB23 FLASH_SCK 7 - - 5/3 7/1 -
31 PA31 LED_RX 11 - - 1/3 1/1 -
27 PA27 LED_TX 15 - - - - -
12 PA12 MISO 12 - 2/0 4/0 2/0 0/6
42 PB10 MOSI 10 - - 4/2 5/0 0/4
30 PA30 NEOPIXEL 10 - - 1/2 1/0 -
43 PB11 SCK 11 - - 4/3 5/1 0/5
23 PA23 SCL 7 - 3/1 5/1 4/1 0/5
22 PA22 SDA 6 - 3/0 5/0 4/0 0/4
30 PA30 SWCLK 10 - - 1/2 1/0 -
31 PA31 SWDIO 11 - - 1/3 1/1 -
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
0 PA00 0 - - 1/0 2/0 -
1 PA01 1 - - 1/1 2/1 -
28 PA28 8 - - - - -
=== ==== ============ ==== ==== ====== ====== ====== ======
For the definition of the table columns see the explanation at the table for
Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
The default devices at the board are:
- UART 0 at pins PA11/PA10, labelled RX/TX
- I2C 3 at pins PA22/PA23, labelled SDA/SCL
- SPI 4 at pins PB10/PA12/PB11, labelled MISO, MOSI and SCK
- DAC output on pin PA02, labelled A0
SparkFun SAMD21 Dev Breakout assignment table
---------------------------------------------
=== ==== ============ ==== ==== ====== ====== ====== ======
Pin GPIO Pin name IRQ ADC Serial Serial TCC/TC TCC/TC
=== ==== ============ ==== ==== ====== ====== ====== ======
2 PA02 A0 2 0 - - - -
40 PB08 A1 8 2 - 4/0 4/0 -
41 PB09 A2 9 3 - 4/1 4/1 -
4 PA04 A3 4 4 - 0/0 0/0 -
5 PA05 A4 5 5 - 0/1 0/1 -
34 PB02 A5 2 10 - 5/0 6/0 -
11 PA11 D0 11 19 0/3 2/3 1/1 0/3
10 PA10 D1 10 18 0/2 2/2 1/0 0/2
14 PA14 D2 14 - 2/2 4/2 3/0 0/4
9 PA09 D3 9 17 0/1 2/1 0/1 1/3
8 PA08 D4 - 16 0/0 2/0 0/0 1/2
15 PA15 D5 15 - 2/3 4/3 3/1 0/5
20 PA20 D6 4 - 5/2 3/2 7/0 0/4
21 PA21 D7 5 - 5/3 3/3 7/1 0/7
6 PA06 D8 6 6 - 0/2 1/0 -
7 PA07 D9 7 7 - 0/3 1/1 -
11 PA11 RX 11 19 0/3 2/3 1/1 0/3
10 PA10 TX 10 18 0/2 2/2 1/0 0/2
3 PA03 AREF 3 1 - - - -
18 PA18 D10 2 - 1/2 3/2 3/0 0/2
16 PA16 D11 0 - 1/0 3/0 2/0 0/6
19 PA19 D12 3 - 1/3 3/3 3/1 0/3
17 PA17 D13 1 - 1/1 3/1 2/1 0/7
54 PB22 D30 6 - - 5/2 7/0 -
55 PB23 D31 7 - - 5/3 7/1 -
13 PA13 D38 13 - 2/1 4/1 2/0 0/7
35 PB03 LED_RX 3 11 - 5/1 6/1 -
27 PA27 LED_TX 15 - - - - -
12 PA12 MISO 12 - 2/0 4/0 2/0 0/6
42 PB10 MOSI 10 - - 4/2 5/0 0/4
43 PB11 SCK 11 - - 4/3 5/1 0/5
23 PA23 SCL 7 - 3/1 5/1 4/1 0/5
22 PA22 SDA 6 - 3/0 5/0 4/0 0/4
30 PA30 SWCLK 10 - - 1/2 1/0 -
31 PA31 SWDIO 11 - - 1/3 1/1 -
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
0 PA00 0 - - 1/0 2/0 -
1 PA01 1 - - 1/1 2/1 -
28 PA28 8 - - - - -
=== ==== ============ ==== ==== ====== ====== ====== ======
For the definition of the table columns see the explanation at the table for
Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
The default devices at the board are:
- UART 0 at pins PA11/PA10, labelled RX/TX
- I2C 3 at pins PA22/PA23, labelled SDA/SCL
- SPI 4 at pins PB10/PA12/PB11, labelled MISO, MOSI and SCK
- DAC output on pin PA02, labelled A0
SAMD21 Xplained PRO pin assignment table
----------------------------------------
@@ -858,10 +656,8 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
34 PB02 DOTSTAR_CLK 2 14 - - 5/0 6/0 2/2 -
35 PB03 DOTSTAR_DATA 9 15 - - 5/1 6/1 - -
15 PA15 LED 15 - - 2/3 4/3 3/1 2/1 1/3
16 PA16 RX 0 - - 1/0 3/1 2/0 1/0 0/4
17 PA17 TX 1 - - 1/1 3/0 2/1 1/1 0/5
55 PB23 MOSI 7 - - 1/3 5/3 7/1 - -
54 PB22 MISO 22 - - 1/2 5/2 7/0 - -
55 PB23 MISO 7 - - 1/3 5/3 7/1 - -
54 PB22 MOSI 22 - - 1/2 5/2 7/0 - -
43 PB11 QSPI_CS 12 - - - 4/3 5/1 0/5 1/1
8 PA08 QSPI_D0 - 8 2 0/0 2/1 0/0 0/0 1/4
9 PA09 QSPI_D1 9 9 3 0/1 2/0 0/1 0/1 1/5
@@ -1010,7 +806,7 @@ Default pin assignments:
There seems to be no default pin assignment for this board.
SparkFun SAMD51 Thing Plus pin assignment table
Sparkfun SAMD51 Thing Plus pin assignment table
------------------------------------------------
=== ==== ============ ==== ==== ==== ====== ====== ===== ===== =====
@@ -1037,8 +833,6 @@ Pin GPIO Pin name IRQ ADC ADC Serial Serial TC PWM PWM
11 PA11 FLASH_MISO 11 11 - 0/3 2/3 1/1 0/3 1/7
8 PA08 FLASH_MOSI - 8 2 0/0 2/1 0/0 0/0 1/4
9 PA09 FLASH_SCK 9 9 3 0/1 2/0 0/1 0/1 1/5
13 PA13 RX 13 - - 2/1 4/0 2/1 0/7 1/3
12 PA12 TX 12 - - 2/0 4/1 2/0 0/6 1/2
43 PB11 MISO 12 - - - 4/3 5/1 0/5 1/1
44 PB12 MOSI 12 - - 4/0 - 4/0 3/0 0/0
55 PB23 RXD 7 - - 1/3 5/3 7/1 - -
@@ -1077,192 +871,10 @@ Adafruit ItsyBitsy M4 Express :ref:`samd51_pinout_table`.
The default devices at the board are:
- UART 2 at pins PA13/PA12, labelled RXD/TXD
- I2C 3 at pins PA22/PA23, labelled SDA/SCL
- I2C 5 at pins PA22/PA23, labelled SDA/SCL
- SPI 4 at pins PB12/PB11/PB13, labelled MOSI, MISO and SCK
- DAC output on pins PA02 and PA05, labelled A0 and A4
Generic SAMD21x18 pin assignment table
--------------------------------------
=== ==== ============ ==== ==== ====== ====== ====== ======
Pin GPIO Name/Package IRQ ADC Serial Serial TCC/TC TCC/TC
=== ==== ============ ==== ==== ====== ====== ====== ======
0 PA00 EGJ 0 - - 1/0 2/0 -
1 PA01 EGJ 1 - - 1/1 2/1 -
2 PA02 EGJ 2 0 - - - -
3 PA03 EGJ 3 1 - - - -
4 PA04 EGJ 4 4 - 0/0 0/0 -
5 PA05 EGJ 5 5 - 0/1 0/1 -
6 PA06 EGJ 6 6 - 0/2 1/0 -
7 PA07 EGJ 7 7 - 0/3 1/1 -
8 PA08 EGJ - 16 0/0 2/0 0/0 1/2
9 PA09 EGJ 9 17 0/1 2/1 0/1 1/3
10 PA10 EGJ 10 18 0/2 2/2 1/0 0/2
11 PA11 EGJ 11 19 0/3 2/3 1/1 0/3
12 PA12 GJ 12 - 2/0 4/0 2/0 0/6
13 PA13 GJ 13 - 2/1 4/1 2/0 0/7
14 PA14 EGJ 14 - 2/2 4/2 3/0 0/4
15 PA15 EGJ 15 - 2/3 4/3 3/1 0/5
16 PA16 EGJ 0 - 1/0 3/0 2/0 0/6
17 PA17 EGJ 1 - 1/1 3/1 2/1 0/7
18 PA18 EGJ 2 - 1/2 3/2 3/0 0/2
19 PA19 EGJ 3 - 1/3 3/3 3/1 0/3
20 PA20 GJ 4 - 5/2 3/2 7/0 0/4
21 PA21 GJ 5 - 5/3 3/3 7/1 0/7
22 PA22 EGJ 6 - 3/0 5/0 4/0 0/4
23 PA23 EGJ 7 - 3/1 5/1 4/1 0/5
24 PA24 USB_DM 12 - 3/2 5/2 5/0 1/2
25 PA25 USB_DP 13 - 3/3 5/3 5/1 1/3
27 PA27 EGJ 15 - - - - -
28 PA28 EGJ 8 - - - - -
30 PA30 SWCLK 10 - - 1/2 1/0 -
31 PA31 SWDIO 11 - - 1/3 1/1 -
32 PB00 J 0 8 - 5/2 7/0 -
33 PB01 J 1 9 - 5/3 7/1 -
34 PB02 GJ 2 10 - 5/0 6/0 -
35 PB03 GJ 3 11 - 5/1 6/1 -
36 PB04 J 4 12 - - - -
37 PB05 J 5 13 - - - -
38 PB06 J 6 14 - - - -
39 PB07 J 7 15 - - - -
40 PB08 GJ 8 2 - 4/0 4/0 -
41 PB09 GJ 9 3 - 4/1 4/1 -
42 PB10 GJ 10 - - 4/2 5/0 0/4
43 PB11 GJ 11 - - 4/3 5/1 0/5
44 PB12 J 12 - 4/0 - 4/0 0/6
45 PB13 J 13 - 4/1 - 4/1 0/7
46 PB14 J 14 - 4/2 - 5/0 -
47 PB15 J 15 - 4/3 - 5/1 -
48 PB16 J 0 - 5/0 - 6/0 0/4
49 PB17 J 1 - 5/1 - 6/1 0/5
54 PB22 GJ 6 - - 5/2 7/0 -
55 PB23 GJ 7 - - 5/3 7/1 -
62 PB30 J 14 - - 5/0 0/0 1/2
63 PB31 J 15 - - 5/1 0/1 1/3
=== ==== ============ ==== ==== ====== ====== ====== ======
For the definition of the table columns see the explanation at the table for
Adafruit ItsyBitsy M0 Express :ref:`samd21_pinout_table`.
The Package column indicates the package letter providing this pin. An entry
EGJ tells for instance, that the pin is available for SAMD21E18, SAMD21G18 and
SAMD21J18.
Generic SAMD51x19 and SAM51x20 pin assignment table
---------------------------------------------------
For the definition of the table columns see the explanation at the table for
Adafruit ItsyBitsy M4 Express :ref:`samd51_pinout_table`.
=== ==== ============ ==== ==== ==== ====== ====== ===== ===== =====
Pin GPIO Name/Package IRQ ADC ADC Serial Serial TC PWM PWM
=== ==== ============ ==== ==== ==== ====== ====== ===== ===== =====
8 PA08 QSPI_D0 - 8 2 0/0 2/1 0/0 0/0 1/4
9 PA09 QSPI_D1 9 9 3 0/1 2/0 0/1 0/1 1/5
10 PA10 QSPI_D2 10 10 - 0/2 2/2 1/0 0/2 1/6
11 PA11 QSPI_D3 11 11 - 0/3 2/3 1/1 0/3 1/7
42 PB10 QSPI_SCK 10 - - - 4/2 5/0 0/4 1/0
23 PA23 USB_SOF 7 - - 3/1 5/0 4/1 1/7 0/3
24 PA24 USB_DM 8 - - 3/2 5/2 5/0 2/2 -
25 PA25 USB_DP 9 - - 3/3 5/3 5/1 - -
0 PA00 GJP 0 - - - 1/0 2/0 - -
1 PA01 GJP 1 - - - 1/1 2/1 - -
2 PA02 GJP 2 0 - - - - - -
3 PA03 GJP 3 10 - - - - - -
4 PA04 GJP 4 4 - - 0/0 0/0 - -
5 PA05 GJP 5 5 - - 0/1 0/1 - -
6 PA06 GJP 6 6 - - 0/2 1/0 - -
7 PA07 GJP 7 7 - - 0/3 1/1 - -
12 PA12 GJP 12 - - 2/0 4/1 2/0 0/6 1/2
13 PA13 GJP 13 - - 2/1 4/0 2/1 0/7 1/3
14 PA14 GJP 14 - - 2/2 4/2 3/0 2/0 1/2
15 PA15 GJP 15 - - 2/3 4/3 3/1 2/1 1/3
16 PA16 GJP 0 - - 1/0 3/1 2/0 1/0 0/4
17 PA17 GJP 1 - - 1/1 3/0 2/1 1/1 0/5
18 PA18 GJP 2 - - 1/2 3/2 3/0 1/2 0/6
19 PA19 GJP 3 - - 1/3 3/3 3/1 1/3 0/7
20 PA20 GJP 4 - - 5/2 3/2 7/0 1/4 0/0
21 PA21 GJP 5 - - 5/3 3/3 7/1 1/5 0/1
22 PA22 GJP 6 - - 3/0 5/1 4/0 1/6 0/2
27 PA27 GJP 11 - - - - - - -
30 PA30 SWCLK 14 - - 7/2 1/2 6/0 2/0 -
31 PA31 SWDIO 15 - - 7/3 1/3 6/1 2/1 -
32 PB00 JP 0 12 - - 5/2 7/0 - -
33 PB01 JP 1 13 - - 5/3 7/1 - -
34 PB02 GJP 2 14 - - 5/0 6/0 2/2 -
35 PB03 GJP 3 15 - - 5/1 6/1 - -
36 PB04 JP 4 - 6 - - - - -
37 PB05 JP 5 - 7 - - - - -
38 PB06 JP 6 - 8 - - - - -
39 PB07 JP 7 - 9 - - - - -
40 PB08 GJP 8 2 0 - 4/0 4/0 - -
41 PB09 GJP 9 3 1 - 4/1 4/1 - -
44 PB12 JP 12 - - 4/0 - 4/0 3/0 0/0
45 PB13 JP 13 - - 4/1 - 4/1 3/1 0/1
46 PB14 JP 14 - - 4/2 - 5/0 4/0 0/2
47 PB15 JP 15 - - 4/3 - 5/1 4/1 0/3
48 PB16 JP 0 - - 5/0 - 6/0 3/0 0/4
49 PB17 JP 1 - - 5/1 - 6/1 3/1 0/5
50 PB18 P 2 - - 5/2 7/2 - 1/0 -
51 PB19 P 3 - - 5/3 7/3 - 1/1 -
52 PB20 P 4 - - 3/0 7/1 - 1/2 -
53 PB21 P 5 - - 3/1 7/0 - 1/3 -
54 PB22 GJP 6 - - 1/2 5/2 7/0 - -
55 PB23 GJP 7 - - 1/3 5/3 7/1 - -
56 PB24 P 8 - - 0/0 2/1 - - -
57 PB25 P 9 - - 0/1 2/0 - - -
58 PB26 P 12 - - 2/0 4/1 - 1/2 -
59 PB27 P 13 - - 2/1 4/0 - 1/3 -
60 PB28 P 14 - - 2/2 4/2 - 1/4 -
61 PB29 P 15 - - 2/3 4/3 - 1/5 -
62 PB30 JP 14 - - 7/0 5/1 0/0 4/0 0/6
63 PB31 JP 15 - - 7/1 5/0 0/1 4/1 0/7
64 PC00 P 0 - 10 - - - - -
65 PC01 P 1 - 11 - - - - -
66 PC02 P 2 - 4 - - - - -
67 PC03 P 3 - 5 - - - - -
68 PC04 P 4 - - 6/0 - - 0/0 -
69 PC05 P 5 - - 6/1 - - - -
70 PC06 P 6 - - 6/2 - - - -
71 PC07 P 9 - - 6/3 - - - -
74 PC10 P 10 - - 6/2 7/2 - 0/0 1/4
75 PC11 P 11 - - 6/3 7/3 - 0/1 1/5
76 PC12 P 12 - - 7/0 6/1 - 0/2 1/6
77 PC13 P 13 - - 7/1 6/0 - 0/3 1/7
78 PC14 P 14 - - 7/2 6/2 - 0/4 1/0
79 PC15 P 15 - - 7/3 6/3 - 0/5 1/1
80 PC16 P 0 - - 6/0 0/1 - 0/0 -
81 PC17 P 1 - - 6/1 0/0 - 0/1 -
82 PC18 P 2 - - 6/2 0/2 - 0/2 -
83 PC19 P 3 - - 6/3 0/3 - 0/3 -
84 PC20 P 4 - - - - - 0/4 -
85 PC21 P 5 - - - - - 0/5 -
86 PC22 P 6 - - 1/0 3/1 - 0/5 -
87 PC23 P 7 - - 1/1 3/0 - 0/7 -
88 PC24 P 8 - - 0/2 2/2 - - -
89 PC25 P 9 - - 0/3 2/3 - - -
90 PC26 P 10 - - - - - - -
91 PC27 P 11 - - 1/0 - - - -
92 PC28 P 12 - - 1/1 - - - -
94 PC30 P 14 - 12 - - - - -
95 PC31 P 15 - 13 - - - - -
96 PD00 P 0 - 14 - - - - -
97 PD01 P 1 - 15 - - - - -
104 PD08 P 3 - - 7/0 6/1 - 0/1 -
105 PD09 P 4 - - 7/1 6/0 - 0/2 -
106 PD10 P 5 - - 7/2 6/2 - 0/3 -
107 PD11 P 6 - - 7/3 6/3 - 0/4 -
108 PD12 P 7 - - - - - 0/5 -
116 PD20 P 10 - - 1/2 3/2 - 1/0 -
117 PD21 P 11 - - 1/3 3/3 - 1/1 -
=== ==== ============ ==== ==== ==== ====== ====== ===== ===== =====
The Package column indicates the package letter providing this pin. An entry
GJP tells for instance, that the pin is available for SAMD51G19, SAMD51J19/-J20 and
SAMD51P19/-P20.
Scripts for creating the pin assignment tables
----------------------------------------------
@@ -1309,22 +921,22 @@ The tables shown above were created with small a Python script running on the ta
else:
return "zzzzzzz%03d" % i[0]
def pinnum(p):
return (ord(p[1]) - ord("A")) * 32 + int(p[2:])
def table(num = 127, sort=True):
def table(num=127, sort=True):
pintbl = []
pinlist = []
for name in Pin.board.__dict__.keys():
p = Pin(name)
pi = pininfo(p)
pintbl.append((pinnum(pi[0]), name, pi))
pinlist.append(p)
for pc in Pin.cpu.__dict__.keys():
p = Pin(pc)
pi = pininfo(p)
if not p in pinlist:
pintbl.append((pinnum(pi[0]), "", pi))
inv_bd = {v: k for k, v in Pin.board.__dict__.items()}
for i in range(num):
try:
p = Pin(i)
pi = pininfo(p)
if p in inv_bd.keys():
name = inv_bd[p]
else:
name = ""
pintbl.append((i, name, pininfo(i)))
except:
pass
# print("not defined")
if sort:
pintbl.sort(key=tblkey)
for item in pintbl:

View File

@@ -163,15 +163,10 @@ See :ref:`machine.UART <machine.UART>`. ::
uart3.write('hello') # write 5 bytes
uart3.read(5) # read up to 5 bytes
uart = UART() # Use the default values for id, rx and tx.
uart = UART(baudrate=9600) # Use the default UART and set the baudrate
The SAMD21/SAMD51 MCUs have up to eight hardware so called SERCOM devices, which can be used as UART,
SPI or I2C device, but not every MCU variant and board exposes all
TX and RX pins for users. For the assignment of Pins to devices and UART signals,
refer to the :ref:`SAMD pinout <samd_pinout>`. If the id, rx or tx pins are not specified,
the default values are used. The first positional argument (if given) is assumed to be the UART id.
If the baudrate is changed and the UART id is omitted, it must be set using the baudrate keyword.
refer to the :ref:`SAMD pinout <samd_pinout>`.
PWM (pulse width modulation)
----------------------------
@@ -220,7 +215,7 @@ PWM Constructor
- *freq* should be an integer which sets the frequency in Hz for the
PWM cycle. The valid frequency range is 1 Hz to 24 MHz.
- *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65535``.
- *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65536``.
- *duty_ns* sets the pulse width in nanoseconds. The limitation for X channels
apply as well.
- *invert*\=True|False. Setting a bit inverts the respective output.
@@ -251,7 +246,7 @@ Use the :ref:`machine.ADC <machine.ADC>` class::
from machine import ADC
adc0 = ADC(Pin('A0')) # create ADC object on ADC pin, average=16
adc0.read_u16() # read value, 0-65535 across voltage range 0.0v - 3.3v
adc0.read_u16() # read value, 0-65536 across voltage range 0.0v - 3.3v
adc1 = ADC(Pin('A1'), average=1) # create ADC object on ADC pin, average=1
The resolution of the ADC is 12 bit with 12 bit accuracy, irrespective of the
@@ -378,18 +373,8 @@ signal pins for users. Hardware SPI is accessed via the
spi = SPI(1, sck=Pin("SCK"), mosi=Pin("MOSI"), miso=Pin("MISO"), baudrate=10000000)
spi.write('Hello World')
For the assignment of Pins to SPI devices and signals, refer to
:ref:`SAMD pinout <samd_pinout>`. If the id, miso, mosi or sck pins are not specified,
the default values are used. So it is possible to create the SPI object as::
from machine import SPI
spi = SPI() # Use the default device and default baudrate
spi = SPI(baudrate=12_000_000) # Use the default device and change the baudrate
If the MISO signal shall be omitted, it must be defined as miso=None.
The first positional argument (if given) is assumed to be the SPI id.
If the baudrate is changed while the SPI id is omitted, it must be
set using the baudrate keyword.
If miso is not specified, it is not used. For the assignment of Pins to SPI devices and signals, refer to
:ref:`SAMD pinout <samd_pinout>`.
Note: Even if the highest reliable baud rate at the moment is about 24 Mhz,
setting a baud rate will not always result in exactly that frequency, especially
@@ -422,7 +407,6 @@ The SAMD21/SAMD51 MCUs have up to eight hardware so called SERCOM devices,
which can be used as UART, SPI or I2C device, but not every MCU variant
and board exposes all signal pins for users.
For the assignment of Pins to devices and I2C signals, refer to :ref:`SAMD pinout <samd_pinout>`.
If the id, scl or sda pins are not specified, the default values are used.
Hardware I2C is accessed via the :ref:`machine.I2C <machine.I2C>` class and
has the same methods as software SPI above::
@@ -432,13 +416,6 @@ has the same methods as software SPI above::
i2c = I2C(2, scl=Pin("SCL"), sda=Pin("SDA"), freq=400_000)
i2c.writeto(0x76, b"Hello World")
i2c2 = I2C() # Use the default values for id, scl and sda.
i2c2 = I2C(freq=100_000) # Use the default device and set freq.
The first positional argument (if given) is assumed to be the I2C id.
If the freq is changed and the I2C id is omitted, it must be set using
the freq keyword.
OneWire driver
--------------

View File

@@ -16,8 +16,6 @@ There are soft resets and hard resets.
import machine
machine.reset()
For more information, see :doc:`/reference/reset_boot`.
Safe boot
---------

View File

@@ -56,21 +56,6 @@ Use the :ref:`machine.Pin <machine.Pin>` class::
switch = Pin(("gpioc", 6), Pin.IN) # create input pin for a switch
switch.irq(lambda t: print("SW2 changed")) # enable an interrupt when switch state is changed
PWM
---
Use the :ref:`machine.PWM <machine.PWM>` class::
from machine import PWM
pwm = PWM(("pwm0", 0), freq=3921568, duty_ns=200, invert=True) # create pwm on PWM0
print(pwm) # print pwm
print(pwm.duty_ns()) # print pwm duty cycle in nanoseconds
pwm.duty_ns(255) # set new pwm duty cycle in nanoseconds
pwm.deinit()
Hardware I2C bus
----------------
@@ -153,8 +138,6 @@ Use the :ref:`zephyr.FlashArea <zephyr.FlashArea>` class to support filesystem::
f.write('Hello world') # write to the file
print(open('/flash/hello.txt').read()) # print contents of the file
The FlashAreas' IDs that are available are listed in the FlashArea module, as ID_*.
Sensor
------

View File

@@ -31,7 +31,7 @@ With your serial program open (PuTTY, screen, picocom, etc) you may see a
blank screen with a flashing cursor. Press Enter (or reset the board) and
you should be presented with the following text::
*** Booting Zephyr OS build v4.0.0 ***
*** Booting Zephyr OS build v3.7.0 ***
MicroPython v1.24.0-preview.179.g5b85b24bd on 2024-08-05; zephyr-frdm_k64f with mk64f12
Type "help()" for more information.
>>>

View File

@@ -37,16 +37,14 @@ enum {
MP_QSPI_IOCTL_DEINIT,
MP_QSPI_IOCTL_BUS_ACQUIRE,
MP_QSPI_IOCTL_BUS_RELEASE,
MP_QSPI_IOCTL_MEMORY_MODIFIED,
};
typedef struct _mp_qspi_proto_t {
int (*ioctl)(void *self, uint32_t cmd, uintptr_t arg);
int (*ioctl)(void *self, uint32_t cmd);
int (*write_cmd_data)(void *self, uint8_t cmd, size_t len, uint32_t data);
int (*write_cmd_addr_data)(void *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src);
int (*read_cmd)(void *self, uint8_t cmd, size_t len, uint32_t *dest);
int (*read_cmd_qaddr_qdata)(void *self, uint8_t cmd, uint32_t addr, uint8_t num_dummy, size_t len, uint8_t *dest);
int (*direct_read)(void *self, uint32_t addr, size_t len, uint8_t *dest); // can be NULL if direct read not supported
int (*read_cmd_qaddr_qdata)(void *self, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest);
} mp_qspi_proto_t;
typedef struct _mp_soft_qspi_obj_t {

View File

@@ -56,9 +56,8 @@ static void nibble_write(mp_soft_qspi_obj_t *self, uint8_t v) {
mp_hal_pin_write(self->io3, (v >> 3) & 1);
}
static int mp_soft_qspi_ioctl(void *self_in, uint32_t cmd, uintptr_t arg) {
static int mp_soft_qspi_ioctl(void *self_in, uint32_t cmd) {
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
(void)arg;
switch (cmd) {
case MP_QSPI_IOCTL_INIT:
@@ -189,13 +188,13 @@ static int mp_soft_qspi_read_cmd(void *self_in, uint8_t cmd, size_t len, uint32_
return 0;
}
static int mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, uint8_t num_dummy, size_t len, uint8_t *dest) {
static int mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest) {
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
uint8_t cmd_buf[16] = {cmd};
uint8_t cmd_buf[7] = {cmd};
uint8_t addr_len = mp_spi_set_addr_buff(&cmd_buf[1], addr);
CS_LOW(self);
mp_soft_qspi_transfer(self, 1, cmd_buf, NULL);
mp_soft_qspi_qwrite(self, addr_len + 1 + num_dummy, &cmd_buf[1]); // 3/4 addr bytes, 1 extra byte (0), N dummy bytes (2*N dummy cycles)
mp_soft_qspi_qwrite(self, addr_len + 3, &cmd_buf[1]); // 3/4 addr bytes, 1 extra byte (0), 2 dummy bytes (4 dummy cycles)
mp_soft_qspi_qread(self, len, dest);
CS_HIGH(self);
return 0;

17
drivers/cyw43/README.md Normal file
View File

@@ -0,0 +1,17 @@
CYW43xx WiFi SoC driver
=======================
This is a driver for the CYW43xx WiFi SoC.
There are four layers to the driver:
1. SDIO bus interface, provided by the host device/system.
2. Low-level CYW43xx interface, managing the bus, control messages, Ethernet
frames and asynchronous events. Includes download of SoC firmware. The
header file `cyw43_ll.h` defines the interface to this layer.
3. Mid-level CYW43xx control, to control and set WiFi parameters and manage
events. See `cyw43_ctrl.c`.
4. TCP/IP bindings to lwIP. See `cyw43_lwip.c`.

304
drivers/cyw43/cywbt.c Normal file
View File

@@ -0,0 +1,304 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019-2020 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include "py/runtime.h"
#include "py/mphal.h"
#include "extmod/mpbthci.h"
#if MICROPY_PY_NETWORK_CYW43
#include "lib/cyw43-driver/src/cyw43_config.h"
#include "lib/cyw43-driver/firmware/cyw43_btfw_4343A1.h"
// Provided by the port, and also possibly shared with the stack.
extern uint8_t mp_bluetooth_hci_cmd_buf[4 + 256];
/******************************************************************************/
// CYW BT HCI low-level driver
#ifdef CYW43_PIN_BT_CTS
// This code is not portable and currently only builds on stm32 port.
#include "pin_static_af.h"
#include "uart.h"
// Provided by the port.
extern machine_uart_obj_t mp_bluetooth_hci_uart_obj;
static void cywbt_wait_cts_low(void) {
mp_hal_pin_config(CYW43_PIN_BT_CTS, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0);
for (int i = 0; i < 200; ++i) {
if (mp_hal_pin_read(CYW43_PIN_BT_CTS) == 0) {
break;
}
mp_hal_delay_ms(1);
}
mp_hal_pin_config_alt(CYW43_PIN_BT_CTS, MP_HAL_PIN_MODE_ALT,
MP_HAL_PIN_PULL_UP, AF_FN_UART, mp_bluetooth_hci_uart_obj.uart_id);
}
#endif
static int cywbt_hci_cmd_raw(size_t len, uint8_t *buf) {
mp_bluetooth_hci_uart_write((void *)buf, len);
for (int c, i = 0; i < 6; ++i) {
while ((c = mp_bluetooth_hci_uart_readchar()) == -1) {
mp_event_wait_indefinite();
}
buf[i] = c;
}
// expect a command complete event (event 0x0e)
if (buf[0] != 0x04 || buf[1] != 0x0e) {
printf("unknown response: %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
return -1;
}
/*
if buf[3:6] != cmd[:3]:
print('response doesn\'t match cmd:', cmd, ev)
return b''
*/
int sz = buf[2] - 3;
for (int c, i = 0; i < sz; ++i) {
while ((c = mp_bluetooth_hci_uart_readchar()) == -1) {
mp_event_wait_indefinite();
}
buf[i] = c;
}
return 0;
}
static int cywbt_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *param_buf) {
uint8_t *buf = mp_bluetooth_hci_cmd_buf;
buf[0] = 0x01;
buf[1] = ocf;
buf[2] = ogf << 2 | ocf >> 8;
buf[3] = param_len;
if (param_len) {
memcpy(buf + 4, param_buf, param_len);
}
return cywbt_hci_cmd_raw(4 + param_len, buf);
}
static void put_le16(uint8_t *buf, uint16_t val) {
buf[0] = val;
buf[1] = val >> 8;
}
static void put_le32(uint8_t *buf, uint32_t val) {
buf[0] = val;
buf[1] = val >> 8;
buf[2] = val >> 16;
buf[3] = val >> 24;
}
static int cywbt_set_baudrate(uint32_t baudrate) {
uint8_t buf[6];
put_le16(buf, 0);
put_le32(buf + 2, baudrate);
return cywbt_hci_cmd(0x3f, 0x18, 6, buf);
}
// download firmware
static int cywbt_download_firmware(const uint8_t *firmware) {
cywbt_hci_cmd(0x3f, 0x2e, 0, NULL);
bool last_packet = false;
while (!last_packet) {
uint8_t *buf = mp_bluetooth_hci_cmd_buf;
memcpy(buf + 1, firmware, 3);
firmware += 3;
last_packet = buf[1] == 0x4e;
if (buf[2] != 0xfc) {
printf("fail1 %02x\n", buf[2]);
break;
}
uint8_t len = buf[3];
memcpy(buf + 4, firmware, len);
firmware += len;
buf[0] = 1;
cywbt_hci_cmd_raw(4 + len, buf);
if (buf[0] != 0) {
printf("fail3 %02x\n", buf[0]);
break;
}
}
// RF switch must select high path during BT patch boot
#if MICROPY_HW_ENABLE_RF_SWITCH
mp_hal_pin_config(CYW43_PIN_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0);
#endif
mp_hal_delay_ms(10); // give some time for CTS to go high
#ifdef CYW43_PIN_BT_CTS
cywbt_wait_cts_low();
#endif
#if MICROPY_HW_ENABLE_RF_SWITCH
// Select chip antenna (could also select external)
mp_hal_pin_config(CYW43_PIN_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_DOWN, 0);
#endif
mp_bluetooth_hci_uart_set_baudrate(115200);
cywbt_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY);
mp_bluetooth_hci_uart_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY);
return 0;
}
int mp_bluetooth_hci_controller_init(void) {
// This is called immediately after the UART is initialised during stack initialisation.
mp_hal_pin_output(CYW43_PIN_BT_REG_ON);
mp_hal_pin_low(CYW43_PIN_BT_REG_ON);
#ifdef CYW43_PIN_BT_HOST_WAKE
mp_hal_pin_input(CYW43_PIN_BT_HOST_WAKE);
#endif
#ifdef CYW43_PIN_BT_DEV_WAKE
mp_hal_pin_output(CYW43_PIN_BT_DEV_WAKE);
mp_hal_pin_low(CYW43_PIN_BT_DEV_WAKE);
#endif
#if MICROPY_HW_ENABLE_RF_SWITCH
// TODO don't select antenna if wifi is enabled
mp_hal_pin_config(CYW43_PIN_WL_GPIO_4, MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0); // RF-switch power
mp_hal_pin_high(CYW43_PIN_WL_GPIO_4); // Turn the RF-switch on
#endif
uint8_t buf[256];
mp_hal_pin_low(CYW43_PIN_BT_REG_ON);
mp_bluetooth_hci_uart_set_baudrate(115200);
mp_hal_delay_ms(100);
mp_hal_pin_high(CYW43_PIN_BT_REG_ON);
#ifdef CYW43_PIN_BT_CTS
cywbt_wait_cts_low();
#else
mp_hal_delay_ms(100);
#endif
// Reset
cywbt_hci_cmd(0x03, 0x0003, 0, NULL);
#ifdef MICROPY_HW_BLE_UART_BAUDRATE_DOWNLOAD_FIRMWARE
// Change baudrate
cywbt_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_DOWNLOAD_FIRMWARE);
mp_bluetooth_hci_uart_set_baudrate(MICROPY_HW_BLE_UART_BAUDRATE_DOWNLOAD_FIRMWARE);
#endif
cywbt_download_firmware((const uint8_t *)&cyw43_btfw_4343A1[0]);
// Reset
cywbt_hci_cmd(0x03, 0x0003, 0, NULL);
// Set BD_ADDR (sent as little endian)
uint8_t bdaddr[6];
mp_hal_get_mac(MP_HAL_MAC_BDADDR, bdaddr);
buf[0] = bdaddr[5];
buf[1] = bdaddr[4];
buf[2] = bdaddr[3];
buf[3] = bdaddr[2];
buf[4] = bdaddr[1];
buf[5] = bdaddr[0];
cywbt_hci_cmd(0x3f, 0x0001, 6, buf);
// Set local name
// memset(buf, 0, 248);
// memcpy(buf, "PYBD-BLE", 8);
// cywbt_hci_cmd(0x03, 0x0013, 248, buf);
// Configure sleep mode
cywbt_hci_cmd(0x3f, 0x27, 12, (const uint8_t *)"\x01\x02\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00");
// HCI_Write_LE_Host_Support
cywbt_hci_cmd(3, 109, 2, (const uint8_t *)"\x01\x00");
#ifdef CYW43_PIN_BT_DEV_WAKE
mp_hal_pin_high(CYW43_PIN_BT_DEV_WAKE); // let sleep
#endif
return 0;
}
int mp_bluetooth_hci_controller_deinit(void) {
mp_hal_pin_low(CYW43_PIN_BT_REG_ON);
return 0;
}
#ifdef CYW43_PIN_BT_DEV_WAKE
static uint32_t bt_sleep_ticks;
#endif
int mp_bluetooth_hci_controller_sleep_maybe(void) {
#ifdef CYW43_PIN_BT_DEV_WAKE
if (mp_hal_pin_read(CYW43_PIN_BT_DEV_WAKE) == 0) {
if (mp_hal_ticks_ms() - bt_sleep_ticks > 500) {
mp_hal_pin_high(CYW43_PIN_BT_DEV_WAKE); // let sleep
}
}
#endif
return 0;
}
bool mp_bluetooth_hci_controller_woken(void) {
#ifdef CYW43_PIN_BT_HOST_WAKE
bool host_wake = mp_hal_pin_read(CYW43_PIN_BT_HOST_WAKE);
/*
// this is just for info/tracing purposes
static bool last_host_wake = false;
if (host_wake != last_host_wake) {
printf("HOST_WAKE change %d -> %d\n", last_host_wake, host_wake);
last_host_wake = host_wake;
}
*/
return host_wake;
#else
return true;
#endif
}
int mp_bluetooth_hci_controller_wakeup(void) {
#ifdef CYW43_PIN_BT_DEV_WAKE
bt_sleep_ticks = mp_hal_ticks_ms();
if (mp_hal_pin_read(CYW43_PIN_BT_DEV_WAKE) == 1) {
mp_hal_pin_low(CYW43_PIN_BT_DEV_WAKE); // wake up
// Use delay_us rather than delay_ms to prevent running the scheduler (which
// might result in more BLE operations).
mp_hal_delay_us(5000); // can't go lower than this
}
#endif
return 0;
}
#endif

View File

@@ -72,7 +72,7 @@ int esp_hosted_hci_cmd(int ogf, int ocf, size_t param_len, const uint8_t *param_
// Receive HCI event packet, initially reading 3 bytes (HCI Event, Event code, Plen).
for (mp_uint_t start = mp_hal_ticks_ms(), size = 3, i = 0; i < size;) {
while (!mp_bluetooth_hci_uart_any()) {
mp_event_wait_ms(1);
MICROPY_EVENT_POLL_HOOK
// Timeout.
if ((mp_hal_ticks_ms() - start) > HCI_COMMAND_TIMEOUT) {
error_printf("timeout waiting for HCI packet\n");
@@ -126,7 +126,7 @@ int mp_bluetooth_hci_controller_init(void) {
if (mp_bluetooth_hci_uart_any()) {
mp_bluetooth_hci_uart_readchar();
}
mp_event_wait_ms(1);
MICROPY_EVENT_POLL_HOOK
}
#ifdef MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY

Some files were not shown because too many files have changed in this diff Show More