#prusawire #einsy #klipper #avr #atmega2560 #atmega32u2 #usbasp #avrdude #3d-printing
# Overview
How to get Klipper running on a Prusa-sourced **Einsy RAMBo 1.1a** with a Raspberry Pi 4 host. The Einsy carries two AVRs: the **ATmega2560** that runs the printer, and an **ATmega32u2** that is only a USB-to-serial bridge. Prusa ships the 32u2 with firmware that corrupts serial traffic under Klipper's protocol, so the job has two halves:
1. Reflash the 32u2 with the PrusaOwners *hoodserial* firmware using a **USBasp** programmer — the method Chris Warkocki worked out and nikolak wrote up. Four commands, no soldering, no auto-reset tricks.
2. Build and flash Klipper onto the 2560 over plain USB through the stock bootloader — no programmer needed for that half.
Scope: USBasp only. The PrusaOwners README's default is an Arduino Uno running ArduinoISP; that and Pi-GPIO (`linuxspi`) routes are not covered here.
# Resources
- [[Prusawire]] — parent build note
- [[Prusawire Software Installation and Configuration]] — Mainsail/Klipper host install and Prusawire config; it stops at "if you're on the Einsy you're done", which is where this note picks up
- [[Prusawire NeoPixel Pico MCU And Level Shifting]] — why the Einsy's spare pins and AVR timing pushed the LEDs onto a KB2040
- [[How to Klipper on Prusa MK3S+]] — clipping of nikolak's post: the USBasp procedure below, plus a known-good MK3S config
- [[PrusaOwnersmk3-32u2-firmware Updated Atmega 32u2 Firmware for the Einsy Rambo]] — clipping of the upstream README (wiring tables, commands, firmware background)
- [[Stock Prusa MK3s+ Einsy Klipper Fix]] — clipping of Chris Warkocki's Patreon post (2021-02-25), the origin of the four-command USBasp procedure; has the close-up photo of the header and the bench setup
- [nikolak — How to: Klipper on Prusa MK3S/+](https://nikolak.com/klipper-on-prusa-mk3s/) — relays Warkocki's procedure with the same commands
- [Chris Warkocki — Stock Prusa MK3s+ Einsy Klipper Fix (Patreon)](https://www.patreon.com/chriswarkocki/posts/stock-prusa-mk3s-48015680) — original
- [PrusaOwners/mk3-32u2-firmware](https://github.com/PrusaOwners/mk3-32u2-firmware) — the fixed 32u2 firmware, USBasp pin table, background
- [USBasp — fischl.de](https://www.fischl.de/usbasp/) — the original design; jumper functions and the 10-pin pinout are documented here
- [DollaTek USBasp (Amazon B07DK5M7LZ)](https://www.amazon.com/DollaTek-USBASP-USBasp_H6-Programmer-Support/dp/B07DK5M7LZ) — the ~$5 clone nikolak used; any 16c0:05dc clone plus a 10→6 pin ISP adapter works
- [Einsy Rambo 1.1a schematic (PDF)](https://raw.githubusercontent.com/ultimachine/Einsy-Rambo/1.1a/board/Project%20Outputs/Schematic%20Prints_Einsy%20Rambo_1.1a.PDF) — sheet 4 "USB-Serial" has X17, JP3/JP4 and the isolator; sheet 5 has J19 and P2
- [Einsy Rambo 1.1a BOM](https://raw.githubusercontent.com/ultimachine/Einsy-Rambo/1.1a/board/Project%20Outputs/Assembly/tab_bom_Einsy%20Rambo_1.1a.txt) — confirms JP3/JP4 are populated with 0 Ω
- [Klipper `generic-einsy-rambo.cfg`](https://github.com/Klipper3d/klipper/blob/master/config/generic-einsy-rambo.cfg) · [Klipper Installation](https://www.klipper3d.org/Installation.html) · [Klipper Bootloaders](https://www.klipper3d.org/Bootloaders.html)
- [charminULTRA 32u2 Hoodserial Flash Guide](https://github.com/charminULTRA/Klipper-Input-Shaping-MK3S-Upgrade/blob/main/32u2-Hoodserial-Flash-Guide.md) — 2026 write-up (also USBasp) with before/after `bytes_invalid` numbers and measured fuses
- [avrdude programmer definitions (`avrdude.conf.in`)](https://github.com/avrdudes/avrdude/blob/main/src/avrdude.conf.in) — `usbasp` vs `usbasp-clone`
# Design
## The two chips and why the 32u2 must be reflashed
| Chip | Role | Package / location | Programmed via |
|---|---|---|---|
| ATmega2560 | Runs Marlin or Klipper | Big 100-pin QFP, board centre | USB, through the stock STK500v2 bootloader (`avrdude -c wiring`) |
| ATmega32u2 | USB↔serial bridge only | Small chip beside the USB-B jack, silk `U1` | ISP header **X17** — schematic "32u2 ICSP", silkscreen **`ICSP-U1`** — the only 2×3 header on the board |
Klipper's own config says it plainly: *"The Einsy boards sold by Prusa have defective firmware on the usb-to-serial chip that make the boards unusable with Klipper (boards sold by Ultimaker do not have this issue)."* Prusa knows the chip's firmware is flaky — PrusaSlicer's bundled avrdude carries a "Prusa3D workaround" that splits semicolons into two nibble writes because early 32u2 firmware emitted a stray 0xFF after one.
**Symptom under Klipper:** `bytes_invalid` and `bytes_retransmit` climb steadily in the klippy.log stats lines, ending in `Lost communication with MCU 'mcu'` — often mid-print. One documented case went from 468,627 invalid bytes after a 75-minute print to 0 after the reflash. Check with:
```bash
grep bytes_invalid ~/printer_data/logs/klippy.log | tail -5
```
## What the replacement firmware is
`DFU-hoodserial-combined-PrusaMK3-32u2.hex` from PrusaOwners = **hoodserial** (a port of Nico Hood's HoodLoader2 USB-serial, with Urja Rannikko's fastserial) + a **DFU bootloader** in the top 4 KiB. Points that matter:
- USB identity is unchanged: VID `2c99`, PID `0002`, product string "Original Prusa i3 MK3". The printer's **serial number is read from the 32u2's EEPROM**, which is why the fuse dance below protects EEPROM.
- hoodserial wires **DTR → 2560 reset**, so both `avrdude -c wiring` and Klipper's `restart_method: arduino` keep working.
- Prusa/Marlin firmware still works over USB afterwards, and `avrdude -c wiring` can still flash the 2560 (confirmed in PrusaOwners issue #1). The change is reversible (see [[#Reverting to Prusa firmware]]).
- The DFU bootloader is resident, but entering it needs the 32u2's **HWB pin (PD7) held low during reset**. On the 1.1a, PD7 sits on the DTR net behind solder jumper **JP1 "USB boot En"** (bottom side, sheet 4) with a 1 kΩ pull-up — there is no dedicated test point. ==In practice, any future 32u2 reflash still goes through ISP.==
## What the programmer's 5 V actually powers
X17 pin 2 is **USBVCC** and pin 6 is **GND1** — nominally the 32u2's own USB-side domain, with an ADUM7441 isolator carrying the serial lines across to the board's 5 V logic (VCC/GND). But on a built 1.1a, solder jumpers **JP3 (USBVCC↔VCC)** and **JP4 (GND1↔GND)** are populated with 0 Ω per UltiMachine's BOM. So the domains are tied together, and the USBasp's 5 V **back-powers the whole 5 V logic rail** — 2560, TMC2130 logic, LCD — exactly as a Pi back-powers an MK3 over USB. That is why:
- the printer PSU stays **off** for the entire 32u2 procedure (README and nikolak both say so) — never have two 5 V sources fighting;
- the LCD and 2560 will wake up when the USBasp is plugged in — expected;
- the USBasp's target-power jumper has no short-circuit protection (Fischl's README), so a rotated connector must be caught **before** the dongle goes into the Pi.
## Programmer: USBasp
A USBasp is a ~$5 ATmega8-based ISP dongle (Thomas Fischl's open design, cloned everywhere). It shows up as USB `16c0:05dc`, needs no driver on Linux, and — unlike an Arduino running ArduinoISP — has no serial port and therefore no auto-reset to defeat. The 10-pin IDC ribbon needs a **10→6 pin ISP adapter** to mate with X17; many clones include one, some don't (charminULTRA bought a Comimark B07WZF6Z27 separately).
| Function | Typical clone label | Setting for the Einsy |
|---|---|---|
| Target power / voltage select | `JP1` (5V/3.3V) or a `VCC` jumper | **5 V** — the USBasp must supply the target |
| Self-programming (update the USBasp's own firmware) | `JP2` | **open** |
| Slow SCK (< 1.5 MHz targets) | `JP3` | **open** — the 32u2 runs at 16 MHz. Close it only if `target doesn't answer` persists |
==Silkscreen labels differ between clones; identify the jumpers by function on the board in hand.==
**10-pin USBasp connector → Einsy X17** (from the PrusaOwners README):
| USBasp 10-pin | Signal | Einsy X17 pin |
|---|---|---|
| 1 | MOSI | 4 |
| 2 | VCC | 2 |
| 4 | GND | 6 |
| 5 | RESET | 5 |
| 7 | SCK | 3 |
| 9 | MISO | 1 |
With the 10→6 adapter you don't wire any of that: the 6-pin socket maps 1 MISO · 2 VCC · 3 SCK · 4 MOSI · 5 RESET · 6 GND, same as X17 (schematic sheet 4: MISO2, USBVCC, SCK2, MOSI2, RESET2, GND1). Only pin-1 orientation matters.
# Configuration
## Part 1 — Reflash the 32u2 with a USBasp
### 1. Prepare the USBasp and the Pi
1. Set the USBasp's voltage/power jumper to **5 V**; leave self-program and slow-SCK open.
2. On the Pi 4:
```bash
sudo apt-get install avrdude
lsusb | grep -i 16c0
# Bus 001 Device 00x: ID 16c0:05dc Van Ooijen Technische Informatica shared ID for use with libusb
```
The `16c0:05dc` line is the USBasp. Commands below use `sudo` because the clone's USB device isn't group-accessible by default (a udev rule is the tidy alternative).
### 2. Connect the USBasp to X17
Everything unplugged: printer PSU off, no USB cable on the Einsy, USBasp not yet in the Pi. (Warkocki's ordering — printer and Pi both off, USBasp into the dead Pi, 6-pin onto the Einsy, then power the Pi — ends in the same state: nothing is live until the connector is seated.)
X17 is the 2×3 header inboard of the USB-B jack — between the reset button `S1` and the 2×7 J19 header — with silkscreen **`ICSP-U1`** beside it. Warkocki's close-up:
![[Stock-Prusa-MK3s+-Einsy-Klipper-Fix-2.jpg|420]]
With the USB jack at the top, the PrusaOwners photo shows pin 1 (MISO, blue wire) top-left and pin 2 (5 V, red) top-right; rows go 3/4, then 5/6: [einsy_uno.png](https://raw.githubusercontent.com/PrusaOwners/mk3-32u2-firmware/master/images/einsy_uno.png). Neither photo shows a legible pin-1 marker on the silk, so orientation rests on that wiring photo plus the continuity check below.
- Plug the adapter's 6-pin socket onto X17 with its **pin 1 (red ribbon stripe / triangle) on X17 pin 1**.
- Rotated 180° maps plug pin *n* → header pin 7−*n*: programmer **VCC lands on RESET2**, **GND on MISO**, **RESET on USBVCC**, SCK/MOSI swapped. RESET2 has a 1N4148 (D4) to USBVCC, so 5 V would forward-bias through that diode into the whole back-powered 5 V rail, and the USBasp would then try to sink that rail when it asserts reset. Catch it before power is applied.
- ==Continuity-check once seated, before the USBasp goes into the Pi: adapter pin 6 → a real ground (USB-B pin 4, J19-14, or the PSU − terminal — JP4 ties GND1 to GND) and adapter pin 2 → a 5 V point (J19-10 or P3 pin 2 — JP3 ties USBVCC to VCC). Do **not** use the USB-B shell as ground: it sits behind 1 MΩ ∥ 4.7 nF and reads open.==
- Then plug the USBasp into the Pi. The board's 5 V rail (LCD included) comes up from the programmer.
### 3. Back up the stock 32u2
```bash
mkdir -p ~/mk3_32u2_backup && cd ~/mk3_32u2_backup
sudo avrdude -p m32u2 -F -P usb -c usbasp-clone \
-U flash:r:firmware_backup.hex:i -U eeprom:r:eeprom.hex:i \
-U lfuse:r:lowfuse:h -U hfuse:r:highfuse:h -U efuse:r:exfuse:h -U lock:r:lockfuse:h
```
- `-c usbasp-clone` matches any device with the USBasp VID/PID regardless of its USB strings; plain `-c usbasp` insists on Fischl's `www.fischl.de` / `USBasp` strings, which many clones don't carry. `-P usb` is required syntax rather than a real port: avrdude ≤ 7.1 ignores it; avrdude 8 accepts `usb` or `usb:<bus:dev>` to pick between several dongles.
- A "cannot set sck period" message (warning in avrdude 6.3, labelled *error* in 7.x, but ignored either way) is normal on clone firmware; it proceeds.
- `-F` skips the signature check; still **read the signature line**. ATmega32U2 is `0x1e 0x95 0x8a`. All zeros or all 0xFF means a rotated connector, an unseated pin, or a miswired adapter — stop.
- Expected stock fuses: lfuse `0xEF`, hfuse `0xD9`, efuse `0xF4`, lock `0xCF`. The EEPROM dump is the valuable part (serial number lives there). If the flash read times out, fuses + EEPROM are what matter.
**Check the backed-up fuses before writing anything:**
```bash
cd ~/mk3_32u2_backup && head lowfuse highfuse exfuse lockfuse
```
| File | Expected |
|---|---|
| `lowfuse` | `0xef` |
| `highfuse` | `0xd9` |
| `exfuse` | `0xf4` |
| `lockfuse` | `0xcf` |
If `highfuse` isn't `0xd9`, stop and work out why before the EESAVE step. Step 4 assumes stock fuses, and the final command writes `0xD9` back no matter what was there before. Copy `eeprom.hex` off the Pi's SD card too (e.g. `scp` it to your local machine): it's the only copy of the printer's serial number.
### 4. Flash hoodserial
```bash
# 1. Enable EESAVE first so the chip erase does not wipe the serial number
sudo avrdude -p m32u2 -F -P usb -c usbasp-clone -U hfuse:w:0xD1:m
# 2. Fetch the combined DFU + hoodserial image
wget https://raw.githubusercontent.com/PrusaOwners/mk3-32u2-firmware/master/hex_files/DFU-hoodserial-combined-PrusaMK3-32u2.hex
# 3. Write it, then hfuse back to 0xD9 (EESAVE off again)
sudo avrdude -p m32u2 -F -P usb -c usbasp-clone \
-U flash:w:DFU-hoodserial-combined-PrusaMK3-32u2.hex \
-U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m
```
The avrdude flags are identical to Warkocki's Steps 7–10 and nikolak's copy of them (the `mkdir`/`cd` line is from the PrusaOwners README). Order matters: 0xD1 before the flash write, 0xD9 after. Because the final state has EESAVE off, **any later reflash must set 0xD1 first again** or the serial number is gone. lfuse ends at `0xFF`, not the stock `0xEF` (SUT bits only — functionally fine); efuse stays `0xF4` (HWBE on); the chip erase clears the lock byte and nothing rewrites it, so it will read `0xFF` afterwards instead of `0xCF`.
### 5. Verify
Unplug the USBasp from the Pi, then lift the adapter off X17. Plug the Einsy's USB into the Pi and **restore printer power** (README: "connect your MK3 to the Pi via USB, and restore power to the MK3"):
```bash
dmesg | tail -n 20
# idVendor=2c99, idProduct=0002 ... Product: Original Prusa i3 MK3
# SerialNumber: <your serial, unchanged> ... cdc_acm ... ttyACM0
ls -l /dev/serial/by-id/
# usb-Prusa_Research__prusa3d.com__Original_Prusa_i3_MK3_<SERIAL>-if00 -> ../../ttyACM0
```
If the serial number is intact and it enumerates as `cdc_acm`, the 32u2 is done. Before Part 2, do one **full power cycle** — USB out, PSU off, wait, PSU on, USB in — so the 32u2 starts clean on the new firmware.
## Part 2 — Klipper on the ATmega2560
No programmer involved. Prusa's 2560 bootloader is their edition of the standard STK500v2 "wiring" bootloader at `0x3E000`, which is exactly what Klipper's `make flash` targets. Printer PSU **on** for this part. This is required, not just cautious: on [[erikbuild - Prusawire 2026.R1 - Enceladus|Enceladus]], `make flash` on USB back-power alone failed with `avrdude error: timeout communicating with programmer`, then succeeded first try once the PSU was connected.
### Build
```bash
cd ~/klipper && make menuconfig
```
- Micro-controller Architecture: **Atmega AVR**
- Processor model: **atmega2560**
- Defaults are already correct: 16 MHz, UART0, 250000 baud. They're only visible after ticking *Enable extra low-level configuration options*; if you look, confirm **UART0** (UART1 would be the Pi GPIO header path).
`Q`, `Y`, then `make`.
### Flash
```bash
ls /dev/serial/by-id/*
sudo service klipper stop
make flash FLASH_DEVICE=/dev/serial/by-id/usb-Prusa_Research__prusa3d.com__Original_Prusa_i3_MK3_<SERIAL>-if00
sudo service klipper start
```
Under the hood that is `avrdude -patmega2560 -cwiring -P<dev> -D -Uflash:w:out/klipper.elf.hex:i` at the wiring driver's default 115200, with DTR/RTS bouncing the 2560 into its bootloader — which only works because hoodserial passes DTR through. A successful run writes ~41 KB and verifies.
### `[mcu]`
```ini
[mcu]
serial: /dev/serial/by-id/usb-Prusa_Research__prusa3d.com__Original_Prusa_i3_MK3_<SERIAL>-if00
# restart_method: default 'arduino' (DTR toggle) works with hoodserial.
# Some MK3S configs (dz0ny, charminULTRA) set 'command'; Positron3D's leaves the default. Either works over USB.
```
Klipper's `generic-einsy-rambo.cfg` ships only `serial: /dev/ttyACM0`; use the by-id path so a USB re-enumeration (e.g. the KB2040 from [[Prusawire NeoPixel Pico MCU And Level Shifting]] grabbing `ttyACM0`) doesn't swap devices. Prusawire-specific pins and macros come from the [Positron3D config](https://github.com/Positron3D/prusawire-klipper-config) per [[Prusawire Software Installation and Configuration]].
Kalico builds for `atmega2560` the same way — same `make menuconfig` path, same `generic-einsy-rambo.cfg` present in its tree.
## Reverting to Prusa firmware
With hoodserial in place, the 2560 flashes back the normal way: `avrdude -p atmega2560 -c wiring -P <dev> -b 115200 -D -U flash:w:<prusa>.hex:i` (confirmed post-hoodserial in PrusaOwners issue #1). PrusaSlicer → *Configuration → Flash Printer Firmware* uses the same `-c wiring -b 115200 -D` path and ==should work too, though no one has documented running the GUI flasher against a hoodserial 32u2==. Nothing about the 32u2 needs to change; leave hoodserial on it.
## Fallback only: ISP-flashing the 2560
Only relevant if the 2560's bootloader is ever destroyed. There is no separate 2560 ICSP header on a 1.1a — the changelog says "Combined 2560 ICSP (X18) with pins 9–14 of J19". Sheet 5: **J19-9 MISO · J19-10 VCC · J19-11 SCK · J19-12 MOSI · J19-14 GND**. **Do not take reset from J19-13**: it drives the base of Q3, so it is an *active-high, inverted* reset — a standard programmer on it would hold the 2560 in reset when idle. UltiMachine's answer in issue #2: "The reset signal on J19 is inverted. If you use the one on the P2 header it should work." Take nRESET from **P2 pin 3** (or test point TP37). Bootloader hex: [prusa3d/stk500v2-prusa](https://github.com/prusa3d/stk500v2-prusa). ==Prusa's shipped 2560 fuse bytes are undocumented; UltiMachine's RAMBo-family values are lfuse 0xFF / hfuse 0xD0 / efuse 0xFD / lock 0x0F.==
# Decisions
- **Decision**: USBasp as the ISP programmer.
- **Why**: It is the method Chris Warkocki documented and nikolak verified — four commands. No serial port means no DTR auto-reset to suppress, so none of the 10 µF-capacitor fiddling an Arduino-as-ISP needs. With a 10→6 adapter it mates directly with X17. ~$5.
- **Alternatives**: Arduino Uno with ArduinoISP (the PrusaOwners README default; needs six jumpers and a reset cap); an Arduino Mega 2560 the same way (hardware SPI on D50/51/52, reset from D10 — considered, dropped); avrdude `linuxspi`/`linuxgpio` straight from the Pi 4 header.
- **Decision**: `-c usbasp-clone -P usb`, as nikolak wrote it.
- **Why**: Clone dongles usually lack Fischl's USB strings, so `-c usbasp` may refuse to find the device. `usbasp-clone` is the same driver minus the string match. If a given dongle does carry the strings, either works.
- **Decision**: Flash the 2560 over USB via the stock bootloader, never via ISP.
- **Why**: The bootloader is there and `make flash` uses it. ISP on the 2560 means J19 pin-hunting, an inverted reset line, and re-burning a bootloader for no gain.
# Troubleshooting
Message wording below is avrdude 6.3's (Raspberry Pi OS bullseye); bookworm/trixie ship 7.1, which prints the same conditions as `avrdude error: cannot find USB device …`, `avrdude error: program enable: target does not answer (0x01)`, `avrdude error: initialization failed, rc=-1`.
- **Symptom**: `could not find USB device with vid=0x16c0 pid=0x5dc vendor='www.fischl.de' product='USBasp'`.
- **Cause**: Used `-c usbasp` with a clone that has blank USB strings — or the dongle isn't visible (permissions, bad USB cable, dead clone).
- **Fix**: `-c usbasp-clone`; confirm with `lsusb | grep 16c0`; run under `sudo` or add a udev rule.
- **Symptom**: `cannot set sck period. please check for usbasp firmware update.`
- **Cause**: Clone firmware predates the settable-SCK feature.
- **Fix**: None needed. It proceeds normally (even when 7.x labels it an error).
- **Symptom**: `program enable: target doesn't answer. 1` / `initialization failed, rc=-1`.
- **Cause**: Adapter rotated 180° on X17, a miswired adapter, target unpowered (voltage jumper not supplying 5 V), or a pin not seated.
- **Fix**: Unplug the USBasp from the Pi first. Re-seat with pin 1 on pin 1; redo the continuity check against real ground/5 V points; check the jumper. As a last resort close the slow-SCK jumper and retry.
- **Symptom**: Signature reads `0x000000` or `0xffffff`.
- **Cause**: Connector rotated, unseated, or MISO/MOSI swapped in a hand-made cable.
- **Fix**: Stop; `-F` only suppresses the check, it does not make the write land somewhere sane. Re-verify X17 pin 1 orientation against the photo.
- **Symptom**: `make flash` prints `avrdude error: timeout` six times, then `timeout communicating with programmer` / `unable to open programmer wiring on port …`. Nothing is written.
- **Cause**: Printer PSU off. The board was running on USB back-power from the Pi, and the 2560's bootloader never answered after the DTR reset.
- **Fix**: Connect and switch on the printer PSU, then rerun `make flash`. Confirmed 2026-09-23. The bootloader is never touched, so a failed attempt is harmless.
- **Symptom**: `make flash` (or PrusaSlicer) times out with `stk500v2_ReceiveMessage(): timeout` right after the 32u2 reflash.
- **Reported fix**: PrusaOwners issue #1 — the reporter's timeouts went away after the printer had been fully disconnected ("I guess unpowering the 32u2 did the trick"). Unplug USB *and* the printer PSU, wait, reconnect with PSU on, retry.
- **Symptom**: Flash *read* during the backup hangs or times out.
- **Cause**: Slow ISP link / cheap clone.
- **Fix**: Make sure `eeprom.hex` and the four fuse files were captured; those are what restore the serial. Retry the flash read separately if you want it.
- **Symptom**: Still seeing `Lost communication with MCU` or climbing `bytes_invalid` after hoodserial.
- **Cause**: The 32u2 is no longer the suspect — look at the USB cable, Pi power supply, EMI from stepper/heater wiring near the USB run, or host overload (`Timer too close`).
- **Fix**: Different cable, ferrite, reroute; check `klippy.log` for which error it actually is.
# TODO
- ==Check Thoth Station's klippy.log for `bytes_invalid` / `bytes_retransmit` to learn whether its 32u2 already carries hoodserial. (The 2026-09-23 reflash was Enceladus's board, not Thoth Station's.)==
- ~~Get a USBasp and a 10→6 pin ISP adapter~~ (done 2026-09-23)
- ~~Identify the voltage / self-program / slow-SCK jumpers on the actual dongle and set 5 V before first use~~ (done 2026-09-23)
- ~~Continuity-check adapter pins 2 / 6 before plugging the USBasp into the Pi~~ (done 2026-09-23)
- ~~Watch `bytes_invalid` in klippy.log over the first long print; it should stay at 0.~~
- ~~Copy `~/mk3_32u2_backup/` (especially `eeprom.hex`) off the Pi.~~
# References
- [[Prusawire]] · [[erikbuild - Prusawire PW.0011 - Thoth Station]] · [[erikbuild - Prusawire 2026.R1 - Enceladus]] · [[Prusawire Software Installation and Configuration]] · [[Prusawire NeoPixel Pico MCU And Level Shifting]]
- [[Stock Prusa MK3s+ Einsy Klipper Fix]] · [[How to Klipper on Prusa MK3S+]] · [[PrusaOwnersmk3-32u2-firmware Updated Atmega 32u2 Firmware for the Einsy Rambo]]
- [Chris Warkocki — Stock Prusa MK3s+ Einsy Klipper Fix (Patreon)](https://www.patreon.com/chriswarkocki/posts/stock-prusa-mk3s-48015680) · [nikolak — Klipper on Prusa MK3S/+](https://nikolak.com/klipper-on-prusa-mk3s/)
- [PrusaOwners/mk3-32u2-firmware README](https://github.com/PrusaOwners/mk3-32u2-firmware) · [issue #1 (post-flash stk500v2 timeout)](https://github.com/PrusaOwners/mk3-32u2-firmware/issues/1) · [`hoodserial.c` (DTR→reset)](https://github.com/PrusaOwners/mk3-32u2-firmware/blob/master/hoodserial/hoodserial.c) · [`Descriptors.c` (serial from EEPROM)](https://github.com/PrusaOwners/mk3-32u2-firmware/blob/master/hoodserial/Descriptors.c)
- [USBasp — fischl.de](https://www.fischl.de/usbasp/) · [USBasp README (target-power caveat)](https://www.fischl.de/usbasp/Readme.txt) · [avrdude.conf.in (`usbasp`, `usbasp-clone`)](https://github.com/avrdudes/avrdude/blob/main/src/avrdude.conf.in) · [avrdude `usbasp.c`](https://github.com/avrdudes/avrdude/blob/main/src/usbasp.c)
- [Einsy Rambo 1.1a schematic](https://raw.githubusercontent.com/ultimachine/Einsy-Rambo/1.1a/board/Project%20Outputs/Schematic%20Prints_Einsy%20Rambo_1.1a.PDF) · [1.1a BOM (JP3/JP4 = 0 Ω)](https://raw.githubusercontent.com/ultimachine/Einsy-Rambo/1.1a/board/Project%20Outputs/Assembly/tab_bom_Einsy%20Rambo_1.1a.txt) · [ultimachine/Einsy-Rambo issue #2 (J19 reset is inverted; use P2)](https://github.com/ultimachine/Einsy-Rambo/issues/2) · [RepRap EinsyRambo development](https://reprap.org/wiki/EinsyRambo_development)
- [Klipper `generic-einsy-rambo.cfg`](https://github.com/Klipper3d/klipper/blob/master/config/generic-einsy-rambo.cfg) · [`src/avr/Makefile`](https://github.com/Klipper3d/klipper/blob/master/src/avr/Makefile) · [Bootloaders](https://www.klipper3d.org/Bootloaders.html) · [Config Reference `[mcu]`](https://www.klipper3d.org/Config_Reference.html#mcu)
- [prusa3d/stk500v2-prusa](https://github.com/prusa3d/stk500v2-prusa) · [PrusaSlicer `FirmwareDialog.cpp`](https://github.com/prusa3d/PrusaSlicer/blob/master/src/slic3r/GUI/FirmwareDialog.cpp) · [PrusaSlicer bundled `stk500v2.c` (semicolon workaround)](https://github.com/prusa3d/PrusaSlicer/blob/master/bundled_deps/avrdude/avrdude/stk500v2.c)
- [Klipper Discourse: MCU disconnect sadness (MK3S)](https://klipper.discourse.group/t/mcu-disconnect-sadness/1396) · [charminULTRA 32u2 flash guide](https://github.com/charminULTRA/Klipper-Input-Shaping-MK3S-Upgrade/blob/main/32u2-Hoodserial-Flash-Guide.md) · [dz0ny/klipper-prusa-mk3s](https://github.com/dz0ny/klipper-prusa-mk3s)
- [KalicoCrew/kalico `src/avr/Kconfig`](https://github.com/KalicoCrew/kalico/blob/main/src/avr/Kconfig)
# Changelog
## 2026-09-21
- Researched the 32u2 fix and the USB path for the 2560; wrote this note.
- Confirmed from the 1.1a schematic (sheet 4): X17 is the 32u2 ICSP, pin 2 = USBVCC, pin 6 = GND1, pin 5 = RESET2.
- First draft used an Arduino Mega 2560 as an ArduinoISP programmer. Replaced with the USBasp method from nikolak / Chris Warkocki: no reset-capacitor dance, plugs straight onto X17 via the 10→6 adapter, and it's the procedure most MK3S Klipper converts have actually run.
- Clean-room review caught a wrong safety claim: the first draft said the ADUM7441 isolates the 32u2's supply so the programmer "can't backfeed the board". Wrong on a built board — JP3/JP4 are 0 Ω per the BOM, so the USBasp back-powers the entire 5 V rail. Rewrote [[#What the programmer's 5 V actually powers]], the rotated-connector analysis, and the continuity check (USB shell is not a DC ground). Also fixed the fallback-ISP section: J19-13 is an inverted reset; use P2-3.
- Clipped Warkocki's Patreon post ([[Stock Prusa MK3s+ Einsy Klipper Fix]]) and checked it directly: Steps 7–10 are the four commands here, same DollaTek dongle, printer unpowered throughout. His close-up photo gives the silkscreen label `ICSP-U1` and confirms the header sits between `S1` and J19.
- ==Not yet flashed — Thoth Station's current 32u2 state is unknown.== (Enceladus's board was flashed 2026-09-23; Thoth Station's is still unchecked.)
## 2026-09-23
- Board: [[erikbuild - Prusawire 2026.R1 - Enceladus|Enceladus]]'s Einsy.
- Backed up the stock 32u2 with the USBasp on the Pi (`enceladus`). Signature `0x1e958a`; flash read took 13.7 s. The clone printed `cannot set sck period` every run, which is harmless.
- Set hfuse to `0xD1`, then flashed the combined DFU + hoodserial hex: 7,418 bytes written and verified; lfuse `0xFF`, hfuse `0xD9` and efuse `0xF4` verified.
- The Einsy enumerated on USB alone with its serial `CZPX3919X004XC48920` intact, so EESAVE worked.
- Klipper `v2026.09.00-5-g84a41057` for the atmega2560: `make flash` on USB power only failed with repeated `avrdude error: timeout`. With the printer PSU connected, it flashed on the first try.