#klipper #kalico #mcu #rp2040 #rp2350 #rp2354 #stm32f0 #pcb #hardware-design #electronics
# Overview
MCU selection for new Klipper/Kalico board designs, comparing **RP2040**, **RP2350/RP2354**, and **STM32F042G6Ux**. Researched 2026-09-18 against current Klipper master, Kalico `main`, and live LCSC stock.
The headline: **RP2350 is the default choice for anything new.** Klipper added it in 0.13.0 (April 2025), Kalico carries the same support, Katapult and can2040 both handle it, and the E9 erratum that made it radioactive in 2024–25 is fixed and fully flushed from the supply chain. The STM32F042 is a genuinely constrained part that only makes sense for a minimal CAN toolhead — for anything bigger the STM32G0B1 (already used on [[Strangelove Toolhead Board|Strangelove]]) is the better STM32.
Related: [[RP2354A Hardware Design Reference]] · [[STM32G0B1CBT6 LQFP-48 Layout Playbook]] · [[JLCPCB Design Notes]] · [[KiCad 9 MCU Board Design Workflow]]
# Design
## Comparison table
| | **RP2040** | **RP2350A / RP2354A** | **RP2350B / RP2354B** | **STM32F042G6U6** |
|---|---|---|---|---|
| Core | 2× Cortex-M0+ | 2× Cortex-M33 +FPU, or 2× Hazard3 RISC-V | same | 1× Cortex-M0 |
| Core clock in Klipper | **200 MHz** (raised from 125 in 0.13.0) | 150 MHz | 150 MHz | 48 MHz |
| Klipper `CLOCK_FREQ` | 12 MHz | **150 MHz** | 150 MHz | 48 MHz |
| SRAM | 264 KB | 520 KB | 520 KB | **6 KB** |
| Flash | external QSPI only | RP2350A external / **RP2354A 2 MB stacked** | same | 32 KB internal |
| GPIO | 30 | 30 | **48** | ~23 (28-pin pkg) |
| ADC | 4 ch | 4 ch | 8 ch | 12-bit, ~10 ch |
| PIO | 2 blocks / 8 SM | **3 blocks / 12 SM** | same | none |
| CAN | software (can2040, uses a PIO) | software (can2040 v1.7) | same | **hardware bxCAN** |
| USB | device | device **+ host** | same | device |
| 5 V tolerant | no | **yes, GPIO0–25** (IOVDD @3.3 V) | yes, GPIO0–25 | no (a few FT pins) |
| Package | QFN-56 7×7 | QFN-60 7×7 | QFN-80 10×10 | **UFQFPN-28 4×4** |
| Klipper support since | 0.10.0 (2021) | **0.13.0 (2025-04-11)** | 0.13.0 | 0.8.0 (2019) |
| RPi 13" reel price | $0.70 | $0.80 / $1.00 | $0.90 / $1.10 | — |
| LCSC | [C2040](https://www.lcsc.com/product-detail/C2040.html) ~$0.73 | [C42411118](https://www.lcsc.com/product-detail/C42411118.html) ~$1.03 | — | see SKU table below |
## Why the `CLOCK_FREQ` row matters
`CONFIG_CLOCK_FREQ` in `src/rp2040/Kconfig` is the clock Klipper schedules against and reports to the host, not the CPU clock:
```
config CLOCK_FREQ
int
default 12000000 if MACH_RP2040
default 150000000 if MACH_RP2350
```
RP2040's timer is fed from the 1 µs tick chain off `clk_ref`, so Klipper gets 12 MHz — ~83 ns scheduling granularity. RP2350 schedules at 150 MHz — ~6.7 ns. ==Worth confirming on real hardware whether this actually shows up as measurably better step timing, or whether the step-generation path dominates.==
## RP2350 E9 — resolved, and gone from the channel
E9 was the Bank 0 GPIO pad defect: a pin configured as input with pull-down, driven to VDD and then released, would latch at roughly 2.1–2.2 V instead of falling. It started life documented as "latching behaviour on Bank 0 GPIO pull-down resistors" and was later redescribed as "increased leakage current on Bank 0 GPIO when pad input is enabled." For Klipper this bit anything using `~pin` (internal pull-down) — endstops, probes, filament sensors — and the community workaround was external pull-down resistor packs.
Status as of 2026:
- **Fixed in hardware in the A3 stepping**, which was an internal qualification stepping never sold as bare silicon (~30k A3 units went into Pico 2 / Pico 2 W boards).
- **A4 is the shipping stepping**, announced 2025-07-29. It carries the A3 hardware fixes plus a new boot ROM (errata 16, 20, 21, 24 — all security findings from the Hacking Challenge). A4 is a *metal spin*: metal layers only, no pinout or package change, software-compatible with A2 from Pico SDK 2.2.0 onward.
- **A2 production has ceased and remaining A2 inventory was withdrawn from the channel.** Anything bought new in 2026 is A4.
- External pull-down resistors are **no longer required**, but "may safely be retained in existing designs."
Identify the stepping two ways: the marking printed on top of the package, or `CHIP_ID.REVISION` / `rp2350_chip_version()` — **0x2 = A2, 0x3 = A3, 0x8 = A4**.
Also fixed in A3: **E3** (GPIO_NSMASK register behaviour on the 60-pin parts). Also fixed in A4 boot ROM: **E14**, where `connect_internal_flash()` always used GPIO0 as the second chip select and ignored the configured `FLASH_DEVINFO` value — relevant if you use CS1 for PSRAM.
**Not** fixed in A4: the OTP passive-voltage-contrast readback vulnerability, and assorted non-security errata with documented workarounds. Neither matters for a printer board.
A4 also brought the official **5 V tolerance** qualification — see [[RP2354A Hardware Design Reference]] for the exact conditions, because they are narrower than the headline suggests.
## RP2040 — still a perfectly good answer
Mature since Klipper 0.10.0, and the 200 MHz overclock in 0.13.0 keeps it competitive on step rate. Dozens of shipping Klipper boards (SKR Pico, Nitehawk-SB, EBB-class clones) to copy from. The reasons to move past it:
- No 5 V tolerance anywhere.
- ADC has known DNL problems.
- 12 MHz scheduling clock.
- Needs external QSPI flash — RP2354A doesn't.
## STM32F042G6U6 — three real constraints
### 1. 32 KB flash triggers `HAVE_LIMITED_CODE_SIZE`
From `src/stm32/Kconfig`:
```
select HAVE_LIMITED_CODE_SIZE if FLASH_SIZE < 0x10000
...
config FLASH_SIZE
hex
default 0x8000 if MACH_STM32F031 || MACH_STM32F042 || MACH_STM32F070x6
config RAM_SIZE
hex
default 0x1800 if MACH_STM32F042
```
32 KB flash, 6 KB RAM. Klipper PR #6884 split `WANT_GPIO_BITBANGING` / `WANT_DISPLAYS` into per-driver flags (`WANT_BUTTONS`, `WANT_TMCUART`, `WANT_NEOPIXEL`, `WANT_PULSE_COUNTER`, `WANT_HX71X`, `WANT_ST7920`, …) largely *because* of this part. Deselect everything and a build lands around 11 KB — but every feature you re-add eats the margin, and Katapult takes another 8 KB off the top.
### 2. USB and CAN share one 512-byte packet SRAM
RM0091 is blunt: the USB and CAN peripherals share a dedicated 512-byte SRAM and "can be used in the same application but not at the same time." In practice candleLight-class firmware works around it by splitting the buffer 256 B each way, which is how the F072-based U2C / FYSETC UCAN adapters function at all. On the F042's 6 KB of total RAM this is miserable. **Pick one interface.**
Klipper's Kconfig will still *offer* `USB to CAN bus bridge` on F0x2 (`HAVE_STM32_USBCANBUS default y`) — don't take that as an endorsement for this part.
### 3. 6 KB RAM is the actual ceiling
The move queue lives there. Fine for a stripped single-extruder toolhead; not fine for steppers + sensors + LEDs.
### What the F042 does well
- **Hardware bxCAN** — no PIO, no software CAN stack, just a transceiver.
- **System DFU bootloader at `0x1FFFC400`** — flash over USB with no programmer and no pre-loaded bootloader.
- **4×4 mm UFQFPN-28**, the smallest of the three by a wide margin.
- Klipper gives F042 exclusive remaps the other STM32s don't get: USB on **PA9/PA10** (`STM32_USB_PA11_PA12_REMAP`) and CAN on **PA9/PA10** (`STM32_CANBUS_PA11_PA12_REMAP`). Useful routing relief on a 28-pin part.
- Bootloader offsets available: 4 KiB or 8 KiB (Katapult).
### The three LCSC SKUs
All the same die, different ordering options. Checked 2026-09-18:
| LCSC | MPN | Package | Temp | Stock | Notes |
|---|---|---|---|---|---|
| [C961597](https://www.lcsc.com/product-detail/C961597.html) | STM32F042G6U6 | UFQFPN-28 4×4 | −40…+85 °C | ~1,300–1,900 | Tray/tube ("Alt. Packaging") |
| [C2971720](https://www.lcsc.com/product-detail/C2971720.html) | STM32F042G6U6**TR** | UFQFPN-28 4×4 | −40…+85 °C | ~840 | **Tape & reel — use this for JLCPCB assembly** |
| [C1340818](https://www.lcsc.com/product-detail/C1340818.html) | STM32F042G6U**7** | UFQFPN-28 4×4 | −40…+105 °C | **Out of stock** | Industrial grade |
Note that at LCSC the F042 is *more* expensive than an RP2040 (from ~$0.86–1.23 vs ~$0.73), even before you account for the RP2040 needing an external flash chip and crystal.
# Decisions
| Use case | Pick | Why |
|---|---|---|
| New general-purpose Klipper board | **RP2350A**, or **RP2354A** if board area is tight | 520 KB RAM, 150 MHz scheduling clock, 5 V tolerant GPIO, E9 is dead, ~$0.20 over RP2040 |
| RP2350B / RP2354B | only if you need >30 GPIO or 8 ADC | QFN-80 10×10 is a big jump in area |
| Lowest-risk, copy an existing design | **RP2040** | Mature since 2021, 200 MHz, huge body of reference designs |
| Minimal CAN toolhead, area-constrained | **STM32F042G6U6TR** | Hardware bxCAN + 4×4 mm, accepting a stripped feature set |
| Anything bigger on STM32 | **STM32G0B1** | FDCAN, 128 KB flash, 144 KB RAM — what BTT's EBB36/42 uses, and what [[Strangelove v2 Board Spec|Strangelove v2]] is built on |
## The RP2350 cost you can't design away
You must follow Raspberry Pi's hardware design guide exactly. The **Abracon AOTA-B201610S3R3-101-T** polarity-marked 3.3 µH inductor for the core SMPS and the **Abracon ABM8-272-T3** 12 MHz crystal are both still mandatory on A4 — they are not generic parts and not JLCPCB basic parts. Budget sourcing effort for both. Full detail in [[RP2354A Hardware Design Reference]].
# Firmware support status
| | Klipper master | Kalico `main` | Katapult | can2040 |
|---|---|---|---|---|
| RP2040 | yes, since 0.10.0 | yes | yes | yes |
| RP2350 | yes, since 0.13.0 | yes — `src/rp2040/Kconfig` is byte-identical apart from one added `HAVE_SOFTWARE_DIVIDE_REQUIRED if MACH_RP2040` | yes | yes, v1.7.0 |
| STM32F042 | yes, since 0.8.0 | yes | yes (F-series CAN) | n/a |
**The old "only the first 30 GPIOs" limit on RP2350 is gone.** Current master has:
```c
#define NUM_GPIO (CONFIG_MACH_RP2040 ? 30 : 48)
```
in `src/rp2040/gpio.c`, with `mask_to_pin()` and the setup paths handling the `pin >= 32` second SIO bank. RP2350B's full 48 pins work. The one leftover cap is CAN pin selection, still `range 0 29` in Kconfig:
```
config RPXXXX_CANBUS_GPIO_RX
int "CAN RX gpio number" if CANBUS
default 4
range 0 29
```
==Check whether the CAN GPIO range has been widened since — if you want CAN on a GPIO above 29 on a 2350B you may need a local patch.==
# TODO
- ==Decide RP2350A + external flash vs RP2354A for the next board — RP2354A saves the flash chip and its decoupling but locks QSPI_IOVDD to 3.3 V==
- ==Confirm current JLCPCB stock/assembly status for RP2350A and RP2354A, and whether the Abracon inductor and crystal are stocked there or need to be hand-supplied==
- ==Benchmark 12 MHz vs 150 MHz `CLOCK_FREQ` effect on real step timing before treating it as a deciding factor==
- ==Verify Katapult's CAN support explicitly lists rp2350 and not just rp2040 — docs lag the code==
# References
## Raspberry Pi
- [RP2350 A4, RP2354, and a new Hacking Challenge](https://www.raspberrypi.com/news/rp2350-a4-rp2354-and-a-new-hacking-challenge/) — the A4 announcement, E9 fix, pricing table
- [RP235x A4 stepping PCN](https://pip.raspberrypi.com/categories/1263-pcn/documents/RP-008771-CC/RP235x-A4-stepping-PCN.pdf)
- [RP2350 datasheet](https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf) — errata are Appendix E, stepping/fix matrix is Appendix C
- [Hardware design with RP2350](https://datasheets.raspberrypi.com/rp2350/hardware-design-with-rp2350.pdf)
- [RP2350 product brief](https://datasheets.raspberrypi.com/rp2350/rp2350-product-brief.pdf)
- [All RP2350 documents (PIP)](https://pip.raspberrypi.com/categories/1214-rp2350)
## Klipper / Kalico
- [Klipper Releases](https://www.klipper3d.org/Releases.html)
- [PR #6725 — Add support for rp2350 micro-controllers](https://github.com/Klipper3d/klipper/pull/6725)
- [PR #6776 — Update can2040 to v1.7.0](https://github.com/Klipper3d/klipper/pull/6776)
- [PR #6884 — For low flash size chips, improve options for reducing size](https://github.com/Klipper3d/klipper/pull/6884)
- [Support for rp2350 micro-controllers — Klipper Discourse](https://klipper.discourse.group/t/support-for-rp2350-micro-controllers/19656)
- [`src/stm32/Kconfig`](https://github.com/Klipper3d/klipper/blob/master/src/stm32/Kconfig) · [`src/rp2040/Kconfig`](https://github.com/Klipper3d/klipper/blob/master/src/rp2040/Kconfig) · [`src/rp2040/gpio.c`](https://github.com/Klipper3d/klipper/blob/master/src/rp2040/gpio.c)
- [Kalico](https://github.com/KalicoCrew/kalico)
- [Katapult](https://github.com/Arksine/katapult)
- [Klipper CANBUS docs](https://www.klipper3d.org/CANBUS.html) · [Bootloaders](https://www.klipper3d.org/Bootloaders.html)
## ST
- [RM0091 — STM32F0x1/F0x2/F0x8 reference manual](https://www.st.com/resource/en/reference_manual/rm0091-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) — the USB/CAN shared-SRAM statement
- [AN4879 — USB hardware and PCB guidelines using STM32 MCUs](https://www.st.com/resource/en/application_note/an4879-introduction-to-usb-hardware-and-pcb-guidelines-using-stm32-mcus-stmicroelectronics.pdf)
## Related notes
- [[RP2354A Hardware Design Reference]]
- [[STM32G0B1CBT6 LQFP-48 Layout Playbook]]
- [[Strangelove v2 Board Spec]]
- [[STM32 Toolboard Track]]
- [[JLCPCB Design Notes]]