本文へ移動
cccskills
無料GitHub で公開

rp2040-pico

Firmware development for the Raspberry Pi Pico (original, RP2040 — dual Cortex-M0+ @ 133 MHz, 264 KB SRAM, 2 MB QSPI flash) — its 26 exposed GPIO, 4-channel 12-bit ADC, 16-channel PWM, 2× UART/I2C/SPI, PIO state machines, USB 1.1 CDC, VSYS/VBUS/SMPS power wiring, and the PlatformIO + arduino-pico (earlephilhower) setup around them. Use when working on this board, any Pico H or Pico clone, or a bare RP2040: project setup, platformio.ini, the earlephilhower-vs-Mbed core choice, pin mapping, USB CDC serial, analogRead/analogWrite behaviour, Wire/SPI defaults, battery power, EEPROM emulation, BOOTSEL/UF2 flashing, or debugging why something on the board does not work.

インストール方法を見る

含まれるファイル(11)

  • SKILL.md13.1 KB
  • assets/IMAGE.md448 B
  • reference/board-hardware.md19.1 KB
  • reference/recipes.md6.5 KB
  • template/.gitignore13 B
  • template/include/board.h3.0 KB
  • template/platformio.ini1.4 KB
  • template/README.md3.5 KB
  • template/src/main.cpp3.4 KB
  • template/variants/minimal/main.cpp535 B
  • template/variants/new-project.sh1.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Raspberry Pi Pico (RP2040)

Board-specific firmware knowledge. The Pico's failure modes are quiet: a wrong platformio.ini line silently links a different Arduino core, Serial goes to a port that does not exist yet, and an ADC pin doubles as a power rail — so read the reference files rather than guessing.

  • reference/board-hardware.md — the complete board reference: 40-pin map with alt functions, the four hidden GPIOs, power tree, clocks, memory map, relevant errata plus a development guide (Part II: §7 toolchain and the core-choice table, §8 peripheral cookbook, §9 flashing, §10 symptom → cause → fix table).
  • reference/recipes.md — copy-paste code: platformio.ini, board.h excerpts, USB CDC + Serial1, ADC with the VSYS ×3 math, PWM and the slice rule, Wire1 remapping, EEPROM with commit(), interrupts, core 1, BOOTSEL tricks.
  • template/ — a project that builds clean, in two variants, plus a scaffold script. See template/README.md.

Orientation

MCURP2040 — 2× ARM Cortex-M0+ @ 133 MHz (arduino-pico default; SDK default 125 MHz), 40 nm QFN-56
Memory264 KB SRAM (6 banks), no internal flash — 2 MB W25Q16JV QSPI, XIP from 0x10000000 + 16 KB cache. Max sketch 2,093,056 B (last 4 KB = emulated EEPROM)
LED / buttonLED = GPIO25, active-HIGH, not on the header · BOOTSEL button, sampled at power-up only
USBmicro-B, FS device/host; Serial = USB CDC; 1200-baud touch reboots into BOOTSEL; enumerates as VID:PID 2E8A:000A ("Raspberry Pi" / "Pico") once the sketch is running
ADC12-bit 500 ksps: A0=GPIO26, A1=27, A2=28, A3=GPIO29 = VSYS/3 (internal) + channel 4 = die temp; analogRead is 10-bit by default; ENOB 8.7 bits
PWMevery GPIO, 16 ch (8 slices × 2); analogWrite default 8-bit @ 1 kHz; GPIO 2n & 2n+1 share one slice
Bus defaultsWire = 4/5 · Wire1 = 26/27 (= A0/A1!) · SPI = 17/18/19/16 · Serial1 = 0/1 · Serial2 = 8/9
PowerVBUS 5 V → diode → VSYS 1.8-5.5 V → RT6150 buck-boost → 3.3 V; 3V3 pin out < 300 mA; 3V3_EN low = board "dead"
Debug3-pin SWD header (SWCLK/GND/SWDIO); boot ROM is mask ROM — unbrickable
ToolchainPlatformIO + raspberrypi 1.19.0 + arduino-pico 5.6.0 (board_build.core = earlephilhower)

Rules that prevent the expensive mistakes

