An Arduino core for budget nRF52840 clones — with hands-free uploads and single-cable source debugging
Flash and debug an AliExpress ProMicro nRF52840 — the kind with no reset button and no SWD header — over a single USB cable, straight from the Arduino IDE.
The cheap nRF52840 clones (AliExpress "ProMicro nRF52840", SuperMini, nRFMicro, …) are fantastic value, but they usually ship without workable board library for Arduino IDE 2.x, which makes those boards extremely difficult to use and debug. Widely-used ProMicro even comes without reset buttons and usable SWD pins (it does has the pads). NiusRobotLab developed this easy-to-use, Arduino IDE compatible third-party board library that makes every upload automatically as a double-tap-reset dance, and source-level debugging possible merely using single USB cable. No debugger needed any more! If you would like to support our work, test this repo with your own nRF board then tell me any issues or possible fix.
| Feature | What it means for you | |
|---|---|---|
| 🔌 | Hands-free uploads | Click Upload. The firmware reboots itself into the bootloader over the USB-CDC maintenance port — no button, no double-reset, no jumper. |
| 🐞 | Single-cable debugging | Click Debug in Arduino IDE 2 and get breakpoints, step in/over/out, registers, memory, watchpoints and pause — all over the same USB cable, with no external SWD/J-Link probe. |
| 🧩 | 10 board definitions, one package | ProMicro (verified on hardware), nice!nano v2, SuperMini, nRFMicro, XIAO, nRF52833/nRF52840 dev boards and more — installed from one Board Manager URL. |
| 📋 | Truth-oriented metadata | ADC, PWM, BLE and bus capabilities are documented as verified, not aspirational. No silent overclaiming. |
| 🛡️ | Robust upload pipeline | Double-click-safe, coexists with a live debug session, rejects the wrong COM with a clear message, and caches slow port scans for speed. |
In Arduino IDE → Settings → Additional Boards Manager URLs, add:
https://raw.githubusercontent.com/dunknowcoding/ArduinoNRF/main/package_arduinonrf_index.json
Then open Boards Manager, search ArduinoNRF, and install. (CLI: arduino-cli core install arduinonrf:nrf52 --additional-urls <url above>.)
Tools → Board → ArduinoNRF nRF52 → e.g. AliExpress ProMicro nRF52840. Select the board's COM port under Tools → Port.
💡 With
usbcdc=enabledthe board shows two COM ports: a user port (yourSerial) and a service/maintenance port. Use the service port (usually the lower COM index /MI_00) for uploads and debugging — picking the user port is rejected with a clear message.
Hit Upload. The first time the board is in application mode, the core's 1200-bps touch reboots it into the bootloader automatically and the new firmware streams in. No button press. 🎉
Select the usbgdbstub build profile, open examples → UsbGdbStubBreakpoint, and press Debug. Set breakpoints in the gutter and step through your code — the GDB stub lives in the firmware and talks over the maintenance CDC. See docs/platform/ARDUINO_IDE2_USB_GDBSTUB.md.
Most clone cores can only enter the bootloader via a physical double-reset. ArduinoNRF's firmware watches the maintenance CDC for the classic 1200-bps "touch" and reboots itself into the UF2/serial-DFU bootloader via SYSRESETREQ — so arduino-cli upload (and the IDE Upload button) work with no hands on the board.
The host-side pipeline (upload.ps1) is hardened against the messy real world:
- Double-click safe — a per-port lock makes a second Upload fail fast before any touch, so two uploads can never interleave and corrupt flash.
- Coexists with debugging — if a debug session holds the port, the upload signals the debug bridge to release it, then proceeds.
- Wrong-port guard — selecting the user CDC instead of the service CDC is rejected with an actionable message; your firmware is never touched.
- Fast — slow Windows PnP enumerations are cached during the stable pre-touch window (~3 s saved per upload).
See docs/uploads/hands_free_upload.md and docs/platform/UPLOAD_BEHAVIOR.md.
A small GDB stub compiled into the firmware uses the Cortex-M DebugMonitor exception plus the FPB (hardware breakpoints) and DWT (watchpoints). A host bridge proxies Arduino IDE 2's cortex-debug over the maintenance USB-CDC port, so you get a full debug experience without any external probe:
✅ breakpoints · ✅ single-step (in/over/out) · ✅ registers & memory · ✅ data watchpoints · ✅ pause/halt · ✅ peripheral (SVD) reads · ✅ user Serial keeps working concurrently on the second CDC
Verified end-to-end on the AliExpress ProMicro nRF52840 clone. Boards that expose real SWD pads can also use the classic OpenOCD/CMSIS-DAP route.
See docs/platform/ARDUINO_IDE2_USB_GDBSTUB.md.
Identities were re-checked against the upstream Adafruit_nRF52_Bootloader board.h files, the Seeed and pdcook Arduino cores, and joric/nrfmicro. See docs/COMPATIBILITY.md for the full audit and per-board change log.
⚠️ In this revision, only the AliExpress ProMicro nRF52840 upload/debug path is verified end-to-end on physical hardware. The other packaged board definitions are derived from the current variants, upstream identities, and smoke-test truth; some remain marked experimental inboards.txt.
| Board | Bootloader VID:PID | Pipeline | Status |
|---|---|---|---|
| AliExpress ProMicro nRF52840 | 0x239A:0x00B3 |
Adafruit serial DFU | ✅ Verified on hardware (hands-free upload + single-cable debug) |
| nice!nano v2 | 0x239A:0x00B3 |
Adafruit serial DFU | Identity corrected; same pipeline as ProMicro |
| SuperMini nRF52840 | 0x239A:0x00B3 |
Adafruit serial DFU | Ships nice!nano bootloader; LED on P0.15 |
| nRFMicro | 0x1209:0x5284 |
Adafruit serial DFU | joric open-hardware; some DIY units carry nice!nano IDs instead |
| Seeed XIAO nRF52840 (+ Sense) | 0x2886:0x0044 / 0x0045 |
Adafruit serial DFU (Seeed) | Identity corrected, UF2 = XIAO-BOOT |
| Makerdiary Pitaya Go | 0x2886:0xF00E |
Adafruit serial DFU | Identity corrected, UF2 = PITAYAGO |
| Mini nRF52840 (AliExpress) | auto |
varies | |
| Generic nRF52840 Dev Board | auto |
varies | |
| Generic nRF52833 Development Board | auto |
varies | |
| nRF52840 USB Dongle (PCA10059) | 0x1915:0x521F |
Nordic Open DFU | nrfutil / nRF Connect — this pipeline does not apply |
Per-board reference notes live in docs/boards/; the support matrix is in docs/platform/BOARD_SUPPORT_STATUS.md.
| OS | Hands-free upload | Single-cable debug |
|---|---|---|
| Windows 10/11 | ✅ Verified (upload.ps1) |
✅ Verified (PowerShell bridge) |
| Linux (Ubuntu / Debian / Fedora / Arch) | ✅ Implemented via upload.py + adafruit-nrfutil (untested in this revision) |
✅ Implemented via usb_gdbstub_bridge.py (untested) |
| macOS (Intel + Apple Silicon) | ✅ Implemented via upload.py + adafruit-nrfutil (untested) |
✅ Implemented via usb_gdbstub_bridge.py (untested) |
Linux/macOS setup: pip3 install --user adafruit-nrfutil, then (Linux only) install the shipped udev rules — see docs/COMPATIBILITY.md.
| Area | Status |
|---|---|
| GPIO / Serial / SPI / Wire | ✅ Supported; global Wire1/SPI1 exist but stay disabled on boards without verified secondary-bus pins |
| ADC | ✅ SAADC-backed analogRead, plus analogReadVDD() / analogReadVDDHDIV5() |
| PWM | ✅ All 4 PWM modules / 16 channels / 4 independent frequency groups + per-pin polarity + complementary pairing with software dead-time. Tools → PWM speed picks the default carrier. See docs/platform/PWM_MULTI_MODULE.md. |
| RTC | ✅ Low-level driver for RTC0/1/2 (24-bit counter, 4 compares each, overflow IRQ, LFCLK-clocked so it survives sleep). See docs/platform/RTC_DRIVER.md. |
| Power | ✅ System ON sleep (WFI/WFE/sleepMs), low-power / constant-latency sub-modes, DCDC enable, RAM retention, SystemOFF with GPIO / NFC / USB wake. See NrfPower.h + examples/PowerSleep. |
| NFC-A Tag | ✅ Type 2 tag emulation (NDEF URL / text records), auto-collision-resolution via NFCT hardware. See NrfNfcTag.h + examples/NfcTag. |
| All small peripherals | ✅ TRNG (NrfRng), die temp sensor (NrfTemp), watchdog (NrfWdt), rotary decoder (NrfQdec), TIMER0–4 w/ 6 CC each (NrfTimer), flash erase/write (NrfNvmc), PPI (peripheral-to-peripheral routing) (NrfPpi), EGU/SWI (software events + IRQ on 6×16 channels) (NrfEgu), analog comparator (NrfComp), memory watch unit (NrfMwu), GPIOTE output channels for PPI use (NrfGpioteOut). All in NrfPeripherals.h + examples PeripheralsDemo, TimerNvmcPpi, EguCompGpiotePpi. |
| Media peripherals | NrfMediaPeripherals.h. API + register sequences complete per nRF52840 PS, but unverified — the reference ProMicro has none of those external chips wired. XIAO Sense (PDM) / Pitaya Go (QSPI) / custom audio boards should work, please test. |
| BLE | BLE library is still advertising-only. libraries/NimBLE/ is not done yet: the Arduino-facing API exists and parts of the Mynewt porting/NPL layer are vendored, but begin() still returns NIMBLE_NOT_VENDORED, isAvailable() stays false, and there is no real connection/GATT stack in-tree yet. See docs/platform/NIMBLE_INTEGRATION_PLAN.md. |
| CC310 (crypto) | libraries/CC310/ is still a true skeleton: the public API is defined, but without Nordic's libcc_310.a every operation returns CC_NOT_VENDORED and isAvailable() stays false. Roadmap: docs/platform/CC310_INTEGRATION_PLAN.md. |
| Zigbee / 802.15.4 | libraries/Zigbee/ is still a true skeleton: the API surface is present, but begin() / sendOnOff() return ZIGBEE_NOT_VENDORED, isAvailable() is false, and the Zboss + nrf-802154 stack is not in-tree yet. Roadmap: docs/platform/ZIGBEE_INTEGRATION_PLAN.md. |
| Thread (OpenThread) | libraries/Thread/ is not done yet: OpenThread headers, some platform glue, and smoke wiring are present, but the real OpenThread core + nrf-802154 radio path are not vendored, begin() returns THREAD_NOT_VENDORED, and isAvailable() / isAttached() stay false. Roadmap: docs/platform/THREAD_INTEGRATION_PLAN.md. |
| EEPROM | ✅ Emulated (see EEPROM examples) |
| Upload | ✅ Hands-free serial-DFU on the maintenance CDC; SWD/OpenOCD also available |
| Debug | ✅ USB-CDC GDB stub (no probe) on ProMicro; SWD route for boards with pads |
Gaps vs. mature Adafruit/Nordic cores: no SoftDevice menu or Bluefruit/TinyUSB BLE stack; not every clone USB profile is claimed interchangeable (the validated path is promicroserialnosd). With usbcdc=disabled the board stays uploadable from the bootloader but its in-app touch is unreliable — keep usbcdc=enabled for the hands-free workflow.
Everything beyond this README lives under docs/ — start at docs/README.md for the full index. Highlights:
- 🧪 docs/VALIDATION.md — what's been tested on real hardware, and how to reproduce it
- 🔼 docs/uploads/ — hands-free, double-reset, and SWD-only upload routes
- 🐞 docs/platform/ARDUINO_IDE2_USB_GDBSTUB.md — single-cable debug setup
- 🧷 docs/platform/USB_1200_TOUCH_V1_FIX.md — the firmware fixes behind hands-free upload
- 🧩 docs/boards/ — per-board reference
- 📦 docs/release/ — release flow and notes
hardware/arduinonrf/nrf52/ # the Arduino platform: cores, variants, boards.txt, tools
examples/ # ~50 examples incl. UsbGdbStub* and capability self-tests
docs/ # all documentation (the only place docs live)
scripts/ , tools/ # build, release, and hardware-validation helpers
package_arduinonrf_index.json # Board Manager index
Issues and PRs welcome at github.com/dunknowcoding/ArduinoNRF. The guiding principle: document what the hardware verifiably does — if a capability isn't proven on a board, it isn't claimed.
ℹ️ A formal open-source license has not yet been added to this repository. Until one is present, treat the code as "all rights reserved" and ask before redistributing.