Enable USB Serial (FTDI230X / Palette 2) on Flashforge Adventurer 5M (Pro)

Background

I replaced my original 3D printer with a smaller Flashforge Adventurer 5M Pro, but the Mosaic Palette 2 wasn’t connecting when plugged into the printer’s USB. dmesg showed the device was seen but not mounted, indicating the kernel was missing the USB-to-serial driver module.

I spent time trying to compile the modules using the kernel.org sources, but got “Oops” errors when enabling them on the printer. A forum comment pointed to a “Tina Linux” kernel source which supposedly worked for their own use case (compiling the wifi module).

Sadly, the comment was from 2024 and the repo was gone, but I found a copy and cloned it. On to the solution!

Prerequisites

  • A Debian/Ubuntu (or compatible) VM with root or sudo privileges
  • Network access to the printer (for scp)
  • Enough storage and CPU to compile kernel modules in a timely manner
  • Basic familiarity with make, scp, insmod, and editing files on the printer
  • In theory these commands won’t brick the printer, but do these steps at your own risk

Solution

1 – Start with a fresh Debian (or your favorite distro) VM with the basic configuration

2 – Update Packages

3 – Install build tools

apt-get install -y build-essential git wget xz-utils bc bison flex libssl-dev rsync file python3 pkg-config

4 – Setup Linaro 7.1 Toolchain

cd /root
mkdir -p toolchains
cd toolchains
wget https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/arm-linux-gnueabi/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi.tar.xz
tar -xf gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi.tar.xz
export CROSS=/root/toolchains/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-

5 – Get the correct kernel source

cd /root
git clone https://github.com/cfelicio/tina-linux-5.4.git linux-5.4.61-tina
cd linux-5.4.61-tina
rm -rf .git

The Tina Linux source matches the kernel used on the printer (5.4.61).

6 – On the printer: get current kernel info and config

uname -a
zcat /proc/config.gz > printer.config

7 – Back on the VM: copy the printer.config file from the printer via SCP

scp -O [email protected]:/root/printer.config /root/printer.config

8 – Copy printer.config into the kernel tree as .config

cd /root/linux-5.4.61-tina
cp /root/printer.config .config

9 – The actual build process

chmod +x scripts/config
./scripts/config --disable CONFIG_LOCALVERSION_AUTO
./scripts/config --set-str CONFIG_LOCALVERSION ""
make ARCH=arm CROSS_COMPILE="$CROSS" olddefconfig
# Enable drivers as modules
./scripts/config --module CONFIG_USB_SERIAL
./scripts/config --module CONFIG_USB_SERIAL_FTDI_SIO

# Re-resolve dependencies and prep build
make ARCH=arm CROSS_COMPILE="$CROSS" olddefconfig
make ARCH=arm CROSS_COMPILE="$CROSS" modules_prepare

# Build only the subdir to save time
make -j"$(nproc)" ARCH=arm CROSS_COMPILE="$CROSS" M=drivers/usb/serial modules

(If you see warnings, the build & zImage sequence below avoids them), but this is not crucial

make -j"$(nproc)" ARCH=arm CROSS_COMPILE="$CROSS" zImage modules
make -j"$(nproc)" ARCH=arm CROSS_COMPILE="$CROSS" M=drivers/usb/serial modules

10 – Verify the modules were built successfully and match your printer’s kernel (from step 6)

file drivers/usb/serial/usbserial.ko
modinfo -F vermagic drivers/usb/serial/usbserial.ko
modinfo -F vermagic drivers/usb/serial/ftdi_sio.ko

vermagic must match the running kernel version (e.g., 5.4.61). If it doesn’t, you will get invalid module format errors.

11 – Copy the modules over to the printer via SCP

scp -O drivers/usb/serial/ftdi_sio.ko [email protected]:/root/ftdi_sio.ko
scp -O drivers/usb/serial/usbserial.ko [email protected]:/root/usbserial.ko

12 – Load the modules and review dmesg for any errors

insmod usbserial.ko
insmod ftdi_sio.ko

13 – Plug in your Palette 2. It should show up under ttyUSB0, indicating success!

14 – If everything worked well and you want to make the change permanent, move the ko files to your modules, and have them auto start

mv ftdi_sio.ko /lib/modules/5.4.61
mv usbserial.ko /lib/modules/5.4.61
vi /etc/init.d/S50usbserialmod
chmod 755 /etc/init.d/S50usbserialmod

Insert the following into your startup script:

