skywalker-1/skywalker1-hardware-reference.md
Ryan Malloy bbdcb243dc Normalize line endings to LF across entire repository
Apply .gitattributes normalization to convert all CRLF line
endings inherited from Windows-origin source files to Unix LF.
175 files, zero content changes.
2026-02-20 10:55:50 -07:00

34 KiB

Genpix SkyWalker-1 Hardware Reference

Consolidated technical reference for the Genpix SkyWalker-1 DVB-S USB 2.0 satellite receiver, derived from Linux kernel driver analysis, firmware reverse engineering (Ghidra), and Windows BDA driver source review.


1. Overview

The Genpix SkyWalker-1 is a standalone USB 2.0 DVB-S satellite receiver built around two ICs:

  • Cypress CY7C68013A (FX2LP) -- USB 2.0 Hi-Speed microcontroller (8051 core, 48 MHz)
  • Broadcom BCM4500 -- DVB-S / 8PSK satellite demodulator

The FX2 handles USB communication, LNB control, DiSEqC signaling, and orchestrates tuning via I2C commands to the BCM4500. The BCM4500 performs RF demodulation, FEC decoding, and outputs an MPEG-2 transport stream on an 8-bit parallel bus. The GPIF engine inside the FX2 transfers the transport stream directly into a USB bulk endpoint with zero firmware intervention in the data path.

Supported Modulations

Index Modulation Constant
0 DVB-S QPSK ADV_MOD_DVB_QPSK
1 Turbo-coded QPSK ADV_MOD_TURBO_QPSK
2 Turbo-coded 8PSK ADV_MOD_TURBO_8PSK
3 Turbo-coded 16QAM ADV_MOD_TURBO_16QAM
4 Digicipher II Combo ADV_MOD_DCII_C_QPSK
5 Digicipher II I-stream (split) ADV_MOD_DCII_I_QPSK
6 Digicipher II Q-stream (split) ADV_MOD_DCII_Q_QPSK
7 Digicipher II Offset QPSK ADV_MOD_DCII_C_OQPSK
8 DSS QPSK ADV_MOD_DSS_QPSK
9 DVB-S BPSK ADV_MOD_DVB_BPSK

DVB-S2 is not supported (incompatible FEC architecture).

RF Specifications

Parameter Value
IF frequency range 950 -- 2150 MHz
Symbol rate 256 Ksps -- 30 Msps
Input connector IEC F-type female
LNB voltage 13/18V (or 14/19V with USE_EXTRA_VOLT)
LNB current 450 mA continuous / 750 mA burst
Switch control 22 kHz, Tone Burst, DiSEqC 1.0/1.2, Legacy Dish Network

2. USB Interface

VID/PID Table

All Genpix products share VID 0x09C0:

PID Product cold_ids warm_ids Kernel Module Notes
0x0200 8PSK-to-USB2 Rev.1 Cold Yes No gp8psk Requires FW01 upload to RAM
0x0201 8PSK-to-USB2 Rev.1 Warm No Yes gp8psk Requires FW02 (BCM4500)
0x0202 8PSK-to-USB2 Rev.2 No Yes gp8psk Boots from EEPROM
0x0203 SkyWalker-1 No Yes gp8psk Boots from EEPROM
0x0204 SkyWalker-1 (alternate) No Yes gp8psk Boots from EEPROM
0x0205 SkyWalker-2 -- -- -- Not in kernel 6.16.5
0x0206 SkyWalker CW3K No Yes gp8psk Requires CW3K_INIT (0x9D)

PID 0x0203 was added to the kernel device table after v6.6.1.

USB Endpoints and Streaming Properties

Property Value
Control endpoint EP0 (default, vendor requests)
Bulk IN endpoint EP2 (0x82) -- MPEG-2 transport stream
Generic bulk CTRL endpoint 0x01 (BCM4500 FW02 upload only)
URB count 7
URB buffer size 8192 bytes each
Stream type USB_BULK
FX2 controller type CYPRESS_FX2

Warm Boot Behavior

The SkyWalker-1 (PID 0x0203) enumerates directly as a "warm" device. The DVB-USB framework skips firmware download when cold_ids is NULL. No host-side firmware files (dvb-usb-gp8psk-01.fw or dvb-usb-gp8psk-02.fw) are required. These files were never open-sourced or included in the linux-firmware package.

Device Needs FW01? Needs FW02? Boot Source
Rev.1 Cold (0x0200) Yes -- RAM (empty)
Rev.1 Warm (0x0201) No Yes RAM (FW01 loaded)
Rev.2 (0x0202) No No EEPROM
SkyWalker-1 (0x0203) No No EEPROM
SkyWalker CW3K (0x0206) No No EEPROM

3. Complete Vendor Command Reference

All vendor commands use USB control transfers:

  • USB Type: USB_TYPE_VENDOR
  • Timeout: 2000 ms
  • Retry: Up to 3 attempts for IN operations if partial data received
  • Data buffer maximum: 80 bytes (kernel driver)

3.1 Command Table

The vendor command dispatcher at CODE:0056 validates bRequest in the range 0x80--0x9D (30 entries) and dispatches via an indexed jump table at CODE:0076. Rev.2 supports only 0x80--0x9A (27 entries).

