FW2.13 Sub-Variant Comparison
The v2.13 firmware was distributed as three sub-variants via the SW1_update_2_13_x.exe Windows updater tool. Ghidra analysis reveals that these target fundamentally different hardware interfaces, not just minor revisions.
Overview
Section titled “Overview”| Aspect | FW1 (v2.13.1) | FW2 (v2.13.2) | FW3 (v2.13.3) |
|---|---|---|---|
| Version ID | 0x020D01 | 0x020D01 | 0x020D01 |
| Build date | 2010-03-12 | 2010-03-12 | 2010-03-12 |
| Functions | 82 | 83 | 83 |
| Binary size | 9,322 bytes | 9,377 bytes | 9,369 bytes |
| Stack pointer | 0x50 | 0x50 | 0x52 |
| P0 init | 0xA4 | 0xA4 | 0xA0 |
| Status register | INTMEM 0x4F | INTMEM 0x4F | INTMEM 0x51 |
| Demod interface | I2C bus | Parallel bus (P0/P1) | Parallel bus (enhanced) |
| Config source | Hardcoded | External (0xE080—0xE08E) | External (0xE080—0xE08E) |
Hardware Detection
Section titled “Hardware Detection”All three sub-variants report the same version ID (0x020D01) to the host. The Windows updater SW1_update_2_13_x.exe selects which sub-variant to flash, but the detection mechanism is not yet fully understood.
Distinguishing Characteristics
Section titled “Distinguishing Characteristics”Although the updater’s detection method is opaque, the firmware binaries themselves contain clear markers that distinguish each target hardware:
| Characteristic | FW1 | FW2 | FW3 | Docs |
|---|---|---|---|---|
| P0 init value | 0xA4 | 0xA4 | 0xA0 (bit 2 cleared) | Register Map — IRAM |
| Stack pointer | 0x50 | 0x50 | 0x52 (+2 for status reg) | Register Map — IRAM |
| Config status IRAM | 0x4F | 0x4F | 0x51 | Config Status |
| I2C buffer IRAM | 0x48/0x49 | 0x48/0x49 | 0x4A/0x4B | Register Map — IRAM |
| Demod interface | I2C bus | Parallel (P0/P1) | Parallel (enhanced, dual-phase) | See tabs below |
| Config source | Hardcoded | External 0xE080—0xE08E | External 0xE080—0xE08E | Register Map — XRAM |
FW1 Demod Type Detection
Section titled “FW1 Demod Type Detection”FW1 is the only sub-variant that performs demodulator type identification at runtime. Function FUN_CODE_1405 reads the P1 port after an I2C transaction and matches the result against known silicon signatures:
| Type Code | P1 Signature | Likely Silicon |
|---|---|---|
| Type 3 | 0xA5 or 0xB5 | Original BCM4500 |
| Type 4 | 0x5A | BCM4500 revision A |
| Type 5 | 0x5B | BCM4500 revision B |
| Type 6 | 0x5C | BCM4500 revision C |
FW2 and FW3 use a different signature check (P1 ^ 0x1D) through the parallel bus, suggesting the demod variant is already known at flash time on those PCBs.
Hardware Interface Evolution
Section titled “Hardware Interface Evolution”FW1 (v2.13.1) I2C
Section titled “FW1 (v2.13.1) ”FW1 targets the original SkyWalker-1 PCB with an I2C-connected demodulator. The FX2 communicates with the demod entirely through standard I2C master-mode transactions.
Evidence from FUN_CODE_0eea:
- Uses
FUN_CODE_23ae(I2C START),FUN_CODE_23ee(I2C byte write),FUN_CODE_23d0(I2C address) - Standard I2C retry with NACK detection
- Timer2-based I2C timeout (TR2 check in vendor handler)
- Reads back via
FUN_CODE_2164
Unique functions:
FUN_CODE_0fc7— I2C write-with-retry (20 attempts via I2C bus)FUN_CODE_1405— Tuner/demodulator identification via I2C + P1 port reads with signature matchingFUN_CODE_14b9— Calibrated delay function with CPUCS clock divider awareness
Demodulator type detection (from FUN_CODE_1405):
| Type Code | P1 Signature |
|---|---|
| Type 3 | 0xA5 or 0xB5 |
| Type 4 | 0x5A |
| Type 5 | 0x5B |
| Type 6 | 0x5C |
FW2 (v2.13.2) Parallel
Section titled “FW2 (v2.13.2) ”FW2 targets a revised PCB with a parallel-bus connected demodulator. The demod data port is connected directly to the FX2’s P1, with P0 bits controlling bus signals.
Evidence from FUN_CODE_0eea:
- Reads demod type from address table (BANK1 pointer + offset)
- Uses
FUN_CODE_11b6for demod selection - Toggles P0 bits 6/7 for bus control (P0.6 = chip select, P0.7 = read strobe)
- Reads data from P1 port (8-bit parallel data bus)
- Single-phase read: one P1 read per bus cycle
Bus protocol (decompiled):
uVar1 = P1; // Read data with one bus stateP0 |= 0x40; // Change control lineuVar2 = P1; // Read again with new stateFUN_CODE_1b2a(uVar2, uVar1); // Process both samplesConfiguration loading:
- Loads 15 configuration bytes from external memory (
0xE080—0xE08E) into demod registers (0xE6C0—0xE6CD) - Same device signature matching as FW1 but via parallel bus (
P1 ^ 0x1Dcheck)
FW3 (v2.13.3) Enhanced
Section titled “FW3 (v2.13.3) ”FW3 targets a further revised PCB with the same parallel-bus architecture as FW2 but with a different bus timing protocol. Uses dual-phase reads with OR-accumulation.
Evidence from FUN_CODE_0eea:
- Initializes OR-accumulators:
DAT_INTMEM_3f = 0; DAT_INTMEM_40 = 0 - Sets P0 | 0x80 once at start (not per-iteration like FW2)
- Two separate P1 reads per cycle with different P0.6 states
- OR-accumulates results before processing
Bus protocol (decompiled):
DAT_INTMEM_3f = 0;DAT_INTMEM_40 = 0; // Clear accumulators
// Phase 1: P0.6 highP0 |= 0x44;bVar2 = P1;DAT_INTMEM_3f |= bVar2; // OR-accumulate
// Phase 2: P0.6 lowP0 &= ~0x40;bVar2 = P1;DAT_INTMEM_40 |= bVar2; // OR-accumulate
FUN_CODE_1b2a(0, DAT_INTMEM_3f, DAT_INTMEM_40);Why OR-accumulation? This pattern suggests the demod chip variant has either:
- Open-drain outputs requiring multiple read cycles
- Bus settling time issues on the newer PCB layout
- A chip revision that serializes data across multiple bus phases
Binary Distance Matrix
Section titled “Binary Distance Matrix”Byte-level differences between sub-variants:
| Pair | Different Bytes | Percentage Different |
|---|---|---|
| FW1 vs FW2 | 3,993 | 42.8% |
| FW1 vs FW3 | 3,789 | 40.6% |
| FW2 vs FW3 | 1,525 | 16.5% |
FW2 and FW3 are 83.5% identical at the byte level, confirming they share the same parallel-bus architecture. FW1 diverges significantly because it uses a completely different bus interface (I2C vs. parallel).
Memory Comparison at Key Offsets
Section titled “Memory Comparison at Key Offsets”Identical Regions
Section titled “Identical Regions”These regions are byte-identical across all three sub-variants:
| Address Range | Content |
|---|---|
0x0000—0x000F | RESET vector (LJMP 0x170D), INT0 handler |
0x0B88—0x0B9F | Init table (same XRAM register initialization) |
0x06D9—0x06F0 | Generic memory access utilities |
0x1740—0x174F | Bit manipulation lookup table |
Critical Divergence: CODE:0EEA
Section titled “Critical Divergence: CODE:0EEA”This is where the three sub-variants diverge most dramatically:
FW1: 8f44 8c45 8d46 8b47 754a14 e544 b451... (I2C transfer parameters in registers)
FW2: 753e14 e50d 240a f582 e435 0cf5 83e0... (reads from DPTR+offset table)
FW3: 753e14 e4f5 3ff5 40 e50d 240a f582... (similar to FW2 + accumulator initialization)FW1’s FUN_CODE_0eea is a standard I2C master transfer function. FW2/FW3’s version is a parallel bus demodulator interface.
Thunk Target Divergence (CODE:1500)
Section titled “Thunk Target Divergence (CODE:1500)”FW1: 02 2252 00 02 22dd 00 02 22c7 00 02 226a 00FW2: 02 228d 00 02 2318 00 02 2302 00 02 22a5 00FW3: 02 228d 00 02 2318 00 02 2302 00 02 22a5 00FW2 and FW3 share identical interrupt handler targets. FW1 jumps to different addresses, reflecting its different internal function layout.
Detailed Differences
Section titled “Detailed Differences”Stack Pointer and Status Register
Section titled “Stack Pointer and Status Register”| Property | FW1 | FW2 | FW3 |
|---|---|---|---|
| SP value | 0x50 | 0x50 | 0x52 |
| Status IRAM | 0x4F | 0x4F | 0x51 |
| I2C buffer IRAM | 0x48/0x49 | 0x48/0x49 | 0x4A/0x4B |
FW3 pushes the stack pointer up by 2 bytes to make room for the additional status register at IRAM 0x51. The 2-byte SP difference exactly accounts for moving the status register from 0x4F to 0x51.
P0 Init Value
Section titled “P0 Init Value”| Variant | P0 Init | Binary | Difference |
|---|---|---|---|
| FW1/FW2 | 0xA4 | 1010 0100 | Bit 2 = 1 |
| FW3 | 0xA0 | 1010 0000 | Bit 2 = 0 |
P0 bit 2 controls a GPIO signal likely related to demodulator interface mode or reset polarity on the FW3 target PCB.
Vendor Handler Differences
Section titled “Vendor Handler Differences”| Feature | FW1 | FW2/FW3 |
|---|---|---|
Case 0x3D3 | TR2 timer check (I2C timeout) | OR operation (parallel bus) |
Case 0x421-0x423 | Simple check | P2.1 write + rotate-left (bus direction) |
| Error path | func_0x06e4 | DAT=0x0 |
FW1’s timer-based case is used for I2C bus timeout recovery. FW2/FW3’s rotate-left and P2.1 write is a parallel bus data direction control.
Hardware Progression Theory
Section titled “Hardware Progression Theory”The three sub-variants represent an evolutionary progression:
-
FW1 (v2.13.1): Original design with I2C-connected demodulator. Simple interface but limited in bandwidth. The FX2 acts purely as an I2C master bridge.
-
FW2 (v2.13.2): Redesigned with parallel-bus demodulator for higher throughput. P1 carries 8-bit data, P0 provides control signals. External calibration data at
0xE080—0xE08E. -
FW3 (v2.13.3): Refined parallel interface for a newer demod silicon revision. Dual-phase reads with OR-accumulation handle bus timing differences. Additional IRAM state tracking (SP bumped to
0x52).
All three support the same modulation types (DVB-S QPSK, Turbo QPSK/8PSK/16QAM, DCII, DSS) and the same demod type codes (3—6). The differences are purely hardware interface, not feature set.