Skip to content

Instantly share code, notes, and snippets.

@crysxd
Last active February 1, 2026 08:35
Show Gist options
  • Select an option

  • Save crysxd/54f758536cf3b45101d195145b55d129 to your computer and use it in GitHub Desktop.

Select an option

Save crysxd/54f758536cf3b45101d195145b55d129 to your computer and use it in GitHub Desktop.
Flashing Klipper and Katapult on a Creality 4.2.2 Board with a broken bootloader

Flashing Katapult Bootloader and Klipper Firmware on Creality 4.2.2 Board without a working bootloader

I accidentally broke the bootloader on my Creality 4.2.2 board while flashing Klipper. These instructions show how I recovered and how I flashed Klipper and Katapult as bootloader. You can always follow these steps also if you have a working bootloader and could flash via SD card as with Katapult you can update Klipper without the SD card.

Table of Contents


Hardware Requirements

  • Creality 4.2.2 board (STM32F103 MCU)
  • Raspberry Pi (any model with GPIO, used as SWD programmer)
  • Jumper wires for SWD connection
  • USB cable or Serial UART adapter for communication
  • Power supply for the 3D printer board

Software Requirements

  • Raspberry Pi OS (Raspbian)
  • OpenOCD (compiled with bcm2835gpio support)
  • Git
  • Build tools (gcc, make, etc.)

Wiring Setup

SWD Connection: Raspberry Pi to Creality 4.2.2

Connect the following pins between your Raspberry Pi and the Creality 4.2.2 board's SWD header:

Raspberry Pi GPIO Function Creality 4.2.2 SWD Header
GPIO 25 (Pin 22) SWCLK SWCLK
GPIO 24 (Pin 18) SWDIO SWDIO
GND (Pin 20) Ground GND
3.3V (Pin 1) Power 3.3V (optional)

Untitled 001

USB Connection (for Klipper communication)

After flashing, connect the Creality 4.2.2 board to your Raspberry Pi (or host computer) via USB cable. The board will appear as a USB serial device.


Setting Up OpenOCD on Raspberry Pi

1. Install Dependencies

sudo apt update
sudo apt install git autoconf libtool make pkg-config libusb-1.0-0-dev telnet

2. Clone and Compile OpenOCD

OpenOCD must be compiled from source to enable bcm2835gpio support:

cd ~
git clone https://github.com/openocd-org/openocd.git
cd openocd
./bootstrap
./configure --enable-bcm2835gpio --enable-sysfsgpio
make -j$(nproc)
sudo make install

3. Create OpenOCD Configuration File

Create a configuration file for the STM32F103 target:

nano ~/stm32-flash.cfg

Add the following content:

source [find interface/raspberrypi-native.cfg]
bcm2835gpio_swd_nums 25 24
transport select swd
source [find target/stm32f1x.cfg]
adapter speed 1000

Explanation:

  • raspberrypi-native.cfg: Uses Raspberry Pi GPIO as programmer
  • bcm2835gpio_swd_nums 25 24: Sets GPIO 25 as SWCLK and GPIO 24 as SWDIO
  • transport select swd: Uses Serial Wire Debug protocol
  • stm32f1x.cfg: Target configuration for STM32F1 family
  • adapter speed 1000: Sets clock speed to 1000 kHz (1 MHz)

Save and exit (Ctrl+X, then Y, then Enter).

4. Test OpenOCD Connection

Ensure the wiring is correct and the board is powered, then test the connection:

sudo openocd -f ~/stm32-flash.cfg

You should see output similar to:

Open On-Chip Debugger 0.12.0
...
Info : SWD DPIDR 0x1ba01477
Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : Listening on port 4444 for telnet connections

If successful, press Ctrl+C to stop OpenOCD. You're ready to proceed!


Compiling Katapult Bootloader

1. Clone Katapult Repository

cd ~
git clone https://github.com/Arksine/katapult
cd katapult

2. Configure Katapult

Run menuconfig:

make menuconfig

Configure with the following settings:

Micro-controller Architecture: STMicroelectronics STM32
Processor model: STM32F103
[ ] Only 10KiB of RAM (for rare stm32f103x6 variant)
[ ] Disable SWD at startup (for GigaDevice stm32f103 clones)
Build Katapult deployment application: Do not build
Clock Reference: 8 MHz crystal
Communication interface: Serial (on USART1 PA10/PA9)
Application start offset: 8KiB offset
GPIO pins to set on bootloader entry: (leave blank)
[*] Support bootloader entry on rapid double click of reset button
[ ] Enable bootloader entry on button (or gpio) state
[ ] Enable Status LED