Cmd Name Dir wValue wIndex wLength Purpose Linux Windows v2.06 Rev.2 v2.13
0x80 GET_8PSK_CONFIG IN 0 0 1 Read configuration status byte Yes Yes OK OK OK
0x81 SET_8PSK_CONFIG OUT varies 0 0 Set config (reserved) No No STALL STALL STALL
0x82 (reserved) -- -- -- -- Reserved No No STALL STALL STALL
0x83 I2C_WRITE OUT dev_addr reg_addr N Write to I2C device Yes Yes OK OK OK
0x84 I2C_READ IN dev_addr reg_addr N Read from I2C device Yes Yes OK OK OK
0x85 ARM_TRANSFER OUT 0/1 0 0 Start (1) / stop (0) MPEG-2 stream Yes Yes OK OK OK
0x86 TUNE_8PSK OUT 0 0 10 Set tuning parameters (see Section 6) Yes Yes OK OK OK
0x87 GET_SIGNAL_STRENGTH IN 0 0 6 Read SNR and diagnostics Yes Yes OK OK Changed
0x88 LOAD_BCM4500 OUT 1 0 0 Initiate BCM4500 FW download Yes* No STALL STALL STALL
0x89 BOOT_8PSK IN 0/1 0 1 Power on (1) / off (0) demodulator Yes Yes OK OK OK
0x8A START_INTERSIL IN 0/1 0 1 Enable (1) / disable (0) LNB supply Yes Yes OK OK OK
0x8B SET_LNB_VOLTAGE OUT 0/1 0 0 13V (0) or 18V (1) Yes Yes OK OK OK
0x8C SET_22KHZ_TONE OUT 0/1 0 0 Tone off (0) or on (1) Yes Yes OK OK OK
0x8D SEND_DISEQC_COMMAND OUT msg[0] 0 len DiSEqC message or tone burst Yes Yes OK OK OK
0x8E SET_DVB_MODE OUT 1 0 0 Enable DVB-S mode Yes No STALL STALL STALL
0x8F SET_DN_SWITCH OUT cmd7bit 0 0 Legacy Dish Network switch protocol Yes Yes OK OK OK
0x90 GET_SIGNAL_LOCK IN 0 0 1 Read signal lock status Yes Yes OK OK OK
0x91 I2C_ADDR_ADJUST IN 0/1 0 1 Inc/dec internal IRAM counter (debug) No No OK OK OK
0x92 GET_FW_VERS IN 0 0 6 Read firmware version + build date Yes No OK OK OK
0x93 GET_SERIAL_NUMBER IN 0 0 4 Read 4-byte serial from I2C EEPROM No Yes OK OK OK
0x94 USE_EXTRA_VOLT OUT 0/1 0 0 Enable +1V LNB boost (14V/19V) Yes Yes OK OK OK
0x95 GET_FPGA_VERS IN 0 0 1 Read EEPROM hardware/platform ID Yes No OK OK OK
0x96 SET_LNB_GPIO_MODE OUT 0/1 0 0 Configure LNB GPIO output enables No No OK OK OK
0x97 SET_GPIO_PINS OUT bitmap 0 0 Direct write to LNB GPIO pins No No OK OK OK
0x98 GET_GPIO_STATUS IN 0 0 1 Read LNB feedback GPIO pin No No OK OK OK
0x99 GET_DEMOD_STATUS IN 0 0 1 Read BCM4500 register 0xF9 No No STALL Proto OK
0x9A INIT_DEMOD OUT 0 0 0 Trigger demod re-init (3 attempts) No No STALL Proto OK
0x9B (reserved) -- -- -- -- Reserved No No STALL N/A STALL
0x9C DELAY_COMMAND OUT delay 0 0 Host-controlled tuning delay + poll No No STALL N/A OK
0x9D CW3K_INIT / SET_MODE_FLAG OUT 0/1 0 0 CW3K init or conditional demod reset Yes** No OK N/A Changed

* Linux driver only sends LOAD_BCM4500 for Rev.1 Warm (PID 0x0201). On SkyWalker-1, bm8pskFW_Loaded is already set and 0x88 routes to STALL.

** Linux driver only sends CW3K_INIT for SkyWalker CW3K (PID 0x0206).

Status key: OK = implemented, STALL = routes to stall handler (endpoint stall returned), Proto = partial/prototype implementation, N/A = command index out of range (Rev.2 only supports 0x80--0x9A), Changed = implementation differs between versions.

3.2 Detailed Parameter Formats

0x8D SEND_DISEQC_COMMAND: When wLength > 0, the payload is a standard DiSEqC message (3--6 bytes) with wValue set to msg[0] (framing byte, typically 0xE0 or 0xE1). When wLength == 0 and wValue == 0, a tone burst A is sent. When wLength == 0 and wValue != 0, a tone burst B is sent.

0x8F SET_DN_SWITCH: wValue carries a 7-bit Dish Network switch command (LSB-first), bit-banged on GPIO P0.4 with specific timing. The 8th bit of the original switch command selects LNB voltage and is sent separately via SET_LNB_VOLTAGE.

