From f65d14f4527ea63f39e8da25bf88bf25581696c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sat, 12 Sep 2026 16:22:08 +0200 Subject: [PATCH 1/6] I2CBUS: Calculate I2C-settings as compiletime instead at runtime. We can reduce the i2c-settings to just one byte, and this new const value can directly be used by the I2C-peripheral without additional computation. This saves 1-xdata load and a lot of bit-shifting. I see a codesize savings of +200 bytes. --- boot.c | 5 +-- machine.c | 95 ++++++++++++++++++++++++++++---------------------- machine.h | 9 +---- rtl837x_pins.c | 35 +------------------ rtl837x_pins.h | 6 ---- 5 files changed, 59 insertions(+), 91 deletions(-) diff --git a/boot.c b/boot.c index c72e24ed..4c188ad8 100644 --- a/boot.c +++ b/boot.c @@ -397,8 +397,9 @@ void setup_i2c(void) __banked // HW Control register, enable I2C depending on PIN configuration reg_read_m(RTL837X_PIN_MUX_1); for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) { - const uint8_t scl_bus = i2c_bus_from_scl_pin(machine.sfp_port[sfp].i2c.scl); - const uint8_t sda_bus = i2c_bus_from_sda_pin(machine.sfp_port[sfp].i2c.sda); + uint8_t i2c = machine.sfp_port[sfp].i2c; + uint8_t scl_bus = (i2c >> 5) & 0x03; + uint8_t sda_bus = (i2c >> 2) & 0x07; print_string("Configuring I2C for SFP idx="); print_byte(sfp); print_string(" SCL="); print_byte(scl_bus); print_string(", SDA="); print_byte(sda_bus); write_char('\n'); switch (scl_bus) { case 3: diff --git a/machine.c b/machine.c index 972df428..a4f8e192 100644 --- a/machine.c +++ b/machine.c @@ -5,6 +5,23 @@ #include "rtl837x_regs.h" #include "rtl837x_common.h" +#define I2CBUS(sda, scl) \ + ((uint8_t)((I2C_BUS_FROM_SCL_PIN(scl) << 5) | \ + (I2C_BUS_FROM_SDA_PIN(sda) << 2))) + +#define I2C_BUS_FROM_SDA_PIN(sda_pin) \ + ((sda_pin) == GPIO47_I2C_SDA0 ? (uint8_t)0 : \ + (sda_pin) == GPIO49_I2C_SDA1 ? (uint8_t)1 : \ + (sda_pin) == GPIO51_I2C_SDA2_UART1_RX ? (uint8_t)2 : \ + (sda_pin) == GPIO41_I2C_SDA3_MDIO1 ? (uint8_t)3 : \ + (sda_pin) == GPIO39_I2C_SDA4 ? (uint8_t)4 : -1) + +#define I2C_BUS_FROM_SCL_PIN(scl_pin) \ + ((scl_pin) == GPIO46_I2C_SCL0 ? 0 : \ + (scl_pin) == GPIO48_I2C_SCL1 ? 1 : \ + (scl_pin) == GPIO50_I2C_SCL2_UART1_TX ? 2 : \ + (scl_pin) == GPIO40_I2C_SCL3_MDC1 ? 3 : -1) + #if defined(MACHINE_KP_9000_6XHML_X2) || \ defined(MACHINE_KP_9000_6XH_X2_V1_1) || \ defined(MACHINE_KP_9000_6XHML_X2_V1_1) || \ @@ -34,13 +51,13 @@ __code const struct machine machine = { .sfp_port[0].pin_los = GPIO10_LED10, .sfp_port[0].pin_tx_disable = GPIO_NA, .sfp_port[0].sds = 0, - .sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[0].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), // Right SFP port (6) .sfp_port[1].pin_detect = GPIO30_ACL_BIT3_EN, .sfp_port[1].pin_los = GPIO37, .sfp_port[1].pin_tx_disable = GPIO_NA, .sfp_port[1].sds = 1, - .sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[1].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO54_ACL_BIT2_EN, .high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 }, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -70,7 +87,7 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, /* Conditions for LED on: * dual led orange: ledset_0 & ledset_2 @@ -105,13 +122,13 @@ __code const struct machine machine = { .sfp_port[0].pin_detect = GPIO38, .sfp_port[0].pin_los = GPIO_NA, .sfp_port[0].sds = 1, - .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), // Right SFP port .sfp_port[1].pin_detect = GPIO37, .sfp_port[1].pin_los = GPIO_NA, .sfp_port[1].sds = 0, - .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO48_I2C_SCL1, // Button-Switch is unpopulated on PCB, but can be added manually (hole in case is already there) .high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 }, @@ -152,7 +169,7 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 }, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -177,7 +194,7 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO54_ACL_BIT2_EN, .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 }, @@ -227,7 +244,7 @@ __code const struct machine machine = { .sfp_port[0].pin_detect = GPIO38, .sfp_port[0].pin_los = GPIO_NA, .sfp_port[0].sds = 1, - .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .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}, @@ -265,13 +282,13 @@ __code const struct machine machine = { .sfp_port[0].pin_los = GPIO_NA, .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 }, /* GPIO 39 */ + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 39 */ // Right SFP port (J2) .sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX, .sfp_port[1].pin_los = GPIO_NA, .sfp_port[1].pin_tx_disable = GPIO_NA, .sfp_port[1].sds = 0, - .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */ + .sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 40 */ .reset_pin = GPIO54_ACL_BIT2_EN, .high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 }, .port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1}, @@ -306,13 +323,13 @@ __code const struct machine machine = { .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 }, /* GPIO 39 */ + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 39 */ // Right SFP port (J2) .sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX, .sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX, .sfp_port[1].pin_tx_disable = GPIO_NA, .sfp_port[1].sds = 0, - .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */ + .sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), /* GPIO 40 */ .reset_pin = GPIO_NA, .high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 }, .port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1}, @@ -346,7 +363,7 @@ __code const struct machine machine = { .sfp_port[0].pin_los = GPIO_NA, .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .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}, @@ -385,12 +402,12 @@ __code const struct machine machine = { .sfp_port[0].pin_los = 10, .sfp_port[0].pin_tx_disable = 0xFF, .sfp_port[0].sds = 1, - .sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[0].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), .sfp_port[1].pin_detect = 30, .sfp_port[1].pin_los = 51, .sfp_port[1].pin_tx_disable = 0xFF, .sfp_port[1].sds = 0, - .sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[1].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = LED_27 , .enable = LED_27 | LED_29 }, .port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1}, @@ -425,7 +442,7 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO54_ACL_BIT2_EN, .high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 }, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1}, @@ -458,7 +475,7 @@ __code const struct machine machine = { .sfp_port[0].pin_los = GPIO_NA, // no LOS pin wired .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO54_ACL_BIT2_EN, .high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 }, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1}, @@ -499,7 +516,7 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO54_ACL_BIT2_EN, .high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 }, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1}, @@ -531,7 +548,7 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = LED_27 | LED_29, .enable = LED_28_SYS | LED_29 }, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -556,12 +573,12 @@ __code const struct machine machine = { .sfp_port[0].pin_los = GPIO50_I2C_SCL2_UART1_TX, .sfp_port[0].pin_tx_disable = GPIO54_ACL_BIT2_EN, .sfp_port[0].sds = 0, - .sfp_port[0].i2c = { .sda = GPIO47_I2C_SDA0, .scl = GPIO46_I2C_SCL0 }, + .sfp_port[0].i2c = I2CBUS( GPIO47_I2C_SDA0, GPIO46_I2C_SCL0 ), .sfp_port[1].pin_detect = GPIO36_PWM_OUT, .sfp_port[1].pin_los = GPIO37, .sfp_port[1].pin_tx_disable = GPIO51_I2C_SDA2_UART1_RX, .sfp_port[1].sds = 1, - .sfp_port[1].i2c = { .sda = GPIO49_I2C_SDA1, .scl = GPIO48_I2C_SCL1 }, + .sfp_port[1].i2c = I2CBUS( GPIO49_I2C_SDA1, GPIO48_I2C_SCL1 ), .reset_pin = GPIO_NA, .port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1}, .led_sets = { @@ -596,13 +613,13 @@ __code const struct machine machine = { .sfp_port[0].pin_detect = GPIO38, .sfp_port[0].pin_los = GPIO_NA, .sfp_port[0].sds = 1, - .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), // Right SFP port .sfp_port[1].pin_detect = GPIO37, .sfp_port[1].pin_los = GPIO_NA, .sfp_port[1].sds = 0, - .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 }, @@ -641,7 +658,7 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 1}, @@ -676,7 +693,7 @@ __code const struct machine machine = { .sfp_port[0].pin_los = GPIO_NA, .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO48_I2C_SCL1, .high_leds = { .mux = LED_28_SYS, .enable = LED_27 | LED_28_SYS | LED_29 }, .led_mux_custom = 1, @@ -720,14 +737,14 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), // Right SFP port (6) // LED pin 24 .sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX, .sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX, .sfp_port[1].pin_tx_disable = GPIO_NA, .sfp_port[1].sds = 0, - .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 }, .port_led_set = { 0, 0, 0, 1, 0, 0, 0, 0, 1}, @@ -769,11 +786,7 @@ __code const struct machine machine = { .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 - }, - + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { @@ -823,14 +836,14 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), /* Right SFP (logical 3, SDS0): GPIO50=ModAbs, GPIO51=RX_LOS */ .sfp_port[1].pin_detect = GPIO50_I2C_SCL2_UART1_TX, .sfp_port[1].pin_los = GPIO51_I2C_SDA2_UART1_RX, .sfp_port[1].pin_tx_disable = GPIO_NA, .sfp_port[1].sds = 0, - .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, @@ -879,14 +892,14 @@ __code const struct machine machine = { .sfp_port[0].pin_los = GPIO_NA, .sfp_port[0].pin_tx_disable = GPIO_NA, .sfp_port[0].sds = 0, - .sfp_port[0].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[0].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), // SFP port on SDS1 / logical port 8 .sfp_port[1].pin_detect = GPIO38, .sfp_port[1].pin_los = GPIO_NA, .sfp_port[1].pin_tx_disable = GPIO_NA, .sfp_port[1].sds = 1, - .sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[1].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 }, @@ -925,7 +938,7 @@ __code const struct machine machine = { .sfp_port[0].pin_los = GPIO_NA, .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 }, @@ -968,7 +981,7 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = LED_28_SYS | LED_29, .enable = LED_27 | LED_28_SYS | LED_29 }, @@ -1049,13 +1062,13 @@ __code const struct machine machine = { .sfp_port[0].pin_detect = GPIO38, .sfp_port[0].pin_los = GPIO_NA, .sfp_port[0].sds = 1, - .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), // Right SFP port .sfp_port[1].pin_detect = GPIO37, .sfp_port[1].pin_los = GPIO_NA, .sfp_port[1].sds = 0, - .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, + .sfp_port[1].i2c = I2CBUS( GPIO41_I2C_SDA3_MDIO1, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 }, @@ -1114,7 +1127,7 @@ __code const struct machine machine = { .sfp_port[0].pin_los = GPIO_NA, .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = LED_27 | LED_28_SYS | LED_29, .enable = LED_28_SYS | LED_29 }, .port_led_set = {0, 0, 0, 0, 0, 0, 0, 0, 1}, diff --git a/machine.h b/machine.h index 6ca90f4c..ecf5f617 100644 --- a/machine.h +++ b/machine.h @@ -49,13 +49,6 @@ // #define MACHINE_PB_2132 // #define MACHINE_HASIVO_S600W_4GT_2XGT_SE -typedef struct { - // GPIO pins for SDA/SCL - uint8_t sda; - uint8_t scl; -} i2c_bus_t; - - #define LED_27 1 // SYSTEM LED #define LED_28_SYS 2 @@ -74,7 +67,7 @@ struct sfp_port uint8_t pin_los; // gpio number 0-63, 0xFF = don't have it? uint8_t pin_tx_disable; // gpio number 0-63, 0xFF = not present uint8_t sds; - i2c_bus_t i2c; + uint8_t i2c; }; struct machine { diff --git a/rtl837x_pins.c b/rtl837x_pins.c index bee98187..a6aaa7b8 100644 --- a/rtl837x_pins.c +++ b/rtl837x_pins.c @@ -10,38 +10,6 @@ extern __xdata uint8_t sfr_data[4]; #pragma codeseg BANK2 #pragma constseg BANK2 -uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin) __banked { - switch (sda_pin) { - case GPIO47_I2C_SDA0: - return 0; - case GPIO49_I2C_SDA1: - return 1; - case GPIO51_I2C_SDA2_UART1_RX: - return 2; - case GPIO41_I2C_SDA3_MDIO1: - return 3; - case GPIO39_I2C_SDA4: - return 4; - default: - return 0xFF; - } -} - -uint8_t i2c_bus_from_scl_pin(uint8_t scl_pin) __banked{ - switch (scl_pin) { - case GPIO46_I2C_SCL0: - return 0; - case GPIO48_I2C_SCL1: - return 1; - case GPIO50_I2C_SCL2_UART1_TX: - return 2; - case GPIO40_I2C_SCL3_MDC1: - return 3; - default: - return 0xFF; - } -} - /* Returns RTL837X_REG_GPIO_XX_OUTPUT register address */ static uint16_t gpio_output_reg(uint8_t pin) __banked{ return pin < 32 ? RTL837X_REG_GPIO_00_31_OUTPUT : RTL837X_REG_GPIO_32_63_OUTPUT; @@ -147,8 +115,7 @@ bool sfp_read_block(uint8_t slot, uint8_t reg, uint8_t len) __banked __reentrant REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH - 16) | len, - (dev >> 5) | i2c_bus_from_scl_pin(machine.sfp_port[slot].i2c.scl) << 5 - | i2c_bus_from_sda_pin(machine.sfp_port[slot].i2c.sda) << 2, + (dev >> 5) | machine.sfp_port[slot].i2c, ((dev << 3) & 0xff) | 0x1); do { diff --git a/rtl837x_pins.h b/rtl837x_pins.h index 9f84226f..cc5ffd9b 100644 --- a/rtl837x_pins.h +++ b/rtl837x_pins.h @@ -71,12 +71,6 @@ /* Not available GPIO */ #define GPIO_NA 0xFF -/* Convert SDA PIN GPIO to I2C bus number */ -uint8_t i2c_bus_from_sda_pin(uint8_t sda_pin) __banked; - -/* Convert SCL PIN GPIO to I2C bus number */ -uint8_t i2c_bus_from_scl_pin(uint8_t scl_pin) __banked; - /* * Setup a GPIO pin as input * pin: GPIO pin number 0-63 From b5fe9f217f7e5003d285d7fe98ce311074928b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 13 Sep 2026 12:01:05 +0200 Subject: [PATCH 2/6] i2c/sfp: Demagic shift-values --- boot.c | 4 ++-- machine.c | 4 ++-- rtl837x_regs.h | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/boot.c b/boot.c index 4c188ad8..3646a0a0 100644 --- a/boot.c +++ b/boot.c @@ -398,8 +398,8 @@ void setup_i2c(void) __banked reg_read_m(RTL837X_PIN_MUX_1); for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) { uint8_t i2c = machine.sfp_port[sfp].i2c; - uint8_t scl_bus = (i2c >> 5) & 0x03; - uint8_t sda_bus = (i2c >> 2) & 0x07; + uint8_t scl_bus = (i2c >> RTL837X_REG_I2C_SCL_SHIFT) & 0x03; + uint8_t sda_bus = (i2c >> RTL837X_REG_I2C_SDA_SHIFT) & 0x07; print_string("Configuring I2C for SFP idx="); print_byte(sfp); print_string(" SCL="); print_byte(scl_bus); print_string(", SDA="); print_byte(sda_bus); write_char('\n'); switch (scl_bus) { case 3: diff --git a/machine.c b/machine.c index a4f8e192..9ce62920 100644 --- a/machine.c +++ b/machine.c @@ -6,8 +6,8 @@ #include "rtl837x_common.h" #define I2CBUS(sda, scl) \ - ((uint8_t)((I2C_BUS_FROM_SCL_PIN(scl) << 5) | \ - (I2C_BUS_FROM_SDA_PIN(sda) << 2))) + ((uint8_t)((I2C_BUS_FROM_SCL_PIN(scl) << RTL837X_REG_I2C_SCL_SHIFT) | \ + (I2C_BUS_FROM_SDA_PIN(sda) << RTL837X_REG_I2C_SDA_SHIFT))) #define I2C_BUS_FROM_SDA_PIN(sda_pin) \ ((sda_pin) == GPIO47_I2C_SDA0 ? (uint8_t)0 : \ diff --git a/rtl837x_regs.h b/rtl837x_regs.h index 6154221b..435c0c2d 100644 --- a/rtl837x_regs.h +++ b/rtl837x_regs.h @@ -126,6 +126,8 @@ #define RTL837X_REG_I2C_CTRL2 0x041c #define RTL837X_REG_I2C_IN 0x0420 #define RTL837X_REG_I2C_OUT 0x0424 +#define RTL837X_REG_I2C_SCL_SHIFT 5 +#define RTL837X_REG_I2C_SDA_SHIFT 2 /* * NIC Related registers From 19ccc4003dff94c741e35e1c0bcb96801b1655c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 13 Sep 2026 12:17:37 +0200 Subject: [PATCH 3/6] i2c: Add compiletime check macro for validating the i2c pins. Use 0x7 as error value for an invalid I2C SDA/SCL-pin value. The macro `I2CBUS_VALID` checks for this value. When a invalid pin is ues, the compiler errors out with: "machine.c:: error 176: sizeof applied to an incomplete type", Error message is not ideal but at-least points to the right location in the code. --- boot.c | 2 +- machine.c | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/boot.c b/boot.c index 3646a0a0..8b8236aa 100644 --- a/boot.c +++ b/boot.c @@ -398,7 +398,7 @@ void setup_i2c(void) __banked reg_read_m(RTL837X_PIN_MUX_1); for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) { uint8_t i2c = machine.sfp_port[sfp].i2c; - uint8_t scl_bus = (i2c >> RTL837X_REG_I2C_SCL_SHIFT) & 0x03; + uint8_t scl_bus = (i2c >> RTL837X_REG_I2C_SCL_SHIFT) & 0x07; uint8_t sda_bus = (i2c >> RTL837X_REG_I2C_SDA_SHIFT) & 0x07; print_string("Configuring I2C for SFP idx="); print_byte(sfp); print_string(" SCL="); print_byte(scl_bus); print_string(", SDA="); print_byte(sda_bus); write_char('\n'); switch (scl_bus) { diff --git a/machine.c b/machine.c index 9ce62920..5830ff27 100644 --- a/machine.c +++ b/machine.c @@ -5,22 +5,28 @@ #include "rtl837x_regs.h" #include "rtl837x_common.h" +#define I2CBUS_INVALID (7) +// This is a MACRO to check if I2C_BUS_FROM_SDA_PIN or I2C_BUS_FROM_SCL_PIN don't return I2CBUS_INVALID. +// When I2CBUS_INVALID is returned, compiler stops with "machine.c:: error 176: sizeof applied to an incomplete type" +#define I2CBUS_VALID(bus) (0 * sizeof(char[(bus) != I2CBUS_INVALID ? 1 : 0])) #define I2CBUS(sda, scl) \ - ((uint8_t)((I2C_BUS_FROM_SCL_PIN(scl) << RTL837X_REG_I2C_SCL_SHIFT) | \ - (I2C_BUS_FROM_SDA_PIN(sda) << RTL837X_REG_I2C_SDA_SHIFT))) + ((uint8_t)((I2C_BUS_FROM_SCL_PIN(scl) << RTL837X_REG_I2C_SCL_SHIFT) | \ + (I2C_BUS_FROM_SDA_PIN(sda) << RTL837X_REG_I2C_SDA_SHIFT) | \ + I2CBUS_VALID(I2C_BUS_FROM_SCL_PIN(scl)) | \ + I2CBUS_VALID(I2C_BUS_FROM_SDA_PIN(sda)))) #define I2C_BUS_FROM_SDA_PIN(sda_pin) \ - ((sda_pin) == GPIO47_I2C_SDA0 ? (uint8_t)0 : \ - (sda_pin) == GPIO49_I2C_SDA1 ? (uint8_t)1 : \ - (sda_pin) == GPIO51_I2C_SDA2_UART1_RX ? (uint8_t)2 : \ - (sda_pin) == GPIO41_I2C_SDA3_MDIO1 ? (uint8_t)3 : \ - (sda_pin) == GPIO39_I2C_SDA4 ? (uint8_t)4 : -1) + ((sda_pin) == GPIO47_I2C_SDA0 ? 0 : \ + (sda_pin) == GPIO49_I2C_SDA1 ? 1 : \ + (sda_pin) == GPIO51_I2C_SDA2_UART1_RX ? 2 : \ + (sda_pin) == GPIO41_I2C_SDA3_MDIO1 ? 3 : \ + (sda_pin) == GPIO39_I2C_SDA4 ? 4 : I2CBUS_INVALID) #define I2C_BUS_FROM_SCL_PIN(scl_pin) \ ((scl_pin) == GPIO46_I2C_SCL0 ? 0 : \ (scl_pin) == GPIO48_I2C_SCL1 ? 1 : \ (scl_pin) == GPIO50_I2C_SCL2_UART1_TX ? 2 : \ - (scl_pin) == GPIO40_I2C_SCL3_MDC1 ? 3 : -1) + (scl_pin) == GPIO40_I2C_SCL3_MDC1 ? 3 : I2CBUS_INVALID) #if defined(MACHINE_KP_9000_6XHML_X2) || \ defined(MACHINE_KP_9000_6XH_X2_V1_1) || \ From 131bc106aff6825a8b3a18b1a0adaeff0784feef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 13 Sep 2026 21:55:50 +0200 Subject: [PATCH 4/6] boot/i2c-setup(): Remove the switch-statement defaults. All the possibilities are handled, or otherwise a compile-time macro I2CBUS_VALID ensures invalid options are rejected with a compiler error. Also fix a compiler warning. --- boot.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/boot.c b/boot.c index 8b8236aa..b5f72b85 100644 --- a/boot.c +++ b/boot.c @@ -398,10 +398,10 @@ void setup_i2c(void) __banked reg_read_m(RTL837X_PIN_MUX_1); for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) { uint8_t i2c = machine.sfp_port[sfp].i2c; - uint8_t scl_bus = (i2c >> RTL837X_REG_I2C_SCL_SHIFT) & 0x07; + uint8_t scl_bus = (i2c >> RTL837X_REG_I2C_SCL_SHIFT); uint8_t sda_bus = (i2c >> RTL837X_REG_I2C_SDA_SHIFT) & 0x07; print_string("Configuring I2C for SFP idx="); print_byte(sfp); print_string(" SCL="); print_byte(scl_bus); print_string(", SDA="); print_byte(sda_bus); write_char('\n'); - switch (scl_bus) { + switch (scl_bus & 0x03) { case 3: // Bit 5-6 0b10 -> SCL (implies enabled SDA on bus 3) sfr_mask_data(0, 0x60, 0x40); @@ -420,8 +420,6 @@ void setup_i2c(void) __banked sfr_mask_data(0, 0x80, 0x80); sfr_mask_data(1, 0x01, 0x00); break; - default: - print_string("Invalid SCL bus number: "); print_byte(scl_bus); write_char('\n'); } switch (sda_bus) { @@ -445,8 +443,6 @@ void setup_i2c(void) __banked // Bit 9-10 0b01 -> SDA sfr_mask_data(1, 0x06, 0x02); break; - default: - print_string("Invalid SDA bus number: "); print_byte(sda_bus); write_char('\n'); } } reg_write_m(RTL837X_PIN_MUX_1); From 1557a7cf3ce0b932e0da489cc12c261b1c62b26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 20 Sep 2026 11:30:17 +0200 Subject: [PATCH 5/6] MACHINE: rebase, update the new added devices --- machine.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/machine.c b/machine.c index 5830ff27..23e7ca41 100644 --- a/machine.c +++ b/machine.c @@ -1179,10 +1179,7 @@ __code const struct machine machine = { .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 - }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .high_leds = { .mux = 0, .enable = 0 }, @@ -1216,7 +1213,7 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, .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}, @@ -1260,7 +1257,7 @@ __code const struct machine machine = { .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 }, + .sfp_port[0].i2c = I2CBUS( GPIO39_I2C_SDA4, GPIO40_I2C_SCL3_MDC1 ), .reset_pin = GPIO_NA, From ce11790a0df8906a6330e3c5997317b64e97d05f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 20 Sep 2026 20:31:43 +0200 Subject: [PATCH 6/6] I2C: Silence compiler warning, de-magic values. --- boot.c | 7 ++++--- rtl837x_regs.h | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/boot.c b/boot.c index b5f72b85..1fde6114 100644 --- a/boot.c +++ b/boot.c @@ -398,10 +398,11 @@ void setup_i2c(void) __banked reg_read_m(RTL837X_PIN_MUX_1); for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) { uint8_t i2c = machine.sfp_port[sfp].i2c; - uint8_t scl_bus = (i2c >> RTL837X_REG_I2C_SCL_SHIFT); - uint8_t sda_bus = (i2c >> RTL837X_REG_I2C_SDA_SHIFT) & 0x07; + uint8_t scl_bus = (i2c >> RTL837X_REG_I2C_SCL_SHIFT) & RTL837X_REG_I2C_SCL_MASK; + uint8_t sda_bus = (i2c >> RTL837X_REG_I2C_SDA_SHIFT) & RTL837X_REG_I2C_SDA_MASK; print_string("Configuring I2C for SFP idx="); print_byte(sfp); print_string(" SCL="); print_byte(scl_bus); print_string(", SDA="); print_byte(sda_bus); write_char('\n'); - switch (scl_bus & 0x03) { + // `& RTL837X_REG_I2C_SCL_MASK` is needed to silens a compiler warning 110. + switch (scl_bus & RTL837X_REG_I2C_SCL_MASK) { case 3: // Bit 5-6 0b10 -> SCL (implies enabled SDA on bus 3) sfr_mask_data(0, 0x60, 0x40); diff --git a/rtl837x_regs.h b/rtl837x_regs.h index 435c0c2d..43e58f87 100644 --- a/rtl837x_regs.h +++ b/rtl837x_regs.h @@ -128,6 +128,8 @@ #define RTL837X_REG_I2C_OUT 0x0424 #define RTL837X_REG_I2C_SCL_SHIFT 5 #define RTL837X_REG_I2C_SDA_SHIFT 2 +#define RTL837X_REG_I2C_SCL_MASK 0x3 +#define RTL837X_REG_I2C_SDA_MASK 0x7 /* * NIC Related registers