Each of these produces a failure that looks like something else.

  1. board_build.core = earlephilhower in platformio.ini. Plain framework = arduino silently builds against the Arduino Mbed core: #include <EEPROM.h> fails to compile, Wire1/Serial2 don't exist, analogWrite is 500 Hz with no frequency API — and none of the usual Pico tutorial code works. The error reads like a broken dependency, not a missing ini line.
  2. Serial is USB CDC, not UART0. A USB-serial adapter wired to GPIO0/1 sees nothing from Serial.print — those pins are Serial1. The CDC port exists only once the host opens it: bytes printed before that are dropped, and while (!Serial) blocks startup until a monitor connects. Never gate bring-up on the port being open.
  3. Upload usually needs no button — until it does. pio run -t upload touches the CDC port at 1200 baud and a running sketch reboots itself into BOOTSEL for picotool. If the firmware has crashed or its USB is dead, the upload dies with Cannot find BOOTSEL disk — hold BOOTSEL while replugging USB, then re-run. That recovery is always available; the boot ROM is mask ROM and cannot be overwritten.
  4. BOOTSEL only works at power-up. Pressing it while the board runs does nothing (it grounds the flash CS line). To get the RPI-RP2 drive: hold BOOTSEL, plug/replug USB, release. A running sketch can re-enter it from code (reset_usb_boot(0, 0) — recipe 13).
  5. analogRead returns 10-bit values (0-1023) by default on a 12-bit ADC. Symptom: "stuck at 1023 at full scale" or calibration off by 4×. analogReadResolution(12) before sampling.
  6. A3/GPIO29 is not a free pin — it measures VSYS/3. Multiply by 3 for the input voltage. GPIO23 (SMPS power-save), GPIO24 (VBUS sense), GPIO25 (LED), GPIO29 are real GPIOs in code but not on the 40-pin header — wiring plans that use them compile and "work" while nothing appears on the breadboard.
  7. GPIO pairs share a PWM slice. Slice = pin/2: 0&1, 2&3 … 28&29 share one counter and therefore one frequency — the last analogWriteFreq() on either pin retimes both, and a stepper/servo pair on one slice glitches in a way that looks like a power problem.
  8. Wire1 defaults to GPIO26/27 — the same pins as A0/A1. I2C bus corruption that starts as soon as analogRead is called is this, not electrical noise. Wire1.setSDA()/setSCL() to another I2C1 pair (2/3, 6/7, 10/11, 14/15, 18/19, 22/23) before begin().
  9. GPIO26-29 are not 5 V tolerant and carry a reverse diode to 3V3. Above ~3.6 V they damage the chip; any voltage on them while the board is unpowered back-powers the 3.3 V rail (a Pico that "ghosts" with no USB connected is being fed through an analog pin). GPIO0-25 tolerate applied voltage while unpowered.
  10. The ADC's accuracy budget is worse than its bit count. Reference = filtered 3.3 V SMPS rail, ~30 mV inherent offset (150 µA through the 200 Ω filter), ENOB 8.7 bits, DNL spikes at codes 512/1536/2560/3584. Naive absolute measurements are ±2-3 %. Average; cancel offset with a grounded channel; drive GPIO23 HIGH during sampling to quiet the SMPS (recipe 5), or fit an LM4040 3.0 V on ADC_VREF (range drops to 3.0 V).
  11. EEPROM lives in flash and only persists on commit(). begin(n) maps a shadow, put() stages (update semantics), commit() burns one 4 KB sector erase (100 k cycles). A sketch that never commits loses everything on reboot — silently, with no error.
  12. Flash writes stall both cores. Code executes from the same QSPI chip (XIP), so EEPROM.commit() and filesystem writes pause the whole processor mid-stream. Keep them out of timing-critical and ISR-adjacent windows; the symptom is a periodic hiccup that looks like a scheduler bug.
  13. USB may not enumerate on a busy hub (erratum E5, B0/B1 silicon — B2 fixes it): next to a chatty device on the same transaction translator, the port never leaves RESET. LED works, no COM port. Plug in directly or move ports before reinstalling drivers.
  14. Power wiring has three traps. Feed VSYS (pin 39, 1.8-5.5 V) for battery/external power — a single Li-ion works. USB host mode needs 5 V supplied to the VBUS pin (pin 40), not just VSYS. And a board that looks completely dead with USB connected usually has 3V3_EN (pin 37) shorted low — that pin disables the entire SMPS. The 3V3 pin (36) is an output (< 300 mA); never back-feed it. RUN (pin 30) shorted to GND is the reset button.
  15. LittleFS/FatFS silently gets zero bytes unless you ask for space. The build always reserves the last 4 KB of flash for EEPROM.h (maximum_sketch_size = flash_size - 4096 - filesystem_size, board_build.filesystem_size default 0MB), and any littlefs/fatfs region is carved out of flash below that, sized by that same option. LittleFS.begin() on the stock template returns false (or mounts an empty 0-byte volume) — not a build error, not a crash — because nothing was reserved. Set board_build.filesystem_size = 1MB (or 2MB, 4MB …) in platformio.ini before using LittleFS, FatFS or SDFS's flash-backed mode, and re-flash with pio run -t uploadfs once for the initial image.