Key Points:

  • 8 MHz crystal: Standard for Creality 4.2.2
  • USB on PA11/PA12: Standard USB interface for communication
  • 8KiB offset: Reserves first 8KB for Katapult, application starts after
  • Double-click reset: Convenient bootloader entry method

Save and exit.

3. Compile Katapult

make clean
make

The compiled bootloader will be at ~/katapult/out/katapult.bin.

Verify the file exists:

ls -lh ~/katapult/out/katapult.bin

Flashing Katapult via OpenOCD

1. Start OpenOCD

In a terminal, start OpenOCD in the background:

sudo openocd -f ~/stm32-flash.cfg &

You should see:

Info : Listening on port 4444 for telnet connections

2. Connect via Telnet

Open a new terminal and connect to OpenOCD:

telnet localhost 4444

You'll see:

Connected to localhost.
Open On-Chip Debugger
>

3. Flash Katapult

In the telnet session, execute the following commands one at a time:

reset halt
stm32f1x unlock 0
reset halt
flash write_image erase /home/YOUR_USERNAME/katapult/out/katapult.bin 0x08000000
verify_image /home/YOUR_USERNAME/katapult/out/katapult.bin 0x08000000
reset
exit

Replace YOUR_USERNAME with your actual username (e.g., /home/pi/katapult/out/katapult.bin).

Expected Output:

[stm32f1x.cpu] halted due to debug-request
device id = 0x10036414
flash size = 512 KiB
stm32x unlocked.
wrote 3048 bytes from file ... in 0.217286s
verified 3048 bytes in 0.058051s

4. Notes

After running reset, you may see a hard fault error. This is normal because Katapult expects a valid application (Klipper) at the 8KiB offset, which we'll flash next.


Compiling Klipper Firmware

1. Navigate to Klipper Directory

cd ~/klipper

If Klipper isn't installed:

cd ~
git clone https://github.com/Klipper3d/klipper
cd klipper

2. Configure Klipper

Run menuconfig:

make menuconfig

Configure with the following settings (must match Katapult):

Micro-controller Architecture: STMicroelectronics STM32
Processor model: STM32F103
Bootloader offset: 8KiB bootloader
Clock Reference: 8 MHz crystal
Communication interface: Serial (on USART1 PA10/PA9)

CRITICAL:

  • Bootloader offset MUST be 8KiB to match Katapult
  • Communication interface MUST match Katapult (Serial (on USART1 PA10/PA9))

Save and exit.

3. Compile Klipper

make clean
make

The compiled firmware will be at ~/klipper/out/klipper.bin.

Verify:

ls -lh ~/klipper/out/klipper.bin

Flashing Klipper via OpenOCD

1. Connect to OpenOCD via Telnet

telnet localhost 4444

2. Flash Klipper to Application Area

In the telnet session, execute:

reset halt
flash write_image erase /home/YOUR_USERNAME/klipper/out/klipper.bin 0x08002000
verify_image /home/YOUR_USERNAME/klipper/out/klipper.bin 0x08002000
reset
exit

Important: Note the address 0x08002000 (not 0x08000000). This is the 8KiB offset where the application starts.

Expected Output:

wrote 37256 bytes from file ... in 1.637276s
verified 37256 bytes in 0.539372s

3. Stop OpenOCD

After successfully flashing both Katapult and Klipper, you can stop OpenOCD:

sudo pkill openocd

Verifying the Installation

1. Disconnect SWD Programmer

Disconnect the SWD wires between the Raspberry Pi and Creality board. The programmer is no longer needed for future updates.

2. Connect USB Cable

Connect a USB cable between the Creality 4.2.2 board and your Raspberry Pi (or host computer).

3. Test Katapult Communication

Verify Katapult is working by requesting the bootloader:

~/katapult/scripts/flashtool.py -r -d /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0

Expected Output:

Connecting to Serial Device...
Requesting serial bootloader...
Bootloader Request Complete

4. Find Klipper USB Device

After Klipper boots, find the USB device:

ls /dev/serial/by-id/

You should see something like:

usb-Klipper_stm32f103xe_XXXXXXXXXXXXXXXX-if00

5. Update printer.cfg

Add the MCU configuration to your printer.cfg:

[mcu]
serial: /dev/serial/by-id/usb-Klipper_stm32f103xe_XXXXXXXXXXXXXXXX-if00

6. Restart Klipper Service

sudo systemctl restart klipper

7. Check Klipper Status

sudo systemctl status klipper

Or check your web interface (Mainsail/Fluidd) - the MCU should show as connected.


Future Firmware Updates

Now that Katapult is installed, you can update Klipper firmware without needing OpenOCD or the SWD programmer.