0x92 GET_FW_VERS: Returns 6 bytes: [minor_minor, minor, major, day, month, year-2000]. Full version = major<<16 | minor<<8 | minor_minor. Build date = (2000+year)/month/day.

0x93 GET_SERIAL_NUMBER: Returns 4 bytes read from I2C EEPROM at device address 0x51 (7-bit), extracted at 8-bit intervals using a shift/rotate routine.

0x94 USE_EXTRA_VOLT: wValue=1 writes 0x6A to XRAM 0xE0B6; wValue=0 writes 0x62. The difference is bit 3 (0x08), which controls the extra voltage boost on the LNB power regulator.

0x95 GET_FPGA_VERS: Reads from I2C EEPROM at 0x51. Despite the name, there is no FPGA -- this returns the EEPROM-stored hardware platform ID. v2.06 reads offset 0x31 (2 bytes); v2.13/Rev.2 read offset 0x00 (1 byte).

0x96--0x98: Internal debug commands for LNB GPIO control. 0x96 configures output enables (OEB/OEA), 0x97 writes pin states, 0x98 reads a feedback pin. GPIO assignments differ between v2.06/v2.13 (Port B) and Rev.2 (Port A + Port B). See Section 10 for pin details.


4. Configuration Status Byte

Returned by GET_8PSK_CONFIG (0x80). Stored in IRAM at version-dependent addresses.

Bit 7 (0x80): bmArmed         - MPEG-2 stream transfer armed / GPIF active
Bit 6 (0x40): bmDCtuned       - DC offset tuning complete (set for DCII modes)
Bit 5 (0x20): bmSEL18V        - 18V LNB voltage selected (else 13V)
Bit 4 (0x10): bm22kHz         - 22 kHz tone active
Bit 3 (0x08): bmDVBmode       - DVB mode enabled
Bit 2 (0x04): bmIntersilOn    - LNB power supply enabled
Bit 1 (0x02): bm8pskFW_Loaded - BCM4500 firmware loaded (always set on SkyWalker-1)
Bit 0 (0x01): bm8pskStarted   - Device booted and running
Version IRAM Address
v2.06 0x6D
Rev.2 v2.10.4 0x4E
v2.13 0x4F

5. Boot Sequence

5.1 Two-Stage Firmware Architecture

The FX2 supports two firmware sources:

  1. Host RAM upload (Rev.1 Cold only): The host writes 8051 code to FX2 RAM via USB 0xA0 vendor requests, using the built-in boot ROM. This requires dvb-usb-gp8psk-01.fw in binary hexline format.

  2. EEPROM boot (Rev.2, SkyWalker-1, CW3K): The FX2 boot ROM reads firmware from an external I2C EEPROM in Cypress C2 format on power-up. No host interaction needed.

5.2 C2 EEPROM Format

SkyWalker-1 firmware is stored in Cypress C2 IIC second-stage boot format:

Header (8 bytes):

Offset Size Field SkyWalker-1 Value
0 1 Marker 0xC2 (external memory, large code model)
1 2 VID (LE) 0x09C0
3 2 PID (LE) 0x0203
5 2 DID (LE) 0x0000
7 1 Config 0x40 (400 kHz I2C)

Code segments follow: 2-byte length (BE) + 2-byte target address (BE) + data. Maximum segment size is 1023 bytes (FX2 I2C boot ROM buffer limit). All SkyWalker-1 variants use 10 segments.

Terminator: 0x80xx (high bit set) + 2-byte entry point address (0xE600 = CPUCS).

5.3 Power-On Boot Sequence

1. GET_8PSK_CONFIG (0x80) -- read config status byte
   |-- Check bit 0: bm8pskStarted?

2. If not started:
   |-- BOOT_8PSK (0x89, wValue=1)
   |-- GET_FW_VERS (0x92) -- read firmware version

3. If bit 1 clear (bm8pskFW_Loaded):
   |-- LOAD_BCM4500 (0x88) -- Rev.1 Warm only; STALLs on SkyWalker-1

4. If bit 2 clear (bmIntersilOn):
   |-- START_INTERSIL (0x8A, wValue=1) -- enable LNB power supply

5. SET_DVB_MODE (0x8E, wValue=1) -- STALLs on all SkyWalker-1 FW versions

6. ARM_TRANSFER (0x85, wValue=0) -- abort any pending MPEG transfer

7. Device ready for tuning

5.4 Firmware Version Identification

The kernel reads firmware version on boot via GET_FW_VERS (0x92) and logs:

gp8psk: FW Version = 2.06.4 (0x20604)  Build 2007/07/13

Kernel revision constants (from gp8psk-fe.h):

GP8PSK_FW_REV1 = 0x020604    (v2.06.4)
GP8PSK_FW_REV2 = 0x020704    (v2.07.4)

If fw_vers >= GP8PSK_FW_REV2, the kernel enables Rev.2-specific code paths. The v2.10 and v2.13 firmwares are newer than either kernel constant.


6. Tuning Protocol

6.1 TUNE_8PSK Command Format (0x86)

The host sends a 10-byte OUT payload via USB control transfer:

