rp2040py 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. rp2040py-0.1.0/.github/actions/setup-rp2040py/action.yml +36 -0
  2. rp2040py-0.1.0/.github/dependabot.yml +39 -0
  3. rp2040py-0.1.0/.github/workflows/ci-kaluma.yml +120 -0
  4. rp2040py-0.1.0/.github/workflows/ci-micropython.yml +117 -0
  5. rp2040py-0.1.0/.github/workflows/ci-pico-sdk.yml +84 -0
  6. rp2040py-0.1.0/.github/workflows/pre-commit.yml +48 -0
  7. rp2040py-0.1.0/.github/workflows/publish.yml +76 -0
  8. rp2040py-0.1.0/.gitignore +98 -0
  9. rp2040py-0.1.0/.pre-commit-config.yaml +48 -0
  10. rp2040py-0.1.0/.python-version +1 -0
  11. rp2040py-0.1.0/.yarn/install-state.gz +0 -0
  12. rp2040py-0.1.0/CHANGELOG.md +369 -0
  13. rp2040py-0.1.0/LICENSE +22 -0
  14. rp2040py-0.1.0/PKG-INFO +441 -0
  15. rp2040py-0.1.0/README.md +389 -0
  16. rp2040py-0.1.0/demo/benchmark.py +31 -0
  17. rp2040py-0.1.0/demo/emulator_run.py +15 -0
  18. rp2040py-0.1.0/demo/kaluma_run.py +18 -0
  19. rp2040py-0.1.0/demo/micropython_run.py +16 -0
  20. rp2040py-0.1.0/docs/BACKLOG.md +554 -0
  21. rp2040py-0.1.0/docs/PORTING.md +601 -0
  22. rp2040py-0.1.0/package.json +8 -0
  23. rp2040py-0.1.0/pyproject.toml +80 -0
  24. rp2040py-0.1.0/src/rp2040py/__init__.py +74 -0
  25. rp2040py-0.1.0/src/rp2040py/__main__.py +4 -0
  26. rp2040py-0.1.0/src/rp2040py/cli/__init__.py +602 -0
  27. rp2040py-0.1.0/src/rp2040py/cli/firmware_retrieve.py +140 -0
  28. rp2040py-0.1.0/src/rp2040py/cli/firmware_specs.json +32 -0
  29. rp2040py-0.1.0/src/rp2040py/cli/intelhex.py +30 -0
  30. rp2040py-0.1.0/src/rp2040py/cli/mklittlefs.py +100 -0
  31. rp2040py-0.1.0/src/rp2040py/cli/stdio_repl.py +142 -0
  32. rp2040py-0.1.0/src/rp2040py/clock/__init__.py +0 -0
  33. rp2040py-0.1.0/src/rp2040py/clock/clock.py +22 -0
  34. rp2040py-0.1.0/src/rp2040py/clock/mock_clock.py +8 -0
  35. rp2040py-0.1.0/src/rp2040py/clock/simulation_clock.py +96 -0
  36. rp2040py-0.1.0/src/rp2040py/cortex_m0_core.py +1523 -0
  37. rp2040py-0.1.0/src/rp2040py/device/__init__.py +3 -0
  38. rp2040py-0.1.0/src/rp2040py/device/base_device.py +66 -0
  39. rp2040py-0.1.0/src/rp2040py/device/bootrom.py +4105 -0
  40. rp2040py-0.1.0/src/rp2040py/device/kaluma_device.py +35 -0
  41. rp2040py-0.1.0/src/rp2040py/device/load_flash.py +121 -0
  42. rp2040py-0.1.0/src/rp2040py/device/mp_device.py +222 -0
  43. rp2040py-0.1.0/src/rp2040py/device/raw_repl.py +100 -0
  44. rp2040py-0.1.0/src/rp2040py/device/repl_runner.py +116 -0
  45. rp2040py-0.1.0/src/rp2040py/gdb/__init__.py +0 -0
  46. rp2040py-0.1.0/src/rp2040py/gdb/gdb_connection.py +56 -0
  47. rp2040py-0.1.0/src/rp2040py/gdb/gdb_server.py +254 -0
  48. rp2040py-0.1.0/src/rp2040py/gdb/gdb_target.py +17 -0
  49. rp2040py-0.1.0/src/rp2040py/gdb/gdb_tcp_server.py +50 -0
  50. rp2040py-0.1.0/src/rp2040py/gdb/gdb_utils.py +53 -0
  51. rp2040py-0.1.0/src/rp2040py/gpio_pin.py +309 -0
  52. rp2040py-0.1.0/src/rp2040py/interpolator.py +161 -0
  53. rp2040py-0.1.0/src/rp2040py/irq.py +38 -0
  54. rp2040py-0.1.0/src/rp2040py/memory_map.py +22 -0
  55. rp2040py-0.1.0/src/rp2040py/peripherals/__init__.py +0 -0
  56. rp2040py-0.1.0/src/rp2040py/peripherals/adc.py +284 -0
  57. rp2040py-0.1.0/src/rp2040py/peripherals/busctrl.py +80 -0
  58. rp2040py-0.1.0/src/rp2040py/peripherals/clocks.py +179 -0
  59. rp2040py-0.1.0/src/rp2040py/peripherals/dma.py +466 -0
  60. rp2040py-0.1.0/src/rp2040py/peripherals/i2c.py +495 -0
  61. rp2040py-0.1.0/src/rp2040py/peripherals/io.py +84 -0
  62. rp2040py-0.1.0/src/rp2040py/peripherals/pads.py +57 -0
  63. rp2040py-0.1.0/src/rp2040py/peripherals/peripheral.py +72 -0
  64. rp2040py-0.1.0/src/rp2040py/peripherals/pio.py +1049 -0
  65. rp2040py-0.1.0/src/rp2040py/peripherals/ppb.py +244 -0
  66. rp2040py-0.1.0/src/rp2040py/peripherals/psm.py +45 -0
  67. rp2040py-0.1.0/src/rp2040py/peripherals/pwm.py +348 -0
  68. rp2040py-0.1.0/src/rp2040py/peripherals/reset.py +37 -0
  69. rp2040py-0.1.0/src/rp2040py/peripherals/rtc.py +122 -0
  70. rp2040py-0.1.0/src/rp2040py/peripherals/spi.py +249 -0
  71. rp2040py-0.1.0/src/rp2040py/peripherals/ssi.py +276 -0
  72. rp2040py-0.1.0/src/rp2040py/peripherals/syscfg.py +19 -0
  73. rp2040py-0.1.0/src/rp2040py/peripherals/sysinfo.py +19 -0
  74. rp2040py-0.1.0/src/rp2040py/peripherals/tbman.py +13 -0
  75. rp2040py-0.1.0/src/rp2040py/peripherals/timer.py +165 -0
  76. rp2040py-0.1.0/src/rp2040py/peripherals/uart.py +206 -0
  77. rp2040py-0.1.0/src/rp2040py/peripherals/usb.py +864 -0
  78. rp2040py-0.1.0/src/rp2040py/peripherals/watchdog.py +133 -0
  79. rp2040py-0.1.0/src/rp2040py/peripherals/xosc.py +120 -0
  80. rp2040py-0.1.0/src/rp2040py/py.typed +0 -0
  81. rp2040py-0.1.0/src/rp2040py/rp2040.py +348 -0
  82. rp2040py-0.1.0/src/rp2040py/simulator.py +59 -0
  83. rp2040py-0.1.0/src/rp2040py/sio.py +385 -0
  84. rp2040py-0.1.0/src/rp2040py/usb/__init__.py +0 -0
  85. rp2040py-0.1.0/src/rp2040py/usb/cdc.py +149 -0
  86. rp2040py-0.1.0/src/rp2040py/usb/interfaces.py +65 -0
  87. rp2040py-0.1.0/src/rp2040py/usb/setup.py +70 -0
  88. rp2040py-0.1.0/src/rp2040py/usb/usb_device.py +153 -0
  89. rp2040py-0.1.0/src/rp2040py/utils/__init__.py +0 -0
  90. rp2040py-0.1.0/src/rp2040py/utils/assembler.py +322 -0
  91. rp2040py-0.1.0/src/rp2040py/utils/bit.py +43 -0
  92. rp2040py-0.1.0/src/rp2040py/utils/fifo.py +49 -0
  93. rp2040py-0.1.0/src/rp2040py/utils/logging.py +50 -0
  94. rp2040py-0.1.0/src/rp2040py/utils/pio_assembler.py +77 -0
  95. rp2040py-0.1.0/src/rp2040py/utils/time.py +26 -0
  96. rp2040py-0.1.0/src/rp2040py/utils/timer32.py +222 -0
  97. rp2040py-0.1.0/tests/kaluma/index-flash-rw.js +44 -0
  98. rp2040py-0.1.0/tests/kaluma/index.js +1 -0
  99. rp2040py-0.1.0/tests/micropython/main-flash-rw.py +20 -0
  100. rp2040py-0.1.0/tests/micropython/main-spi.py +18 -0
  101. rp2040py-0.1.0/tests/micropython/main.py +9 -0
  102. rp2040py-0.1.0/tests/micropython_spi_run.py +100 -0
  103. rp2040py-0.1.0/tests/test_assembler.py +412 -0
  104. rp2040py-0.1.0/tests/test_cdc.py +96 -0
  105. rp2040py-0.1.0/tests/test_cli.py +444 -0
  106. rp2040py-0.1.0/tests/test_cli_bootrom.py +108 -0
  107. rp2040py-0.1.0/tests/test_cli_intelhex.py +69 -0
  108. rp2040py-0.1.0/tests/test_cli_mklittlefs.py +181 -0
  109. rp2040py-0.1.0/tests/test_device.py +177 -0
  110. rp2040py-0.1.0/tests/test_dispatch_table.py +34 -0
  111. rp2040py-0.1.0/tests/test_dma.py +107 -0
  112. rp2040py-0.1.0/tests/test_fifo.py +45 -0
  113. rp2040py-0.1.0/tests/test_firmware_retrieve.py +242 -0
  114. rp2040py-0.1.0/tests/test_gpio_pin.py +68 -0
  115. rp2040py-0.1.0/tests/test_instructions.py +1531 -0
  116. rp2040py-0.1.0/tests/test_kaluma_device.py +128 -0
  117. rp2040py-0.1.0/tests/test_pio.py +591 -0
  118. rp2040py-0.1.0/tests/test_pio_assembler.py +54 -0
  119. rp2040py-0.1.0/tests/test_raw_repl.py +171 -0
  120. rp2040py-0.1.0/tests/test_repl_runner.py +103 -0
  121. rp2040py-0.1.0/tests/test_rp2040.py +188 -0
  122. rp2040py-0.1.0/tests/test_simulator.py +74 -0
  123. rp2040py-0.1.0/tests/test_sio.py +120 -0
  124. rp2040py-0.1.0/tests/test_ssi.py +266 -0
  125. rp2040py-0.1.0/tests/test_time.py +7 -0
  126. rp2040py-0.1.0/tests/test_timer.py +60 -0
  127. rp2040py-0.1.0/tests/test_uart.py +21 -0
  128. rp2040py-0.1.0/tests/utils/__init__.py +0 -0
  129. rp2040py-0.1.0/tests/utils/cortex_test_driver.py +53 -0
  130. rp2040py-0.1.0/tests/utils/create_test_driver.py +11 -0
  131. rp2040py-0.1.0/tests/utils/rp2040_test_driver.py +130 -0
  132. rp2040py-0.1.0/uv.lock +770 -0
