CAN bus, Katapult and Klipper on a Voron 0

Basic Information:

Printer Model: Voron 0
MCU / Printerboard: SKR-Pico and EBB36
USB to CAN bus bridge using the CAN Transceiver SN65HVD230

After trying to identify the cause of an error:

Unable to read tmc uart ‘stepper_x’ register IFCNT

(See: [Possible bug in recent commit - #23 by mark.dunn]),

I thought I should document the new process of installing and even more importantly re-installing the CAN bus firmware (Katapult and Klipper) into the SKR_Pico and the EBB36 and post it here.

NOTE - Katapult is not required for my CAN bus solution, both the SKR-Pico and the EBB36 can be installed with Klipper directly. But I have a Voron 0.1 with some mods which still has the fixed hat, and fixed rear panel. This makes pressing buttons on the SKR-Pico and EBB36 a pain. The Katapult firmware (was CanBoot) allows me to upgrade the firmware without pulling the machine apart.

I have tried to include all the linux commands required to do the task AND to keep track of what is happening at every step. Please report any errors or spelling mistakes to me.

Installing the firmware on the SKR-Pico

Installing 1st Katapult (katapult.bin)

git clone https://github.com/Arksine/katapult.git
cd katapult
make distclean
make clean

Using default symbol values (no '/home/mark/katapult/.config')
Configuration saved to '/home/mark/katapult/.config'
Creating symbolic link out/board

make menuconfig

               Katapult Configuration v0.0.1-57-gabd1545
    Micro-controller Architecture (Raspberry Pi RP2040)  --->
    Flash chip (W25Q080 with CLKDIV 2)  --->
    Build Katapult deployment application (Do not build)  --->
    Communication interface (USB)  --->
    USB ids  --->
()  GPIO pins to set on bootloader entry
[*] Support bootloader entry on rapid double click of reset button
[ ] Enable bootloader entry on button (or gpio) state
[ ] Enable Status LED

.

Creating symbolic link out/board
Loaded configuration '/home/mark/katapult/.config'
Configuration saved to '/home/mark/katapult/.config'

make -j4

Creating symbolic link out/board
Building out/autoconf.h
Building out/lib/rp2040/elf2uf2/elf2uf2
Compiling out/src/sched.o
Compiling out/src/bootentry.o
Compiling out/src/command.o
Compiling out/src/flashcmd.o
Compiling out/src/initial_pins.o
Compiling out/src/rp2040/armcm_canboot.o
Compiling out/src/rp2040/main.o
Compiling out/src/rp2040/gpio.o
Compiling out/src/rp2040/timer.o
Compiling out/src/rp2040/flash.o
Compiling out/src/../lib/rp2040/pico/flash/hw_flash.o
Compiling out/src/generic/armcm_irq.o
Compiling out/src/generic/crc16_ccitt.o
Compiling out/src/rp2040/can.o
Compiling out/src/rp2040/chipid.o
Compiling out/src/../lib/can2040/can2040.o
Compiling out/src/generic/canserial.o
Compiling out/src/generic/canbus.o
Compiling out/src/../lib/fast-hash/fasthash.o
Building rp2040 stage2 out/stage2.o
Preprocessing out/src/rp2040/rp2040_link.ld
Building out/compile_time_request.o
Linking out/katapult.elf
Creating bin file out/katapult.bin
Creating uf2 file out/katapult.uf2
Creating legacy uf2 file out/canboot.uf2
Creating legacy binary out/canboot.bin

Physical Actions:
Install the boot jumper.
Press the reset button.

sudo mount /dev/sda1 /mnt
sudo cp out/katapult.uf2 /mnt
sudo umount /mnt

Physical Actions:
Remove the boot jumper.
Press the reset button.

lsusb

Bus 001 Device 005: ID 1d50:6177 OpenMoko, Inc. rp2040
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

ls /dev/serial/by-id

usb-katapult_4550357129118BE8-if00

Installing 2nd katapult (deployer.bin)

make distclean
make clean

Using default symbol values (no '/home/mark/katapult/.config')
Configuration saved to '/home/mark/katapult/.config'

make menuconfig

              Katapult Configuration v0.0.1-57-gabd1545
    Micro-controller Architecture (Raspberry Pi RP2040)  --->
    Flash chip (W25Q080 with CLKDIV 2)  --->
    Build Katapult deployment application (16KiB bootloader)  --->
    Communication interface (USB)  --->
    USB ids  --->
()  GPIO pins to set on bootloader entry
[*] Support bootloader entry on rapid double click of reset button
[ ] Enable bootloader entry on button (or gpio) state
[ ] Enable Status LED

.

Creating symbolic link out/board
Loaded configuration '/home/mark/katapult/.config'
Configuration saved to '/home/mark/katapult/.config'

make -j4

Creating symbolic link out/board
Building out/autoconf.h
Building out/lib/rp2040/elf2uf2/elf2uf2
Compiling out/src/sched.o
Compiling out/src/bootentry.o
Compiling out/src/command.o
Compiling out/src/flashcmd.o
Compiling out/src/initial_pins.o
Compiling out/src/rp2040/armcm_canboot.o
Compiling out/src/rp2040/main.o
Compiling out/src/rp2040/gpio.o
Compiling out/src/rp2040/timer.o
Compiling out/src/rp2040/flash.o
Compiling out/src/../lib/rp2040/pico/flash/hw_flash.o
Compiling out/src/generic/armcm_irq.o
Compiling out/src/generic/crc16_ccitt.o
Compiling out/src/rp2040/usbserial.o
Compiling out/src/generic/usb_cdc.o
Compiling out/src/rp2040/chipid.o
Building rp2040 stage2 out/stage2.o
Preprocessing out/src/rp2040/rp2040_link.ld
Compiling out/src/deployer.o
Compiling out/src/generic/armcm_boot.o
Compiling out/src/generic/armcm_reset.o
Preprocessing out/src/generic/armcm_deployer.ld
Building out/compile_time_request.o
Building out/deployer_ctr.o
Linking out/katapult.elf
Creating bin file out/katapult.bin
Creating uf2 file out/katapult.uf2
Creating legacy uf2 file out/canboot.uf2
Creating legacy binary out/canboot.bin
Compiling out/katapult_payload.o
Linking out/deployer.elf
Creating hex file out/deployer.bin

There is no klipper at this point, so no canbus:

ls /dev/serial/by-id

usb-katapult_4550357129118BE8-if00

~/katapult/scripts/flashtool.py -d /dev/serial/by-id/usb-katapult_4550357129118BE8-if00 -f ~/katapult/out/deployer.bin

Attempting to connect to bootloader
Katapult Connected
Protocol Version: 1.0.0
Block Size: 64 bytes
Application Start: 0x10004000
MCU type: rp2040
Flashing '/home/mark/katapult/out/deployer.bin'...

[##################################################]

Write complete: 26 pages
Verifying (block count = 103)...

[#################################################]

Verification Complete: SHA = 3A9EC72201DD20AD05B8EDB3E3A8D09A042F6E27
Flash Success

Installing 1st klipper

git clone https://github.com/Klipper3d/klipper.git
cd klipper
make distclean
make clean

Using default symbol values (no '/home/mark/klipper/.config')
Configuration saved to '/home/mark/klipper/.config'
  Creating symbolic link out/board

make menuconfig

                            Klipper Firmware Configuration
[*] Enable extra low-level configuration options
    Micro-controller Architecture (Raspberry Pi RP2040)  --->
    Bootloader offset (16KiB bootloader)  --->
    Communication interface (USB to CAN bus bridge)  --->
(1) CAN RX gpio number
(0) CAN TX gpio number
    USB ids  --->
(1000000) CAN bus speed
()  GPIO pins to set at micro-controller startup

.

  Creating symbolic link out/board
Loaded configuration '/home/mark/klipper/.config'
Configuration saved to '/home/mark/klipper/.config'

make -j4

Creating symbolic link out/board
Building out/autoconf.h
Compiling out/src/sched.o
Compiling out/src/command.o
Compiling out/src/basecmd.o
Compiling out/src/debugcmds.o
Compiling out/src/initial_pins.o
Compiling out/src/gpiocmds.o
Compiling out/src/stepper.o
Compiling out/src/endstop.o
Compiling out/src/trsync.o
Compiling out/src/adccmds.o
Compiling out/src/spicmds.o
Compiling out/src/i2ccmds.o
Compiling out/src/pwmcmds.o
Compiling out/src/buttons.o
Compiling out/src/tmcuart.o
Compiling out/src/neopixel.o
Compiling out/src/pulse_counter.o
Compiling out/src/lcd_st7920.o
Compiling out/src/lcd_hd44780.o
Compiling out/src/spi_software.o
Compiling out/src/i2c_software.o
Compiling out/src/thermocouple.o
Compiling out/src/sensor_adxl345.o
Compiling out/src/sensor_angle.o
Compiling out/src/sensor_mpu9250.o
Compiling out/src/rp2040/main.o
Compiling out/src/rp2040/watchdog.o
Compiling out/src/rp2040/gpio.o
Compiling out/src/rp2040/adc.o
Compiling out/src/rp2040/timer.o
Compiling out/src/rp2040/bootrom.o
Compiling out/src/generic/armcm_boot.o
Compiling out/src/generic/armcm_irq.o
Compiling out/src/generic/armcm_reset.o
Compiling out/src/generic/timer_irq.o
Compiling out/src/generic/crc16_ccitt.o
Compiling out/src/rp2040/can.o
Compiling out/src/rp2040/chipid.o
Compiling out/src/../lib/can2040/can2040.o
Compiling out/src/generic/canserial.o
Compiling out/src/generic/usb_canbus.o
Compiling out/src/../lib/fast-hash/fasthash.o
Compiling out/src/rp2040/usbserial.o
Compiling out/src/rp2040/hard_pwm.o
Compiling out/src/rp2040/spi.o
Compiling out/src/rp2040/i2c.o
Preprocessing out/src/generic/armcm_link.ld
Building out/compile_time_request.o
Version: v0.11.0-257-ged66982b
Linking out/klipper.elf
Creating bin file out/klipper.bin

~/katapult/scripts/flashtool.py -d /dev/serial/by-id/usb-katapult_4550357129118BE8-if00 -f ~/klipper/out/klipper.bin

Attempting to connect to bootloader
Katapult Connected
Protocol Version: 1.0.0
Block Size: 64 bytes
Application Start: 0x10004000
MCU type: rp2040
Flashing '/home/mark/klipper/out/klipper.bin'...

[##################################################]

Write complete: 129 pages
Verifying (block count = 515)...

[##################################################]

Verification Complete: SHA = D83CB43402EBD825B2EBDEC534D7EF4D1BA61E6D
Flash Success

At this point the serial port was disabled:

ls /dev/serial/by-id

ls: cannot access '/dev/serial/by-id': No such file or directory

And the canbus was enabled:

ip link show

…
5: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 128
link/can 

~/katapult/scripts/flashtool.py -q -v

Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: fc7c3907fd17, Application: Klipper
Query Complete

Installing 2nd Klipper

Unfortunately, I cannot deploy this with katapult over USB as klipper is now in control.
But if I leave the klipper service running then I can see the can UUID:

~/katapult/scripts/flashtool.py -q -v

Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: fc7c3907fd17, Application: Klipper

lsusb

Bus 001 Device 009: ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

We should flash the second Katapult here (deployer.bin) because trying to use klipper’s ‘USB to can bridge’ to flash another klipper crashes the original klipper (of course).

But both methods leave Katapult in control:
~/katapult/scripts/flashtool.py -i can0 -u fc7c3907fd17 -f ~/klipper/out/klipper.bin

Sending bootloader jump command...
Resetting all bootloader node IDs...
Checking for Katapult nodes...
ERROR:root:Flash Error
Traceback (most recent call last):
  File "/home/mark/katapult/scripts/flashtool.py", line 628, in main
    loop.run_until_complete(sock.run(intf, uuid, fpath, req_only))
  File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/home/mark/katapult/scripts/flashtool.py", line 474, in run
    raise FlashCanError(
FlashCanError: Unable to find node matching UUID: fc7c3907fd17

lsusb

Bus 001 Device 008: ID 1d50:6177 OpenMoko, Inc. rp2040
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

ls /dev/serial/by-id

usb-katapult_4550357129118BE8-if00

~/katapult/scripts/flashtool.py -q -v

Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: fc7c3907fd17, Application: Klipper
Query Complete

~/katapult/scripts/flashtool.py -d /dev/serial/by-id/usb-katapult_4550357129118BE8-if00 -f ~/klipper/out/klipper.bin

Attempting to connect to bootloader
Katapult Connected
Protocol Version: 1.0.0
Block Size: 64 bytes
Application Start: 0x10004000
MCU type: rp2040
Flashing '/home/mark/klipper/out/klipper.bin'...

[##################################################]

Write complete: 129 pages
Verifying (block count = 515)...

[##################################################]

Verification Complete: SHA = D83CB43402EBD825B2EBDEC534D7EF4D1BA61E6D
Flash Success

Installing the firmware on the EBB36

Installing 1st Katapult (katapult.bin)

cd katapult
make distclean
make clean

Using default symbol values (no '/home/mark/katapult/.config')
Configuration saved to '/home/mark/katapult/.config'
Creating symbolic link out/board

make menuconfig

                   Katapult Configuration v0.0.1-57-gabd1545
    Micro-controller Architecture (STMicroelectronics STM32)  --->
    Processor model (STM32G0B1)  --->
    Build Katapult deployment application (Do not build)  --->
    Clock Reference (8 MHz crystal)  --->
    Communication interface (CAN bus (on PB0/PB1))  --->
    Application start offset (8KiB offset)  --->
(1000000) CAN bus speed
()  GPIO pins to set on bootloader entry
[*] Support bootloader entry on rapid double click of reset button
[ ] Enable bootloader entry on button (or gpio) state
[ ] Enable Status LED

Creating symbolic link out/board
Loaded configuration '/home/mark/katapult/.config'
Configuration saved to '/home/mark/katapult/.config'

make -j4

Creating symbolic link out/board
Building out/autoconf.h
Compiling out/src/sched.o
Compiling out/src/bootentry.o
Compiling out/src/command.o
Compiling out/src/flashcmd.o
Compiling out/src/initial_pins.o
Compiling out/src/generic/armcm_canboot.o
Compiling out/src/stm32/gpio.o
Compiling out/src/stm32/flash.o
Compiling out/src/stm32/clockline.o
Compiling out/src/stm32/dfu_reboot.o
Compiling out/src/generic/armcm_irq.o
Compiling out/src/generic/crc16_ccitt.o
Compiling out/src/stm32/stm32f0_timer.o
Compiling out/src/stm32/stm32g0.o
Compiling out/src/stm32/gpioperiph.o
Compiling out/src/generic/canserial.o
Compiling out/src/../lib/fast-hash/fasthash.o
Compiling out/src/stm32/fdcan.o
Compiling out/src/generic/canbus.o
Compiling out/src/stm32/chipid.o
Preprocessing out/src/generic/armcm_link.ld
Building out/compile_time_request.o
Linking out/katapult.elf
Creating bin file out/katapult.bin
Creating legacy binary out/canboot.bin

lsusb

Bus 001 Device 003: ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Physical Actions:
Connect a USB cable from the Raspberry Pi to the EBB36
Press and hold boot button
Press rst button
Release the boot button

lsusb

Bus 001 Device 003: ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Bus 001 Device 005: ID 0483:df11 STMicroelectronics STM Device in DFU Mode
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

sudo dfu-util -a 0 -D ~/katapult/out/katapult.bin --dfuse-address 0x08000000:force:mass-erase:leave -d 0483:df11

dfu-util 0.11-dev

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Warning: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release
Opening DFU capable USB device...
Device ID 0483:df11
Device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Interface #0 ...
Determining device status...
DFU state(2) = dfuIDLE, status(0) = No error condition is present
DFU mode device DFU version 011a
Device returned transfer size 1024
DfuSe interface name: "Internal Flash   "
Performing mass erase, this can take a moment
Downloading element to address = 0x08000000, size = 4244
Erase   	[=========================] 100%         4244 bytes
Erase    done.
Download	[=========================] 100%         4244 bytes
Download done.
File downloaded successfully
Submitting leave request...
dfu-util: Error during download get_status: -9 (LIBUSB_ERROR_PIPE)

lsusb

Bus 001 Device 003: ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

~/katapult/scripts/flashtool.py -q -v

Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: c80a2d7c1c33, Application: Katapult
Query Complete

Physical action:
Remove the USB cable from the Raspberry Pi to the EBB36

Installing 2nd katapult (deployer.bin)

make menuconfig

                   Katapult Configuration v0.0.1-57-gabd1545
    Micro-controller Architecture (STMicroelectronics STM32)  --->
    Processor model (STM32G0B1)  --->
    Build Katapult deployment application (8KiB bootloader)  --->
    Clock Reference (8 MHz crystal)  --->
    Communication interface (CAN bus (on PB0/PB1))  --->
    Application start offset (8KiB offset)  --->
(1000000) CAN bus speed
()  GPIO pins to set on bootloader entry
[*] Support bootloader entry on rapid double click of reset button
[ ] Enable bootloader entry on button (or gpio) state
[ ] Enable Status LED

Loaded configuration '/home/mark/katapult/.config'
Configuration saved to '/home/mark/katapult/.config'

make -j4

Creating symbolic link out/board
Building out/autoconf.h
Compiling out/src/sched.o
Compiling out/src/bootentry.o
Compiling out/src/command.o
Compiling out/src/flashcmd.o
Compiling out/src/initial_pins.o
Compiling out/src/generic/armcm_canboot.o
Compiling out/src/stm32/gpio.o
Compiling out/src/stm32/flash.o
Compiling out/src/stm32/clockline.o
Compiling out/src/stm32/dfu_reboot.o
Compiling out/src/generic/armcm_irq.o
Compiling out/src/generic/crc16_ccitt.o
Compiling out/src/stm32/stm32f0_timer.o
Compiling out/src/stm32/stm32g0.o
Compiling out/src/stm32/gpioperiph.o
Compiling out/src/generic/canserial.o
Compiling out/src/../lib/fast-hash/fasthash.o
Compiling out/src/stm32/fdcan.o
Compiling out/src/generic/canbus.o
Compiling out/src/stm32/chipid.o
Preprocessing out/src/generic/armcm_link.ld
Compiling out/src/deployer.o
Compiling out/src/generic/armcm_boot.o
Compiling out/src/generic/armcm_reset.o
Preprocessing out/src/generic/armcm_deployer.ld
Building out/compile_time_request.o
Linking out/katapult.elf
Building out/deployer_ctr.o
Creating bin file out/katapult.bin
Creating legacy binary out/canboot.bin
Compiling out/katapult_payload.o
Linking out/deployer.elf
Creating hex file out/deployer.bin

~/katapult/scripts/flashtool.py -i can0 -u c80a2d7c1c33 -f ~/katapult/out/deployer.bin

Sending bootloader jump command...
Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: c80a2d7c1c33, Application: Katapult
Attempting to connect to bootloader
Katapult Connected
Protocol Version: 1.0.0
Block Size: 64 bytes
Application Start: 0x8002000
MCU type: stm32g0b1xx
Verifying canbus connection
Flashing '/home/mark/katapult/out/deployer.bin'...

[##################################################]

Write complete: 3 pages
Verifying (block count = 87)...

[#################################################]

Verification Complete: SHA = C7416740E377A958D87E1C002DD37362CE1BAB7E
Flash Success

lsusb

Bus 001 Device 003: ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

~/katapult/scripts/flashtool.py -q -v

Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: c80a2d7c1c33, Application: Katapult
Query Complete

Install 1st Klipper

cd klipper
make distclean

Using default symbol values (no '/home/mark/klipper/.config')
Configuration saved to '/home/mark/klipper/.config'
Creating symbolic link out/board

make clean

Using default symbol values (no '/home/mark/klipper/.config')
Configuration saved to '/home/mark/klipper/.config'
  Creating symbolic link out/board

make menuconfig

                        Klipper Firmware Configuration
[*] Enable extra low-level configuration options
    Micro-controller Architecture (STMicroelectronics STM32)  --->
    Processor model (STM32G0B1)  --->
    Bootloader offset (8KiB bootloader)  --->
    Clock Reference (8 MHz crystal)  --->
    Communication interface (CAN bus (on PB0/PB1))  --->
(1000000) CAN bus speed
()  GPIO pins to set at micro-controller startup

Creating symbolic link out/board
Loaded configuration '/home/mark/klipper/.config'
Configuration saved to '/home/mark/klipper/.config'

make -j4

Building out/autoconf.h
Compiling out/src/sched.o
Compiling out/src/command.o
Compiling out/src/basecmd.o
Compiling out/src/debugcmds.o
Compiling out/src/initial_pins.o
Compiling out/src/gpiocmds.o
Compiling out/src/stepper.o
Compiling out/src/endstop.o
Compiling out/src/trsync.o
Compiling out/src/adccmds.o
Compiling out/src/spicmds.o
Compiling out/src/i2ccmds.o
Compiling out/src/pwmcmds.o
Compiling out/src/buttons.o
Compiling out/src/tmcuart.o
Compiling out/src/neopixel.o
Compiling out/src/pulse_counter.o
Compiling out/src/lcd_st7920.o
Compiling out/src/lcd_hd44780.o
Compiling out/src/spi_software.o
Compiling out/src/i2c_software.o
Compiling out/src/thermocouple.o
Compiling out/src/sensor_adxl345.o
Compiling out/src/sensor_angle.o
Compiling out/src/sensor_mpu9250.o
Compiling out/src/stm32/watchdog.o
Compiling out/src/stm32/gpio.o
Compiling out/src/stm32/clockline.o
Compiling out/src/stm32/dfu_reboot.o
Compiling out/src/generic/crc16_ccitt.o
Compiling out/src/generic/armcm_boot.o
Compiling out/src/generic/armcm_irq.o
Compiling out/src/generic/armcm_reset.o
Compiling out/src/generic/timer_irq.o
Compiling out/src/stm32/stm32f0_timer.o
Compiling out/src/stm32/stm32g0.o
Compiling out/src/stm32/gpioperiph.o
Compiling out/src/stm32/stm32f0_adc.o
Compiling out/src/stm32/stm32f0_i2c.o
Compiling out/src/stm32/spi.o
Compiling out/src/generic/canserial.o
Compiling out/src/../lib/fast-hash/fasthash.o
Compiling out/src/stm32/fdcan.o
Compiling out/src/generic/canbus.o
Compiling out/src/stm32/chipid.o
Compiling out/src/stm32/hard_pwm.o
Preprocessing out/src/generic/armcm_link.ld
Building out/compile_time_request.o
Version: v0.11.0-257-ged66982b
Linking out/klipper.elf
Creating hex file out/klipper.bin

~/katapult/scripts/flashtool.py -i can0 -u c80a2d7c1c33 -f ~/klipper/out/klipper.bin

Sending bootloader jump command...
Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: c80a2d7c1c33, Application: Katapult
Attempting to connect to bootloader
Katapult Connected
Protocol Version: 1.0.0
Block Size: 64 bytes
Application Start: 0x8002000
MCU type: stm32g0b1xx
Verifying canbus connection
Flashing '/home/mark/klipper/out/klipper.bin'...

[##################################################]

Write complete: 14 pages
Verifying (block count = 434)...

[##################################################]

Verification Complete: SHA = 1593139EB61AA40E0BD9DDD34D207D42008D86FF
Flash Success

lsusb

Bus 001 Device 003: ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

~/katapult/scripts/flashtool.py -q -v

Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: c80a2d7c1c33, Application: Klipper
Query Complete

Installing 2nd klipper

First reinstall katapult 2 (deployer.bin) to gain access to katapult.
~/katapult/scripts/flashtool.py -i can0 -u c80a2d7c1c33 -f ~/katapult/out/deployer.bin

Sending bootloader jump command...
Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: c80a2d7c1c33, Application: Katapult
Attempting to connect to bootloader
Katapult Connected
Protocol Version: 1.0.0
Block Size: 64 bytes
Application Start: 0x8002000
MCU type: stm32g0b1xx
Verifying canbus connection
Flashing '/home/mark/katapult/out/deployer.bin'...

[##################################################]

Write complete: 3 pages
Verifying (block count = 87)...

[#################################################]

Verification Complete: SHA = C7416740E377A958D87E1C002DD37362CE1BAB7E
Flash Success

lsusb

Bus 001 Device 006: ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

~/katapult/scripts/flashtool.py -q -v

Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: c80a2d7c1c33, Application: Katapult
Query Complete

~/katapult/scripts/flashtool.py -i can0 -u c80a2d7c1c33 -f ~/klipper/out/klipper.bin

Sending bootloader jump command...
Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: c80a2d7c1c33, Application: Katapult
Attempting to connect to bootloader
Katapult Connected
Protocol Version: 1.0.0
Block Size: 64 bytes
Application Start: 0x8002000
MCU type: stm32g0b1xx
Verifying canbus connection
Flashing '/home/mark/klipper/out/klipper.bin'...

[##################################################]

Write complete: 14 pages
Verifying (block count = 434)...

[##################################################]

Verification Complete: SHA = 1593139EB61AA40E0BD9DDD34D207D42008D86FF
Flash Success

When the System is working

When the system is working, determining the can_uuids can be difficult:
lsusb

Bus 001 Device 006: ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

~/katapult/scripts/flashtool.py -q -v

Resetting all bootloader node IDs...
Checking for Katapult nodes...
Query Complete

Even stopping the klipper service does not work:
service klipper stop
~/katapult/scripts/flashtool.py -q -v

Resetting all bootloader node IDs...
Checking for Katapult nodes...
Query Complete

service klipper start

But, if we comment out the canbus_uuids in printer.cfg :

[mcu]
#canbus_uuid: fc7c3907fd17 

[mcu EBB36]
#canbus_uuid: c80a2d7c1c33

Then press “SAVE and RESTART” we get the following message in mainsail:

Option 'serial' in section 'mcu' must be specified

Once the underlying issue is corrected, use the "RESTART"
command to reload the config and restart the host software.
Printer is halted.

My guess here is that the devices are no longer in use, and therefore can now be queried.
lsusb

Bus 001 Device 022: ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

ip link

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
link/ether e4:5f:01:ec:12:c2 brd ff:ff:ff:ff:ff:ff
4: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DORMANT group default qlen 1000
link/ether e4:5f:01:ec:12:c5 brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
link/ether 02:42:9a:b3:3d:5c brd ff:ff:ff:ff:ff:ff
22: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 128
link/can 

~/katapult/scripts/flashtool.py -q -v

Resetting all bootloader node IDs...
Checking for Katapult nodes...
Detected UUID: fc7c3907fd17, Application: Klipper
Detected UUID: c80a2d7c1c33, Application: Klipper
Query Complete
1 Like

Thank you for posting this.

Three questions for you:

  1. Could you give a high level explanation of what you’re doing here? I’m trying to understand why you are installing Katapult and Klipper twice in your process.
  2. What is the Klipper update process down the road with this installation? I’m also not sure how you determine which UUID is which (ie which one is for the PICO SKR and the EBB42).
  3. Why are you running “make -j4” and not just “make”?

Thanx for putting this out there - I understand the basic steps but the reasons for the overall process isn’t obvious.

1 Like

@mark.dunn
Wow, what a thing, but I would delete this thread and hook it up to Possible bug in recent commit - #22 by mark.dunn
I have the impression, that makes more sense.

I originally upgraded to a CAN bus due to this excellent article
https://github.com/rootiest/zippy_guides/blob/main/guides/pico_can.md
Which provides the simplest and cheapest hardware CAN bus setup for the Voron 0. It is leaps and bounds better than the stock setup in terms of reliability and speed. But (due to the bug mentioned earlier), I have found that the software architecture is more challenging.

I think it goes something like this:

Klipper communicates over CAN on the raspberry Pi
But the raspberry Pi doesn’t have CAN
So the raspberry Pi has one side of a USB bridge to the SKR-Pico
The SKR-Pico has the other side of the USB bridge back to CAN
The SKR-Pico accepts CAN messages addressed to it.
The SKR-Pico forwards the other CAN messages to the EBB36

So, as you are installing everything. The first can address must be for the SKR-Pico.
Because you cannot get to the EBB36 unless this is setup first.

Generally, If you install klipper on either the SKR-Pico or the EBB36 then you require physical access to the hardware. On my Voron 0, this involves removing the top hat and the back panel.

Katapult (was canboot) should allow this to be done in software alone, but how you do it is not obvious.

In this article, the first installation of either katapult or klipper gains nothing, you still need access to the hardware.

It is only the 2nd (3rd, 4th etc.) install which can be done without access to the hardware. This will allow us to upgrade either piece of firmware automatically.

Finally, ‘make -j4’ just tells the raspberry pi that it can use all 4 cores in parallel to compile the software (its quicker)

I posted a short message on that thread that the underlying software now worked on my setup due presumably to changes in katapult (was CanBoot).

But this article grew out of frustration with trying to use Katapult (was CanBoot).
It is important to me, I thought it might help others.

Thanx for the reply.

Now, when I read the article, there’s no mention of Katapult or CanBoot - it’s a basic CAN installation. I’ve done CanBoot installations before and I haven’t had to install it and Klipper multiple times to access the hardware and update the CAN addressable devices. Where did you get the process of loading them multiple times?

Thanx for the hint on the “make -j4”.

By ‘the article’ I assume you mean the one I referenced and not my article (which references Katapult many times)

I feel like I am repeating myself here, so either I do not understand youre question correctly or you don’t understand my answer. This article does not indicate that you have to install Katapult (was CanBoot) and Klipper multiple times to access the hardware.

It shows you how to re-install either Katapult or Klipper in software without having to use the boot buttons or jumpers and reset buttons, or adding USB cables.(which, for me, means messing about removing the top hat and back plate each time).

This is something I had to do multiple times while investigating the '“Unable to read tmc uart ‘stepper_x’ register IFCNT” software bug I mentioned in my article. So if you know a simpler way, I am all ears. There may be a way for the Klipper firmware to update itself, but I haven’t read about it.

I guess my question to you would be:

If you have used CanBoot before, and DIDN’T need to re-install the Klipper firmware, then why didn’t you just load the Klipper firmware directly and avoid CanBoot altogether?

EDIT: I made some modifications to this post to make it easier to follow including putting in link titles to make things more understandable.

I’m confused as to what “article” you’re referring to. You linked to the Katapult GitHub page (Katapult
(formerly known as CanBoot)
), which looks like it’s identical to the old CanBoot one - with no mention of having to install Katapult and Klipper twice. When asked, you pointed to this “excellent article”: CANbus your Pico which has no mention of installing things more than once. So I’m guessing there is another “article” that I’m not seeing?

The issue I have is that in the OP you have under Installing the firmware on the SKR-Pico:

Then, under Installing the firmware on the EBB36 you have:

Now, I haven’t tried to work with the deployer.bin version before but I thought that used a single installation of CanBoot (Katapult now, I guess). I have no idea why you’re installing Klipper twice in both devices.

Regardless, what you’re describing doesn’t make sense based on my experience; I’m running Klipper on Octopus and Manta controllers over CanBoot (haven’t moved to Katapult but I will now in a few days), just one installation of each, and communicating with either an EBB42 or FLY SH42 toolhead controller with Klipper running over CanBoot. No issues with accessing hardware on any of the boards or communicating via the CAN bus.

Honestly, it doesn’t make sense doing multiple installations - it just looks like you’re putting firmware on top of firmware and the UUIDs you’re finding are for only one of the installations. If you ended up with multiple UUIDs for each device then things would make more sense.

Sorry for being thick on this but your instructions seem to be unique in the need for multiple loadings of Klipper over Katapult and I don’t understand the need for doing this.

Isn’t a Katapult something to sink ships? SCNR, but back to the topic:

@mark.dunn, many thanks for providing such instructions. Some items I have noticed and also mentioned by @mykepredko:

  • It is too long with too much noise, like the output of the build process or the flash processes
  • The “deployer” is used to update Katapult itself without the need for additional flashing tools
  • It is crucial to have the deployer configured with the bootloader offset of the original bootloader. Once installed, the deployer will basically sit “in front of” the Katapult bootloader
  • Initial installing the deployer does not need a two-step approach. You just build with deployer and then flash deployer and Katapult will come with it
  • Once the deploy.bin is flashed, the board should automatically reset and enter Katapult. Now you can flash Klipper just normally
1 Like

My apologies, Please treat the original article more of a how-to or reference guide, It was written as something I could prove worked.

I will try and provide the explanation of why you would use any of the steps in the original article here. It feels weird to be commenting on other peoples software though, let’s hope Arksine and koconner will step in if I make any mistakes. The following explanation should be treated as 70% true. With 20% nuance that is omitted for clarity and 10% guesswork.

Klipper is a distributed application with Klippy software running on the host and Klipper firmware running on the mcus. In my case the host is a Raspberry Pi, the primary mcu is an SKR-Pico and the toolhead mcu is an EBB36 .

The Katapult firmware is declared as a bootloader and a bootloader has a very specific role:

  1. Initialise the minimum hardware it requires
  2. Provide any security functionality
  3. Check the integrity of the main software
  4. Load the main software
  5. Pass control to that software
  6. Do nothing until the next boot (get out of the way)

Depending on how it is compiled, the Katapult firmware can listen either to

  1. The serial port
  2. The USB port
  3. The CAN port

My guess is that the Katapult firmware

  1. Checks the validity of the version of Klipper firmware in the mcu’s memory
  2. While the validity of Klipper firmware is not valid it will wait to be contacted on the designated port and accept the new Klipper firmware (from the host) then return to step 1
  3. The version of Klipper firmware is now valid so the Katapult firmware hands control to the Klipper firmware and gets out of the way.

A bootloader like Katapult is often used by developers and testers but not included in the final product. However, if you are like me, using kiauh to make sure you have the very latest software then this is a very exciting but dangerous place to be. Every new feature (and bug) is available at the moment it is incorporated into the software!

I should point out that not using Katapult requires the user to have direct access to the hardware reset and boot features and so they must be physically present. This provides some basic security from remote attack.

At some point, the developers of the Klipper firmware will decide that it has the required minimum set of features and that the software and firmware is adequately tested. Those who want a stable (but possibly out of date) product might load the klipper directly into the mcus then.

With that initial explanation out of the way, I will now try to explain the need for my original article.
In order to use Katapult and the Klipper firmware in the mcus we need to perform the following actions (details of how to do this are documented in the original article: ‘CAN bus, katapult and Klipper on a Voron 0’)

  1. Install the Katapult firmware for the first time in the primary mcu (SKR-Pico) under:
    Installing the firmware on the SKR-Pico
    Installing 1st Katapult (katapult.bin)

  2. We can then use the installed the Katapult firmware, which is listening on the USB port, to load the Klipper firmware for the first time on the primary mcu (SKR-Pico) under:

    Installing the firmware on the SKR-Pico
    Installing 1st klipper

When the Klipper firmware is working properly on the primary mcu (SKR-Pico) Software on the host (Raspberry Pi) can now transmit and receive CAN messages. These CAN messages are wrapped in USB messages and sent to the klipper firmware on the primary mcu. The Klipper firmware removes the wrapper and directs the CAN messages where they need to go. This wrapping/unwrapping technique is known as the USB to CAN bus bridge.

  1. Install the Katapult firmware in the toolhead mcu (EBB36) for the fist time. Details are under:

    Installing the firmware on the EBB36
    Installing 1st Katapult (katapult.bin)

  2. We can then use the Klipper firmware on the primary mcu (SKR-Pico) with the USB to CAN bus bridge and the installed Katapult on the toolhead mcu (EBB36), listening on the CAN bus, to load the Klipper firmware for the first time under:

    Installing the firmware on the EBB36
    Install 1st Klipper

At this point you now should have a working system.

Software (klippy.py or flashtool.py) on the host (Raspberry Pi) can communicate via the CAN bus.
The CAN bus messages go over the ‘USB to CAN bridge’ to the Klipper firmware on the primary mcu (SKR-Pico). This Klipper firmware either directs these CAN bus messages to itself or to the Klipper firmware on the toolhead mcu (EBB36).

That’s half the story…

If in the future, you find that the Klipper firmware in any mcu is missing a feature or has a bug then you can change it without needing direct access to the hardware :

  1. If you need to change the Klipper firmware in the primary mcu (SKR-Pico) you can use the technique documented in:

    Installing the firmware on the SKR-Pico
    Installing 2nd Klipper

  2. Similarly, if you need to change the Klipper firmware in the toolhead mcu (EBB36) you can use:

    Installing the firmware on the EBB36
    Installing 2nd Klipper

So far so good. But what if there is a problem with the Katapult firmware? The writers of the Katapult firmware have thought of that too. I am guessing that they supply the firmware (deployer.bin) that passes the integrity test of the current katapult firmware. Then when control is passed to this deployer.bin firmware it copies a new Katapult firmware over the one we just booted from.

Effectively lifting itself up by it’s own boostraps! - hence the term bootloader.

  1. The technique for changing the Katapult firmware in the primary mcu (SKR-Pico):

    Installing the firmware on the SKR-Pico
    Installing 2nd katapult (deployer.bin)

  2. The technique for changing the Katapult firmware in the toolhead mcu (EBB36):

    Installing the firmware on the EBB36
    Installing 2nd katapult (deployer.bin)

You will notice in the original article ‘CAN bus, katapult and Klipper on a Voron 0’ that I often use commands to observe the state of the USB port and the CAN network. This is because, depending on which of the documented sections you are in, these may or may not be visible. Then I use a command to obtain either a USB address or CAN address as no firmware can be installed without knowing the address where it is to be installed.

My guess is that if the klipper firmware is active (connected to klippy) then it does not respond to address requests:

  1. When everything is working and you still want to upgrade the firmware you can obtain the CAN addresses using the section:
    When the System is working

Hopefully that is clearer. If you need me to drill down further, I would have to swat up on the specifics of Katapult, and Klipper, I am new to this software.

Using distributed applications is a tricky business :slight_smile:

Sorry Sineos,
I was busy writing a reply before I got to your message

Yes,It does have too much noise.
I would have liked to cut the linux responses down just to the lines that were important and then highlighing the keywords that mattered within those lines. But my formatting capability is still in its infancy.

In my response I would like to have referred directly to the section in my original article like mykepredko, but I haven’t yet figured that out.

I think I have covered off the rest of your points in my response to mykepredko

Sorry, but this seems all quite convoluted and IMO your answer to @mykepredko is partially not correct.

  • Katapult is a bootloader
  • Its main task is to download the application program to the internal flash memory through one of the available serial peripherals (such as USART, CAN, USB, I2C, SPI).
  • The branching code of the bootloader decides whether the control should be passed to the bootstrap application itself (e.g. Katapult) or to the main application (e.g. the Klipper firmware)
  • Entering the bootloader to update the application code is typically done via some interaction with the board, e.g. inserting an SD card with a special file, pulling a pin low, pressing a button etc. → Katapult can overcome this limitation
  • Updating the bootloader itself often requires special tools or flashing procedures → Katapult can overcome this via the deployer functionality
  • As stated above this does not need a two-step approach and most of the time updating the bootloader is rarely needed (if ever)
  • There is no additional magic in the bootloader to verify something etc.
1 Like

Formatting test - please ignore

“Katapult is a bootloader” - yes thats what I said
“Its main task…” - On the version of Katapult for SKR-Pico that I have it shows just:

(Top) → Communication interface
                          Katapult Configuration v0.0.1-57-gabd1545
( ) USB (on PA11/PA12)
( ) Serial (on USART1 PA10/PA9)
( ) Serial (on USART1 PB7/PB6)
( ) Serial (on USART2 PA3/PA2)
( ) Serial (on USART2 PD6/PD5)
( ) Serial (on USART3 PB11/PB10)
( ) Serial (on USART3 PD9/PD8)
( ) CAN bus (on PA11/PA12)
( ) CAN bus (on PA11/PB9)
( ) CAN bus (on PB8/PB9)
( ) CAN bus (on PD0/PD1)
(X) CAN bus (on PB0/PB1)
( ) CAN bus (on PD12/PD13)
( ) CAN bus (on PC2/PC3)

It does not show I2C, SPI

“The branching code of the bootloader …” OK, this was a guess, I wrapped it in a while loop because it would be rather silly to download some software and NOT have a basic check that it is complete. Surely this would mean that the next time it booted It would pass controll to a partial piece of software
and crash in a dangerous and unexpected way, my bad!

“Entering the bootloader… Katapult can overcome this limitation”. - yes that IS the whole point of my article.

“Updating the bootloader itself…” - yes again, that is ALSO the point of the article.

“As stated above this does not need a two-step approach” - In the rare occasion that updating the bootloader is needed then AT THAT POINT the second step IS needed, you have already made your 1st step when you installed katapult, and you must make a second step before a third - Surely that IS your second step.

“There is no additional magic…” Again, I would be very dissapointed to hear that there is no attempt for verify the Klipper firmware is complete before passing control to it. It sounds very dangerous. But this is the second time you have emphasised that so I bow to your greater experience.