Update Process

# Step 1: Compile new Klipper firmware
cd ~/klipper
make menuconfig  # if configuration changes needed
make

# Step 2: Request bootloader entry
~/katapult/scripts/flashtool.py -r -d /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0

# Step 3: Flash the new firmware immediately
~/katapult/scripts/flashtool.py -f ~/klipper/out/klipper.bin -d /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0

Note: Replace the device ID with your actual Klipper device ID from /dev/serial/by-id/.


Troubleshooting

OpenOCD Cannot Connect

Symptoms:

Error: SWD DPIDR 0x00000000
Error: Failed to connect to target

Solutions:

  1. Check wiring connections (SWDIO, SWCLK, GND)
  2. Ensure the board is powered
  3. Try slower adapter speed: Change adapter speed 1000 to adapter speed 500 in stm32-flash.cfg
  4. Verify GPIO pins are correct for your Raspberry Pi model
  5. Check that OpenOCD was compiled with --enable-bcm2835gpio

Katapult Hard Fault After First Flash

Symptoms:

[stm32f1x.cpu] clearing lockup after double fault
xPSR: 0x60000003 pc: 0x2000018c

Cause: This is normal if only Katapult is flashed without Klipper. Katapult expects a valid application.

Solution: Flash Klipper immediately (see Flashing Klipper via OpenOCD).

Bootloader Not Responding

Symptoms:

Timeout waiting for bootloader response

Solutions:

  1. Double-click the reset button quickly to enter bootloader mode
  2. Check USB cable is properly connected and supports data transfer
  3. Verify the correct device path in /dev/serial/by-id/
  4. Use -r flag to request bootloader: flashtool.py -r -d /dev/serial/by-id/...
  5. Power cycle the board and Raspberry Pi

Wrong Bootloader Offset

Symptoms:

Klipper won't start, or immediate crash after boot

Cause: Klipper compiled with wrong bootloader offset.

Solution: Recompile Klipper with 8KiB bootloader offset in menuconfig, then reflash.

Flash Write Failed

Symptoms:

Error writing to flash

Solutions:

  1. Run stm32f1x unlock 0 before flashing
  2. Ensure flash isn't write-protected
  3. Try erasing: flash erase_sector 0 0 last then retry
  4. Check if enough space (Katapult ~3KB + Klipper ~35KB)

Klipper Won't Connect / Device Not Showing in lsusb

Symptoms:

  • Klipper service shows MCU connection errors
  • lsusb doesn't show the Klipper device
  • Serial device disappears from /dev/serial/by-id/

Solution: Restart the Raspberry Pi and power cycle the printer board:

# Shut down the Pi
sudo shutdown now

# After Pi shut down, also pull power from the printer board completely
# Wait 5-10 seconds, then power it back on

This clears any stuck USB or serial states that can prevent proper enumeration.

Permission Denied on USB Device

Symptoms:

Permission denied: /dev/serial/by-id/usb-...

Solutions:

# Add user to dialout group
sudo usermod -a -G dialout $USER

# Then logout and login again, or reboot
sudo reboot

OpenOCD Port Already in Use

Symptoms:

Error: couldn't bind telnet to socket on port 4444

Solution:

# Kill existing OpenOCD instance
sudo pkill openocd

# Wait a moment, then restart
sudo openocd -f ~/stm32-flash.cfg

Memory Layout Summary

Address Range Size Contents
0x08000000 - 0x08001FFF 8 KB Katapult Bootloader
0x08002000 - 0x0807FFFF 504 KB Klipper Firmware

Useful Commands Reference

OpenOCD Commands (in telnet session)

reset halt              # Stop CPU execution
reset                   # Reset and run
flash info 0            # Show flash information
flash list              # List flash banks
mdw 0x08000000 16       # Read memory (16 words from 0x08000000)
exit                    # Close telnet connection

Katapult Flashtool Commands

# Show help
~/katapult/scripts/flashtool.py -h

# Request bootloader
~/katapult/scripts/flashtool.py -r -d /dev/serial/by-id/usb-Klipper_stm32f103xe_XXX-if00

# Flash firmware
~/katapult/scripts/flashtool.py -f ~/klipper/out/klipper.bin -d /dev/serial/by-id/usb-Klipper_stm32f103xe_XXX-if00

# Query device info
~/katapult/scripts/flashtool.py -i -d /dev/serial/by-id/usb-Klipper_stm32f103xe_XXX-if00

Additional Resources


Credits


License

This guide is provided as-is for educational purposes. Please refer to individual project licenses for Katapult, Klipper, and OpenOCD.


Last Updated: February 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment