Add BCM4500 register map and fill documentation gaps
New page: bcm4500/register-map.mdx consolidates all register addresses (direct, indirect page 0, FX2 XRAM/IRAM, I2C controller) into a single lookup reference with cross-reference index. Expanded sections: - fw213-variants: hardware detection mechanism, distinguishing characteristics table, FW1 demod type detection signatures - demodulator: probe logic (3x3 retry, INT0 40-iteration boot probe at 0x7F/0x3F, no_demod_flag graceful degradation) - version-comparison: version ID gap aside (v2.07.04 is a kernel constant, not a real firmware release) Cross-links added to signal-monitoring and tuning-protocol pages.
This commit is contained in:
parent
3f970967c4
commit
867b304773
@ -8,6 +8,22 @@ export default defineConfig({
|
||||
devToolbar: {
|
||||
enabled: false,
|
||||
},
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: 4321,
|
||||
},
|
||||
vite: {
|
||||
server: {
|
||||
allowedHosts: [process.env.PUBLIC_DOMAIN, 'localhost'].filter(Boolean),
|
||||
...(process.env.VITE_HMR_HOST && {
|
||||
hmr: {
|
||||
host: process.env.VITE_HMR_HOST,
|
||||
protocol: 'wss',
|
||||
clientPort: 443,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
integrations: [
|
||||
starlight({
|
||||
title: 'SkyWalker-1 Docs',
|
||||
@ -44,6 +60,7 @@ export default defineConfig({
|
||||
{
|
||||
label: 'BCM4500',
|
||||
items: [
|
||||
{ label: 'Register Map', slug: 'bcm4500/register-map' },
|
||||
{ label: 'Demodulator', slug: 'bcm4500/demodulator' },
|
||||
{ label: 'Tuning Protocol', slug: 'bcm4500/tuning-protocol' },
|
||||
{ label: 'GPIF Streaming', slug: 'bcm4500/gpif-streaming' },
|
||||
@ -78,7 +95,8 @@ export default defineConfig({
|
||||
{ label: 'Rev.2 Analysis', slug: 'firmware/rev2-analysis' },
|
||||
{ label: 'Kernel FW01', slug: 'firmware/kernel-fw01' },
|
||||
{ label: 'FW2.13 Variants', slug: 'firmware/fw213-variants' },
|
||||
{ label: 'Custom v3.01\u2013v3.02', slug: 'firmware/custom-v301' },
|
||||
{ label: 'Custom v3.01', slug: 'firmware/custom-v301' },
|
||||
{ label: 'Custom v3.02', slug: 'firmware/custom-v302' },
|
||||
{ label: 'Storage Formats', slug: 'firmware/storage-formats' },
|
||||
],
|
||||
},
|
||||
|
||||
@ -7,6 +7,8 @@ import { Tabs, TabItem, Badge, Aside, Steps } from '@astrojs/starlight/component
|
||||
|
||||
The Broadcom BCM4500 is a 128-pin MQFP satellite demodulator that handles RF demodulation, forward error correction, and MPEG-2 transport stream output. The FX2 communicates with it exclusively over the shared I2C bus using an indirect register protocol.
|
||||
|
||||
See the [Register Map](/bcm4500/register-map/) for a consolidated lookup of all BCM4500 and FX2 register addresses referenced on this page.
|
||||
|
||||
## I2C Addressing
|
||||
|
||||
| Parameter | Value |
|
||||
@ -122,9 +124,49 @@ The trailing zero write (step 3) appears in all stock firmware versions. Its pur
|
||||
|
||||
## Demodulator Scan
|
||||
|
||||
The tune function tries up to 3 different I2C address configurations per attempt, with 3 outer retries (up to 9 total I2C programming attempts). This supports hardware variants where the BCM4500 may appear at different bus addresses.
|
||||
### Tuning Retry (All Firmware Versions)
|
||||
|
||||
The v2.13 firmware adds boot-time probing: the INT0 handler polls addresses 0x7F and 0x3F up to 40 times, setting a flag if neither responds. This flag prevents tuning attempts on boards with absent demodulators.
|
||||
The tune function wraps the BCM4500 I2C programming sequence in a two-level retry loop:
|
||||
|
||||
- **Inner loop**: tries up to 3 different I2C address configurations per attempt. This supports hardware variants where the BCM4500 may appear at different bus addresses.
|
||||
- **Outer loop**: retries the entire inner scan up to 3 times.
|
||||
|
||||
This yields up to **3 × 3 = 9 total I2C programming attempts** per tune command. The v2.13 firmware adds a 20-attempt retry with checksum verification on each individual I2C write within the programming step.
|
||||
|
||||
### Boot-Time Probe (v2.13 Only)
|
||||
|
||||
The v2.13 firmware repurposed the INT0 interrupt handler (vector at `CODE:0003`) from USB re-enumeration to demodulator availability detection. The handler runs once during boot, before the main loop:
|
||||
|
||||
```c title="INT0 handler (v2.13) — demod probe"
|
||||
void INT0_vector(void) {
|
||||
for (counter = 0x28; counter != 0; counter--) { // 40 iterations
|
||||
byte result = I2C_read(0x7F); // Probe first alternate address
|
||||
if (result != 0x01) {
|
||||
result = I2C_read(0x3F); // Probe second alternate address
|
||||
if (result != 0x01) break; // Got a response — demod present
|
||||
}
|
||||
}
|
||||
no_demod_flag = (counter == 0); // True if all 40 attempts failed
|
||||
}
|
||||
```
|
||||
|
||||
If neither address responds after 40 iterations, `no_demod_flag` is set. This flag causes the firmware to skip all tuning attempts, avoiding I2C bus hangs on boards where the demodulator is absent or unpopulated.
|
||||
|
||||
<Aside type="note" title="Probe vs. Operating Address">
|
||||
The probe addresses (0x7F and 0x3F) are **not** the normal operating address. During regular tuning and signal monitoring, the BCM4500 is always accessed at its standard 7-bit address **0x08**. The probe addresses may be factory-default or configuration-pin-selected addresses that the BCM4500 responds to before its I2C address is programmed, or they may belong to different sub-systems on the demodulator IC. See the [Register Map — I2C Bus Addresses](/bcm4500/register-map/#i2c-bus-addresses) for the full address table.
|
||||
</Aside>
|
||||
|
||||
### `no_demod_flag` Behavior
|
||||
|
||||
When the boot probe fails (all 40 attempts exhausted):
|
||||
|
||||
1. `no_demod_flag` is set to a non-zero value
|
||||
2. The firmware enters its normal main loop but skips BCM4500 initialization
|
||||
3. `TUNE_8PSK` (0x86) commands are accepted but silently fail (no I2C transactions issued)
|
||||
4. `GET_SIGNAL_LOCK` (0x90) returns 0x00 (unlocked)
|
||||
5. The device remains functional for USB communication but cannot tune
|
||||
|
||||
This graceful degradation allows the host software to detect the condition via persistent lock failure rather than USB timeouts.
|
||||
|
||||
## FEC Architecture
|
||||
|
||||
|
||||
199
site/src/content/docs/bcm4500/register-map.mdx
Normal file
199
site/src/content/docs/bcm4500/register-map.mdx
Normal file
@ -0,0 +1,199 @@
|
||||
---
|
||||
title: BCM4500 Register Map
|
||||
description: Definitive register lookup for BCM4500 direct registers, indirect registers, FX2 XRAM/IRAM locations, and I2C controller addresses.
|
||||
---
|
||||
|
||||
import { Badge, Aside } from '@astrojs/starlight/components';
|
||||
|
||||
<Aside type="caution" title="Reverse-Engineered Data">
|
||||
No public BCM4500 datasheet exists. All register addresses and functions on this page were determined through firmware disassembly, I2C bus captures, and behavioral testing. Register names are conventions used throughout this documentation, not official Broadcom nomenclature.
|
||||
</Aside>
|
||||
|
||||
This page consolidates every known register address used by the SkyWalker-1 hardware into a single lookup reference.
|
||||
|
||||
## BCM4500 Direct Registers
|
||||
|
||||
These registers are accessed via standard I2C read/write to the BCM4500 at 7-bit address **0x08** (write byte 0x10, read byte 0x11).
|
||||
|
||||
| Address | Name | R/W | Function |
|
||||
|---------|------|-----|----------|
|
||||
| 0xA2 | Status | R | Readiness status. Returns 0x02 when powered on, no signal locked. Polled during boot probe and [signal strength readback](/bcm4500/signal-monitoring/). |
|
||||
| 0xA4 | Lock | R | Signal lock indicator. Bit 5 (mask 0x20) = signal locked. Read by `GET_SIGNAL_LOCK` (0x90). The kernel treats any non-zero value as locked. |
|
||||
| 0xA6 | Indirect Page | W | Page/address select for the [indirect register protocol](/bcm4500/demodulator/#indirect-register-protocol). Typically written with 0x00 (page 0). |
|
||||
| 0xA7 | Indirect Data | R/W | Data register for indirect reads and writes. Supports auto-increment for multi-byte writes within a single I2C transaction. |
|
||||
| 0xA8 | Indirect Command | R/W | Command register. Write 0x01 = indirect read, 0x03 = indirect write. Read to poll: bit 0 clear = command complete. |
|
||||
| 0xF9 | Demod Status | R | Extended demodulator status. Read by `GET_DEMOD_STATUS` (0x99) in v2.13 firmware. Also polled by the v2.13 INT0 handler. Not accessed by v2.06 or Rev.2. |
|
||||
|
||||
### Indirect Register Triad
|
||||
|
||||
Registers 0xA6, 0xA7, and 0xA8 form a triad that provides access to the BCM4500's internal register space. The sequence is always: select page (0xA6) → write/read data (0xA7) → execute command (0xA8) → poll 0xA8 for completion.
|
||||
|
||||
See [Demodulator — Indirect Register Protocol](/bcm4500/demodulator/#indirect-register-protocol) for the full byte-level I2C sequences.
|
||||
|
||||
## Indirect Registers (Page 0)
|
||||
|
||||
These are the BCM4500 internal registers accessed through the 0xA6/0xA7/0xA8 indirect protocol. All known registers are on page 0x00.
|
||||
|
||||
### Signal Quality
|
||||
|
||||
| Register | Size | Function | Read By |
|
||||
|----------|------|----------|---------|
|
||||
| 0x00--0x01 | 2 bytes | SNR value (16-bit, little-endian). Bytes 0--1 of `GET_SIGNAL_STRENGTH` (0x87) response. | [Signal Monitoring](/bcm4500/signal-monitoring/) |
|
||||
| 0x02--0x05 | 4 bytes | AGC and diagnostic data. Bytes 2--5 of `GET_SIGNAL_STRENGTH` (0x87) response. | [Signal Monitoring](/bcm4500/signal-monitoring/) |
|
||||
|
||||
### Initialization Blocks
|
||||
|
||||
Three blocks written during BCM4500 firmware load. The first byte of each block is the starting register address.
|
||||
|
||||
| Block | Start Reg | Length | Data (hex) | Purpose |
|
||||
|-------|-----------|--------|------------|---------|
|
||||
| 0 | 0x06 | 7 bytes | `06 0b 17 38 9f d9 80` | Primary demod configuration |
|
||||
| 1 | 0x07 | 8 bytes | `07 09 39 4f 00 65 b7 10` | Secondary demod configuration |
|
||||
| 2 | 0x0F | 3 bytes | `0f 0c 09` | Final demod configuration |
|
||||
|
||||
<Aside type="note" title="Init Block Overlap">
|
||||
Blocks 0 and 1 both write to register 0x07 and above, meaning block 1 overwrites the tail end of block 0. This is intentional: block 0 sets initial defaults, block 1 refines registers 0x07--0x0E, and block 2 configures the 0x0F--0x11 range independently. All stock firmware versions use the same init block data.
|
||||
</Aside>
|
||||
|
||||
### Tuning Configuration
|
||||
|
||||
After modulation dispatch, the [tuning protocol](/bcm4500/tuning-protocol/) writes frequency, symbol rate, FEC, and modulation parameters into BCM4500 page 0 registers via the indirect write protocol. The exact target register range depends on the configuration data length (typically 12--18 bytes starting at register 0x00).
|
||||
|
||||
## FX2 XRAM Locations
|
||||
|
||||
External RAM (XRAM) addresses used by the FX2 microcontroller for tuning state and configuration. These are **not** BCM4500 registers — they are FX2 memory locations that hold data destined for or read from the demodulator.
|
||||
|
||||
### Modulation Configuration
|
||||
|
||||
| Address | Name | Function |
|
||||
|---------|------|----------|
|
||||
| 0xE0EB | FEC Code Rate | Looked up from the FEC table for the active modulation. DCII modes use fixed value 0xFC. DSS/BPSK modes OR the lookup with 0x80. |
|
||||
| 0xE0EC | Modulation Type | 0x09 for DVB-S, Turbo, DSS, and BPSK modes. DCII modes load from the DCII lookup table. |
|
||||
| 0xE0F5 | Demod Mode | 0x10 for most modes. DCII variants use 0x10 (combo), 0x11 (offset QPSK), 0x12 (I-stream), or 0x16 (Q-stream). |
|
||||
| 0xE0F6 | Turbo Flag | 0x00 = standard FEC. 0x01 = turbo FEC (QPSK/8PSK/16QAM turbo modes). |
|
||||
|
||||
### Tuning Parameters
|
||||
|
||||
| Address | Size | Content | Source |
|
||||
|---------|------|---------|--------|
|
||||
| 0xE0CB--0xE0CE | 4 bytes | Symbol rate (big-endian) | Byte-reversed from EP0BUF[0--3] during `TUNE_8PSK` |
|
||||
| 0xE0DB--0xE0DE | 4 bytes | IF frequency (big-endian) | Byte-reversed from EP0BUF[4--7] during `TUNE_8PSK` |
|
||||
|
||||
### FEC Rate Lookup Tables
|
||||
|
||||
Populated at boot from CODE-space initialization tables. Indexed by the FEC rate byte from the `TUNE_8PSK` command payload.
|
||||
|
||||
| Base Address | Modulation | Max Index | Rates |
|
||||
|-------------|-----------|-----------|-------|
|
||||
| 0xE0B1 | Turbo 8PSK | 5 | Turbo-specific code rates |
|
||||
| 0xE0B7 | Turbo QPSK | 5 | Turbo-specific code rates |
|
||||
| 0xE0BC | Turbo 16QAM | 1 | Single code rate |
|
||||
| 0xE0BD | DCII (all variants) | 9 | Combined code + modulation values |
|
||||
| 0xE0F9 | DVB-S QPSK / DSS / BPSK | 7 | 1/2, 2/3, 3/4, 5/6, 7/8, auto, none |
|
||||
|
||||
### FW2/FW3 External Configuration
|
||||
|
||||
| Address | Size | Content |
|
||||
|---------|------|---------|
|
||||
| 0xE080--0xE08E | 15 bytes | External calibration data loaded by [FW2 and FW3](/firmware/fw213-variants/) into demod registers at 0xE6C0--0xE6CD. Not used by FW1 (hardcoded config). |
|
||||
|
||||
### USB Endpoint Buffer
|
||||
|
||||
| Address | Size | Content |
|
||||
|---------|------|---------|
|
||||
| 0xE740--0xE749 | 10 bytes | EP0BUF — USB control transfer buffer. Contains the raw `TUNE_8PSK` payload before parsing. |
|
||||
|
||||
## FX2 IRAM by Firmware Version
|
||||
|
||||
Internal RAM (IRAM) addresses vary between firmware versions due to different stack pointer placement. This table maps the key locations for each version.
|
||||
|
||||
### Stack and Status
|
||||
|
||||
| Location | v2.06 | Rev.2 v2.10 | v2.13 FW1/FW2 | v2.13 FW3 |
|
||||
|----------|-------|-------------|---------------|-----------|
|
||||
| Stack pointer (SP) | 0x72 | 0x4F | 0x50 | 0x52 |
|
||||
| Config status byte | 0x6D | 0x4E | 0x4F | 0x51 |
|
||||
| I2C buffer high | -- | 0x48 | 0x48 | 0x4A |
|
||||
| I2C buffer low | -- | 0x49 | 0x49 | 0x4B |
|
||||
|
||||
The config status byte is returned by `GET_8PSK_CONFIG` (0x80). See [Config Status](/usb/config-status/) for bit definitions.
|
||||
|
||||
### Tuning Parameter Storage
|
||||
|
||||
| Location | Address | Function |
|
||||
|----------|---------|----------|
|
||||
| Modulation type | 0x4D | Copied from EP0BUF[8] during `TUNE_8PSK` parsing |
|
||||
| FEC rate index | 0x4F | Copied from EP0BUF[9] during `TUNE_8PSK` parsing |
|
||||
|
||||
<Aside type="note">
|
||||
On v2.13 FW1/FW2, the FEC rate index (IRAM 0x4F) shares the same address as the config status byte. The firmware distinguishes between contexts — the FEC index is only written during tune operations, while config status is read/written at other times. FW3 avoids this collision by moving the config status to 0x51.
|
||||
</Aside>
|
||||
|
||||
### Custom Firmware (v3.01+)
|
||||
|
||||
The custom firmware built with SDCC + fx2lib uses C variables instead of fixed IRAM addresses. The compiler manages allocation, so addresses are not guaranteed stable across builds. Key variables:
|
||||
|
||||
| Variable | Type | Purpose |
|
||||
|----------|------|---------|
|
||||
| `config_status` | `volatile BYTE` | Configuration status byte |
|
||||
| `boot_stage` | `volatile BYTE` | Boot progress (0x00 = not started, 0xFF = complete) |
|
||||
| `i2c_buf[16]` | `__xdata BYTE` | I2C scratch buffer for writes |
|
||||
| `i2c_rd[8]` | `__xdata BYTE` | I2C scratch buffer for reads |
|
||||
| `tm_result[10]` | `__xdata BYTE` | Tune monitor result buffer |
|
||||
|
||||
## FX2 I2C Controller
|
||||
|
||||
The Cypress FX2LP's built-in I2C master controller uses three hardware registers in the SFR-mapped XRAM space.
|
||||
|
||||
| Register | Address | Function |
|
||||
|----------|---------|----------|
|
||||
| I2CS | 0xE678 | Control/Status. Bit fields: DONE (bit 0), ACK (bit 1), BERR (bit 2), ID (bits 4:3), LASTRD (bit 5), STOP (bit 6), START (bit 7). |
|
||||
| I2DAT | 0xE679 | Data register. Write to transmit a byte, read to receive. First write after START sends the slave address byte. |
|
||||
| I2CTL | 0xE67A | Control register. Bit 0 = 400 kHz mode (set by all firmware versions at init). Bit 1 = STOPIE (stop interrupt enable). |
|
||||
|
||||
### I2C Bus Addresses
|
||||
|
||||
| 7-bit Address | 8-bit Write | 8-bit Read | Device |
|
||||
|--------------|-------------|------------|--------|
|
||||
| 0x08 | 0x10 | 0x11 | BCM4500 demodulator (operating address) |
|
||||
| 0x10 | 0x20 | 0x21 | Tuner / LNB controller |
|
||||
| 0x51 | 0xA2 | 0xA3 | Configuration EEPROM (serial number, calibration, firmware storage) |
|
||||
| 0x3F | 0x7E | 0x7F | BCM4500 alternate probe address (v2.13 boot detection only) |
|
||||
| 0x7F | 0xFE | 0xFF | BCM4500 alternate probe address (v2.13 boot detection only) |
|
||||
|
||||
See [I2C Bus Architecture](/i2c/bus-architecture/) for bus topology and the [STOP Corruption Bug](/i2c/stop-corruption-bug/) for the spurious STOP issue affecting the FX2 controller.
|
||||
|
||||
## Cross-Reference Index
|
||||
|
||||
Every documentation page that references specific registers or memory addresses:
|
||||
|
||||
### BCM4500 Direct Registers
|
||||
|
||||
| Register | Pages |
|
||||
|----------|-------|
|
||||
| 0xA2 (Status) | [Demodulator](/bcm4500/demodulator/), [Signal Monitoring](/bcm4500/signal-monitoring/), [Version Comparison](/firmware/version-comparison/) |
|
||||
| 0xA4 (Lock) | [Demodulator](/bcm4500/demodulator/), [Signal Monitoring](/bcm4500/signal-monitoring/), [Tuning Protocol](/bcm4500/tuning-protocol/) |
|
||||
| 0xA6/0xA7/0xA8 (Indirect) | [Demodulator](/bcm4500/demodulator/), [Tuning Protocol](/bcm4500/tuning-protocol/), [Signal Monitoring](/bcm4500/signal-monitoring/) |
|
||||
| 0xF9 (Demod Status) | [Demodulator](/bcm4500/demodulator/), [Signal Monitoring](/bcm4500/signal-monitoring/), [Version Comparison](/firmware/version-comparison/) |
|
||||
|
||||
### FX2 XRAM
|
||||
|
||||
| Address Range | Pages |
|
||||
|--------------|-------|
|
||||
| 0xE0B1--0xE0F9 (FEC tables) | [Tuning Protocol](/bcm4500/tuning-protocol/) |
|
||||
| 0xE0CB--0xE0DE (Tune params) | [Tuning Protocol](/bcm4500/tuning-protocol/) |
|
||||
| 0xE0EB--0xE0F6 (Mod config) | [Tuning Protocol](/bcm4500/tuning-protocol/) |
|
||||
| 0xE080--0xE08E (FW2/FW3 cal) | [FW2.13 Variants](/firmware/fw213-variants/) |
|
||||
|
||||
### FX2 IRAM
|
||||
|
||||
| Address | Pages |
|
||||
|---------|-------|
|
||||
| Config status (version-dependent) | [Config Status](/usb/config-status/), [Version Comparison](/firmware/version-comparison/), [FW2.13 Variants](/firmware/fw213-variants/) |
|
||||
| SP, I2C buffers | [FW2.13 Variants](/firmware/fw213-variants/), [Version Comparison](/firmware/version-comparison/) |
|
||||
|
||||
### I2C Controller
|
||||
|
||||
| Register | Pages |
|
||||
|----------|-------|
|
||||
| I2CS/I2DAT/I2CTL (0xE678--0xE67A) | [I2C Bus Architecture](/i2c/bus-architecture/), [STOP Corruption Bug](/i2c/stop-corruption-bug/), [Demodulator](/bcm4500/demodulator/) |
|
||||
@ -7,6 +7,8 @@ import { Badge, Aside } from '@astrojs/starlight/components';
|
||||
|
||||
Signal monitoring uses two vendor commands: GET_SIGNAL_LOCK (0x90) for lock status and GET_SIGNAL_STRENGTH (0x87) for SNR and diagnostic data. Both read BCM4500 direct registers via I2C.
|
||||
|
||||
See the [Register Map](/bcm4500/register-map/) for a consolidated lookup of all register addresses referenced on this page.
|
||||
|
||||
## Signal Lock (GET_SIGNAL_LOCK, 0x90)
|
||||
|
||||
Returns 1 byte from BCM4500 direct register 0xA4.
|
||||
|
||||
@ -7,6 +7,8 @@ import { Tabs, TabItem, Badge, Steps, Aside } from '@astrojs/starlight/component
|
||||
|
||||
The TUNE_8PSK vendor command (0x86) is the primary mechanism for programming the BCM4500 demodulator to receive a satellite signal. The command carries a 10-byte payload encoding frequency, symbol rate, modulation type, and FEC rate. The firmware parses this payload, dispatches to a modulation-specific handler, programs the BCM4500 via I2C, and the host then polls for signal lock.
|
||||
|
||||
See the [Register Map](/bcm4500/register-map/) for a consolidated lookup of all XRAM addresses and BCM4500 registers referenced on this page.
|
||||
|
||||
## Command Format
|
||||
|
||||
```
|
||||
|
||||
@ -21,10 +21,40 @@ The v2.13 firmware was distributed as three sub-variants via the `SW1_update_2_1
|
||||
| Demod interface | **I2C bus** | **Parallel bus (P0/P1)** | **Parallel bus (enhanced)** |
|
||||
| Config source | Hardcoded | External (`0xE080`--`0xE08E`) | External (`0xE080`--`0xE08E`) |
|
||||
|
||||
<Aside type="note">
|
||||
All three sub-variants report the same version ID (`0x020D01`) to the host. The updater program selects the correct sub-variant based on hardware detection (likely a GPIO strap or I2C device ID read at flash time).
|
||||
## 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.
|
||||
|
||||
<Aside type="caution" title="Open Investigation">
|
||||
The exact hardware detection method remains unknown. The updater binary has not been fully disassembled. Candidates include a GPIO strap read (cheap, common in consumer electronics), an I2C device ID probe (the demod responds differently on I2C vs. parallel-bus hardware), or a USB descriptor field that encodes the PCB revision. If you have access to the updater binary or multiple hardware revisions, this would be a valuable area to investigate.
|
||||
</Aside>
|
||||
|
||||
### 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](/bcm4500/register-map/#fx2-iram-by-firmware-version) |
|
||||
| Stack pointer | `0x50` | `0x50` | `0x52` (+2 for status reg) | [Register Map — IRAM](/bcm4500/register-map/#fx2-iram-by-firmware-version) |
|
||||
| Config status IRAM | `0x4F` | `0x4F` | `0x51` | [Config Status](/usb/config-status/) |
|
||||
| I2C buffer IRAM | `0x48`/`0x49` | `0x48`/`0x49` | `0x4A`/`0x4B` | [Register Map — IRAM](/bcm4500/register-map/#fx2-iram-by-firmware-version) |
|
||||
| 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](/bcm4500/register-map/#fw2fw3-external-configuration) |
|
||||
|
||||
### 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
|
||||
|
||||
<Tabs>
|
||||
|
||||
@ -173,6 +173,16 @@ GP8PSK_FW_REV2 = 0x020704 // v2.07.4
|
||||
|
||||
If the firmware version reported by `GET_FW_VERS` (command `0x92`) is >= `GP8PSK_FW_REV2`, the kernel enables Rev.2-specific code paths. All v2.10 and v2.13 firmwares are newer than either constant.
|
||||
|
||||
<Aside type="caution" title="Version ID Gaps">
|
||||
`GP8PSK_FW_REV2` (`0x020704` = v2.07.04) is a **kernel threshold constant**, not an actual firmware release. No firmware with version 2.07.x was ever distributed. The real version progression is:
|
||||
|
||||
**v2.06.04** → **v2.10.04** → **v2.13.01**
|
||||
|
||||
Versions v2.07 through v2.09 and v2.11 through v2.12 do not exist. The kernel developers chose `0x020704` as a convenient threshold above the known v2.06.04 release.
|
||||
|
||||
All three v2.13 sub-variants (FW1, FW2, FW3) report the same version ID `0x020D01` despite targeting different hardware. See [FW2.13 Variants](/firmware/fw213-variants/) for how they differ.
|
||||
</Aside>
|
||||
|
||||
## Binary Similarity Matrix
|
||||
|
||||
Byte-level comparison across the shared code length (percentage of identical bytes):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user