USB SETUP:  bmRequestType=0x40, bRequest=0x86, wValue=0, wIndex=0, wLength=10

EP0BUF Layout:
  Byte  Content             Encoding
  ----  ------------------  ----------------
  [0]   Symbol Rate byte 0  Little-endian LSB
  [1]   Symbol Rate byte 1
  [2]   Symbol Rate byte 2
  [3]   Symbol Rate byte 3  Little-endian MSB
  [4]   Frequency byte 0    Little-endian LSB
  [5]   Frequency byte 1
  [6]   Frequency byte 2
  [7]   Frequency byte 3    Little-endian MSB
  [8]   Modulation Type      0--9 (see Section 1 table)
  [9]   Inner FEC Rate       Index into modulation-specific table

Symbol Rate is in samples per second (sps). The Windows driver multiplies ksps by 1000.

Frequency is the IF frequency in kHz (950000--2150000), computed by the host as (RF_freq - LO_freq) * multiplier.

6.2 Firmware EP0BUF Parsing

The firmware reads the 10-byte payload from EP0BUF (XRAM 0xE740--0xE749) and stores:

Source Destination Notes
EP0BUF[8] (mod) IRAM 0x4D Direct copy
EP0BUF[9] (FEC) IRAM 0x4F Direct copy
EP0BUF[4--7] (freq) XRAM 0xE0DB--0xE0DE Byte-reversed (LE to BE)
EP0BUF[0--3] (SR) XRAM 0xE0CB--0xE0CE Byte-reversed (LE to BE)

The byte reversal converts host little-endian to BCM4500 big-endian so values can be written directly to the demodulator via I2C.

6.3 Modulation Dispatch

After parsing, the firmware validates the modulation type (< 10) and dispatches via a jump table to modulation-specific handlers. Each handler:

  1. Validates the FEC index against the maximum for that modulation
  2. Looks up a preconfigured byte from an XRAM table
  3. Writes configuration to four XRAM registers

FEC Rate Lookup Tables (populated from the CODE-space init table at boot):

XRAM Base Modulation Max FEC Index Notes
0xE0F9 DVB-S QPSK, DSS, BPSK 7 Standard Viterbi rates (1/2, 2/3, 3/4, 5/6, 7/8, auto, none)
0xE0B7 Turbo QPSK 5 Turbo code rates
0xE0B1 Turbo 8PSK 5 Turbo code rates
0xE0BC Turbo 16QAM 1 Single code rate
0xE0BD DCII (all variants) 9 Combined code rate + modulation

BCM4500 XRAM Configuration after dispatch:

XRAM Addr Register DVB-S QPSK Turbo (Q/8/16) DCII DSS/BPSK
0xE0EB FEC Code Rate Table lookup Table lookup 0xFC (fixed) Table lookup OR 0x80
0xE0EC Modulation Type 0x09 0x09 From DCII table 0x09
0xE0F5 Demod Mode 0x10 0x10 0x10/0x11/0x12/0x16 0x10
0xE0F6 Turbo Flag 0x00 0x01 0x00 0x00

DCII Demod Mode values:

Modulation XRAM 0xE0F5 Value
DCII Combo (4) 0x10
DCII Offset QPSK (7) 0x11
DCII I-stream (5) 0x12
DCII Q-stream (6) 0x16

DSS (8) and DVB BPSK (9) share the same handler; they use the DVB-S QPSK FEC table but OR the lookup value with 0x80.

6.4 Complete Tuning Sequence (Host to Satellite)

=== Phase 1: LNB Configuration (separate vendor commands) ===
1. SET_LNB_VOLTAGE (0x8B) -- GPIO P0.4 (no I2C)
   H / Circular-L -> wValue=1 (18V)
   V / Circular-R -> wValue=0 (13V)
2. SET_22KHZ_TONE (0x8C)  -- GPIO P0.3 (no I2C)
   High band -> wValue=1 (tone on)
   Low band  -> wValue=0 (tone off)
3. SEND_DISEQC_COMMAND (0x8D) -- if multi-switch needed

=== Phase 2: Tune Command ===
4. TUNE_8PSK (0x86) -- 10-byte payload

=== Phase 3: Firmware Internal Processing ===
5. EP0BUF parsing: mod/FEC to IRAM, freq/SR byte-reversed to XRAM
6. Modulation dispatch: FEC lookup, XRAM config registers set
7. GPIO P3.6: DVB mode select

=== Phase 4: BCM4500 I2C Programming (3 outer retries x 3 I2C addresses) ===
8. Poll BCM4500 ready: I2C READ regs 0xA2, 0xA8, 0xA4
9. Write page: I2C WRITE reg 0xA6 <- 0x00
10. Write config: I2C WRITE reg 0xA7 <- [freq, SR, FEC, mod, demod params]
11. Execute: I2C WRITE reg 0xA8 <- 0x03 (indirect write command)
12. Poll completion: I2C READ regs 0xA8, 0xA2
13. Verify: I2C READ reg 0xA7 (read-back compare)

=== Phase 5: Signal Acquisition (host polling) ===
14. GET_SIGNAL_LOCK (0x90) -- poll until non-zero
15. GET_SIGNAL_STRENGTH (0x87) -- read SNR