#!/bin/sh
#
# start usb-serial modules for Palette 2 communication
#

insmod /lib/modules/5.4.61/usbserial.ko
insmod /lib/modules/5.4.61/ftdi_sio.ko

15 – Modify your printer.cfg to include palette2

[palette2]
serial: /dev/ttyUSB0
baud: 115200

Klipper Fix

Despite the connection being successful, I was getting an error when issuing the PALETTE_CONNECT command on Klipper. I opened a PR, but will likely take a while to make it downstream:

https://github.com/Klipper3d/klipper/pull/7085

Internal error on command:”PALETTE_CONNECT”
Internal Error on WebRequest: gcode/script
Traceback (most recent call last):
File “/opt/klipper/klippy/webhooks.py”, line 257, in _process_request
func(web_request)
File “/opt/klipper/klippy/webhooks.py”, line 438, in _handle_script
self.gcode.run_script(web_request.get_str(‘script’))
File “/opt/klipper/klippy/gcode.py”, line 216, in run_script
self._process_commands(script.split(‘\n’), need_ack=False)
File “/opt/klipper/klippy/gcode.py”, line 198, in _process_commands
handler(gcmd)
File “/opt/klipper/klippy/gcode.py”, line 135, in
func = lambda params: origfunc(self._get_extended_params(params))
File “/opt/klipper/klippy/extras/palette2.py”, line 173, in cmd_Connect
self._wait_for_heartbeat()
File “/opt/klipper/klippy/extras/palette2.py”, line 225, in _wait_for_heartbeat
currTs – SETUP_TIMEOUT) and startTs > (
TypeError: ‘<‘ not supported between instances of ‘NoneType’ and ‘float’
MCU ‘mcu’ shutdown: Command request

File location (might be present on multiple places on your printer, use find): klipper/klippy/extras/palette2.py

def _wait_for_heartbeat(self):
    startTs = self.reactor.monotonic()
    currTs = startTs
    while True:
        currTs = self.reactor.pause(currTs + 1.0)
        if (
            self.heartbeat is not None
            and self.heartbeat >= (currTs - SETUP_TIMEOUT)
        ):
            break
        if currTs - startTs > SETUP_TIMEOUT:
            self.signal_disconnect = True
            raise self.printer.command_error(
                "No response from Palette 2"
            )

Bonus: Building other modules

This guide is specifically designed for the Palette 2 with the FT230X USB to Serial chip, but you can use the same pattern for any in-tree module that you might need

1- Find the Kconfig symbol and path and grep the kernel tree for your driver (example for the CH341):

grep -R "config USB_SERIAL_CH341" -n .

#Enable the config symbol
./scripts/config --module CONFIG_USB_SERIAL_CH341

make ARCH=arm CROSS_COMPILE="$CROSS" olddefconfig
make ARCH=arm CROSS_COMPILE="$CROSS" modules_prepare

#Build the module
make -j"$(nproc)" ARCH=arm CROSS_COMPILE="$CROSS" M=drivers/usb/serial modules
  • For other classes:
    • CDC ACM: CONFIG_USB_ACM; path: M=drivers/usb/class
    • PL2303: CONFIG_USB_SERIAL_PL2303; path: M=drivers/usb/serial
    • CH341: CONFIG_USB_SERIAL_CH341; path: M=drivers/usb/serial
    • UVC camera: CONFIG_USB_VIDEO_CLASS; path: M=drivers/media/usb/uvc
  • Install to the printer and insmod in dependency order (core first, then subdriver). Examples:
    • For serial: usbserial.ko before subdrivers (ftdi_sio.ko, pl2303.ko, ch341.ko)
    • For USB storage: usbcore/usb-common dependencies load before storage class modules

Common failure modes and fixes:

  • Invalid module format; version magic ‘5.4.61+ …’ should be ‘5.4.61 …’
    • Remove .git from kernel source, disable CONFIG_LOCALVERSION_AUTO, set CONFIG_LOCALVERSION=””
  • Invalid module format without details
    • Verify uname -r is 5.4.61; your .ko vermagic must be 5.4.61 exactly
  • Built with wrong ABI/toolchain
    • Use the vendor toolchain (Linaro 7.4.1 arm-linux-gnueabi-). Rebuild modules with that cross-compiler.

Conclusion

After all this work, you get to print with multiple colors. Yay! If you want to take the easy road, I have the modules pre-compiled here, but no guarantees it will work for your specific printer:

http://carlosfelic.io/5.4.61modules/modules.zip

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top