Skip to content

Firmware Loader

Two complementary tools handle firmware on the SkyWalker-1: fw_load.py loads firmware into FX2 RAM for testing, and fw_dump.py extracts firmware and device information from a running device.

Both tools require pyusb and typically need root access (or appropriate udev rules) to communicate with the USB device.

Terminal window
pip install pyusb

fw_load.py loads firmware into the Cypress FX2 internal/external RAM via the standard 0xA0 vendor request built into the FX2 silicon boot ROM. This is the primary tool for firmware development: load, test, power-cycle to revert.

SubcommandPurpose
loadLoad a firmware file into FX2 RAM
resetHalt and restart the FX2 CPU
readRead and hex-dump FX2 RAM contents
  1. Halt the CPU — writes 0x01 to the CPUCS register at 0xE600
  2. Write code segments into RAM in 64-byte chunks via vendor request 0xA0
  3. Start the CPU — writes 0x00 to CPUCS, triggering USB re-enumeration

Supported file formats:

ExtensionFormatLoad Address
.ihx, .hexIntel HEXAddresses embedded in file
.bix, .binRaw binary0x0000 (start of internal RAM)

Options:

FlagDescription
FILEFirmware file path (positional, required)
--no-resetLoad segments without halting/starting the CPU
--wait SECONDSWait for USB re-enumeration after load
-v, --verboseShow per-chunk transfer progress
--forceAllow loading to devices with unknown VID/PID

Examples:

Load custom firmware and wait for re-enumeration
sudo python3 tools/fw_load.py load firmware/build/skywalker1.ihx --wait 3
Load raw binary with verbose output
sudo python3 tools/fw_load.py load firmware.bix -v --wait 5
Load without CPU reset (write segments only)
sudo python3 tools/fw_load.py load firmware.ihx --no-reset

Typical output:

SkyWalker-1 RAM Firmware Loader
========================================
Firmware: firmware/build/skywalker1.ihx
Segments: 3
Total size: 3072 bytes
Address: 0x0000 - 0x0BFF
Found SkyWalker-1: Bus 1 Addr 12 (VID 0x09C0 PID 0x0203)
[1/3] Halting CPU (CPUCS = 0x01)...
CPU halted
[2/3] Loading 3 segment(s) into RAM...
0x0000-0x03FF (1024 bytes)
0x0400-0x07FF (1024 bytes)
0x0800-0x0BFF (1024 bytes)
3072 bytes loaded
[3/3] Starting CPU (CPUCS = 0x00)...
CPU released
Firmware is running. The device will re-enumerate
with new USB descriptors if the firmware does so.

Halts and restarts the CPU without loading new code. Useful for triggering USB re-enumeration when the device is in a bad state.

Terminal window
sudo python3 tools/fw_load.py reset --wait 3
FlagDescription
--wait SECONDSWait for re-enumeration after reset
--forceAllow reset on unknown VID/PID

Read memory contents from a running FX2. Useful for verifying loaded firmware or inspecting register state.

Read first 256 bytes of internal RAM
sudo python3 tools/fw_load.py read --addr 0x0000 --len 256
Check CPUCS register
sudo python3 tools/fw_load.py read --addr 0xe600 --len 1
Dump to file
sudo python3 tools/fw_load.py read --addr 0x0000 --len 8192 -o ram_dump.bin
FlagDescription
--addr ADDRStart address in hex (default: 0x0000)
--len LENGTHBytes to read (default: 256)
-o, --output FILESave raw bytes to file
--forceAllow read on unknown VID/PID

The loader searches for devices in this order:

  1. SkyWalker-1 — VID 0x09C0, PID 0x0203
  2. Bare Cypress FX2 — VID 0x04B4, PID 0x8613 (unprogrammed/blank EEPROM)

Use --force to override VID/PID checks for devices with non-standard descriptors.

The Linux dvb_usb_gp8psk module auto-loads when the SkyWalker-1 enumerates on USB. It will race with these tools for device access.

Before using any tool, either blacklist the module or unload it:

Unload for current session
sudo modprobe -r dvb_usb_gp8psk gp8psk_fe
Permanent blacklist
echo -e "blacklist dvb_usb_gp8psk\nblacklist gp8psk_fe" | \
sudo tee /etc/modprobe.d/blacklist-gp8psk.conf