When the task is analog measurement

The ADC is ratiometric to a filtered SMPS rail, not to a reference. What that means in numbers: full scale is 3.3 V ± the SMPS tolerance (±1-2 %); there is a built-in ~30 mV offset because the ADC's ~150 µA supply current flows through the 200 Ω filter resistor (it varies ±20 µA with sampling); effective resolution is 8.7 bits, with DNL spikes at four codes roughly every 1024 counts (512, 1536, 2560, 3584 — erratum E11). So a single raw 12-bit reading implies far more accuracy than it has.

Work in that order: average many samples (free, fixes noise + DNL); tie a spare ADC channel to AGND and subtract its reading (cancels the offset); drive GPIO23 HIGH while sampling to force the SMPS into PWM mode, LOW after (cuts ripple, costs light-load efficiency); and only then consider the LM4040 3.0 V shunt on ADC_VREF — that also shrinks the input range to 3.0 V. For battery monitoring, analogRead(A3) × 3 is well inside the ADC's envelope — relative changes are trustworthy even when absolutes aren't.

When the task is powering the board

The chain is VBUS → Schottky D1 → VSYS → RT6150 buck-boost → 3V3. The buck-boost accepts 1.8-5.5 V at VSYS, which makes power the most flexible part of the board: USB, one Li-ion cell (with protection!), 3×AA, or any 2.3-5.5 V supply with an ORing diode/P-FET into VSYS. The traps: USB host mode must see 5 V on the VBUS pin (VSYS power alone leaves the host port dead); USB-only setups may bridge VBUS to VSYS to remove the diode drop; and never feed the 3V3 pin — it's an output, and > 3.3 V there goes straight into the RP2040 and flash. VSYS current draw: ~10 mA idle in BOOTSEL, ~1.3 mA sleep, ~0.8 mA dormant, 90+ mA loaded.

Starting a new project

Do not hand-assemble one. template/ builds clean; scaffold from it:

~/.claude/skills/rp2040-pico/template/variants/new-project.sh <target-dir> [--full|--minimal]
cd <target-dir> && pio run -t upload -t monitor
  • --minimal — classic Blink on GPIO25. 58,172 B flash / 8,732 B RAM. Flash this first on an unfamiliar board: if the LED does not blink after upload, the problem is the cable, the BOOTSEL dance or rule 1, not the code. (The floor is TinyUSB CDC — a bare blink costs ~58 KB flash here, vs ~4 KB flash / ~40 KB RAM on the Mbed core.)
  • --full (default) — non-blocking heartbeat, USB-CDC report, A0 at 12 bits, die temperature, VSYS via A3, VBUS sense, EEPROM boot counter. 61,112 B flash / 9,036 B RAM.

Both build as-is with platform-raspberrypi 1.19.0 + arduino-pico 5.6.0 (verified). Nothing is generated and no paths are embedded, so copying the tree by hand works identically. template/README.md maps files to subsystems.

When the user already has a project, prefer adding board_build.core = earlephilhower to their platformio.ini over rewriting their code — that one line is usually the whole fix.

