Releases: PyMCU/RP2040Sharp
Release list
v1.0.4 — fix _thread.start_new_thread() / core0 WFE hang
_thread.start_new_thread in MicroPython (≥ v1.28.0) caused core0 to hang indefinitely in WFE. Before launching a new thread, MicroPython invokes multicore_reset_core1() from the pico-sdk, which asserts and de-asserts the PROC1 bit in PSM.FRCE_OFF. On real hardware, releasing this bit brings core1 out of reset, restarts its bootrom, and pushes a synchronization word (0) through the FIFO to core0. Core0 blocks on multicore_fifo_pop_blocking() waiting for it. In the emulator, writing to PSM.FRCE_OFF was an inert register store: core1 never exited reset, never sent the 0, and core0 slept in WFE forever (dying before ever reaching the existing launch handshake).
PsmPeripheral now features an OnProc1Released callback, triggered by the set-to-clear transition of the PROC1 bit (bit 16) in FRCE_OFF. Because the APB bridge translates atomic aliases to read-modify-write operations, this detection is direct and reliable. RP2040Machine wires this callback to reset core1 and signal readiness: SioPeripheral flushes the input mailbox, enqueues the 0 into the Core1→Core0 FIFO, and triggers Interrupt 15 + EventRegistered (SEV) to wake core0. The existing logic handles the subsequent launch sequence.
Includes new regression tests running a real micropython-v1.28.0.uf2 firmware (embedded in the test assembly for offline capability). It asserts that a worker thread successfully runs on core1 while the main thread continues past the call. Older MicroPython versions (v1.21.0) masked the bug by not invoking multicore_reset_core1().
Tests: Unit (MulticoreResetTests) and integration (MicroPythonThreadTests) green.
v1.0.3 — fix machine.bitstream() / NeoPixel
machine.bitstream() — the transport under MicroPython's neopixel module —
produced constant-width pulses, so every NeoPixel painted (0,0,0): a bit-0 and a
bit-1 left the pin with the same high time.
The rp2 port times each bit's pulse against SysTick (write CVR, raise the pin,
busy-wait on (start − CVR) < width, lower it). PpbPeripheral advanced SysTick
only from the peripheral tick, so CVR was frozen for the whole busy-wait and both
delays expired at the same instant. SysTick now advances off the core cycle
counter, which resolves per instruction.
Includes a regression test over a real 3-pixel WS2812 frame asserting the
pulse-width histogram splits into two clusters (T0H/T1H). Companion to the same fix
in RP2350Sharp 1.0.2.
Tests: 533 unit, integration green.
v1.0.2 — third-party notices, and mufplib out of the boot ROM
Two licensing failures that were invisible from this repo, because the repo was right and the package was not.
The notices never shipped. The MIT licence requires its copyright and permission notice to travel with every copy. Only LICENSE-BUSL.txt was ever packaged, and it does not mention Uri Shaked. NOTICE.txt now ships inside all four packages, carrying the MIT notice for the rp2040js-derived portions and the BSD-3-Clause notice for the boot ROM.
We were redistributing code we had no right to. The RP2040 boot ROM is BSD-3-Clause, but its licence excludes mufplib.S / mufplib-double.S — licensed for use "solely on a Raspberry Pi RP2040 device", or GPLv2 from Mark Owen. Neither permits shipping it here. That was 35% of both ROM images, in every version published until now.
tools/strip_mufplib.py removes it, resolving the region from the ROM's own markers. BootromFloat implements the SF/SD ROM float API natively behind the tables firmware resolves, so firmware keeps working unmodified — pico-sdk builds float against the ROM by default, and with the hooks disabled every MicroPython float test fails.
Two deviations from silicon, documented in the source: the hooks cost one cycle where the real routines cost tens to hundreds, and transcendentals can differ in the last ulp (ours are the more accurate).
Attribution corrected. Uri Shaked's copyright said 2026; upstream says 2021. Sergio Domínguez Rojas's MIT notice is retained — his contributions came in under MIT while the project was MIT, and the grant that lets them be relicensed is conditional on keeping his name.
A gate so it cannot recur. CI now opens every .nupkg before the push and requires a licence file (never an SPDX expression) plus NOTICE.txt, and refuses to pack a ROM with mufplib in it.
Tests: 533 unit, 157 integration.
v1.0.1
RP2040Sharp v1.0.1 — first stable BUSL release 🎉
First stable release under the Business Source License 1.1 (whole project BUSL-1.1, converts to MIT on the Change Date).
✨ Included
fix(pwm): implement PWMCSR.DIVMODE(B-pin gated and edge-count modes). Unit: 521/0.
📦 NuGet
RP2040Sharp, RP2040Sharp.TestKit, RP2040Sharp.Wireless, RP2040Sharp.NanoFramework.TestKit @ 1.0.1.
🤖 Generated with Claude Code
v1.0.1-beta.12
RP2040Sharp v1.0.1-beta.12
⚖️ Licensing correction
The entire project is BUSL-1.1 — the emulator core (RP2040Sharp) and every package — converting to MIT on the Change Date. The core is no longer MIT. MIT is retained in LICENSE only as attribution for the rp2040js-derived (© Uri Shaked) portions of the core.
All four packages now publish under BUSL-1.1.
🤖 Generated with Claude Code
v1.0.1-beta.11
RP2040Sharp v1.0.1-beta.11
🐛 Fix
- ARMv6-M exception priority model — a GPIO IRQ no longer self-preempts. Corrects the Cortex-M0+ exception priority/preemption handling (
CortexM0Plus,SystemOps,PpbPeripheral); addsMicroPythonGpioIrqTests.
Verified: unit 516/0, new GPIO IRQ integration test 2/0. BUSL Change Date stamped to release + 4 years (rolling).
🤖 Generated with Claude Code
v1.0.1-beta.10
RP2040Sharp v1.0.1-beta.10
⚙️ CI / Licensing
- First release built with the rolling BUSL Change Date automation: the packaged license
Change Dateis now stamped to release date + 4 years at pack time, so every version gets its own full 4-year window before converting to MIT.
Dual model unchanged: RP2040Sharp core is MIT; RP2040Sharp.TestKit, RP2040Sharp.Wireless, RP2040Sharp.NanoFramework.TestKit are BUSL-1.1.
🤖 Generated with Claude Code
v1.0.1-beta.9
RP2040Sharp v1.0.1-beta.9
⚖️ Licensing (clarification only)
Sharpens the BUSL-1.1 commercial-use exception — no functional code change:
- The Commercial Use definition (a)/(b)/(c) is now authoritative; the free-use list (personal / hobby / educational / academic / evaluation / OSS) is subordinate to it.
- Uniform Change Date 2030-07-11 → converts to MIT (per-version).
Dual model unchanged: RP2040Sharp core is MIT; RP2040Sharp.TestKit, RP2040Sharp.Wireless, RP2040Sharp.NanoFramework.TestKit are BUSL-1.1.
🤖 Generated with Claude Code
v1.0.1-beta.8
RP2040Sharp v1.0.1-beta.8
✨ Changes
- RTC and SSI peripheral corrections.
- DREQ-paced DMA:
OnRxPushnow fires fromInjectRxData. - New integration coverage: CYW43 HTTP RX, FreeRTOS kernel, MicroPython REPL, PyMCU-vs-MicroPython benchmark.
- Built on top of the
NfClr.Coreextraction + Trusted Publishing (1.0.1-beta.6).
Supersedes v1.0.1-beta.7, which was tagged from a stale base and has been withdrawn.
⚖️ Licensing (unchanged dual model)
| Package | License |
|---|---|
RP2040Sharp (core) |
MIT |
RP2040Sharp.TestKit |
BUSL-1.1 → MIT on 2030-06-25 |
RP2040Sharp.Wireless |
BUSL-1.1 → MIT on 2030-06-25 |
RP2040Sharp.NanoFramework.TestKit |
BUSL-1.1 → MIT on 2030-06-25 |
📦 NuGet
All four packages @ 1.0.1-beta.8.
🤖 Generated with Claude Code
Pre-Release v1.0.1-beta.6
Follow-up to v1.0.1-beta.5.
This release extracts the chip-agnostic nanoCLR introspection into a shared package and
moves publishing to NuGet Trusted Publishing. Licensing is unchanged — only the RP2040Sharp
core is MIT; the rest are BUSL-1.1.
🔧 Changed
- Extracted the nanoCLR introspection into
NfClr.Core.
ClrInspector,ClrLayout, the heap walk andClrSessionnow live once in the shared
NfClr.Corepackage (1.0.0-beta.1).RP2040Sharp.NanoFramework.TestKitkeeps only the
RP2040IClrMemory/IClrHostadapter (Rp2040ClrHost/Rp2040ClrMemory) and depends on
NfClr.Corevia PackageReference.NanoClrHarnessis now a thin facade overClrSession;
firmware symbols, layout and checksums derive from the nanoCLR ELF/DWARF when present. - Publishing migrated to NuGet Trusted Publishing (OIDC) — short-lived keys minted from the
GitHub OIDC token, no long-livedNUGET_API_KEY.
📦 Packages
# MIT core
dotnet add package RP2040Sharp --version 1.0.1-beta.6
# BUSL-1.1
dotnet add package RP2040Sharp.TestKit --version 1.0.1-beta.6
dotnet add package RP2040Sharp.Wireless --version 1.0.1-beta.6
dotnet add package RP2040Sharp.NanoFramework.TestKit --version 1.0.1-beta.6 # now depends on NfClr.CoreFull changelog: https://github.com/PyMCU/RP2040Sharp/blob/master/CHANGELOG.md