6.5 Signal Lock (GET_SIGNAL_LOCK, 0x90)

Returns 1 byte from BCM4500 register 0xA4. Bit 5 (0x20) indicates signal lock. Both the Linux and Windows drivers interpret any non-zero value as locked and report full lock status (FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER).

6.6 Signal Strength (GET_SIGNAL_STRENGTH, 0x87)

Returns 6 bytes. The first two bytes contain a 16-bit SNR value (little-endian, in dBu * 256 units):

Byte 0: SNR low byte (LSB)
Byte 1: SNR high byte (MSB)
Bytes 2-5: Reserved / BCM4500 diagnostic registers

SNR scaling formula (from Windows BDA driver):

snr_raw = (buf[1] << 8) | buf[0]
if snr_raw <= 0x0F00:
    signal_strength = snr_raw * 17     // maps to 0--65535
else:
    signal_strength = 0xFFFF           // 100% at SNR >= 0x0F00

The firmware performs a multi-step I2C transaction to read signal quality: BCM4500 indirect register write/read via 0xA6/0xA7/0xA8, with read-back verification.

Version differences:

  • v2.06: polls 3 registers (0xA2, 0xA8, 0xA4), loops up to 6 times
  • v2.13: simplified polling (consolidated to 1 register), different call chain
  • Rev.2: explicit write/read-back verification step

7. BCM4500 Demodulator Interface

7.1 I2C Bus

The BCM4500 is accessed via the FX2's I2C controller at XRAM 0xE678.

Parameter Value
Primary I2C address 0x10 (7-bit)
Alternate addresses 0x3F, 0x7F (probed by v2.13 INT0 handler)
Bus speed 400 kHz (set via C2 header config byte 0x40)
EEPROM address 0x51 (7-bit, 24Cxx-family, for serial number / platform ID)

The FX2 I2C controller is accessed through XRAM registers:

  • 0xE678: I2C control/status register
  • 0xE679: I2C data register

7.2 Indirect Register Protocol

The BCM4500 uses an indirect register access scheme through three I2C-accessible registers:

Register 0xA6: Page/address select (write page number)
Register 0xA7: Data register (read/write indirect data)
Register 0xA8: Command register (write 0x03 to execute indirect write)

Write sequence:

1. I2C WRITE device 0x10, reg 0xA6 <- page_number (typically 0x00)
2. I2C WRITE device 0x10, reg 0xA7 <- data_bytes (N bytes)
3. I2C WRITE device 0x10, reg 0xA8 <- 0x03 (execute)
4. Poll reg 0xA8 until command complete
5. Read back reg 0xA7 to verify

7.3 Status Registers

Register Function
0xA2 BCM4500 status (polled for readiness)
0xA4 Lock/ready register; bit 5 = signal locked
0xA8 Command register; bit 0 = command done (polled)
0xF9 Demod status (read by v2.13 GET_DEMOD_STATUS / INT0 polling)

7.4 Demod Scan

The tune function tries up to 3 different I2C address configurations per attempt, with 3 outer retries (total: up to 9 I2C programming attempts). This supports hardware variants where the BCM4500 may appear at different bus addresses.

The demod scan function (Rev.2 FUN_CODE_1dd0) iterates through parameter sets computed from the iteration index (address offsets multiplied by 0x11), calling the indirect write function (FUN_CODE_1670) for each.

v2.13 adds a more sophisticated probe at boot: INT0 polls addresses 0x7F and 0x3F up to 40 times (0x28), setting a "no demod found" flag (_1_4) if neither responds. This flag prevents tuning attempts on boards with absent or failed demodulators.


8. GPIF Streaming Path

8.1 Data Flow

BCM4500              Cypress FX2 (CY7C68013A)              USB Host
Demodulator    P3.5  GPIF Engine    EP2 FIFO     EP2 (0x82)
  (I2C:0x10) <-----> (Master Read)  (AUTOIN)   ------------> Bulk IN
             8-bit   0xE4xx wfm     4x buffer                7 URBs
             parallel               8-bit                     x 8KB

The path is fully hardware-managed. The GPIF engine reads data from the BCM4500's 8-bit parallel transport stream output directly into the EP2 FIFO. The AUTOIN bit causes automatic USB commit when the FIFO buffer is full. The FLOWSTATE engine automatically re-triggers GPIF transactions when buffer space becomes available. No firmware intervention occurs in the data path after initial setup.

8.2 Key Register Configuration

All values are identical across the three firmware versions:

Register Address Value Function
IFCONFIG 0xE601 0xEE Internal 48 MHz clock, GPIF master mode, async, debug output
EP2FIFOCFG 0xE618 0x0C AUTOIN=1, ZEROLENIN=1, 8-bit data path
REVCTL 0xE60B 0x03 NOAUTOARM + SKIPCOMMIT
CPUCS 0xE600 bits [4:3]=10 48 MHz CPU clock
FLOWSTATEA 0xE668 OR= 0x09 FSEN (flow state enable) + FS[3]
GPIFIE 0xE65C OR= 0x3D Waveform, TC, DONE, FIFO flag, WF2 interrupts