Flashing

Over the micro-USB cable:

pio run -t upload -t monitor

Normally nothing is pressed. PlatformIO opens the CDC port at 1200 baud, the running sketch reboots into BOOTSEL, picotool flashes and reboots the board — the LED blinks again within a second of SUCCESS. The board enumerates as a CDC port (/dev/cu.usbmodem*, COMx); the monitor's baud rate is ignored.

When the running firmware cannot respond (crashed, USB disabled, power-only cable), the keystroke sequence is: hold BOOTSEL → plug/replug USB → release → a 128 MB RPI-RP2 drive appears → either re-run pio run -t upload (picotool picks up the BOOTSEL device), or drag .pio/build/pico/firmware.uf2 onto the drive — the board reboots itself when the copy completes. pio run -t erase copies a flash_nuke.uf2 that erases all 2 MB (including EEPROM) — the clean-slate recovery. A power-only USB cable is the most common cause of "no RPI-RP2 drive".

The alternative route is SWD over the 3-pin bottom header with a second Pico as Picoprobe (upload_protocol = picoprobe) — needed only when flash itself is wedged; the mask-ROM bootloader survives everything.

Reporting

State honestly what was verified on hardware and what came from the datasheet. In this skill: both template variants and the recipes marked compile-verified build clean against platform-raspberrypi 1.19.0 + arduino-pico 5.6.0; the --minimal blink is the user project this skill was extracted from. No analog measurement, power draw or timing figure was measured on hardware by the author — the ADC accuracy envelope, VSYS divider, SMPS behaviour and current figures are datasheet-derived (Pico datasheet §3-4, RP2040 datasheet errata), and core-behaviour claims (read resolution defaults, Wire1 pins, upload touch) come from the arduino-pico 5.6.0 sources. Anything over 133 MHz F_CPU a user requests is overclocking — label it as outside spec.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Firmware development for the Arduino Nano (A000005, ATmega328P @ 16 MHz, 5 V) — its 30 KB usable flash, 2 KB SRAM, 1 KB EEPROM, 8-channel 10-bit ADC, six 8-bit PWM pins across three timers, UART shared with the USB-serial chip, I2C on A4/A5, SPI on D10–D13, sleep modes, and the Arduino AVR core + PlatformIO setup around them. Use when working on this board or any ATmega328P Nano clone (FTDI or CH340 USB): project setup, platformio.ini, old-vs-new bootloader uploads, pin mapping, A6/A7 restrictions, timer/Servo/tone conflicts, the 2 KB SRAM budget, analog references, powering from VIN, ICSP recovery, or debugging why something on the board does not work.

日本語の概要は準備中です。原文の説明を表示しています。

alexex1993/mcu-skills182026年9月25日 更新

Firmware development for the Beetle — the CJMCU / DFRobot "Mini Arduino Leonardo" USB board (ATmega32U4 @ 16 MHz, 5 V, 21×28 mm, castellated pads) — its native USB (CDC serial + HID keyboard/mouse/joystick), Caterina bootloader and 1200 bps touch upload, ten exposed I/O pads, four PWM pins across Timer0/Timer1, five ADC channels, I2C on D2/D3, SPI on the back-side ICSP pads, 28 KB usable flash and 2.5 KB SRAM, and the PlatformIO + Arduino AVR core (`board = leonardo`) setup around them. Use when working on this board or any ATmega32U4 Leonardo/Micro/Pro-Micro-class clone: project setup, platformio.ini, why the board shows up as two different serial ports, uploads that fail or hang, recovering a bricked or HID-spamming board by shorting the ICSP reset pads, pin mapping and which pads are missing, PWM/timer conflicts, Servo and tone, USB HID keyboard projects, the SRAM budget, powering from the + pad, or debugging why something on the board does not work.

日本語の概要は準備中です。原文の説明を表示しています。

alexex1993/mcu-skills182026年9月25日 更新

