mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge main into KP-9000 PCB revision split
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
# SWTG018AS-A V2.0
|
||||
## Brands
|
||||
| Brand | Type |Managed| PCB | Flash | Chip RTL |
|
||||
|--------|------------------|-------|------------------|-----------------|---------------|
|
||||
| Ampcom | SWTG018AS-A V2.0 | No | SWTG018AS-A V2.0 | 2MB | 8273N + 8224N |
|
||||
| Horaco | HC-SWTGW218AS-A | Yes | SWTG018AS-A V2.0 | 2MB(25Q16JVSIQ) | 8273N + 8224N |
|
||||
|
||||
|
||||
The following is a documentation for the unmanaged switch marked as `SWTG018AS-A V2.0`.
|
||||
It is e.g. sold under the Ampcom brand, but no branh-markings are found on the device.
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
### SWTG024AS-V2.0
|
||||
|
||||
## Brands
|
||||
|Brand|Type|Managed|PCB|Flash|Chip RTL|
|
||||
|---|---|---|---|---|---|
|
||||
| hongyavision | LG-SG5T1 | No | PCB-SWTG024AS-V2.0_16895 | 25Q40 | 8272 |
|
||||
|
||||
### Label specifications
|
||||
|
||||
- **Name**:
|
||||
- **Ports**:
|
||||
- 5 × RJ45: 10/100/1000/2500 Mbps
|
||||
- 1 × SFP+: 1000 / 2500 / 10000 Mbps
|
||||
- **Power**: 12V DC, 1A 5525 connector
|
||||
|
||||
<img src="photos/SWTG024AS-V2.0/label.jpg" width="300" />
|
||||
|
||||
### What works
|
||||
The device is fully supported:
|
||||
- ALL 2.5GBASE-T RJ45 ports work at 10/100/1000/2500 Mbps
|
||||
- The SFP+ port supports 1G, 2.5G and 10G modules
|
||||
- LEDs work with the same indiciations as the OEM firmware
|
||||
- Online update does not work with 512KiB flash.
|
||||
### PCB overview
|
||||
|
||||
**Board markings**
|
||||
- Top silkscreen: PCB-SWTG024AS-V2.0
|
||||
|
||||
Top side
|
||||
|
||||
<img src="photos/SWTG024AS-V2.0/pcb_top.jpg" width="300" />
|
||||
|
||||
Bottom
|
||||
|
||||
<img src="photos/SWTG024AS-V2.0/pcb_bottom.jpg" width="300" />
|
||||
|
||||
### J1, serial console
|
||||
|
||||
| `J1` pin | Signal |
|
||||
| -------- | ----------- |
|
||||
| 1 | GND |
|
||||
| 2 | RX (Input) |
|
||||
| 3 | TX (Output) |
|
||||
|
||||
Note,`R52`、`R53`may not be installed.You need to bridge them using either solder or resistors.
|
||||
|
||||
## Power supply
|
||||
|
||||
Input power is delivered via barell plug, `12V 1A` adapter was provided.
|
||||
@@ -6,6 +6,7 @@
|
||||
| Mokerlink | ZX-SWTGW218AS | Yes| SWTG118AS-V2.0-16029 | 2MB (FM25Q16A)| 8273N + 8224N |
|
||||
| Sodola | | | | | |
|
||||
| Horaco | | | | | |
|
||||
| XikeStor | SKS3200-8E1X | Yes | SWTG118AS-V2.1-17462 | 2MB (25Q16JVSIQ) | |
|
||||
|
||||
|
||||
## Photos
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.7 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 36 MiB |
+29
-12
@@ -1,18 +1,35 @@
|
||||
# Supported Hardware
|
||||
The following devices have been tested and are fully working:
|
||||
- Horaco ZX_SG4T2
|
||||
- keepLINK KP-9000-6XH-X2 / KP-9000-6XHML-X2 (RTL8372: 4x 2.5GBit + 2x 10GBit SFP+);
|
||||
select the machine target by PCB revision, see [KP-9000-6XH-X2](devices/KP-9000-6XH-X2.md)
|
||||
- keepLINK kp-9000-6hx-x (RTL8372 + RTL8221B 2.5GBit PHY: 5 x 2.5GBit + 1x 10GBit SFP+)
|
||||
- keepLINK kp-9000-9xh-x-eu (1 x RTL8373 + RTL8224: 8x 2.5GBit + 1x 10GBit SFP+)
|
||||
- Lianguo LG-SWTGW218AS (RTL8373 + RTL8224 PHY: 8x 2.5GBit + 1x 10GBit SFP+)
|
||||
- No-Name ZX-SWTGW215AS, managed version of kp-9000-6hx-x, ordered on
|
||||
AliExpress as keepLINK 5+1 port managed
|
||||
- TrendNet TEG-S562 (RTL8372: 4x 2.5GBit + 2x 10GBit SFP+)
|
||||
- FNS-1200P (RTL8372: 4x 2.5GBit + 2x 10GBit SFP+)
|
||||
|
||||
Other device based on RTL8272/3 that may work are described here: [Up-N-Atoms 2.5 GBit RTL Switch hacking guide]
|
||||
(https://github.com/up-n-atom/SWTG118AS)
|
||||
| Brand | Type | Managed | PCB | Flash | Ports |
|
||||
|----------|-----------------|---------|------------------------------------------------------------------------------------------------------------------|-------|-------|
|
||||
| Ampcom | WAM902-SWTG018AS| No | [SWTG018AS-A V2.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTG018AS_A_V2_0.md) | | 8 + 1 |
|
||||
| Davuaz | Da-K6501W | No | [PCB-K0501W-V2.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/K0501W_V2_0.md) | | 5 + 1 |
|
||||
| FOXNEO | FNS-1200P | No | [PCB-K0402W-U13-V2.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/FNS-1200P.md) | 2M | 4 + 2 |
|
||||
| Hisource | Hi-K0402WS | No | [PCB-K0402WS-V3.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
||||
| Hisource | Hi-K0801WS | No | [PCB-KO801W-V2.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/HI-K0801WS.md) | | 8 + 1 |
|
||||
| hongyavision | LG-SG5T1 | No | [PCB-SWTG024AS-V2.0_16895](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTG024AS-V2.0.md) | 0.5M | 5 + 1 |
|
||||
| Horaco | HC-SWTGW218AS | Yes | [SWTG018AS-A V2.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTG018AS_A_V2_0.md) | | 8 + 1 |
|
||||
| Horaco | ZX310S-4T2XH | Yes | [PCB-SL310S-4T1T1X-V1.0.1-24107](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/ZX310S-4T2XH.md) | 2M | 5 + 1 |
|
||||
| Horaco | ZX310S-4T2XT | Yes | [PCB-SL310S-4T2XT-V1.0.0-22273](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/ZX310S-4T2XT.md) | 2M | 6 |
|
||||
| Horaco | ZX-SWTG124AS | Yes | [SWTG024AS-v2.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTG024AS.md) | | 4 + 2 |
|
||||
| Keeplink | KP-9000-6XH-X2 / KP-9000-6XHML-X2 | No/Yes | [2M-PCB43-V1.2 / V2.1](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/KP-9000-6XH-X2.md) | | 4 + 2 |
|
||||
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V2.2](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/2M-PCB23-V2_2.md) | 2M | 8 + 1 |
|
||||
| keepLINK | KP-9000-9XHML-X | Yes | [2M-PCB23-V3.1](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/2M-PCB23-V3_1.md) | 2M | 8 + 1 |
|
||||
| LIANGUO | SWTG024AS | No | [SWTG024AS-v2.0-17452](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTG024AS.md) | 0.5M | 4 + 2 |
|
||||
| Lianguo | ZX-SWTGW215AS | Yes | [PCB-SWTG115AS-V2.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTGW215AS.md) | 2M | 5 + 1 |
|
||||
| Mokerlink| ZX-SWTGW218AS | Yes | [SWTG118AS-V2.0-16029](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTGW218AS.md) | 2M | 8 + 1 |
|
||||
| Sodola | SL-SWTG124AS-D | Yes | [SWTG024AS-v2.0-17452](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTG024AS.md) | 2M | 4 + 2 |
|
||||
| Steamemo | IG204-V1 | No | [PB-2131](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/STEAMEMO_IG204_V1.md) | | 4 + 2 |
|
||||
| TrendNet | TEG-S562 | No | [TEG-S563/EU H/W: V1.0R](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/TEG-S562.md) | 2M | 4 + 2 |
|
||||
| Xikestore| SKS3200M-4GPY2XF| Yes | [SWTG024AS-v1.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTG024AS.md) | | 4 + 2 |
|
||||
| XikeStor | SKS3200-8E1X | Yes | [SWTG118AS-V2.1-17462](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/SWTGW218AS.md) | 2M | 8 + 1 |
|
||||
| Ztyuav | Z-QWYT0402 | No | [PCB-K0402WS-V3.0](https://github.com/logicog/RTLPlayground/blob/main/doc/devices/PCB-K0402WS-V3.0.md) | | 4 + 2 |
|
||||
|
||||
For KP-9000-6XH-X2 / KP-9000-6XHML-X2 devices, select the machine target by PCB
|
||||
revision. The managed/unmanaged label alone does not identify the wiring.
|
||||
|
||||
Other device based on RTL8272/3 that may work are described here: [Up-N-Atoms 2.5 GBit RTL Switch hacking guide](https://github.com/up-n-atom/SWTG118AS)
|
||||
|
||||
Many of the RTL8272/3 devices come in versions with PoE support. The RTLPlayground usually also
|
||||
works on these, however, no support for configuring PoE is provided, simply because these
|
||||
|
||||
+7
-3
@@ -14,6 +14,7 @@ const conf_cmds = [
|
||||
/^pvid\s+\d{1,2}\s+\d{1,4}$/,
|
||||
/^ingress(\s+\d{1,2}[tua])+$/,
|
||||
/^ingress\s+[tua]$/,
|
||||
/^port\s+\d{1,2}\s+(10m|100m|1g|2g5|5g|10g|auto|on|off)(\s+(half|full))?$/,
|
||||
/^port\s+\d{1,2}\s+name\s+\S+$/,
|
||||
/^eee(\s+\d{1,2})?\s+(on|off)$/,
|
||||
/^mirror(\s+\d{1,2})(\s+\d{1,2}[tr]?)+$/,
|
||||
@@ -36,6 +37,7 @@ const conf_overwrite = [
|
||||
/^vlan\s+\d{1,4}(?!\s+mgmt\b)/,
|
||||
/^pvid\s+\d{1,2}\b/,
|
||||
/^ingress\b/,
|
||||
/^port\s+\d{1,2}(?!\s+name\b)/,
|
||||
/^port\s+\d{1,2}\s+name\b/,
|
||||
/^eee\s+\d{1,2}\b/,
|
||||
/^eee\b/,
|
||||
@@ -57,8 +59,7 @@ function parseConf(s){
|
||||
const deleteMatch = line.match(/^vlan\s+(\d{1,4})\s+d$/);
|
||||
if (deleteMatch) {
|
||||
const prefix = "vlan " + deleteMatch[1] + " ";
|
||||
configuration = configuration.filter(c =>
|
||||
c !== "vlan " + deleteMatch[1] && !c.startsWith(prefix));
|
||||
configuration = configuration.filter(c => !c.startsWith(prefix));
|
||||
continue;
|
||||
}
|
||||
console.log(l + ' --> ' + line);
|
||||
@@ -71,10 +72,13 @@ function parseConf(s){
|
||||
let m = line.match(x);
|
||||
let matchStr = m[0];
|
||||
configuration = configuration.filter(item =>
|
||||
!(item === matchStr || item.startsWith(matchStr + " ")));
|
||||
!(item === matchStr || (item.startsWith(matchStr + " ") && !item.endsWith(" mgmt") && !item.startsWith(matchStr + " name "))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Only one management VLAN can be active, so drop any previous mgmt entry
|
||||
if (/^vlan\s+\d{1,4}\s+mgmt$/.test(line))
|
||||
configuration = configuration.filter(item => !/^vlan\s+\d{1,4}\s+mgmt$/.test(item));
|
||||
configuration.push(line);
|
||||
}
|
||||
console.log("Configuration now:");
|
||||
|
||||
@@ -365,7 +365,7 @@ __code const struct machine machine = {
|
||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||
.sfp_port[0].sds = 1,
|
||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||
.reset_pin = GPIO_NA,
|
||||
.reset_pin = GPIO48_I2C_SCL1,
|
||||
.high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 },
|
||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||
.led_sets = {
|
||||
@@ -917,6 +917,68 @@ void machine_custom_init(void)
|
||||
reg_bit_clear(RTL837X_REG_LED_MODE, 7);
|
||||
}
|
||||
|
||||
#elif defined MACHINE_SWTG024AS_V2_0
|
||||
__code const struct machine machine = {
|
||||
.machine_name = "SWTG024AS-V2.0",
|
||||
.isRTL8373 = 0,
|
||||
.min_port = 3,
|
||||
.max_port = 8,
|
||||
.n_sfp = 1,
|
||||
.log_to_phys_port = {0, 0, 0, 5, 1, 2, 3, 4, 6},
|
||||
.phys_to_log_port = {4, 5, 6, 7, 3, 8, 0, 0, 0},
|
||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||
.sfp_port[0].pin_detect = GPIO30_ACL_BIT3_EN,
|
||||
.sfp_port[0].pin_los = GPIO37,
|
||||
.sfp_port[0].pin_tx_disable = GPIO_NA,
|
||||
.sfp_port[0].sds = 1,
|
||||
.sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 },
|
||||
|
||||
.reset_pin = GPIO_NA,
|
||||
.high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 },
|
||||
.port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||
/* Ports 1-5 RJ45 use set 0, port 9 SFP uses set 1
|
||||
* Ports 1-5: Green: 2.5GBit, Amber: 10/100/1000MBit
|
||||
* SFP-port: Blue: 10GBit, Amber: 100MBit-2.5GBit
|
||||
*/
|
||||
.led_sets = {
|
||||
{
|
||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT,
|
||||
LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT,
|
||||
LEDS_DUPLEX,
|
||||
LEDS_2G5 | LEDS_LINK | LEDS_ACT
|
||||
},
|
||||
{
|
||||
LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_LINK | LEDS_ACT,
|
||||
LEDS_10G | LEDS_LINK | LEDS_ACT,
|
||||
LEDS_2G5 | LEDS_LINK,
|
||||
LEDS_COL | LEDS_DUPLEX
|
||||
},
|
||||
},
|
||||
.led_mux_custom = 1,
|
||||
.led_mux = {
|
||||
0x00,0x01,0x04,0x05,0x08,0x09,0x0c,0x3f,0x0d,0x10,0x11,0x0e,0x14,0x11,0x12,0x15,0x15,0x16,0x18,0x19,0x1a,0x19,0x1d,0x1e,0x1c,0x1d,0x20,0x21
|
||||
},
|
||||
};
|
||||
|
||||
void machine_custom_init(void)
|
||||
{
|
||||
uint16_t pval;
|
||||
|
||||
reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 6);
|
||||
reg_bit_set(RTL837X_REG_LED_MODE, 17);
|
||||
reg_bit_clear(RTL837X_REG_LED_MODE, 9);
|
||||
reg_bit_clear(RTL837X_REG_LED_MODE, 7);
|
||||
|
||||
// OEM firmware sets these companion SDS0 polarity bits for the RTL8221B.
|
||||
sds_read(0, 0, 0);
|
||||
pval = SFR_DATA_U16;
|
||||
sds_write_v(0, 0, 0, pval | 0x100);
|
||||
|
||||
sds_read(0, 6, 2);
|
||||
pval = SFR_DATA_U16;
|
||||
sds_write_v(0, 6, 2, pval | 0x4000);
|
||||
}
|
||||
|
||||
#elif defined MACHINE_ZX310S_4T2XT
|
||||
__code const struct machine machine = {
|
||||
.machine_name = "ZX310S_4T2XT",
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
// #define MACHINE_HI_K0801WS
|
||||
// #define MACHINE_FNS1200P
|
||||
// #define MACHINE_PCB_SWTG024AS_A_2_0_1
|
||||
// #define MACHINE_SWTG024AS_V2_0
|
||||
|
||||
typedef struct {
|
||||
// GPIO pins for SDA/SCL
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
# LED GPIO Utilities
|
||||
|
||||
This directory contains utility talking to RTL837x switch IC via I2C bus.
|
||||
These scripts are designed to help with monitoring, debugging GPIO, and identifying LED configurations.
|
||||
(Only tested in Linux)
|
||||
|
||||
## Hardware requirements
|
||||
|
||||
To use these utilities, you need:
|
||||
|
||||
- A hardware dongle that can communicate with I2C devices. One example is the [I2C-Pico-USB](https://github.com/dquadros/I2C-Pico-USB) which provides USB-to-I2C connectivity.
|
||||
- Connection between the hardware dongle and the RTL837x's I2C communication port.
|
||||
|
||||
## Scripts
|
||||
|
||||
### 1. `i2c_read_rtl_gpio.py`
|
||||
|
||||
This script reads RTL GPIO register values via I2C and displays changes in GPIO states.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Reads live RTL GPIO register values via I2C (default address 0x5C)
|
||||
- Monitors GPIO changes with delta detection
|
||||
- Allows specification of I2C bus, sleep interval, and ignored GPIO pins
|
||||
- Shows changes in real-time with GPIO index display
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
# Basic usage (defaults to I2C bus 1, 2s sleep interval)
|
||||
python3 i2c_read_rtl_gpio.py
|
||||
|
||||
# Specify I2C bus
|
||||
python3 i2c_read_rtl_gpio.py --i2c-bus 0
|
||||
|
||||
# Specify sleep interval in seconds
|
||||
python3 i2c_read_rtl_gpio.py --sleep-interval 5
|
||||
|
||||
# Ignore specific GPIO pins
|
||||
python3 i2c_read_rtl_gpio.py --ignored-ios 28 31 34 44
|
||||
|
||||
# Combine options
|
||||
python3 i2c_read_rtl_gpio.py --i2c-bus 2 --sleep-interval 1 --ignored-ios 28 31
|
||||
```
|
||||
|
||||
**Output Format:**
|
||||
|
||||
- Displays register address and data in hex format
|
||||
- Shows GPIO pins that have changed since last read
|
||||
- Example: `0044: 00 00 00 00 00 00 00 00`
|
||||
|
||||
### 2. `i2c_dump_rtl_regs.py`
|
||||
|
||||
This script dumps all register values from an RTL device via I2C.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Dumps registers sequentially from address 0x0000 to 0xFFFF
|
||||
- Reads 16 bytes at a time for efficiency
|
||||
- Configurable I2C bus number
|
||||
- Provides complete register dump in hex format
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
# Basic usage (defaults to I2C bus 1)
|
||||
python3 i2c_dump_rtl_regs.py >reg_dump.txt
|
||||
|
||||
# Specify I2C bus
|
||||
python3 i2c_dump_rtl_regs.py --bus 0 >reg_dump.txt
|
||||
|
||||
# Or using short option
|
||||
python3 i2c_dump_rtl_regs.py -b 2 >reg_dump.txt
|
||||
```
|
||||
|
||||
**Output Format:**
|
||||
|
||||
- Displays address and 16 bytes of data in hex format
|
||||
- Example: `0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00`
|
||||
|
||||
### 3. `dec_leds_from_dump.py`
|
||||
|
||||
This script decodes LED configuration from a register dump file ( the output from `i2c_dump_rtl_regs.py`).
|
||||
|
||||
**Features:**
|
||||
|
||||
- Parses register dump files (reg_dump.txt format)
|
||||
- Decodes LED pad configurations and LED sets
|
||||
- Maps LED types to bit positions based on configuration
|
||||
- Outputs LED mux configuration and set mappings
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
# Must be run in same directory as reg_dump.txt
|
||||
python3 dec_leds_from_dump.py
|
||||
```
|
||||
|
||||
**Output Format:**
|
||||
|
||||
- LED pad configuration (hex values for each pad)
|
||||
- LED set configurations with descriptions of LED types
|
||||
- Port selection mappings
|
||||
|
||||
**Requirements:**
|
||||
|
||||
- Requires a `reg_dump.txt` file containing the register dump output
|
||||
|
||||
## Requirements
|
||||
|
||||
All scripts require:
|
||||
|
||||
- Python 3
|
||||
- `smbus2` Python package
|
||||
|
||||
(Depend upon Linux distribution) Install with:
|
||||
```bash
|
||||
apt install python3-smbus2
|
||||
```
|
||||
OR
|
||||
```bash
|
||||
pip3 install smbus2
|
||||
```
|
||||
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
Both `i2c_read_rtl_gpio.py` and `i2c_dump_rtl_regs.py` shall run with the **original** firmware, not RTLPlayground firmware.
|
||||
|
||||
|
||||
### Monitoring GPIO Changes
|
||||
```bash
|
||||
# Monitor GPIO changes on bus 1 with 1-second intervals
|
||||
python3 i2c_read_rtl_gpio.py --i2c-bus 1 --sleep-interval 1
|
||||
```
|
||||
|
||||
### Register Analysis
|
||||
```bash
|
||||
# Dump all device registers
|
||||
python3 i2c_dump_rtl_regs.py --bus 2 > reg_dump.txt
|
||||
|
||||
# Analyze the register dump to understand LED configuration
|
||||
python3 dec_leds_from_dump.py
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
All scripts support command-line arguments for flexible configuration:
|
||||
|
||||
- `--i2c-bus` or `-b`: Specify I2C bus (default: 1)
|
||||
- `--sleep-interval` or `-s`: Sleep between reads in seconds (default: 2)
|
||||
- `--ignored-ios` or `-i`: GPIO pins to ignore (default: [28, 31, 34, 44])
|
||||
Executable
+115
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
regs = list(range(65536))
|
||||
|
||||
glb_mux = 0x65E0
|
||||
|
||||
led3_0_set1 = 0x6528
|
||||
led1_0_set0 = 0x6548
|
||||
led_port_sel = 0x654C
|
||||
|
||||
|
||||
def get_word(i):
|
||||
val = (regs[i + 3] << 24) + (regs[i + 2] << 16) + (regs[i + 1] << 8) + regs[i]
|
||||
# print(f"READING {i:04x} : {val:08x}")
|
||||
return val
|
||||
|
||||
|
||||
with open("reg_dump.txt", "r") as file:
|
||||
for line in file:
|
||||
addr, data = line.split(":")
|
||||
data = [int(x, 16) for x in data.strip().split(" ")]
|
||||
addr = int(addr, 16)
|
||||
for x in range(len(data)):
|
||||
regs[addr + x] = data[x]
|
||||
|
||||
ledstr = []
|
||||
ledfmt = []
|
||||
print("LED pad Configuration:")
|
||||
for i in range(28):
|
||||
j = i % 5
|
||||
if j == 0:
|
||||
idx = glb_mux + (i // 5) * 4
|
||||
val = get_word(idx)
|
||||
ledval = (val >> (6 * j)) & 0x3F
|
||||
ledstr.append(f"{ledval:02x}")
|
||||
ledfmt.append(f"{i:02x}")
|
||||
print(f"{' '.join(ledfmt)}")
|
||||
print(f"{' '.join(ledstr)}")
|
||||
print(f".led_mux = {{ 0x{', 0x'.join(ledstr)} }},")
|
||||
|
||||
LED_TYPES = [
|
||||
" 10G",
|
||||
16,
|
||||
" TWO_5G",
|
||||
17,
|
||||
" 5G",
|
||||
18,
|
||||
" TWO_2G5",
|
||||
19,
|
||||
" 2G5",
|
||||
0,
|
||||
" TWO_1G",
|
||||
1,
|
||||
" 1G",
|
||||
2,
|
||||
" 500M",
|
||||
3,
|
||||
" 100M",
|
||||
4,
|
||||
" 10M",
|
||||
5,
|
||||
" LINK",
|
||||
6,
|
||||
" LINK_FLASH",
|
||||
7,
|
||||
" ACT",
|
||||
8,
|
||||
" RX",
|
||||
9,
|
||||
" TX",
|
||||
10,
|
||||
" COL",
|
||||
11,
|
||||
" DUPLEX",
|
||||
12,
|
||||
" TRAINING",
|
||||
13,
|
||||
" MASTER",
|
||||
14,
|
||||
"",
|
||||
15,
|
||||
]
|
||||
|
||||
led_set = []
|
||||
led_set_str = []
|
||||
print("\nLED-set Configuration:")
|
||||
print("LED-ID 0 1 2 3")
|
||||
for i in range(4):
|
||||
idval = []
|
||||
idvalstr = []
|
||||
for id in range(4):
|
||||
val = 0xFFFF & (
|
||||
get_word(led1_0_set0 - 8 * i - ((id >> 1) << 2)) >> (16 * (id & 1))
|
||||
)
|
||||
valhi = (
|
||||
0xF & (get_word(led3_0_set1 - 4 * (i >> 1)) >> (16 * (i & 1) + 4 * id))
|
||||
) << 16
|
||||
val += valhi
|
||||
idval.append(val)
|
||||
valstr = "("
|
||||
for bit in range(0, len(LED_TYPES), 2):
|
||||
if val & (1 << (LED_TYPES[bit + 1])):
|
||||
valstr += LED_TYPES[bit]
|
||||
valstr += ")"
|
||||
idvalstr.append(valstr)
|
||||
led_set.append(idval)
|
||||
led_set_str.append(idvalstr)
|
||||
idstr = " ".join([f"{d:05x}" for d in idval])
|
||||
print(f"SET {i}: {idstr}")
|
||||
# print(f"{idvalstr}")
|
||||
|
||||
portsel = get_word(led_port_sel)
|
||||
for i in range(3, 9):
|
||||
sel = (portsel >> (i << 1)) & 3
|
||||
print(f"Port {i}: SET {sel}: {', '.join(led_set_str[sel])}")
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
from smbus2 import SMBus, i2c_msg
|
||||
|
||||
# Configuration
|
||||
DEVICE_ADDR = 0x5C # Replace with your device address
|
||||
NUM_BYTES = 16 # Bytes to read
|
||||
|
||||
# Parse command line arguments
|
||||
parser = argparse.ArgumentParser(description="Dump RTL registers via I2C")
|
||||
parser.add_argument(
|
||||
"-b",
|
||||
"--i2c-bus",
|
||||
type=int,
|
||||
required=True,
|
||||
help="I2C bus number (use i2cdetect -l to find out the bus number of the dongle)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
# Open I2C bus
|
||||
with SMBus(args.i2c_bus) as bus:
|
||||
|
||||
for addr in range(0, 65536, NUM_BYTES):
|
||||
# Create write message (send register address)
|
||||
write = i2c_msg.write(DEVICE_ADDR, [addr >> 8, addr & 0xFF])
|
||||
|
||||
# Create read message (read 2 bytes)
|
||||
read = i2c_msg.read(DEVICE_ADDR, NUM_BYTES)
|
||||
|
||||
# Perform combined transaction
|
||||
bus.i2c_rdwr(write, read)
|
||||
|
||||
new_data = list(read)
|
||||
|
||||
# Convert read message to string
|
||||
datastr = " ".join([f"{x:02x}" for x in new_data])
|
||||
print(f"{addr:04x}: {datastr}")
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import time
|
||||
import argparse
|
||||
from smbus2 import SMBus, i2c_msg
|
||||
|
||||
# Configuration
|
||||
I2C_BUS = 1
|
||||
DEVICE_ADDR = 0x5C # Replace with your device address
|
||||
NUM_BYTES = 8 # Bytes to read
|
||||
SLEEP_INTERVAL = 1
|
||||
|
||||
# Handle command line arguments for ignored IOs
|
||||
# default to ignore IOs related to SYS_LED, UART, SMI, SPI
|
||||
IGNORED_IOS = [28, 31, 32, 34, 35, 42, 43, 44, 45]
|
||||
|
||||
# Setup argument parser
|
||||
parser = argparse.ArgumentParser(description="Read I2C data from RTL GPIO expander")
|
||||
parser.add_argument(
|
||||
"-b",
|
||||
"--i2c-bus",
|
||||
type=int,
|
||||
required=True,
|
||||
help="I2C bus number (use i2cdetect -l to find out the bus number of the dongle)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--sleep-interval",
|
||||
type=int,
|
||||
default=SLEEP_INTERVAL,
|
||||
help=f"Sleep interval in seconds (default: {SLEEP_INTERVAL})",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
"--ignored-ios",
|
||||
nargs="*",
|
||||
type=int,
|
||||
default=IGNORED_IOS,
|
||||
help=f"List of GPIO pins to ignore (default: {IGNORED_IOS})",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
I2C_BUS = args.i2c_bus
|
||||
|
||||
first_read = True
|
||||
last_data = [0 for x in range(NUM_BYTES)]
|
||||
|
||||
# Open I2C bus
|
||||
with SMBus(I2C_BUS) as bus:
|
||||
addr = 0x44
|
||||
|
||||
while True:
|
||||
# Create write message (send register address)
|
||||
write = i2c_msg.write(DEVICE_ADDR, [addr >> 8, addr & 0xFF])
|
||||
|
||||
# Create read message (read NUM_BYTES bytes)
|
||||
read = i2c_msg.read(DEVICE_ADDR, NUM_BYTES)
|
||||
|
||||
# Perform combined transaction
|
||||
bus.i2c_rdwr(write, read)
|
||||
|
||||
new_data = list(read)
|
||||
if first_read:
|
||||
delta_data = last_data
|
||||
first_read = False
|
||||
else:
|
||||
delta_data = [new_data[x] ^ last_data[x] for x in range(NUM_BYTES)]
|
||||
last_data = new_data
|
||||
|
||||
# Convert read message to list
|
||||
datastr = " ".join([f"{x:02x}" for x in new_data])
|
||||
deltastr = ""
|
||||
chg_list = []
|
||||
for x in range(NUM_BYTES):
|
||||
if delta_data[x] == 0:
|
||||
continue
|
||||
for y in range(8):
|
||||
if delta_data[x] & (1 << y):
|
||||
idx = x * 8 + y
|
||||
if idx not in args.ignored_ios:
|
||||
deltastr += f"\n{' ':8s}GPIO{idx}"
|
||||
# deltastr = " ".join([ f"{x:02x}" for x in delta_data])
|
||||
print(f"{addr:04x}: {datastr}{deltastr}")
|
||||
time.sleep(args.sleep_interval)
|
||||
Reference in New Issue
Block a user