IFCONFIG decode (0xEE = 1110_1110):

  • Bit 7: IFCLKSRC=1 (internal clock)
  • Bit 6: 3048MHZ=1 (48 MHz)
  • Bit 5: IFCLKOE=1 (clock output to BCM4500)
  • Bit 4: IFCLKPOL=0 (non-inverted)
  • Bit 3: ASYNC=1 (RDY pin handshaking, not clock-edge sampling)
  • Bit 2: GSTATE=1 (debug state output on PORTE)
  • Bits 1:0: IFCFG=10 (GPIF internal master)

8.3 ARM_TRANSFER Sequences

Start streaming (wValue=1):

  1. Set config_byte bit 7 (streaming active)
  2. Load GPIF transaction count: GPIFTCB3:2 = 0x8000 (effectively infinite)
  3. Reset GPIF address and EP2 FIFO byte count
  4. Assert P3.5 LOW (BCM4500 transport stream enable)
  5. Wait for initial GPIF transaction (poll GPIFTRIG bit 7)
  6. De-assert P3.5 HIGH
  7. Trigger continuous GPIF read: GPIFTRIG = 0x04 (read into EP2)
  8. Set P0.7 LOW (streaming indicator)

Stop streaming (wValue=0):

  1. Set P0.7 HIGH (streaming stopped)
  2. Write EP2FIFOBCH = 0xFF (force-flush current buffer)
  3. Wait for GPIF idle (poll GPIFTRIG bit 7)
  4. Write OUTPKTEND = 0x82 (skip/discard partial EP2 packet)
  5. Clear config_byte bit 7 (streaming inactive)
  6. Set P3 bits 7:5 = 1 (de-assert all BCM4500 control lines)

8.4 Interrupt Handling

INT4 and INT6 (GPIF/FIFO events) share a common handler that sets a software flag and clears the hardware interrupt. The main loop polls this flag, enters CPU idle mode (PCON.0) between events, and checks EP2CS for buffer availability before re-arming the GPIF.


9. LNB and DiSEqC Control

9.1 LNB Voltage

LNB voltage is controlled via GPIO P0.4 on all firmware versions. No I2C is involved.

wValue Voltage GPIO P0.4 Polarization
0 13V LOW Vertical / Circular-Right
1 18V HIGH Horizontal / Circular-Left

USE_EXTRA_VOLT (0x94) enables a +1V boost (13V->14V, 18V->19V) for long cable runs, by writing to XRAM 0xE0B6 (0x62=normal, 0x6A=boosted; difference is bit 3).

9.2 22 kHz Tone

The 22 kHz tone is controlled via GPIO P0.3 on all firmware versions. P0.3 gates an external 22 kHz oscillator on the PCB. The firmware does not generate the 22 kHz signal directly.

wValue State GPIO P0.3 Band
0 OFF LOW Low band (9.75 GHz LO on universal LNB)
1 ON HIGH High band (10.6 GHz LO on universal LNB)

9.3 DiSEqC Protocol

All firmware versions implement DiSEqC via Timer2-based GPIO bit-bang. The algorithm is identical across versions; only the data pin assignment differs (see Section 10).

Timer2 configuration (identical across all versions):

Parameter Value
T2CON 0x04 (auto-reload, running)
RCAP2H:RCAP2L 0xF82F (reload = 63535)
CKCON.T2M 0 (Timer2 clock = 48 MHz / 12 = 4 MHz)
Tick period (65536 - 63535) / 4 MHz = 500.25 us

DiSEqC timing:

Parameter Value
Bit period 1.5 ms (3 Timer2 ticks)
Byte period 13.5 ms (9 bits: 8 data + 1 parity)
Tone burst 12.5 ms (25 ticks)
Pre-TX settling delay 7.5 ms (15 ticks)
Data '0' 1.0 ms tone + 0.5 ms silence (2/3 duty)
Data '1' 0.5 ms tone + 1.0 ms silence (1/3 duty)
Carrier frequency 22 kHz (external oscillator gated by P0.3)

Manchester encoding (decompiled from Rev.2 FUN_CODE_213c):

Each DiSEqC bit = 3 Timer2 ticks:
  Tick 1: inter-bit gap (carrier OFF)
  Tick 2: carrier ON via P0.3
  Tick 3: if data='1', carrier OFF early; if data='0', carrier stays ON
  End: carrier OFF

Byte transmission: 8 data bits MSB-first + 1 odd parity bit, each encoded as a Manchester symbol. The parity bit is '1' when the number of '1' data bits is even.

Tone burst (mini DiSEqC): 25 consecutive Timer2 ticks of carrier (12.5 ms).

9.4 SET_DN_SWITCH (0x8F) -- Legacy Dish Network Protocol

A 7-bit serial command bit-banged on GPIO P0.4 with specific timing:

  1. Assert P0.4 HIGH (start pulse)
  2. Delay ~32 cycles
  3. De-assert P0.4
  4. Delay ~8 cycles
  5. Shift out 7 bits LSB-first via P0.4, with ~8 cycle delays between bits