Разработка прошивок для BE-U1000 (Baikal Electronics / Байкал Электроникс, три ядра RISC-V: BR-350 и BM-310) на отладочных платах EVU-BA-2.1, EVU-BA-2.0 и EVU-BA-1.2 — её eFlash и QSPI flash, UART0/BootROM CLI, PWMA (захват и импульсы), АЦП с DMA, CAN FD, SPI, WDT, CLIC, а также SDK Байкала и его система сборки на make. Use when working on this board or any BE-U1000 / BMCU_U project (SDK 2.1/2.3, riscv32-none-elf, dfu-util, OpenOCD): настройка проекта, Makefile и MEM_REG_ROM, карта выводов и разъёмы XP1/XP8/XP9/XP10, режимы начальной загрузки и страповые выводы, прошивка по UART XMODEM либо USB DFU, работа с eFlash и TCM, прерывания и CLIC, отладка по JTAG — и разбор, почему плата молчит, не стартует, зависает или почему периферия «настроилась», а обмена нет.

日本語の概要は準備中です。原文の説明を表示しています。

alexex1993/mcu-skills182026年9月25日 更新

Firmware development for the 30-pin ESP32-WROOM-32 development board — the DOIT ESP32 DevKit V1 / ESP32 CH340 Type-C / NodeMCU-ESP32 30-pin form factor, 15 pins per side, CH340G or CP2102 USB-UART bridge, AMS1117 LDO, user LED on GPIO2. Use when working on a 30-pin ESP32 devkit (ESP32-D0WDQ6 / ESP32-D0WD-V3, ESP-WROOM-32 module): project setup, platformio.ini and sdkconfig for ESP-IDF or Arduino, pin mapping and which GPIOs are safe, strapping pins, ADC1 vs ADC2 with Wi-Fi, SPI speed and IO_MUX pins, I2C, deep sleep and RTC wake pins, flashing over the CH340 bridge, BOOT/EN recovery, brownouts, or debugging why something on the board does not work.

日本語の概要は準備中です。原文の説明を表示しています。

alexex1993/mcu-skills182026年9月25日 更新

Firmware development for the 36-pin ESP32-WROOM-32 development board — the original DOIT ESP32 DevKit V1 with 18 pins per side, i.e. the 30-pin layout plus the six in-package flash pins (SD0 SD1 SD2 SD3 CMD CLK = GPIO6-11) broken out at the USB end, CH340G or CP2102 bridge, AMS1117 LDO, user LED on GPIO2, GPIO0 not on the header. Use when working on a 36-pin ESP32 devkit (ESP32-D0WDQ6 / ESP32-D0WD-V3, ESP-WROOM-32 module), or when identifying which ESP32 board size you have: project setup, platformio.ini and sdkconfig for ESP-IDF or Arduino, pin mapping and which GPIOs are safe, the flash-pin trap, strapping pins, ADC1 vs ADC2 with Wi-Fi, SPI speed and IO_MUX pins, deep sleep and RTC wake pins, flashing, BOOT/EN recovery, brownouts, or debugging why something on the board does not work.

日本語の概要は準備中です。原文の説明を表示しています。

alexex1993/mcu-skills182026年9月25日 更新

Firmware development for the 38-pin ESP32-WROOM-32 development board — Espressif ESP32-DevKitC V4, Ai-Thinker NodeMCU-32S, DOIT ESP32 DevKit V1 38-pin and their CH340/CP2102 clones, 19 pins per side, with GPIO0 and the six in-package flash pins (GPIO6-11, labelled D0 D1 D2 D3 CMD CLK or SD0-SD3) broken out. Use when working on a 38-pin ESP32 devkit (ESP32-D0WDQ6 / ESP32-D0WD-V3, ESP-WROOM-32 or ESP32-WROVER module): project setup, platformio.ini and sdkconfig for ESP-IDF or Arduino, pin mapping and which GPIOs are safe, the flash-pin and IO0 traps, WROVER GPIO16/17 PSRAM conflict, strapping pins, ADC1 vs ADC2 with Wi-Fi, SPI speed and IO_MUX pins, deep sleep and RTC wake pins, flashing, BOOT/EN recovery, brownouts, or debugging why something on the board does not work.

日本語の概要は準備中です。原文の説明を表示しています。

alexex1993/mcu-skills182026年9月25日 更新

alexex1993 のスキルをすべて見る

このスキルの問題を報告する