From 4c9150b998f428d3ce97df867a59950ce4e1187f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 11 Jan 2026 19:50:54 +0100 Subject: [PATCH 1/7] docs: Slave Interface --- doc/howto_new_device.md | 128 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 doc/howto_new_device.md diff --git a/doc/howto_new_device.md b/doc/howto_new_device.md new file mode 100644 index 00000000..f1129a92 --- /dev/null +++ b/doc/howto_new_device.md @@ -0,0 +1,128 @@ +# Tool and Tip to Add a New Device. + +# Advanced Tips & Ticks + +## Slave Port + +The RTL837x has a Slave Port, this port is normally used to controller the chip with an external CPU, as can be found for example in a router or Wifi Accesspoint configuration. +The Slave Port supports 3 protocols, `I2C`, `SPI`, `SMI`, which are selected by the `strapping Pins`. Most `strapping Pins` are used as a LED output, after a reset the SOC senses a pull-up or pull-down resistor on these pins to determine the state of the setting. Many of these strapping pins are not easy to change, because the LED-circuit also would need to change. + +>[!NOTE] +> Currently, this document only describes the `I2C` protocol. + +### I2C-Host using a Raspberry Pi Pico RP2040 + +On Linux, the easiest way to create an 3.3V I2C-Host is with a standard Raspberry Pi Pico rp2040 with special firmware, suggested [here](https://github.com/logicog/RTLPlayground/issues/69#issuecomment-3704161277). +Firmware can be downloaded [here](https://github.com/dquadros/I2C-Pico-USB/). + +#### Connect the I2C-Interface to the SOC + +Many boards have an empty `SO8` spot on the PCB where an I2C-EEPROM can be placed.After reset, the SOC always tries to read the I2C-EEPROM, when that is done the I2C-bus turns into Slave Interface. A few boards also have a header with the Slave Port signals, for example the`SWTG024AS` and `2M-PCB23-V3_1` devices. + +> [!CAUTION] +> Use at your own risk. This can damage your device and even worse your COMPUTER/LAPTOP. + +|Signal | I2C-EEPROM pin | RP2040 with Firmware above | +| ----- | -------------- | ------ | +| DATA / SDA | 5 | GPIO6 | +| CLOCK / SCL | 6 | GPIO7 | +| Ground / GND | 4 | PIN 8 | + +When connected and powered-up, the `i2ctransfer` tool from the `i2c-tools` package, can be used to read/write from/to the SOC. + +The SOC's i2c-address is `0x5c` (7-bit notation). + +Reading out the chip ID can for example be done in the Linux shell +via `i2ctransfer w2@0x5c 0x00 0x04 r4`. +Note, that the value being returned is in 32-bit Little-endian. + +For example; The I2C-bus number is `1`, so: +```bash +# i2ctransfer 1 w2@0x5c 0x00 0x04 r4 +WARNING! This program can confuse your I2C bus, cause data loss and worse! +I will send the following messages to device file /dev/i2c-1: +msg 0: addr 0x5c, write, len 2, buf 0x00 0x04 +msg 1: addr 0x5c, read, len 4 +Continue? [y/N] y +0x00 0x00 0x72 0x83 +``` +Value of register `0x0004` is `0x00, 0x00, 0x72, 0x83`, so full 32-bit +value is `0x83720000`. +So, my device is an RTL8372. + +#### Dump script + +With this script you can dump all the registers. It takes about 45 seconds to run. +This allows you for example to inspect the GPIO/LED settings from the original firmware. + +*Note:* Some registers are redacted, because they are known to be unique to your device. + +```bash +#!/bin/bash + +# Check if i2ctransfer is installed +if ! command -v i2ctransfer &>/dev/null; then + echo "i2ctransfer could not be found. Please install i2c-tools." + exit 1 +fi + +# Check for the required argument +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + echo "Example: $0 1" + exit 1 +fi + +I2C_BUS=$1 +DEVICE_ADDRESS=0x5C + +redacted_registers=(16 20 24) +echo "--- DUMP START ---" +# Loop through the addresses from 0x0000 to 0xFFFF in steps of 4 +for ADDRESS_16BIT in $(seq 0 4 65535); do + # Redacted these number because they are known to be unique to your device. + ADDRESS_HEX=$(printf "%04x" $ADDRESS_16BIT) + if [[ " ${redacted_registers[@]} " =~ " $ADDRESS_16BIT " ]]; then + echo "0x${ADDRESS_HEX}=" + continue + fi + HIGH_BYTE="0x${ADDRESS_HEX:0:2}" + LOW_BYTE="0x${ADDRESS_HEX:2:2}" + + # Execute i2ctransfer: write the two bytes and read 4 bytes + VALUE=$(i2ctransfer -y $I2C_BUS w2@$DEVICE_ADDRESS $HIGH_BYTE $LOW_BYTE r4) + + if [ $? -eq 0 ]; then + BYTE1=${VALUE:17:2} + BYTE2=${VALUE:12:2} + BYTE3=${VALUE:7:2} + BYTE4=${VALUE:2:2} + echo "0x${ADDRESS_HEX}=0x$BYTE1$BYTE2$BYTE3$BYTE4" + else + echo "Failed to read from address 0x$(printf "%04x" $ADDRESS_16BIT)" + exit 1 + fi +done + +echo "--- DUMP END ---" +exit 0 +``` + +Output looks like this: + +``` +# bash slave-port-i2c-dump-all.sh 1 +--- DUMP START --- +0x0000=0x00000000 +0x0004=0x83737000 +0x0008=0x00008000 +0x000c=0x00300000 +0x0010= +0x0014= +0x0018= +0x001c=0xcad0001c +0x0020=0xffff0000 +...... +0xFFFC=0x00000000 +--- DUMP END --- +``` From 8ff08675a01a4fca4e9dd2b8c812c835406316f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 11 Jan 2026 20:05:57 +0100 Subject: [PATCH 2/7] docs: GPIO-Scanner --- doc/howto_new_device.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/doc/howto_new_device.md b/doc/howto_new_device.md index f1129a92..6604b438 100644 --- a/doc/howto_new_device.md +++ b/doc/howto_new_device.md @@ -2,6 +2,22 @@ # Advanced Tips & Ticks +## GPIO-Scanner Firmware + +> [!CAUTION] +> Use at your own risk. This can damage your device and even worse your COMPUTER/LAPTOP. + +To find GPIO pins on the board, you can use the [gpio-scanner firmware](https://github.com/vDorst/RTLPlayground/tree/gpio_scanner). It prints every second the GPIO status to the console, similarly to the `GPIO` command. +The firmware only initializes the UART pins, the rest is used as an input. + +Using a `100 Ohm` resistor in series with a wire to ground, you can carefully touch the resistors/pins you believe to be GPIO pins, one at the time. Be careful not to short multiple pins. +Most useful places to find GPIO's is on connectors, LEDs, or buttons. + +> [!NOTE] +> The SOC can also read-back the value on a pin, even when the pin is not configured as a GPIO input. +> So sometimes your see a GPIO change without touching a pin. +> As an example, UART-TX is one of the signals you will often see changing the pin value. + ## Slave Port The RTL837x has a Slave Port, this port is normally used to controller the chip with an external CPU, as can be found for example in a router or Wifi Accesspoint configuration. @@ -111,7 +127,6 @@ exit 0 Output looks like this: ``` -# bash slave-port-i2c-dump-all.sh 1 --- DUMP START --- 0x0000=0x00000000 0x0004=0x83737000 @@ -123,6 +138,6 @@ Output looks like this: 0x001c=0xcad0001c 0x0020=0xffff0000 ...... -0xFFFC=0x00000000 +0xfffc=0x00000000 --- DUMP END --- ``` From eaea9e2a4da9ed5a7eb5d69a70afe02a93efeea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 16 Jan 2026 00:13:03 +0100 Subject: [PATCH 3/7] Add Probing-circuit --- doc/assets/probe-circuit.svg | 28 ++++++++++++++++++++++++++++ doc/howto_new_device.md | 12 ++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 doc/assets/probe-circuit.svg diff --git a/doc/assets/probe-circuit.svg b/doc/assets/probe-circuit.svg new file mode 100644 index 00000000..088ae7ed --- /dev/null +++ b/doc/assets/probe-circuit.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + V + + + + + + + + + + + + + + 100 Ω + + + \ No newline at end of file diff --git a/doc/howto_new_device.md b/doc/howto_new_device.md index 6604b438..6cdb4df9 100644 --- a/doc/howto_new_device.md +++ b/doc/howto_new_device.md @@ -10,8 +10,16 @@ To find GPIO pins on the board, you can use the [gpio-scanner firmware](https://github.com/vDorst/RTLPlayground/tree/gpio_scanner). It prints every second the GPIO status to the console, similarly to the `GPIO` command. The firmware only initializes the UART pins, the rest is used as an input. -Using a `100 Ohm` resistor in series with a wire to ground, you can carefully touch the resistors/pins you believe to be GPIO pins, one at the time. Be careful not to short multiple pins. -Most useful places to find GPIO's is on connectors, LEDs, or buttons. +### Probing Circuit + +![Probing Circuit](assets/probe-circuit.svg) + +To make probing more easy, you can make this `probing circuit` on a breadboard, using a `100 Ohm` resistor, push-button, a voltmeter, and some wires. + +Bottom wire have to connected to the ground of the switch. Top wire can be used to carefully probe the resistors/pins you believe to be GPIO pin, one at the time. Be careful not to short multiple pins. When you have picked a spot to probe, look at the voltmeter to see if the probed-signal is around 3.3 Volt. So you know that spot has a signal. +When pressing the button, the voltage should drop below 0.5 Volts. When it is below 0.5 Volts, check the console to see if a GPIO has changed. Repeat button press multiple times so you are sure which GPIO it is. +When the voltage is not dropping, you probably have a 3.3 volt supply. +Most useful places to find GPIO's are around connectors, LEDs, or buttons. > [!NOTE] > The SOC can also read-back the value on a pin, even when the pin is not configured as a GPIO input. From 9af72943b5ee63fb0c3cd8f80e774e4fb3428262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Thu, 22 Jan 2026 23:31:57 +0100 Subject: [PATCH 4/7] doc: tell about other i2c-tools. --- doc/howto_new_device.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/doc/howto_new_device.md b/doc/howto_new_device.md index 6cdb4df9..8a4b9c85 100644 --- a/doc/howto_new_device.md +++ b/doc/howto_new_device.md @@ -52,7 +52,27 @@ Many boards have an empty `SO8` spot on the PCB where an I2C-EEPROM can be place | CLOCK / SCL | 6 | GPIO7 | | Ground / GND | 4 | PIN 8 | -When connected and powered-up, the `i2ctransfer` tool from the `i2c-tools` package, can be used to read/write from/to the SOC. +When connected and powered-up, the `i2ctransfer` tool from the `i2c-tools` package, can be used to read/write from/to the SOC.
+Use `i2cdetect -l` to list all the I2C-adaptors.
+Look for `i2c- i2c i2c-tiny-usb at bus ... device ... I2C adapter`. +``-number is the bus number. + +Use `i2cdetect ` to scan the I2C-bus for devices. +``` +WARNING! This program can confuse your I2C bus, cause data loss and worse! +I will probe file /dev/i2c-7. +I will probe address range 0x08-0x77. +Continue? [Y/n] + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +50: -- -- -- -- -- -- -- -- -- -- -- -- 5c -- -- -- +60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +70: -- -- -- -- -- -- -- -- +``` The SOC's i2c-address is `0x5c` (7-bit notation). @@ -74,7 +94,7 @@ Value of register `0x0004` is `0x00, 0x00, 0x72, 0x83`, so full 32-bit value is `0x83720000`. So, my device is an RTL8372. -#### Dump script +#### Dump script I2C Slave Port With this script you can dump all the registers. It takes about 45 seconds to run. This allows you for example to inspect the GPIO/LED settings from the original firmware. From 1c0ea2f40f3815dfb38e5460cb4f7306a3b30798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Thu, 22 Jan 2026 23:39:14 +0100 Subject: [PATCH 5/7] doc: Pull-up part --- doc/howto_new_device.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/howto_new_device.md b/doc/howto_new_device.md index 8a4b9c85..af8025f6 100644 --- a/doc/howto_new_device.md +++ b/doc/howto_new_device.md @@ -14,7 +14,7 @@ The firmware only initializes the UART pins, the rest is used as an input. ![Probing Circuit](assets/probe-circuit.svg) -To make probing more easy, you can make this `probing circuit` on a breadboard, using a `100 Ohm` resistor, push-button, a voltmeter, and some wires. +To make probing more easy, you can make this `probing circuit` on a breadboard, using a `100 Ohm` resistor, push-button, a voltmeter, and some wires. This circuit works well because most of the pins are internally pull-up by default. Bottom wire have to connected to the ground of the switch. Top wire can be used to carefully probe the resistors/pins you believe to be GPIO pin, one at the time. Be careful not to short multiple pins. When you have picked a spot to probe, look at the voltmeter to see if the probed-signal is around 3.3 Volt. So you know that spot has a signal. When pressing the button, the voltage should drop below 0.5 Volts. When it is below 0.5 Volts, check the console to see if a GPIO has changed. Repeat button press multiple times so you are sure which GPIO it is. From cf4083152bb5388c95a4f45673d9c885ae6ba5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Thu, 22 Jan 2026 23:56:06 +0100 Subject: [PATCH 6/7] doc: How to interpret the values --- doc/howto_new_device.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/doc/howto_new_device.md b/doc/howto_new_device.md index af8025f6..da70ccac 100644 --- a/doc/howto_new_device.md +++ b/doc/howto_new_device.md @@ -10,6 +10,22 @@ To find GPIO pins on the board, you can use the [gpio-scanner firmware](https://github.com/vDorst/RTLPlayground/tree/gpio_scanner). It prints every second the GPIO status to the console, similarly to the `GPIO` command. The firmware only initializes the UART pins, the rest is used as an input. +### Interpet the output. + +The output looks like this. + +``` +GPIO 0: bcfbedff 00000000 +GPIO 1: 0a7fcbfb 00400000 +``` + +`GPIO 0` are the GPIOs `31..0` and `GPIO 1` are the GPIO `64..32`.
+The first hex-value is the current state of the input-registers.
+The second hex-value is what has change, just an XOR-value of the previous sample.
+Hex-value is shown as MSB..LSB. +In the example `00400000 = bit 22` has changes in `GPIO 1`, so the gpio change was on `GPIO54`. + + ### Probing Circuit ![Probing Circuit](assets/probe-circuit.svg) From bd0b4c5e9cc1362a8e19fbc11c539cd046a9a0d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Fri, 23 Jan 2026 00:02:52 +0100 Subject: [PATCH 7/7] doc: Dump register values using the original firmware commands. --- doc/howto_new_device.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/doc/howto_new_device.md b/doc/howto_new_device.md index da70ccac..9a8efd59 100644 --- a/doc/howto_new_device.md +++ b/doc/howto_new_device.md @@ -10,7 +10,7 @@ To find GPIO pins on the board, you can use the [gpio-scanner firmware](https://github.com/vDorst/RTLPlayground/tree/gpio_scanner). It prints every second the GPIO status to the console, similarly to the `GPIO` command. The firmware only initializes the UART pins, the rest is used as an input. -### Interpet the output. +### How to interpret the values The output looks like this. @@ -185,3 +185,30 @@ Output looks like this: 0xfffc=0x00000000 --- DUMP END --- ``` + +### Dump script original firmware + +#### Manager firmware + +On the managed firmware you can login with a [password](https://github.com/up-n-atom/SWTG118AS?tab=readme-ov-file#uboot-password).
+After login you can use the `regget` command to fetch register values. + +* TODO: `MAKE SCRIPT TO DUMP VALUES FOR YOU` + +#### Unmanager firmware + +On the unmanaged firmware you can use the `rd` command to fetch register values. + +* TODO: `MAKE SCRIPT TO DUMP VALUES FOR YOU` + +#### Registers to dump + +| What | Address | Note | +| --- | --- | ---| +| MODEL_NAME | 0x0004 | This gives you the chip model number | +| GPIO_OUT0 | 0x003c | GPIO Output value 31..0 | +| GPIO_OUT0 | 0x0040 | GPIO Output value 63..32 | +| OE_OUT0 | 0x004c | GPIO Output Enable value 31..0 | +| OE_OUT0 | 0x0050 | GPIO Output Enable value 63..32 | +| MUX_SEL_0 | 0x7F8C | GPIO Mux settings 0 | +| MUX_SEL_1 | 0x7F90 | GPIO Mux settings 1 | \ No newline at end of file