The Linux kernel calls this via the dishnetwork_send_legacy_command frontend callback. The 8th bit (0x80) of the original switch command controls LNB voltage and is sent separately via SET_LNB_VOLTAGE.


10. GPIO Pin Map

Port 0 (SFR 0x80, a.k.a. IOA)

Pin v2.06 Rev.2 v2.10 v2.13 Notes
P0.0 -- LNB control (0x97) DiSEqC data DiSEqC data pin moved across versions
P0.1 -- -- --
P0.2 Init set Init set (0x84) Init set BCM4500 control
P0.3 22 kHz tone 22 kHz tone 22 kHz tone Gates external 22 kHz oscillator
P0.4 LNB 13V/18V LNB 13V/18V + DiSEqC data LNB 13V/18V Also SET_DN_SWITCH bit-bang (all versions)
P0.5 -- GPIO status (0x98) input -- LNB feedback on Rev.2
P0.6 -- GPIO control (0x97) -- LNB control on Rev.2
P0.7 DiSEqC data Streaming indicator Streaming indicator DiSEqC data on v2.06 only

Port 3 (SFR 0xB0)

Pin Function Notes
P3.0 Init HIGH
P3.4 GPIO control Used by FUN_CODE_1fcf (Rev.2)
P3.5 TS_EN Transport stream enable: LOW=active, HIGH=idle
P3.6 DVB mode BCM4500 mode select; DiSEqC port direction (Rev.2)
P3.7 BCM4500 control De-asserted (HIGH) when streaming stops

Port B (XRAM-mapped IOB)

Used by internal debug commands 0x96--0x98:

Pin v2.06/v2.13 Rev.2
IOB.0 GPIO status input (0x98) --
IOB.1 LNB control (0x97) --
IOB.2 LNB control (0x97) --
IOB.3 LNB GPIO mode (0x96) --
IOB.4 -- LNB GPIO mode (0x96) + control (0x97)

Init values (Rev.2):

  • P0 = 0x84 (P0.7=1, P0.2=1)
  • P3 = 0xE1 (P3.7:5=1, P3.0=1)
  • IPL1 = 0x9E

DiSEqC Data Pin Summary

Version Data Pin Carrier Pin
v2.06 P0.7 P0.3
Rev.2 v2.10 P0.4 P0.3
v2.13 P0.0 P0.3

The carrier pin (P0.3) is the same across all versions. The data pin is used only internally by the firmware's Manchester encoding logic to control whether the carrier is cut short or held for the full bit period.


11. Firmware Versions

11.1 Version Table

Firmware Version Build Date PID Functions Binary Size Stack Ptr
v2.06.04 0x020604 2007-07-13 0x0203 61 ~9,472 bytes SP=0x72
Rev.2 v2.10.04 0x020A04 2010-03-12 0x0202 107 ~8,843 bytes SP=0x4F
v2.13.01 0x020D01 2010-03-12 0x0203 88 ~9,322 bytes SP=0x50

Note: Rev.2 v2.10 targets a different product (PID 0x0202). The v2.13 family has three sub-variants (FW1/FW2/FW3) targeting different SkyWalker-1 hardware sub-revisions.

11.2 GET_FW_VERS (0x92) Format

Returns 6 bytes of hardcoded constants:

Byte 0: version minor_minor  (e.g., 0x04)
Byte 1: version minor        (e.g., 0x06)
Byte 2: version major        (e.g., 0x02)
Byte 3: build day            (e.g., 0x0D = 13)
Byte 4: build month          (e.g., 0x07 = July)
Byte 5: build year - 2000    (e.g., 0x07 = 2007)

Full version number: byte[2] << 16 | byte[1] << 8 | byte[0]

Kernel constants for comparison:

GP8PSK_FW_REV1 = 0x020604
GP8PSK_FW_REV2 = 0x020704

11.3 Binary Comparison Matrix

Byte-level similarity (percentage of matching bytes within shared length):

v2.06 v2.13.1 v2.13.2 v2.13.3 Rev.2
v2.06 -- 4.8% 4.3% 4.3% 6.0%
v2.13.1 -- 57.2% 59.4% 8.0%
v2.13.2 -- 83.5% 5.8%
v2.13.3 -- 5.8%
Rev.2 --

The very low similarity between major versions (4--8%) indicates complete recompilation with different linker configurations. Functions are relocated even when logic is identical. Within the v2.13 family, FW2 and FW3 are 83.5% similar (minor hardware tuning), while FW1 differs more (57--59%, different demod interface).

11.4 Key Differences Between Versions

Feature v2.06 Rev.2 v2.10 v2.13
Vendor commands 30 (0x80--0x9D) 27 (0x80--0x9A) 30 (0x80--0x9D)
INT0 purpose USB re-enumeration USB re-enumeration Demod availability polling
Demod probe at init No No Yes (40 attempts at 0x7F + 0x3F)
Retry loops No No Yes (20-attempt with checksum verification)
HW revision detection No Yes (descriptor walker) Yes (flag _1_3)
DiSEqC data pin P0.7 P0.4 P0.0
Config byte IRAM 0x6D 0x4E 0x4F
Descriptor base 0x1200 0x0E00 0x0E00
Init table address CODE:0B46 CODE:0B48 CODE:0B88
BCM4500 status poll 3 registers 3 registers 1 register (consolidated)
Anti-tampering string No No Yes (at offset 0x1880)
New commands -- 0x99/0x9A proto 0x99 GET_DEMOD_STATUS, 0x9A INIT_DEMOD, 0x9C DELAY_COMMAND
0x9D behavior HW revision mode switch N/A (out of range) Conditional demod reset

