From ebc6cd06ade47f50bf84f26fc49e6b42252160b3 Mon Sep 17 00:00:00 2001 From: HL Yi Date: Sun, 21 Jun 2026 13:04:04 -0500 Subject: [PATCH 1/7] add utilities for led and gpio dump and detection --- tools/led_gpio_utils/README.md | 139 +++++++++++++++++++++ tools/led_gpio_utils/dec_leds_from_dump.py | 95 ++++++++++++++ tools/led_gpio_utils/i2c_dump_rtl_regs.py | 37 ++++++ tools/led_gpio_utils/i2c_read_rtl_gpio.py | 69 ++++++++++ 4 files changed, 340 insertions(+) create mode 100644 tools/led_gpio_utils/README.md create mode 100755 tools/led_gpio_utils/dec_leds_from_dump.py create mode 100755 tools/led_gpio_utils/i2c_dump_rtl_regs.py create mode 100755 tools/led_gpio_utils/i2c_read_rtl_gpio.py diff --git a/tools/led_gpio_utils/README.md b/tools/led_gpio_utils/README.md new file mode 100644 index 0000000..4205e68 --- /dev/null +++ b/tools/led_gpio_utils/README.md @@ -0,0 +1,139 @@ +# 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. + +## 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 + +Install with: +```bash +pip3 install smbus2 +``` + +## Common Usage Patterns + +### 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]) diff --git a/tools/led_gpio_utils/dec_leds_from_dump.py b/tools/led_gpio_utils/dec_leds_from_dump.py new file mode 100755 index 0000000..92a1d88 --- /dev/null +++ b/tools/led_gpio_utils/dec_leds_from_dump.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 + +#!/usr/bin/env python3 + +import os +import sys + + +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 = [ + " 2G5", + " TWO_1G", + " 1G", + " 500M", + " 100M", + " 10M", + " LINK", + " LINK_FLASH", + " ACT", + " RX", + " TX", + " COL", + " DUPLEX", + " TRAINING", + " MASTER", + "", + " 10G", + " TWO_5G", + " 5G", + " TWO_2G5", +] + +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(20): + if val & (1<>(i<<1)) & 3 + print(f"Port {i}: SET {sel}: {', '.join(led_set_str[sel])}") diff --git a/tools/led_gpio_utils/i2c_dump_rtl_regs.py b/tools/led_gpio_utils/i2c_dump_rtl_regs.py new file mode 100755 index 0000000..de69a55 --- /dev/null +++ b/tools/led_gpio_utils/i2c_dump_rtl_regs.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +import time +import argparse +from smbus2 import SMBus, i2c_msg + +# Configuration +DEFAULT_I2C_BUS = 1 +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', '--bus', type=int, default=DEFAULT_I2C_BUS, + help='I2C bus number (default: {})'.format(DEFAULT_I2C_BUS)) +args = parser.parse_args() + +I2C_BUS = args.bus + +# Open I2C bus +with SMBus(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}") \ No newline at end of file diff --git a/tools/led_gpio_utils/i2c_read_rtl_gpio.py b/tools/led_gpio_utils/i2c_read_rtl_gpio.py new file mode 100755 index 0000000..0c505c6 --- /dev/null +++ b/tools/led_gpio_utils/i2c_read_rtl_gpio.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 + +import time +import sys +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 = 2 + +# Handle command line arguments for ignored IOs +IGNORED_IOS = [ 28, 31, 34, 44] + +# Setup argument parser +parser = argparse.ArgumentParser(description='Read I2C data from RTL GPIO expander') +parser.add_argument('--i2c-bus', '-b', type=int, default=1, + help='I2C bus number (default: 1)') +parser.add_argument('--sleep-interval', '-s', type=int, default=2, + help='Sleep interval in seconds (default: 2)') +parser.add_argument('--ignored-ios', '-i', nargs='*', type=int, default=[28, 31, 34, 44], + help='List of GPIO pins to ignore (default: [28, 31, 34, 44])') +args = parser.parse_args() +I2C_BUS = args.i2c_bus +SLEEP_INTERVAL = args.sleep_interval +IGNORED_IOS = args.ignored_ios + +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< Date: Sun, 21 Jun 2026 13:08:58 -0500 Subject: [PATCH 2/7] add disclaim that tool tested in linux --- tools/led_gpio_utils/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/led_gpio_utils/README.md b/tools/led_gpio_utils/README.md index 4205e68..bdb0f32 100644 --- a/tools/led_gpio_utils/README.md +++ b/tools/led_gpio_utils/README.md @@ -1,6 +1,8 @@ # 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. +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 From c61e94527e7458fb156d4d5748ef419f705ecfc4 Mon Sep 17 00:00:00 2001 From: HL Yi Date: Sun, 21 Jun 2026 13:21:06 -0500 Subject: [PATCH 3/7] add clarification for firmware requirement --- tools/led_gpio_utils/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/led_gpio_utils/README.md b/tools/led_gpio_utils/README.md index bdb0f32..65e1a35 100644 --- a/tools/led_gpio_utils/README.md +++ b/tools/led_gpio_utils/README.md @@ -115,7 +115,10 @@ Install with: pip3 install smbus2 ``` -## Common Usage Patterns +## 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 From d152f895492207fda2489b9c830c9c2cdea834f9 Mon Sep 17 00:00:00 2001 From: HL Yi Date: Sun, 21 Jun 2026 13:22:54 -0500 Subject: [PATCH 4/7] remove redundant code --- tools/led_gpio_utils/dec_leds_from_dump.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/led_gpio_utils/dec_leds_from_dump.py b/tools/led_gpio_utils/dec_leds_from_dump.py index 92a1d88..f6d05fa 100755 --- a/tools/led_gpio_utils/dec_leds_from_dump.py +++ b/tools/led_gpio_utils/dec_leds_from_dump.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -#!/usr/bin/env python3 - import os import sys From 70be673fcad1c5db5261ae8ad0861eabbf61f66a Mon Sep 17 00:00:00 2001 From: HL Yi Date: Mon, 22 Jun 2026 00:18:32 -0500 Subject: [PATCH 5/7] updates based upon vDorst's feedback. change i2c_read_rtl_gpio sleep tiemr to 1s update README.md Sorted port speed --- tools/led_gpio_utils/README.md | 7 +++- tools/led_gpio_utils/dec_leds_from_dump.py | 44 +++++++++++----------- tools/led_gpio_utils/i2c_read_rtl_gpio.py | 8 ++-- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/tools/led_gpio_utils/README.md b/tools/led_gpio_utils/README.md index 65e1a35..0e0a2a8 100644 --- a/tools/led_gpio_utils/README.md +++ b/tools/led_gpio_utils/README.md @@ -110,11 +110,16 @@ All scripts require: - Python 3 - `smbus2` Python package -Install with: +(Depend upon Linux distribution) Install with: +```bash +pip3 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. diff --git a/tools/led_gpio_utils/dec_leds_from_dump.py b/tools/led_gpio_utils/dec_leds_from_dump.py index f6d05fa..7cd7a38 100755 --- a/tools/led_gpio_utils/dec_leds_from_dump.py +++ b/tools/led_gpio_utils/dec_leds_from_dump.py @@ -41,26 +41,26 @@ print(f"{' '.join(ledstr)}") print(f".led_mux = {{ 0x{', 0x'.join(ledstr)} }},") LED_TYPES = [ - " 2G5", - " TWO_1G", - " 1G", - " 500M", - " 100M", - " 10M", - " LINK", - " LINK_FLASH", - " ACT", - " RX", - " TX", - " COL", - " DUPLEX", - " TRAINING", - " MASTER", - "", - " 10G", - " TWO_5G", - " 5G", - " TWO_2G5", + " 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 = [] @@ -76,8 +76,8 @@ for i in range(4): val += valhi idval.append(val) valstr = "(" - for bit in range(20): - if val & (1< Date: Mon, 22 Jun 2026 07:08:19 -0500 Subject: [PATCH 6/7] Fixed document based upon vDorst Expand ignore IO list to the GPIOs related to SYS_LED, UART, SMI, and SPI --- tools/led_gpio_utils/README.md | 2 +- tools/led_gpio_utils/i2c_read_rtl_gpio.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/led_gpio_utils/README.md b/tools/led_gpio_utils/README.md index 0e0a2a8..e0ac336 100644 --- a/tools/led_gpio_utils/README.md +++ b/tools/led_gpio_utils/README.md @@ -112,7 +112,7 @@ All scripts require: (Depend upon Linux distribution) Install with: ```bash -pip3 install python3-smbus2 +apt install python3-smbus2 ``` OR ```bash diff --git a/tools/led_gpio_utils/i2c_read_rtl_gpio.py b/tools/led_gpio_utils/i2c_read_rtl_gpio.py index 701a397..e6e0094 100755 --- a/tools/led_gpio_utils/i2c_read_rtl_gpio.py +++ b/tools/led_gpio_utils/i2c_read_rtl_gpio.py @@ -12,7 +12,8 @@ NUM_BYTES = 8 # Bytes to read SLEEP_INTERVAL = 1 # Handle command line arguments for ignored IOs -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') @@ -20,8 +21,8 @@ parser.add_argument('--i2c-bus', '-b', type=int, default=1, help='I2C bus number (default: 1)') parser.add_argument('--sleep-interval', '-s', type=int, default=2, help='Sleep interval in seconds (default: 2)') -parser.add_argument('--ignored-ios', '-i', nargs='*', type=int, default=[28, 31, 34, 44], - help='List of GPIO pins to ignore (default: [])') +parser.add_argument('--ignored-ios', '-i', nargs='*', type=int, default=[28, 31, 32, 34, 35, 42, 43, 44, 45], + help='List of GPIO pins to ignore (default: [28, 31, 32, 34, 35, 42, 43, 44, 45])') args = parser.parse_args() I2C_BUS = args.i2c_bus SLEEP_INTERVAL = args.sleep_interval From a56e2a419b7278804f2b4400f772fa8c0903f1b7 Mon Sep 17 00:00:00 2001 From: HL Yi Date: Mon, 22 Jun 2026 18:02:34 -0500 Subject: [PATCH 7/7] sleep-interval default value is reduced to 1. i2c-bus is required argument replace --bus with --i2c-bus for i2c_dump_rtl_regs.py for better consistency format lint clean up --- tools/led_gpio_utils/dec_leds_from_dump.py | 152 ++++++++++++--------- tools/led_gpio_utils/i2c_dump_rtl_regs.py | 47 +++---- tools/led_gpio_utils/i2c_read_rtl_gpio.py | 57 +++++--- 3 files changed, 146 insertions(+), 110 deletions(-) diff --git a/tools/led_gpio_utils/dec_leds_from_dump.py b/tools/led_gpio_utils/dec_leds_from_dump.py index 7cd7a38..5885068 100755 --- a/tools/led_gpio_utils/dec_leds_from_dump.py +++ b/tools/led_gpio_utils/dec_leds_from_dump.py @@ -1,66 +1,84 @@ #!/usr/bin/env python3 -import os -import sys - - regs = list(range(65536)) glb_mux = 0x65E0 -led3_0_set1 = 0x6528 -led1_0_set0 = 0x6548 -led_port_sel = 0x654c +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 + 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] + +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}") + 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, + " 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 = [] @@ -68,26 +86,30 @@ 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}") + 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])}") +for i in range(3, 9): + sel = (portsel >> (i << 1)) & 3 + print(f"Port {i}: SET {sel}: {', '.join(led_set_str[sel])}") diff --git a/tools/led_gpio_utils/i2c_dump_rtl_regs.py b/tools/led_gpio_utils/i2c_dump_rtl_regs.py index de69a55..e90ac00 100755 --- a/tools/led_gpio_utils/i2c_dump_rtl_regs.py +++ b/tools/led_gpio_utils/i2c_dump_rtl_regs.py @@ -1,37 +1,38 @@ #!/usr/bin/env python3 -import time import argparse from smbus2 import SMBus, i2c_msg # Configuration -DEFAULT_I2C_BUS = 1 DEVICE_ADDR = 0x5C # Replace with your device address -NUM_BYTES = 16 # Bytes to read +NUM_BYTES = 16 # Bytes to read # Parse command line arguments -parser = argparse.ArgumentParser(description='Dump RTL registers via I2C') -parser.add_argument('-b', '--bus', type=int, default=DEFAULT_I2C_BUS, - help='I2C bus number (default: {})'.format(DEFAULT_I2C_BUS)) +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() -I2C_BUS = args.bus - # Open I2C bus -with SMBus(I2C_BUS) as 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) + for addr in range(0, 65536, NUM_BYTES): + # Create write message (send register address) + write = i2c_msg.write(DEVICE_ADDR, [addr >> 8, addr & 0xFF]) - # Convert read message to string - datastr = " ".join([ f"{x:02x}" for x in new_data]) - print(f"{addr:04x}: {datastr}") \ No newline at end of file + # 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}") diff --git a/tools/led_gpio_utils/i2c_read_rtl_gpio.py b/tools/led_gpio_utils/i2c_read_rtl_gpio.py index e6e0094..12612ed 100755 --- a/tools/led_gpio_utils/i2c_read_rtl_gpio.py +++ b/tools/led_gpio_utils/i2c_read_rtl_gpio.py @@ -1,14 +1,13 @@ #!/usr/bin/env python3 import time -import sys 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 +NUM_BYTES = 8 # Bytes to read SLEEP_INTERVAL = 1 # Handle command line arguments for ignored IOs @@ -16,20 +15,34 @@ SLEEP_INTERVAL = 1 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('--i2c-bus', '-b', type=int, default=1, - help='I2C bus number (default: 1)') -parser.add_argument('--sleep-interval', '-s', type=int, default=2, - help='Sleep interval in seconds (default: 2)') -parser.add_argument('--ignored-ios', '-i', nargs='*', type=int, default=[28, 31, 32, 34, 35, 42, 43, 44, 45], - help='List of GPIO pins to ignore (default: [28, 31, 32, 34, 35, 42, 43, 44, 45])') +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 -SLEEP_INTERVAL = args.sleep_interval -IGNORED_IOS = args.ignored_ios first_read = True -last_data = [ 0 for x in range(NUM_BYTES) ] +last_data = [0 for x in range(NUM_BYTES)] # Open I2C bus with SMBus(I2C_BUS) as bus: @@ -37,14 +50,14 @@ with SMBus(I2C_BUS) as bus: while True: # Create write message (send register address) - write = i2c_msg.write(DEVICE_ADDR, [addr>>8, addr & 0xff]) - + 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 @@ -52,19 +65,19 @@ with SMBus(I2C_BUS) as bus: 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]) + 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<