diff --git a/Makefile b/Makefile index fb02001..a6a2bf5 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ all: create_build_dir $(VERSION_HEADER) $(SUBDIRS) $(BUILDDIR)rtlplayground.bin create_build_dir: mkdir -p $(BUILDDIR) -SRCS = rtlplayground.c rtl837x_flash.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c +SRCS = rtlplayground.c rtl837x_flash.c rtl837x_leds.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel} OBJS += uip/$(BUILDDIR)/timer.rel uip/$(BUILDDIR)/uip-fw.rel uip/$(BUILDDIR)/uip-neighbor.rel uip/$(BUILDDIR)/uip-split.rel uip/$(BUILDDIR)/uip.rel uip/$(BUILDDIR)/uip_arp.rel uip/$(BUILDDIR)/uiplib.rel httpd/$(BUILDDIR)/httpd.rel httpd/$(BUILDDIR)/page_impl.rel diff --git a/cmd_parser.c b/cmd_parser.c index 33e4101..afc1408 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -156,7 +156,7 @@ uint8_t atoi_hex(uint8_t idx) uint8_t atoi_short(register uint16_t *vlan, register uint8_t idx) { - uint8_t err = 1; + __xdata uint8_t err = 1; *vlan = 0; while (isnumber(cmd_buffer[idx])) { @@ -1018,7 +1018,7 @@ void execute_config(void) __banked flash_region.len = FLASH_READ_BURST_SIZE; flash_read_bulk(flash_buf); - uint8_t cfg_idx = 0; + __xdata uint8_t cfg_idx = 0; uint8_t c = 0; do { for (uint8_t cmd_idx = 0; cmd_idx < (SBUF_SIZE - 1); cmd_idx++) { diff --git a/machine.c b/machine.c index 60aeac7..460dae1 100644 --- a/machine.c +++ b/machine.c @@ -1,5 +1,7 @@ #include "machine.h" #include "rtl837x_pins.h" +#include "rtl837x_leds.h" +#include "rtl837x_regs.h" #ifdef MACHINE_KP_9000_6XHML_X2 __code const struct machine machine = { @@ -22,7 +24,25 @@ __code const struct machine machine = { .sfp_port[1].sds = 1, .sfp_port[1].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .reset_pin = GPIO46_I2C_SCL0, + .high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 }, + .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0}, + /* Conditions for LED on: + * dual led orange: ledset_0 & ledset_2 + * dual led green: ledset_2 & !ledset_0 + * single right led green: ledset_0 & !ledset_1 + */ + .led_sets = { { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G, + LEDS_2G5 | LEDS_LINK | LEDS_10G, + LEDS_1G | LEDS_LINK, + 0 }, + }, + .led_mux_custom = 1, + .led_mux = {0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x0f, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, + 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23 }, }; + +void machine_custom_init(void) { } + #elif defined MACHINE_KP_9000_6XH_X __code const struct machine machine = { .machine_name = "keepLink KP-9000-6XH-X", @@ -39,7 +59,20 @@ __code const struct machine machine = { .sfp_port[0].sds = 1, .sfp_port[0].i2c = { .sda = GPIO39_I2C_SDA4, .scl = GPIO40_I2C_SCL3_MDC1 }, .reset_pin = GPIO_NA, + /* Conditions for LED on: + * dual led orange: ledset_0 & ledset_2 + * dual led green: ledset_2 & !ledset_0 + * single right led green: ledset_0 & !ledset_1 + */ + .led_sets = { { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G, + LEDS_2G5 | LEDS_LINK | LEDS_10G, + LEDS_1G | LEDS_LINK, + 0 }, + }, }; + +void machine_custom_init(void) { } + #elif defined MACHINE_KP_9000_9XH_X_EU __code const struct machine machine = { .machine_name = "keepLink KP-9000-6XH-X-EU", @@ -56,8 +89,17 @@ __code const struct machine machine = { .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_27 | LED_29, .enable = LED_28 | LED_29 }, + .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .led_sets = { { LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5, + LEDS_2G5 | LEDS_LINK, + LEDS_1G | LEDS_LINK, + LEDS_2G5 | LEDS_LINK | LEDS_ACT }, + }, }; +void machine_custom_init(void) { } + #elif defined MACHINE_SWGT024_V2_0 __code const struct machine machine = { .machine_name = "SWGT024 V2.0", @@ -81,8 +123,62 @@ __code const struct machine machine = { .sfp_port[1].sds = 0, .sfp_port[1].i2c = { .sda = GPIO41_I2C_SDA3_MDIO1, .scl = GPIO40_I2C_SCL3_MDC1 }, /* GPIO 40 */ .reset_pin = GPIO36_PWM_OUT, + .high_leds = { .mux = LED_27 | LED_29, .enable = LED_28 | LED_29 }, + .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0}, + /* Conditions for LED on: + * dual led orange: ledset_0 & ledset_2 + * dual led green: ledset_2 & !ledset_0 + * single right led green: ledset_0 & !ledset_1 + */ + .led_sets = { { LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G, + LEDS_2G5 | LEDS_LINK | LEDS_10G, + LEDS_1G | LEDS_LINK, + 0 }, + }, }; +void machine_custom_init(void) { } + +#elif defined MACHINE_HG0402XG_V1_1 +__code const struct machine machine = { + .machine_name = "HG0402XG V1.1", + .isRTL8373 = 0, + .min_port = 3, + .max_port = 8, + .n_sfp = 2, + .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, 2, 0, 0, 0, 0, 1}, + .sfp_port[0].pin_detect = 50, + .sfp_port[0].pin_los = 10, + .sfp_port[0].pin_tx_disable = 0xFF, + .sfp_port[0].sds = 1, + .sfp_port[0].i2c_bus ={ .sda = GPIO41_I2C_SDA3_MDIO1, .scl = 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_bus = { .sda = GPIO39_I2C_SDA4, .scl = 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}, + /* The Ethernet ports have 1 amber LED (left) and 1 green LED (right) + * The SFP ports have also 1 amber LED and 1 green LED + * Ethernet ports use LED-set 0, SFP ports use LED-set 1 + */ + .led_sets = { { LEDS_10M | LEDS_LINK | LEDS_ACT, + LEDS_1G | LEDS_100M | LEDS_10M | LEDS_2G5 | LEDS_LINK | LEDS_ACT, + LEDS_2G5 | LEDS_LINK | LEDS_ACT, + 0 }, + { LEDS_100M | LEDS_10M | LEDS_LINK, + LEDS_2G5 | LEDS_1G | LEDS_100M | LEDS_10M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G, + LEDS_10G | LEDS_LINK, + 0 }, + }, +}; + +void machine_custom_init(void) { } + #elif defined DEFAULT_8C_1SFP __code const struct machine machine = { .machine_name = "8+1 SFP Port Switch", @@ -99,7 +195,17 @@ __code const struct machine machine = { .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_27 | LED_29, .enable = LED_28 | LED_29 }, + .port_led_set = { 0, 0, 0, 0, 0, 0, 0, 0, 0}, + .led_sets = { { LEDS_2G5 | LEDS_TWO_PAIR_1G | LEDS_1G | LEDS_500M | LEDS_100M | LEDS_10M | LEDS_LINK | LEDS_ACT | LEDS_10G | LEDS_TWO_PAIR_5G | LEDS_5G | LEDS_TWO_PAIR_2G5, + LEDS_2G5 | LEDS_LINK, + LEDS_1G | LEDS_LINK, + LEDS_2G5 | LEDS_LINK | LEDS_ACT }, + }, }; + +void machine_custom_init(void) { } + #elif defined MACHINE_TRENDNET_TEG_S562 __code const struct machine machine = { .machine_name = "Trendnet TEG-S562", @@ -122,4 +228,7 @@ __code const struct machine machine = { .sfp_port[1].i2c = { .sda = GPIO49_I2C_SDA1, .scl = GPIO48_I2C_SCL1 }, .reset_pin = GPIO_NA, }; + +void machine_custom_init(void) { } + #endif diff --git a/machine.h b/machine.h index 24de207..cba1ac8 100644 --- a/machine.h +++ b/machine.h @@ -12,7 +12,7 @@ // #define MACHINE_SWGT024_V2_0 // #define MACHINE_HORACO_ZX_SG4T2 // #define MACHINE_TRENDNET_TEG_S562 - +// #define MACHINE_HG0402XG_V1_1 // #define DEFAULT_8C_1SFP // #define DEFAULT_5C_1SFP @@ -23,6 +23,18 @@ typedef struct { uint8_t scl; } i2c_bus_t; + +#define LED_27 1 +#define LED_28 2 +#define LED_29 4 + +struct high_leds { + // Defines MUX and LED enabling for pins 27-29 + uint8_t mux : 3; + uint8_t enable : 3; + uint8_t reserved : 2; +}; + struct sfp_port { uint8_t pin_detect; // gpio number 0-63, 0xFF = don't have it? @@ -44,6 +56,11 @@ typedef struct machine { // sfp_port[0] is the first SFP-port from the left on the device, sfp_port[1] the next if present struct sfp_port sfp_port[2]; int8_t reset_pin; + struct high_leds high_leds; + uint8_t port_led_set[9]; + uint32_t led_sets[4][4]; + uint8_t led_mux_custom; + uint8_t led_mux[28]; }; typedef struct machine_runtime @@ -52,4 +69,6 @@ typedef struct machine_runtime uint8_t isN : 1; }; +void machine_custom_init(void); + #endif diff --git a/rtl837x_igmp.c b/rtl837x_igmp.c index 21dadf4..e36dda6 100644 --- a/rtl837x_igmp.c +++ b/rtl837x_igmp.c @@ -118,11 +118,8 @@ void igmp_setup(void) __banked * For now the IGMP protocols are flooded (01), MLD which MAC-based is handled by ASIC * All messages are allowed and maximum MC group is 0xff */ - for (i = machine.min_port; i <= machine.max_port; i++) { - print_byte(i); write_char(':'); + for (i = machine.min_port; i <= machine.max_port; i++) REG_SET(RTL837X_IGMP_PORT_CFG + (i << 2), IGMP_MAX_GROUP | IGMP_PROTOCOL_ENABLE | IGMP_FLOOD); - write_char('\n'); - } /* // Allow all physical ports to be dynamic router ports reg_read_m(RTL837X_IGMP_ROUTER_PORT); diff --git a/rtl837x_leds.c b/rtl837x_leds.c new file mode 100644 index 0000000..86e7f97 --- /dev/null +++ b/rtl837x_leds.c @@ -0,0 +1,296 @@ +/* + * This is a driver implementation for the IGMP features for the RTL827x platform + * This code is in the Public Domain + */ + +// #define REGDBG +// #define DEBUG + +#define IPMC_USES_L3MC + +#include +#include "rtl837x_common.h" +#include "rtl837x_sfr.h" +#include "rtl837x_regs.h" +#include "rtl837x_leds.h" +#include "machine.h" + +extern __code struct machine machine; + +#include "uip.h" + +#pragma codeseg BANK2 +#pragma constseg BANK2 + +extern __xdata uint8_t sfr_data[4]; + +void leds_dump(void) __banked +{ + print_string("RTL837X_PIN_MUX_0: "); print_reg(RTL837X_PIN_MUX_0); write_char('\n'); + print_string("RTL837X_REG_LED_GLB_IO_EN: "); print_reg(RTL837X_REG_LED_GLB_IO_EN); write_char('\n'); + print_string("RTL837X_REG_LED1_0_SET0: "); print_reg(RTL837X_REG_LED1_0_SET0); write_char('\n'); + print_string("RTL837X_REG_LED3_2_SET0: "); print_reg(RTL837X_REG_LED3_2_SET0); write_char('\n'); + print_string("RTL837X_REG_LED1_0_SET1: "); print_reg(RTL837X_REG_LED1_0_SET1); write_char('\n'); + print_string("RTL837X_REG_LED3_2_SET1: "); print_reg(RTL837X_REG_LED3_2_SET1); write_char('\n'); + print_string("RTL837X_REG_LED1_0_SET2: "); print_reg(RTL837X_REG_LED1_0_SET2); write_char('\n'); + print_string("RTL837X_REG_LED3_2_SET2: "); print_reg(RTL837X_REG_LED3_2_SET2); write_char('\n'); + print_string("RTL837X_REG_LED1_0_SET3: "); print_reg(RTL837X_REG_LED1_0_SET3); write_char('\n'); + print_string("RTL837X_REG_LED3_0_SET1: "); print_reg(RTL837X_REG_LED3_0_SET1); write_char('\n'); + print_string("RTL837X_REG_LED3_0_SET3: "); print_reg(RTL837X_REG_LED3_0_SET3); write_char('\n'); + print_string("RTL837X_LED_PORT_SET_SEL: "); print_reg(RTL837X_LED_PORT_SET_SEL); write_char('\n'); + print_string("RTL837X_REG_LED_GLB_MUX_1: "); print_reg(RTL837X_REG_LED_GLB_MUX_1); write_char('\n'); + print_string("RTL837X_REG_LED_GLB_MUX_2: "); print_reg(RTL837X_REG_LED_GLB_MUX_2); write_char('\n'); + print_string("RTL837X_REG_LED_GLB_MUX_3: "); print_reg(RTL837X_REG_LED_GLB_MUX_3); write_char('\n'); + print_string("RTL837X_REG_LED_GLB_MUX_4: "); print_reg(RTL837X_REG_LED_GLB_MUX_4); write_char('\n'); + print_string("RTL837X_REG_LED_GLB_MUX_5: "); print_reg(RTL837X_REG_LED_GLB_MUX_5); write_char('\n'); + print_string("RTL837X_REG_LED_GLB_MUX_6: "); print_reg(RTL837X_REG_LED_GLB_MUX_6); write_char('\n'); + print_string("RTL837X_REG_LED_GLB_ACTIVE: "); print_reg(RTL837X_REG_LED_GLB_ACTIVE); write_char('\n'); + print_string("LED pad Configuration:\n"); + for (uint8_t i = 0; i < 28; i++) { + print_byte(i); + write_char(' '); + } + write_char('\n'); + for (uint8_t i = 0; i < 28; i++) { + switch (i % 5) { + case 0: // 0 + reg_read_m(RTL837X_REG_LED_GLB_MUX_1 + (i / 5) * 4); + print_byte(sfr_data[3] & 0x3f); + break; + case 1: // 6 + print_byte(((sfr_data[3] >> 6) | (sfr_data[2] << 2)) & 0x3f); + break; + case 2: // 12 + print_byte(((sfr_data[1] << 4) | (sfr_data[2] >> 4)) & 0x3f); + break; + case 3: // 18 + print_byte((sfr_data[1] >> 2) & 0x3f); + break; + case 4: // 24 + print_byte(sfr_data[0] & 0x3f); + break; + } + write_char(' '); + } + write_char('\n'); + print_string("LED-set Configuration:\n"); + print_string("LED-ID\t\t0\t\t1\t\t2\t\t3\n"); + for (__xdata uint8_t set = 0; set < 4; set++) { + print_string("SET "); write_char('0' + set); write_char(':'); + for (__xdata uint8_t ledid = 0; ledid < 4; ledid++) { + print_string("\t "); + uint8_t b; + if (set < 2) { + reg_read_m(RTL837X_REG_LED3_0_SET1); + b = sfr_data[3-((set << 1) + (ledid >> 1))]; + print_byte(ledid & 1 ? b >> 4 : b & 0xf); + } else { + reg_read_m(RTL837X_REG_LED3_0_SET3); + b = sfr_data[3-(((set-2) << 1) + (ledid >> 1))]; + print_byte(ledid & 1 ? b >> 4 : b & 0xf); + } + reg_read_m(RTL837X_REG_LED1_0_SET0 - set * 8 - ((ledid >> 1) * 4)); + if (! (ledid & 1)) { // LEDID 0, 2 + print_byte(sfr_data[2]); print_byte(sfr_data[3]); + } else { + print_byte(sfr_data[0]); print_byte(sfr_data[1]); + } + } + write_char('\n'); + } + for (uint8_t i = machine.min_port; i <= machine.max_port; i++) { + reg_read_m(RTL837X_LED_PORT_SET_SEL); + __xdata uint8_t set = sfr_data[3 - (i >> 2)]; + set = (set >> ((i & 3) << 1)); + print_string("Port "); write_char('0' + i); print_string(": SET "); + write_char('0' + set); + print_string(": "); + for (__xdata uint8_t ledid = 0; ledid < 4; ledid++) { + write_char('('); + reg_read_m(RTL837X_REG_LED1_0_SET0 - set * 8 - ((ledid >> 1) * 4)); + if (ledid & 1) { // LEDID 1, 3 + sfr_data[2] = sfr_data[0]; + sfr_data[3] = sfr_data[1]; + } + if (sfr_data[3] & 0x01) + print_string(" 2G5"); + if (sfr_data[3] & 0x02) + print_string(" TWO_1G"); + if (sfr_data[3] & 0x04) + print_string(" 1G"); + if (sfr_data[3] & 0x08) + print_string(" 500M"); + if (sfr_data[3] & 0x10) + print_string(" 100M"); + if (sfr_data[3] & 0x20) + print_string(" 10M"); + if (sfr_data[3] & 0x40) + print_string(" LINK"); + if (sfr_data[3] & 0x80) + print_string(" LINK_FLASH"); + if (sfr_data[2] & 0x01) + print_string(" ACT"); + if (sfr_data[2] & 0x02) + print_string(" RX"); + if (sfr_data[2] & 0x04) + print_string(" TX"); + if (sfr_data[2] & 0x08) + print_string(" COL"); + if (sfr_data[2] & 0x10) + print_string(" DUPLEX"); + if (sfr_data[2] & 0x20) + print_string(" TRAINING"); + if (sfr_data[2] & 0x40) + print_string(" MASTER"); + __xdata uint8_t b; + if (set < 2) { + reg_read_m(RTL837X_REG_LED3_0_SET1); + b = sfr_data[3-((set << 1) + (ledid >> 1))]; + } else { + reg_read_m(RTL837X_REG_LED3_0_SET3); + b = sfr_data[3-(((set-2) << 1) + (ledid >> 1))]; + } + b = ledid & 1 ? b >> 4 : b & 0xf; + if (b & 0x1) + print_string(" 10G"); + if (b & 0x2) + print_string(" TWO_5G"); + if (b & 0x4) + print_string(" 5G"); + if (b & 0x8) + print_string(" TWO_2G5"); + print_string("), "); + } + write_char('\n'); + } +} + + +void leds_setup(void) __banked +{ + print_string("leds_setup called\n"); + REG_SET(RTL837X_REG_LED_MODE, 0x0021e6b0); + + // Disable RLDP (Realtek Loop Detection Protocol) LEDs on loop detection + reg_read_m(RTL837X_REG_LED_RLDP_1); + sfr_mask_data(0, 0x03, 0); + reg_write_m(RTL837X_REG_LED_RLDP_1); + + // Set up all Port-LEDs to belong to RLDP + sfr_data[3] = sfr_data[2] = sfr_data[1] = sfr_data[0] = 0; + for (uint8_t i = machine.min_port; i <= (machine.max_port > 7 ? 7 : machine.max_port); i++) + sfr_data[3 - (i >> 2)] |= i & 1 ? 0xf0 : 0x0f; + reg_write_m(RTL837X_REG_LED_RLDP_2); + if (machine.max_port == 8) + REG_SET(RTL837X_REG_LED_RLDP_3, 0x0000000f); // Port 8 + + // Configure high LEDs 27-29: mux and LED enable + if (machine.high_leds.mux & LED_27) + reg_bit_set(RTL837X_PIN_MUX_0, 27); + else + reg_bit_clear(RTL837X_PIN_MUX_0, 27); + + if (machine.high_leds.mux & LED_28) + reg_bit_set(RTL837X_PIN_MUX_0, 28); + else + reg_bit_clear(RTL837X_PIN_MUX_0, 28); + + if (machine.high_leds.mux & LED_29) + reg_bit_set(RTL837X_PIN_MUX_0, 29); + else + reg_bit_clear(RTL837X_PIN_MUX_0, 29); + + if (machine.high_leds.enable & LED_27) + reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 27); + else + reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 27); + + if (machine.high_leds.enable & LED_28) + reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 28); + else + reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 28); + + if (machine.high_leds.enable & LED_29) + reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 29); + else + reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 29); + + // Configure the LED-mux + if (machine.led_mux_custom) { + print_string("Configuring custom LED-muxes: "); + for (uint8_t i = 0; i < 28; i++) { + switch (i % 5) { + case 0: // 0 + sfr_data[3] = machine.led_mux[i]; + break; + case 1: // 6 + sfr_data[3] |= machine.led_mux[i] << 6; + sfr_data[2] = machine.led_mux[i] >> 2; + break; + case 2: // 12 + sfr_data[2] |= machine.led_mux[i] << 4; + sfr_data[1] = machine.led_mux[i] >> 4; + break; + case 3: // 18 + sfr_data[1] |= machine.led_mux[i] << 2; + break; + case 4: // 24 + sfr_data[0] = machine.led_mux[i]; + print_sfr_data(); write_char(' '); + reg_write_m(RTL837X_REG_LED_GLB_MUX_1 + (i / 5) * 4); + break; + } + write_char(' '); + } + sfr_data[0] = 0; sfr_data[1] &= 0xf; + print_sfr_data(); write_char('\n'); + reg_write_m(RTL837X_REG_LED_GLB_MUX_6); + } + + // Configure the LED-set of a port + sfr_data[3] = sfr_data[2] = sfr_data[1] = sfr_data[0] = 0; + for (uint8_t i = machine.min_port; i <= machine.max_port; i++) + sfr_data[3 - (i >> 2)] |= machine.port_led_set[i] << ((i & 3) << 1); + reg_write_m(RTL837X_LED_PORT_SET_SEL); + + // Configure the LED-sets + sfr_data[3] = sfr_data[2] = sfr_data[1] = sfr_data[0] = 0; + reg_write_m(RTL837X_REG_LED3_0_SET1); + reg_write_m(RTL837X_REG_LED3_0_SET3); + __code uint8_t * __xdata lptr = &machine.led_sets[0][0]; + for (__xdata uint8_t set = 0; set < 4; set++) { + sfr_data[0] = *(lptr + 5); + sfr_data[1] = *(lptr + 4); + sfr_data[2] = *(lptr + 1); + sfr_data[3] = *(lptr); + reg_write_m(RTL837X_REG_LED1_0_SET0 - set * 8); + + if (set < 2) { + reg_read_m(RTL837X_REG_LED3_0_SET1); + sfr_data[3 - (set << 1)] = (*(lptr + 6) << 4) | (*(lptr + 2)); + reg_write_m(RTL837X_REG_LED3_0_SET1); + } else { + reg_read_m(RTL837X_REG_LED3_0_SET3); + sfr_data[3 - (set << 1)] = (*(lptr + 6) << 4) | (*(lptr + 2)); + reg_write_m(RTL837X_REG_LED3_0_SET3); + } + lptr += 8; + sfr_data[0] = *(lptr + 5); + sfr_data[1] = *(lptr + 4); + sfr_data[2] = *(lptr + 1); + sfr_data[3] = *(lptr); + reg_write_m(RTL837X_REG_LED1_0_SET0 - set * 8 - 4); + + if (set < 2) { + reg_read_m(RTL837X_REG_LED3_0_SET1); + sfr_data[2 - (set << 1)] = (*(lptr + 6) << 4) | (*(lptr + 2)); + reg_write_m(RTL837X_REG_LED3_0_SET1); + } else { + reg_read_m(RTL837X_REG_LED3_0_SET3); + sfr_data[2 - (set << 1)] = (*(lptr + 6) << 4) | (*(lptr + 2)); + reg_write_m(RTL837X_REG_LED3_0_SET3); + } + lptr += 8; + } + print_string("leds_setup done\n"); +} diff --git a/rtl837x_leds.h b/rtl837x_leds.h new file mode 100644 index 0000000..0ca1d20 --- /dev/null +++ b/rtl837x_leds.h @@ -0,0 +1,28 @@ +#ifndef _RTL837X_LEDS_H_ +#define _RTL837X_LEDS_H_ + +#define LEDS_2G5 0x00001 +#define LEDS_TWO_PAIR_1G 0x00002 +#define LEDS_1G 0x00004 +#define LEDS_500M 0x00008 +#define LEDS_100M 0x00010 +#define LEDS_10M 0x00020 +#define LEDS_LINK 0x00040 +#define LEDS_LINK_FLASH 0x00080 +#define LEDS_ACT 0x00100 +#define LEDS_RX 0x00200 +#define LEDS_TX 0x00400 +#define LEDS_COL 0x00800 +#define LEDS_DUPLEX 0x01000 +#define LEDS_TRAINING 0x02000 +#define LEDS_MASTER 0x04000 +#define LEDS_10G 0x10000 +#define LEDS_TWO_PAIR_5G 0x20000 +#define LEDS_5G 0x40000 +#define LEDS_TWO_PAIR_2G5 0x80000 + +#include +void leds_dump(void) __banked; +void leds_setup(void) __banked; + +#endif diff --git a/rtl837x_regs.h b/rtl837x_regs.h index b6d0e54..32e7a98 100644 --- a/rtl837x_regs.h +++ b/rtl837x_regs.h @@ -22,10 +22,24 @@ // BIT 17 set: LED solid on // Bytes 0/1 hold the LED mode, e.g. serial, RTL8231? // Blink rate is defined by setAsicRegBits(0x6520,0xe00000,rate); +#define RTL837X_REG_LED_GLB_MUX_1 0x65E0 +#define RTL837X_REG_LED_GLB_MUX_2 0x65E4 +#define RTL837X_REG_LED_GLB_MUX_3 0x65E8 +#define RTL837X_REG_LED_GLB_MUX_4 0x65EC +#define RTL837X_REG_LED_GLB_MUX_5 0x65F0 +#define RTL837X_REG_LED_GLB_MUX_6 0x65F4 +#define RTL837X_REG_LED_GLB_ACTIVE 0x65D8 #define RTL837X_REG_LED_GLB_IO_EN 0x65DC +#define RTL837X_REG_LED3_0_SET3 0x6524 #define RTL837X_REG_LED3_0_SET1 0x6528 +#define RTL837X_REG_LED1_0_SET3 0x6530 +#define RTL837X_REG_LED3_2_SET2 0x6534 +#define RTL837X_REG_LED1_0_SET2 0x6538 +#define RTL837X_REG_LED3_2_SET1 0x653C +#define RTL837X_REG_LED1_0_SET1 0x6540 #define RTL837X_REG_LED3_2_SET0 0x6544 #define RTL837X_REG_LED1_0_SET0 0x6548 +#define RTL837X_LED_PORT_SET_SEL 0x654c // SMI control #define RTL837X_REG_SMI_PORT0_5_ADDR 0x644C diff --git a/rtlplayground.c b/rtlplayground.c index 129b8e7..a694958 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -13,6 +13,7 @@ #include "rtl837x_port.h" #include "rtl837x_stp.h" #include "rtl837x_igmp.h" +#include "rtl837x_leds.h" #include "dhcp.h" #include "cmd_parser.h" #include "uip/uipopt.h" @@ -630,12 +631,14 @@ void print_reg(uint16_t reg) } +/* +// TODO: This uses 2 DSEG bytes and is not used! void print_sds_reg(uint8_t sds_id, uint8_t page, uint8_t reg) { sds_read(sds_id, page, reg); print_phy_data(); } - +*/ char cmp_4(__xdata uint8_t a[], __xdata uint8_t b[]) { @@ -1453,46 +1456,6 @@ void sds_init(void) } -void led_config_9xh(void) -{ - // r65d8:3ffbedff R65d8-3ffbedff - reg_bit_set(0x65d8, 0x1d); - - // r6520:0021fdb0 R6520-0021e7b0 r6520:0021e7b0 R6520-0021e6b0 - reg_read_m(RTL837X_REG_LED_MODE); - sfr_mask_data(1, 0x1f, 0x6); - sfr_mask_data(0, 0xe0, 0xa0); - reg_write_m(RTL837X_REG_LED_MODE); - - // Set LED blink rate to slow during booting - set_sys_led_state(SYS_LED_SLOW); - - // Disable RLDP (Realtek Loop Detection Protocol) LEDs on loop detection - reg_read_m(RTL837X_REG_LED_RLDP_1); - sfr_mask_data(0, 0, 0x3); - reg_write_m(RTL837X_REG_LED_RLDP_1); - // Configure LED group for RLDP per port - REG_SET(RTL837X_REG_LED_RLDP_2, 0xffffffff); // Ports 0-7 - REG_SET(RTL837X_REG_LED_RLDP_3, 0x0000000f); // Port 8 - - reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 29); - reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 27); - - // GPIO 27 is LED - reg_bit_set(RTL837X_PIN_MUX_0, 27); - - // Configure LED_SET_0, ledid 0/1 - REG_SET(RTL837X_REG_LED1_0_SET0, 0x0041017f); - - // Configure LED_SET_0 ledid 2 - REG_SET(RTL837X_REG_LED3_2_SET0, 0x01410044); - - // r6528:00000000 R6528-0000000f - reg_read_m(RTL837X_REG_LED3_0_SET1); - sfr_mask_data(0, 0x0f, 0x0f); - reg_write_m(RTL837X_REG_LED3_0_SET1); -} - void set_sys_led_state(uint8_t state) { reg_read_m(RTL837X_REG_LED_MODE); @@ -1500,55 +1463,6 @@ void set_sys_led_state(uint8_t state) reg_write_m(RTL837X_REG_LED_MODE); } -void led_config(void) -{ - // LED initialization - // r6520:0021fdb0 R6520-0021e7b0 r6520:0021e7b0 R6520-0021e6b0 - reg_read_m(RTL837X_REG_LED_MODE); - sfr_mask_data(2, 0xe0, 0x23); // Mask blink rate field (0xe0), set blink rate and LED to solid (set bit 1 = bit 17 overall) - // Configure led-mode (serial?) - sfr_data[2] = 0xe6; - sfr_data[3] = 0xb0; - reg_write_m(RTL837X_REG_LED_MODE); - - // Disable RLDP (Realtek Loop Detection Protocol) LEDs on loop detection - reg_read_m(RTL837X_REG_LED_RLDP_1); - sfr_mask_data(0, 0x03, 0); - reg_write_m(RTL837X_REG_LED_RLDP_1); - // Configure LED group for RLDP per port - REG_SET(RTL837X_REG_LED_RLDP_2, 0xffffffff); // Ports 0-7 - REG_SET(RTL837X_REG_LED_RLDP_3, 0x0000000f); // Port 8 - - reg_bit_set(RTL837X_REG_LED_GLB_IO_EN, 29); - reg_bit_clear(RTL837X_REG_LED_GLB_IO_EN, 27); - - // Configure GPIO for LEDs 27-29 - if (machine.n_sfp == 2) { - reg_bit_set(RTL837X_PIN_MUX_0, 27); - reg_bit_clear(RTL837X_PIN_MUX_0, 28); - reg_bit_set(RTL837X_PIN_MUX_0, 29); - } else { - reg_bit_set(RTL837X_PIN_MUX_0, 27); - reg_bit_set(RTL837X_PIN_MUX_0, 28); - reg_bit_set(RTL837X_PIN_MUX_0, 29); - } - // LED setup - // r6520:0021fdb0 R6520-0021e7b0 r6520:0021e7b0 R6520-0021e6b0 r65f8:00000018 R65f8-00000018 R65fc-fffff000 r6600:00000000 R6600-0000000f r65dc:5fffff00 R65dc-7fffff00 r65dc:7fffff00 R65dc-77ffff00 - // r7f8c:30000000 R7f8c-30000000 r7f8c:30000000 R7f8c-38000000 R6548-00410175 r6544:01411000 R6544-01410044 r6528:00000000 R6528-00000011 - - // Configure LED_SET_0, ledid 0/1 - REG_SET(RTL837X_REG_LED1_0_SET0, 0x00410175); - - // Configure led-sets 2 and 3 - REG_SET(RTL837X_REG_LED3_2_SET0, 0x01410044); - - // Further configure LED_SET_0 - // r6528:00000000 R6528-00000011 - reg_read_m(RTL837X_REG_LED3_0_SET1); - sfr_data[3] = 0x11; - reg_write_m(RTL837X_REG_LED3_0_SET1); -} - void rtl8373_revision(void) { reg_read_m(RTL837X_REG_CHIP_INFO); @@ -1567,7 +1481,9 @@ void rtl8373_init(void) { print_string("\nrtl8373_init called\n"); - led_config_9xh(); + // r65d8:3ffbedff R65d8-3ffbedff + reg_bit_set(0x65d8, 0x1d); + sds_init(); // Disable all SERDES for configuration REG_SET(RTL837X_REG_SDS_MODES, 0x000037ff); @@ -1662,8 +1578,6 @@ void rtl8372_init(void) { print_string("\nrtl8372_init called\n"); - led_config(); - sds_init(); phy_config(8); // PHY configuration: External 8221B? phy_config(3); // PHY configuration: all internal PHYs? @@ -1982,6 +1896,12 @@ void bootloader(void) init_smi(); rtl8373_revision(); + + leds_setup(); + machine_custom_init(); + + leds_dump(); + if (machine_detected.isRTL8373) rtl8373_init(); else @@ -1992,7 +1912,6 @@ void bootloader(void) flash_region.addr = FIRMWARE_UPLOAD_START; flash_region.len = 0x100; flash_read_bulk(flash_buf); - if (flash_buf[0] == 0x00 && flash_buf[1] == 0x40) { __xdata uint32_t dest = 0x0; __xdata uint32_t source = FIRMWARE_UPLOAD_START; @@ -2063,7 +1982,6 @@ void bootloader(void) dest += 0x1000; } } - set_sys_led_state(SYS_LED_SLOW); #ifdef DEBUG