11.5 EEPROM Format Details

All SkyWalker-1 C2 files use uniform 1023-byte segments:

Segment  Address   Length
-------  -------   ------
1        0x0000    1023    Contains reset vector, interrupt handlers
2        0x03FF    1023
3        0x07FE    1023
4        0x0BFD    1023
5        0x0FFC    1023
6        0x13FB    1023
7        0x17FA    1023
8        0x1BF9    1023
9        0x1FF8    1023
10       0x23F7    varies  (115--265 bytes depending on version)

11.6 Anti-Tampering (v2.13 only)

At firmware offset 0x1880, all v2.13 sub-variants contain:

"Tampering is detected. Attempt is logged. Warranty is voided ! \n"

Followed by I2C register write commands (01 10 aa 82 02 41 41 83). This string and mechanism are absent from v2.06 and Rev.2 firmware.

11.7 Rev.2 as Transitional Firmware

Rev.2 v2.10.4 sits architecturally between v2.06 and v2.13:

  • Adopted v2.13's stack pointer (SP=0x4F) and descriptor base (0x0E00)
  • Retained v2.06's INT0 USB re-enumeration behavior
  • Lacks v2.13's demodulator polling, retry loops, and 3 additional vendor commands
  • Has the most functions (107) but smallest binary (~8.7 KB) due to granular decomposition
  • The INT0 repurposing was the last major architectural change between Rev.2 and v2.13

12. Internal Debug Commands

Commands 0x91 and 0x96--0x98 are not used by any driver (Linux or Windows). They appear to be manufacturing/debug interfaces.

0x91 I2C_ADDR_ADJUST

Increments (wValue != 0) or decrements (wValue == 0) an internal IRAM counter and returns its current value (1 byte). The counter is at IRAM 0x66 (v2.06) or IRAM 0x18 (v2.13/Rev.2). Likely used for I2C bus address or tuner register index adjustment during development.

0x96 SET_LNB_GPIO_MODE

Configures GPIO output enable registers for LNB voltage regulator hardware:

Mode v2.06/v2.13 Rev.2
Default (wValue=0) OEB=0xF0 OEB=0xE7, OEA=0x9E
Active (wValue=1) IOB=(IOB & 0xF7) OR 0x06; OEB=0xFE IOB.4 clear; P0.6, P0.0 set; OEA OR= 0x41

0x97 SET_GPIO_PINS

Direct GPIO pin write for LNB control:

wValue Bit v2.06/v2.13 Target Rev.2 Target
bit 1 IOB.1 P0.6 (Port A)
bit 2 IOB.2 P0.0 (Port A)
bit 3 IOB.3 IOB.4 (Port B)

0x98 GET_GPIO_STATUS

Returns 1 byte (0 or 1) from a single GPIO input pin -- likely an LNB overcurrent or power-good feedback signal:

Version Pin Read
v2.06/v2.13 IOB.0 (Port B bit 0)
Rev.2 P0.5 (Port A bit 5)

Sources

Firmware Analysis

  • Ghidra decompilation/disassembly of three firmware images:
    • v2.06.04 (Ghidra port 8193) -- extracted from SkyWalker-1 EEPROM
    • Rev.2 v2.10.04 (Ghidra port 8197) -- extracted from Rev.2 hardware
    • v2.13.01 FW1 (Ghidra port 8194) -- extracted from Windows updater
  • Firmware dumps: /home/rpm/claude/ham/satellite/genpix/skywalker-1/firmware-dump/

Driver Source

  • Linux kernel 6.16.5: drivers/media/usb/dvb-usb/gp8psk.c, gp8psk.h, gp8psk-fe.c, gp8psk-fe.h
  • Linux kernel: drivers/media/usb/dvb-usb/dvb-usb-firmware.c
  • Windows BDA driver: SkyWalker1_Final_Release/Source/SkyWalker1Control.cpp
  • Windows BDA driver: SkyWalker1_Final_Release/Include/SkyWalker1Control.h, SkyWalker1CommonDef.h

Hardware Documentation

Phase 1 Analysis Reports

  1. gp8psk-driver-analysis.md -- Linux kernel driver analysis
  2. firmware-analysis-v206-vs-v213.md -- Cross-version firmware comparison
  3. rev2-deep-analysis.md -- Rev.2 deep function inventory (107 functions)
  4. gpif-streaming-analysis.md -- GPIF/MPEG-2 streaming path
  5. kernel-fw01-analysis.md -- Kernel firmware format and EEPROM boot
  6. vendor-commands-unknown.md -- Complete vendor command decode (0x8F, 0x91--0x98)
  7. tuning-protocol-analysis.md -- TUNE_8PSK protocol deep dive