@@ -0,0 +1,36 @@
1
+ name: Setup rp2040py
2
+ description: >
3
+ Installs rp2040py emulator globally as a standalone tool.
4
+ After this action, you can use rp2040py command directly
5
+ in subsequent steps.
6
+
7
+ inputs:
8
+ version:
9
+ description: >
10
+ rp2040py release version to install from PyPI (e.g. "0.1.0b2"), passed as
11
+ `rp2040py[fs]==<version>`. If empty, installs the latest published release.
12
+ required: false
13
+ default: ""
14
+ python_version:
15
+ description: >
16
+ Python interpreter to install rp2040py's tool environment under (e.g. "pypy-3.10",
17
+ "cpython-3.12"). Defaults to PyPy for its large real-firmware-boot speedup - see
18
+ docs/PORTING.md#known-differences-from-rp2040js.
19
+ required: false
20
+ default: "pypy-3.10"
21
+
22
+ runs:
23
+ using: composite
24
+ steps:
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
27
+
28
+ - name: Install rp2040py and verify
29
+ shell: bash
30
+ run: |
31
+ if [ -z "${{ inputs.version }}" ]; then
32
+ uv tool install --python "${{ inputs.python_version }}" rp2040py[fs]
33
+ else
34
+ uv tool install --python "${{ inputs.python_version }}" rp2040py[fs]==${{ inputs.version }}
35
+ fi
36
+ rp2040py --version
@@ -0,0 +1,39 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5
+
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: "uv" # See documentation for possible values
9
+ directory: "/" # Location of package manifests
10
+ schedule:
11
+ interval: "weekly"
12
+ groups:
13
+ python-dependencies:
14
+ patterns:
15
+ - "*"
16
+
17
+ - package-ecosystem: "github-actions"
18
+ directory: "/"
19
+ schedule:
20
+ interval: "weekly"
21
+ groups:
22
+ actions:
23
+ patterns:
24
+ - "*"
25
+
26
+ - package-ecosystem: "pre-commit"
27
+ directory: "/"
28
+ schedule:
29
+ interval: "weekly"
30
+
31
+ # rp2040js-dependabot-tracker
32
+ - package-ecosystem: "npm"
33
+ directory: "/"
34
+ schedule:
35
+ interval: "weekly"
36
+ groups:
37
+ dependencies:
38
+ patterns:
39
+ - "*"
@@ -0,0 +1,120 @@
1
+ name: Test Kaluma Releases
2
+
3
+ on:
4
+ push:
5
+ paths-ignore: &non-code-paths
6
+ - "**.md"
7
+ - "docs/**"
8
+ - "LICENSE"
9
+ pull_request:
10
+ branches: [main]
11
+ paths-ignore: *non-code-paths
12
+
13
+ concurrency:
14
+ group: ci-kaluma-${{ github.workflow }}-${{ github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ # This image doesn't depend on kaluma_version or python_runtime (always the same freshly
19
+ # formatted, empty image) - built once here and shared via artifact instead of rebuilt
20
+ # redundantly in every matrix job below.
21
+ build-littlefs:
22
+ name: Build littlefs test image
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v7
26
+
27
+ - name: Install uv
28
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
29
+ with:
30
+ python-version: "3.10"
31
+
32
+ - name: Install dependencies
33
+ run: uv sync
34
+
35
+ # Kaluma's littlefs filesystem has no auto-run semantics of its own (unlike MicroPython's
36
+ # main.py) - it's plain storage the staged script below writes into at runtime, so this just
37
+ # needs a freshly formatted, empty image sized to Kaluma's own board.js block layout.
38
+ - name: Create flash read/write test filesystem
39
+ run: uv run rp2040py mklittlefs --target kaluma -o kaluma-littlefs-flash-rw.img
40
+
41
+ - name: Upload littlefs image
42
+ uses: actions/upload-artifact@v7
43
+ with:
44
+ name: kaluma-littlefs-image
45
+ path: kaluma-littlefs-flash-rw.img
46
+ retention-days: 1
47
+
48
+ test-kaluma:
49
+ needs: build-littlefs
50
+ name: Kaluma ${{ matrix.kaluma_version }} / ${{ matrix.python_runtime }}
51
+ runs-on: ubuntu-latest
52
+ strategy:
53
+ fail-fast: false
54
+ matrix:
55
+ # Only the one version manually verified end-to-end (see demo/kaluma_run.py's docstring).
56
+ # 1.0.0/1.1.0/1.2.0 also ship a plain (non-`-w`) RP2040 `pico` build and could be added,
57
+ # but their exact boot-banner wording (matched below via --expect-text) wasn't checked
58
+ # against this older firmware, unlike 1.2.1 - 1.3.0+ dropped the plain `pico` build
59
+ # entirely (see rp2040py.cli.firmware_specs.json's "kaluma" entry).
60
+ kaluma_version:
61
+ - "1.2.1"
62
+ python_runtime:
63
+ - pypy-3.10
64
+ - cpython-3.10
65
+ - cpython-3.14
66
+
67
+ steps:
68
+ - uses: actions/checkout@v7
69
+
70
+ - name: Install uv
71
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
72
+ with:
73
+ python-version: "3.10"
74
+
75
+ - name: Install dependencies
76
+ run: uv sync
77
+
78
+ - name: Download littlefs image
79
+ uses: actions/download-artifact@v8
80
+ with:
81
+ name: kaluma-littlefs-image
82
+
83
+ - name: Setup Python ${{ matrix.python_runtime }}
84
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
85
+ with:
86
+ python-version: ${{ matrix.python_runtime }}
87
+
88
+ # Downloads (and caches) this version's UF2 outside the timed test steps below, so a slow
89
+ # kaluma-project/kaluma GitHub-release fetch doesn't get counted as (or blow the budget of)
90
+ # actual boot/run time. Stages tests/kaluma/index.js (same as the real test step below) and
91
+ # matches its own console.log() output rather than Kaluma's boot banner - the banner is racy
92
+ # (see the Kaluma test step's comment below), a staged script's own output isn't.
93
+ # continue-on-error: a hiccup here shouldn't fail the job on its own - the real test step
94
+ # right after will fail with a clearer signal if genuinely broken.
95
+ - name: Warm up Kaluma ${{ matrix.kaluma_version }} download cache
96
+ continue-on-error: true
97
+ run: timeout 1m uv run --python ${{ matrix.python_runtime }} --no-dev -- rp2040py kaluma --image ${{ matrix.kaluma_version }} tests/kaluma/index.js --expect-text "Hello, Kaluma!"
98
+
99
+ # Real code-execution test: stages tests/kaluma/index.js into Kaluma's "user program" flash
100
+ # region (same one `kaluma flash index.js` writes to on real hardware), which Kaluma
101
+ # auto-executes on every boot. This needed the GPIO pull-up/pull-down resolution fix in
102
+ # gpio_pin.py to actually work (km_running_script_check() in Kaluma's system.c reads GP22
103
+ # with a pull-up enabled to decide whether to skip auto-run - an undriven pin used to always
104
+ # read low regardless of the pull, which looked identical to GP22 being pulled to GND, i.e.
105
+ # "skip loading"). No mklittlefs step needed - the program stages directly from the file.
106
+ - name: Test Kaluma ${{matrix.python_runtime}}-${{ matrix.kaluma_version }}
107
+ run: timeout 10m uv run --python ${{ matrix.python_runtime }} --no-dev -- rp2040py kaluma --image ${{ matrix.kaluma_version }} tests/kaluma/index.js --expect-text "Hello, Kaluma!"
108
+ env:
109
+ PYTHON_JIT: ${{ matrix.python_runtime == 'cpython-3.14' && '1' || '' }}
110
+
111
+ # Exercises the SSI flash-write path (see docs/BACKLOG.md) from Kaluma's side: mounts a
112
+ # littlefs image sized to Kaluma's own board.js layout (--target kaluma - a different
113
+ # block-size/count than MicroPython's), stages tests/kaluma/index-flash-rw.js as the
114
+ # auto-run user program (a separate flash region from the littlefs filesystem itself - see
115
+ # README's Kaluma section), and matches its own printed result rather than the racy
116
+ # boot-time "Welcome to Kaluma" banner.
117
+ - name: Test Kaluma flash read/write ${{matrix.python_runtime}}-${{ matrix.kaluma_version }}
118
+ run: timeout 10m uv run --python ${{ matrix.python_runtime }} --no-dev -- rp2040py kaluma --image ${{ matrix.kaluma_version }} --littlefs kaluma-littlefs-flash-rw.img tests/kaluma/index-flash-rw.js --expect-text "FLASH RW OK"
119
+ env:
120
+ PYTHON_JIT: ${{ matrix.python_runtime == 'cpython-3.14' && '1' || '' }}
@@ -0,0 +1,117 @@
1
+ name: Test MicroPython Releases
2
+
3
+ on:
4
+ push:
5
+ paths-ignore: &non-code-paths
6
+ - "**.md"
7
+ - "docs/**"
8
+ - "LICENSE"
9
+ pull_request:
10
+ branches: [main]
11
+ paths-ignore: *non-code-paths
12
+
13
+ concurrency:
14
+ group: ci-micropython-${{ github.workflow }}-${{ github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ # The three littlefs images below don't depend on micropython_version or python_runtime at all
19
+ # (same source .py files every time) - built once here and shared via artifact instead of
20
+ # rebuilt redundantly in all 24 matrix jobs below.
21
+ build-littlefs:
22
+ name: Build littlefs test images
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v7
26
+
27
+ - name: Install uv
28
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
29
+ with:
30
+ python-version: "3.10"
31
+
32
+ - name: Install dependencies
33
+ run: uv sync
34
+
35
+ - name: Create filesystem
36
+ run: uv run rp2040py mklittlefs -o littlefs.img tests/micropython/main.py --main main.py
37
+
38
+ - name: Create SPI test filesystem
39
+ run: uv run rp2040py mklittlefs -o littlefs-spi.img tests/micropython/main-spi.py --main main-spi.py
40
+
41
+ - name: Create flash read/write test filesystem
42
+ run: uv run rp2040py mklittlefs -o littlefs-flash-rw.img tests/micropython/main-flash-rw.py --main main-flash-rw.py
43
+
44
+ - name: Upload littlefs images
45
+ uses: actions/upload-artifact@v7
46
+ with:
47
+ name: littlefs-images
48
+ path: |
49
+ littlefs.img
50
+ littlefs-spi.img
51
+ littlefs-flash-rw.img
52
+ retention-days: 1
53
+
54
+ test-micropython:
55
+ needs: build-littlefs
56
+ name: Micropython ${{ matrix.micropython_version }} / ${{ matrix.python_runtime }}
57
+ runs-on: ubuntu-latest
58
+ strategy:
59
+ fail-fast: false
60
+ matrix:
61
+ micropython_version:
62
+ - "1.16"
63
+ - "1.17"
64
+ - "1.18"
65
+ - "1.19.1"
66
+ - "1.20.0"
67
+ - "1.21.0"
68
+ - "1.28.0"
69
+ - "1.29.0-preview"
70
+ python_runtime:
71
+ - pypy-3.10
72
+ - cpython-3.10
73
+ - cpython-3.14
74
+
75
+ steps:
76
+ - uses: actions/checkout@v7
77
+
78
+ - name: Install uv
79
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
80
+ with:
81
+ python-version: "3.10"
82
+
83
+ - name: Install dependencies
84
+ run: uv sync
85
+
86
+ - name: Download littlefs images
87
+ uses: actions/download-artifact@v8
88
+ with:
89
+ name: littlefs-images
90
+
91
+ - name: Setup Python ${{ matrix.python_runtime }}
92
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
93
+ with:
94
+ python-version: ${{ matrix.python_runtime }}
95
+
96
+ # Downloads (and caches) this version's UF2 outside the timed test steps below, so a slow
97
+ # micropython.org fetch doesn't get counted as (or blow the budget of) actual boot/run time.
98
+ # continue-on-error: a hiccup here shouldn't fail the job on its own - the real test step
99
+ # right after will fail with a clearer signal if the download is genuinely broken.
100
+ - name: Warm up MicroPython ${{ matrix.micropython_version }} download cache
101
+ continue-on-error: true
102
+ run: timeout 1m uv run --python ${{ matrix.python_runtime }} --no-dev -- rp2040py micropython --image ${{ matrix.micropython_version }} -c "import sys; sys.implementation"
103
+
104
+ - name: Test MicroPython ${{matrix.python_runtime}}-${{ matrix.micropython_version }}
105
+ run: timeout 10m uv run --python ${{ matrix.python_runtime }} --no-dev -- rp2040py micropython --image ${{ matrix.micropython_version }} --expect-text "Hello, MicroPython!"
106
+ env:
107
+ PYTHON_JIT: ${{ matrix.python_runtime == 'cpython-3.14' && '1' || '' }}
108
+
109
+ - name: Test MicroPython SPI ${{matrix.python_runtime}}-${{ matrix.micropython_version }}
110
+ run: timeout 10m uv run --python ${{ matrix.python_runtime }} --no-dev -- python tests/micropython_spi_run.py --image ${{ matrix.micropython_version }} "hello world" "h" "0123456789abcdef0123456789abcdef0123456789abcdef"
111
+ env:
112
+ PYTHON_JIT: ${{ matrix.python_runtime == 'cpython-3.14' && '1' || '' }}
113
+
114
+ - name: Test MicroPython flash read/write ${{matrix.python_runtime}}-${{ matrix.micropython_version }}
115
+ run: timeout 10m uv run --python ${{ matrix.python_runtime }} --no-dev -- rp2040py micropython --image ${{ matrix.micropython_version }} --littlefs littlefs-flash-rw.img --expect-text "FLASH RW OK"
116
+ env:
117
+ PYTHON_JIT: ${{ matrix.python_runtime == 'cpython-3.14' && '1' || '' }}
@@ -0,0 +1,84 @@
1
+ name: Test Pi Pico SDK
2
+
3
+ on:
4
+ push:
5
+ paths-ignore: &non-code-paths
6
+ - "**.md"
7
+ - "docs/**"
8
+ - "LICENSE"
9
+ pull_request:
10
+ branches: [main]
11
+ paths-ignore: *non-code-paths
12
+
13
+ concurrency:
14
+ group: ci-pico-sdk-${{ github.workflow }}-${{ github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ test-pico-sdk:
19
+ name: Pico SDK ${{ matrix.sdk_version }} / ${{ matrix.python_runtime }}
20
+ runs-on: ubuntu-latest
21
+ strategy:
22
+ fail-fast: false
23
+ matrix:
24
+ sdk_version:
25
+ - 1.2.0
26
+ - 1.3.1
27
+ - 1.4.0
28
+ - 1.5.1
29
+ - 2.0.0
30
+ - 2.1.1
31
+ - 2.2.0
32
+ - 2.3.0
33
+ python_runtime:
34
+ - pypy-3.10
35
+ - cpython-3.10
36
+ - cpython-3.14
37
+ steps:
38
+ - uses: actions/checkout@v7
39
+
40
+ - name: Cache Pico SDK
41
+ id: cache-pico-sdk
42
+ uses: actions/cache@v6
43
+ with:
44
+ path: ~/pico
45
+ key: ${{ runner.os }}-pico-sdk-${{ matrix.sdk_version }}
46
+
47
+ - name: Set up the toolchain
48
+ if: steps.cache-pico-sdk.outputs.cache-hit != 'true'
49
+ run: |
50
+ sudo apt-get update
51
+ sudo apt-get install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
52
+
53
+ - name: Set up the Pi Pico SDK and examples
54
+ if: steps.cache-pico-sdk.outputs.cache-hit != 'true'
55
+ run: |
56
+ mkdir ~/pico
57
+ cd ~/pico
58
+ git clone https://github.com/raspberrypi/pico-sdk.git --depth 1 --branch ${SDK_VERSION}
59
+ cd pico-sdk && git submodule update --init && cd ..
60
+ git clone https://github.com/raspberrypi/pico-examples.git --depth 1 --branch "sdk-${SDK_VERSION}"
61
+ cd pico-examples && mkdir build && cd build && cmake .. && make -C hello_world/usb -j4
62
+ env:
63
+ SDK_VERSION: ${{ matrix.sdk_version }}
64
+ PICO_SDK_PATH: ~/pico/pico-sdk
65
+
66
+ - name: Install uv
67
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
68
+ with:
69
+ python-version: "3.10"
70
+
71
+ - name: Setup Python ${{ matrix.python_runtime }}
72
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
73
+ with:
74
+ python-version: ${{ matrix.python_runtime }}
75
+
76
+ # CortexM0Core.execute_instruction() is a pure-Python instruction interpreter; CPython is
77
+ # much slower here than V8 JIT-compiling the equivalent JS in rp2040js, hence the generous
78
+ # 10-minute timeout - and why this also runs under PyPy and CPython 3.14's experimental JIT
79
+ # (see docs/PORTING.md#known-differences-from-rp2040js). demo/micropython_run.py has zero
80
+ # runtime dependencies, so no `uv sync` is needed here.
81
+ - name: Test "Hello World" example ${{ matrix.python_runtime }}
82
+ run: timeout 10m uv run --python ${{ matrix.python_runtime }} --no-dev -- python demo/micropython_run.py --image ~/pico/pico-examples/build/hello_world/usb/hello_usb.uf2 --expect-text "Hello, world!"
83
+ env:
84
+ PYTHON_JIT: ${{ matrix.python_runtime == 'cpython-3.14' && '1' || '' }}
@@ -0,0 +1,48 @@
1
+ name: Pre-commit
2
+
3
+ on:
4
+ push:
5
+ paths-ignore: &non-code-paths
6
+ - "**.md"
7
+ - "docs/**"
8
+ - "LICENSE"
9
+ pull_request:
10
+ paths-ignore: *non-code-paths
11
+ workflow_dispatch:
12
+ workflow_call:
13
+
14
+ concurrency:
15
+ group: pre-commit-${{ github.workflow }}-${{ github.ref }}
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ pre-commit:
20
+ name: pre-commit run --all-files
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v7
24
+ with:
25
+ fetch-depth: 0
26
+
27
+ - name: Install uv
28
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
29
+ with:
30
+ python-version: "3.10"
31
+
32
+ - name: Install pre-commit
33
+ run: uv tool install pre-commit
34
+
35
+ - name: Run pre-commit
36
+ run: |
37
+ pre-commit run --all-files --show-diff-on-failure
38
+
39
+ - name: Run tests with coverage
40
+ run: uv run --group dev pytest --cov=rp2040py --cov-report=xml
41
+
42
+ - name: Upload coverage to Codecov
43
+ if: github.actor != 'dependabot[bot]'
44
+ uses: codecov/codecov-action@v7
45
+ with:
46
+ token: ${{ secrets.CODECOV_TOKEN }}
47
+ files: ./coverage.xml
48
+ fail_ci_if_error: false
@@ -0,0 +1,76 @@
1
+ name: Upload Python Package
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+ workflow_dispatch:
8
+ inputs:
9
+ tag:
10
+ description: "Tag to build and publish (e.g. v0.11.0b1)"
11
+ required: true
12
+ type: string
13
+
14
+ permissions:
15
+ contents: write
16
+
17
+ jobs:
18
+ deploy:
19
+ runs-on: ubuntu-latest
20
+
21
+ # Specifying a GitHub environment is optional, but strongly encouraged
22
+ environment: pypi
23
+ permissions:
24
+ # job-level permissions replace (not merge with) the workflow-level block above,
25
+ # so everything this job needs must be listed here explicitly.
26
+ contents: write # required to create the GitHub Release
27
+ # IMPORTANT: this permission is mandatory for trusted publishing
28
+ id-token: write
29
+
30
+ steps:
31
+ - uses: actions/checkout@v7
32
+ with:
33
+ ref: ${{ inputs.tag || github.ref_name }}
34
+
35
+ - name: Install uv
36
+ uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
37
+
38
+ - name: Build package
39
+ run: uv build
40
+
41
+ - name: Resolve tag and version
42
+ id: meta
43
+ run: |
44
+ TAG="${{ inputs.tag || github.ref_name }}"
45
+ VERSION="${TAG#v}"
46
+ if [[ "$VERSION" =~ (alpha|beta|pre|rc) ]]; then
47
+ PRERELEASE=true
48
+ else
49
+ PRERELEASE=false
50
+ fi
51
+ echo "tag=$TAG" >> $GITHUB_OUTPUT
52
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
53
+ echo "prerelease=$PRERELEASE" >> $GITHUB_OUTPUT
54
+
55
+ - name: Extract changelog section
56
+ id: changelog
57
+ run: |
58
+ VERSION=${{ steps.meta.outputs.version }}
59
+ BODY=$(awk "/^## \[${VERSION}\]/{found=1; next} /^## \[/{found=0} found" CHANGELOG.md | sed '/^[[:space:]]*$/d' | head -50)
60
+ if [ -z "$BODY" ]; then
61
+ BODY="See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details."
62
+ fi
63
+ echo "body<<EOF" >> $GITHUB_OUTPUT
64
+ echo "$BODY" >> $GITHUB_OUTPUT
65
+ echo "EOF" >> $GITHUB_OUTPUT
66
+
67
+ - name: Create GitHub Release
68
+ uses: softprops/action-gh-release@v3
69
+ with:
70
+ tag_name: ${{ steps.meta.outputs.tag }}
71
+ name: ${{ steps.meta.outputs.tag }}
72
+ body: ${{ steps.changelog.outputs.body }}
73
+ prerelease: ${{ steps.meta.outputs.prerelease }}
74
+
75
+ - name: Publish package to PyPI
76
+ run: uv publish --check-url https://pypi.org/simple/
@@ -0,0 +1,98 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # PyInstaller
28
+ *.manifest
29
+ *.spec
30
+
31
+ # Installer logs
32
+ pip-log.txt
33
+ pip-delete-this-directory.txt
34
+
35
+ # Unit test / coverage reports
36
+ htmlcov/
37
+ .tox/
38
+ .nox/
39
+ .coverage
40
+ .coverage.*
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+ *.cover
45
+ *.py,cover
46
+ .hypothesis/
47
+ .pytest_cache/
48
+
49
+ # Translations
50
+ *.mo
51
+ *.pot
52
+
53
+ # Environments
54
+ .env
55
+ .venv
56
+ env/
57
+ venv/
58
+ ENV/
59
+ env.bak/
60
+ venv.bak/
61
+
62
+ # IDEs
63
+ .idea/
64
+ .vscode/
65
+ *.swp
66
+ *.swo
67
+ *~
68
+
69
+ # mypy
70
+ .mypy_cache/
71
+ .dmypy.json
72
+ dmypy.json
73
+
74
+ # ruff
75
+ .ruff_cache/
76
+
77
+ # pyright
78
+ pyrightconfig.json
79
+
80
+ # claude
81
+ .claude/
82
+
83
+ # OS
84
+ .DS_Store
85
+ Thumbs.db
86
+
87
+ **/target
88
+ **/mips*.tar
89
+ **/mips*--glibc*
90
+ **/mips*--musl*
91
+ **/lib.rs:*
92
+
93
+ # images
94
+ **/*.img
95
+ **/*.uf2
96
+ **/*.elf
97
+ **/*.bin
98
+ tmp/
@@ -0,0 +1,48 @@
1
+ default_install_hook_types: [pre-commit]
2
+ default_language_version:
3
+ python: python3
4
+
5
+ repos:
6
+ - repo: local
7
+ hooks:
8
+ - id: uv-lock
9
+ name: uv lock
10
+ entry: uv
11
+ args: ["lock", "--upgrade"]
12
+ language: system
13
+ pass_filenames: false
14
+
15
+ - id: uv-sync
16
+ name: uv sync before hooks
17
+ entry: uv
18
+ args: ["sync", "--python", "cpython-3.10"]
19
+ language: system
20
+ pass_filenames: false
21
+
22
+ - id: uv-mypy
23
+ name: mypy
24
+ entry: uv
25
+ args: ["run", "mypy"]
26
+ language: system
27
+ pass_filenames: false
28
+
29
+ - id: uv-ruff-check
30
+ name: ruff lint & fix
31
+ entry: uv
32
+ args: ["run", "ruff", "check", "--fix"]
33
+ language: system
34
+ pass_filenames: false
35
+
36
+ - id: uv-ruff-format
37
+ name: ruff format
38
+ entry: uv
39
+ args: ["run", "ruff", "format"]
40
+ language: system
41
+ pass_filenames: false
42
+
43
+ - id: uv-pytest
44
+ name: uv run pytest
45
+ entry: uv
46
+ args: ["run", "pytest"]
47
+ language: system
48
+ pass_filenames: false
@@ -0,0 +1 @@
1
+ 3.10
Binary file