mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Advanced I2C pin definition
RTL has up to 3 SCL pins and up to 4 SDA pins. Lets allow configuring I2C with individual BUS numbers instead of 0/1 I2C. This enables support for devices where SCL line is not shared between SFP modules. MUX registry is now initialized depending on needed pin function. More over, some SFP pins require special MUX settings, lets initialize those depending on SFP configuration. This adds TX Disable pin, which right now is set to low at startup. Caveats: - We may still override MUX registry later - Not sure how to handle invalid bus definitions - Without SFP is it fine to *not* initialize anything? - Do to RAM limitation we do inititalize output GPIO to low
This commit is contained in:
+1
-1
@@ -178,7 +178,7 @@ void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||||
sfr_mask_data(1, 0xfc, machine.sfp_port[slot].i2c == 0 ? SCL_PIN << 5 | SDA_PIN_0 << 2 : SCL_PIN << 5 | SDA_PIN_1 << 2 );
|
sfr_mask_data(1, 0xfc, machine.sfp_port[slot].i2c_bus.scl << 5 | machine.sfp_port[slot].i2c_bus.sda << 2);
|
||||||
reg_write_m(RTL837X_REG_I2C_CTRL);
|
reg_write_m(RTL837X_REG_I2C_CTRL);
|
||||||
|
|
||||||
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
|
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
|
||||||
|
|||||||
@@ -12,12 +12,14 @@ __code const struct machine machine = {
|
|||||||
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
.is_sfp = {0, 0, 0, 2, 0, 0, 0, 0, 1},
|
||||||
.sfp_port[0].pin_detect = 50,
|
.sfp_port[0].pin_detect = 50,
|
||||||
.sfp_port[0].pin_los = 10,
|
.sfp_port[0].pin_los = 10,
|
||||||
|
.sfp_port[0].pin_tx_disable = 0xFF,
|
||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
.sfp_port[0].i2c = 1,
|
.sfp_port[0].i2c_bus = { .sda = 3, .scl = 3 },
|
||||||
.sfp_port[1].pin_detect = 30,
|
.sfp_port[1].pin_detect = 30,
|
||||||
.sfp_port[1].pin_los = 37,
|
.sfp_port[1].pin_los = 37,
|
||||||
|
.sfp_port[1].pin_tx_disable = 0xFF,
|
||||||
.sfp_port[1].sds = 0,
|
.sfp_port[1].sds = 0,
|
||||||
.sfp_port[1].i2c = 0,
|
.sfp_port[1].i2c_bus = { .sda = 4, .scl = 3 },
|
||||||
.reset_pin = 46,
|
.reset_pin = 46,
|
||||||
};
|
};
|
||||||
#elif defined MACHINE_KP_9000_6XH_X
|
#elif defined MACHINE_KP_9000_6XH_X
|
||||||
@@ -32,8 +34,9 @@ __code const struct machine machine = {
|
|||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
.sfp_port[0].pin_detect = 30,
|
.sfp_port[0].pin_detect = 30,
|
||||||
.sfp_port[0].pin_los = 37,
|
.sfp_port[0].pin_los = 37,
|
||||||
|
.sfp_port[0].pin_tx_disable = 0xFF,
|
||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
.sfp_port[0].i2c = 0,
|
.sfp_port[0].i2c_bus = { .sda = 4, .scl = 3 },
|
||||||
};
|
};
|
||||||
#elif defined MACHINE_KP_9000_9XH_X_EU
|
#elif defined MACHINE_KP_9000_9XH_X_EU
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
@@ -47,9 +50,11 @@ __code const struct machine machine = {
|
|||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
.sfp_port[0].pin_detect = 30,
|
.sfp_port[0].pin_detect = 30,
|
||||||
.sfp_port[0].pin_los = 37,
|
.sfp_port[0].pin_los = 37,
|
||||||
|
.sfp_port[0].pin_tx_disable = 0xFF,
|
||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
.sfp_port[0].i2c = 0,
|
.sfp_port[0].i2c_bus = { .sda = 4, .scl = 3 },
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif defined MACHINE_SWGT024_V2_0
|
#elif defined MACHINE_SWGT024_V2_0
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "SWGT024 V2.0",
|
.machine_name = "SWGT024 V2.0",
|
||||||
@@ -63,15 +68,18 @@ __code const struct machine machine = {
|
|||||||
// Left SFP port (J4)
|
// Left SFP port (J4)
|
||||||
.sfp_port[0].pin_detect = 30,
|
.sfp_port[0].pin_detect = 30,
|
||||||
.sfp_port[0].pin_los = 37,
|
.sfp_port[0].pin_los = 37,
|
||||||
|
.sfp_port[0].pin_tx_disable = 0xFF,
|
||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
.sfp_port[0].i2c = 0, /* GPIO 39 */
|
.sfp_port[0].i2c_bus = { .sda = 4, .scl = 3 }, /* GPIO 39 */
|
||||||
// Right SFP port (J2)
|
// Right SFP port (J2)
|
||||||
.sfp_port[1].pin_detect = 50,
|
.sfp_port[1].pin_detect = 50,
|
||||||
.sfp_port[1].pin_los = 51,
|
.sfp_port[1].pin_los = 51,
|
||||||
|
.sfp_port[1].pin_tx_disable = 0xFF,
|
||||||
.sfp_port[1].sds = 0,
|
.sfp_port[1].sds = 0,
|
||||||
.sfp_port[1].i2c = 1, /* GPIO 40 */
|
.sfp_port[1].i2c_bus = { .sda = 3, .scl = 3 }, /* GPIO 40 */
|
||||||
.reset_pin = 36,
|
.reset_pin = 36,
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif defined DEFAULT_8C_1SFP
|
#elif defined DEFAULT_8C_1SFP
|
||||||
__code const struct machine machine = {
|
__code const struct machine machine = {
|
||||||
.machine_name = "8+1 SFP Port Switch",
|
.machine_name = "8+1 SFP Port Switch",
|
||||||
@@ -84,8 +92,8 @@ __code const struct machine machine = {
|
|||||||
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
.is_sfp = {0, 0, 0, 0, 0, 0, 0, 0, 1},
|
||||||
.sfp_port[0].pin_detect = 30,
|
.sfp_port[0].pin_detect = 30,
|
||||||
.sfp_port[0].pin_los = 37,
|
.sfp_port[0].pin_los = 37,
|
||||||
|
.sfp_port[0].pin_tx_disable = 0xFF,
|
||||||
.sfp_port[0].sds = 1,
|
.sfp_port[0].sds = 1,
|
||||||
.sfp_port[0].i2c = 0,
|
.sfp_port[0].i2c_bus = { .sda = 4, .scl = 3 },
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,12 +16,21 @@
|
|||||||
|
|
||||||
// #define DEFAULT_5C_1SFP
|
// #define DEFAULT_5C_1SFP
|
||||||
|
|
||||||
|
struct i2c_bus {
|
||||||
|
// These are I2C bus identifiers refer to GPIO MUX document
|
||||||
|
// for GPIO pin assignments for given bus numbers
|
||||||
|
uint8_t sda : 3; // SDA pin number 0-4
|
||||||
|
uint8_t scl : 3; // SCL pin number 0-3
|
||||||
|
uint8_t reserved : 2;
|
||||||
|
};
|
||||||
|
|
||||||
struct sfp_port
|
struct sfp_port
|
||||||
{
|
{
|
||||||
uint8_t pin_detect; // gpio number 0-63, 0xFF = don't have it?
|
uint8_t pin_detect; // gpio number 0-63, 0xFF = don't have it?
|
||||||
uint8_t pin_los; // gpio number 0-63, 0xFF = don't have it?
|
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;
|
uint8_t sds;
|
||||||
uint8_t i2c;
|
struct i2c_bus i2c_bus;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct machine {
|
typedef struct machine {
|
||||||
|
|||||||
@@ -7,11 +7,6 @@
|
|||||||
|
|
||||||
#define SYS_TICK_HZ 200
|
#define SYS_TICK_HZ 200
|
||||||
|
|
||||||
// SCL and SDA pin numbers for SFP cage 0 and SFP cage 1
|
|
||||||
#define SCL_PIN 3
|
|
||||||
#define SDA_PIN_0 4
|
|
||||||
#define SDA_PIN_1 3
|
|
||||||
|
|
||||||
#define CPU_PORT 9
|
#define CPU_PORT 9
|
||||||
|
|
||||||
// Define Port-masks for 9-port devices and 6-port devices
|
// Define Port-masks for 9-port devices and 6-port devices
|
||||||
|
|||||||
+3
-13
@@ -356,20 +356,10 @@ void port_stats_print(void) __banked
|
|||||||
else
|
else
|
||||||
print_string("Off\t");
|
print_string("Off\t");
|
||||||
} else { // An SFP Module
|
} else { // An SFP Module
|
||||||
if (i != 3) {
|
if (!gpio_pin_test(machine.sfp_port[machine.is_sfp[i]-1].pin_detect)) {
|
||||||
reg_read_m(RTL837X_REG_GPIO_00_31_INPUT);
|
print_string("SFP IN\t");
|
||||||
if (!(sfr_data[0] & 0x40)) {
|
|
||||||
print_string("SFP OK\t");
|
|
||||||
} else {
|
|
||||||
print_string("NO SFP\t");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
reg_read_m(RTL837X_REG_GPIO_32_63_INPUT);
|
print_string("NO SFP\t");
|
||||||
if (!(sfr_data[1] & 0x04)) {
|
|
||||||
print_string("SFP OK\t");
|
|
||||||
} else {
|
|
||||||
print_string("NO SFP\t");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+98
-6
@@ -807,7 +807,7 @@ uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||||
sfr_mask_data(1, 0xfc, machine.sfp_port[slot].i2c == 0 ? SCL_PIN << 5 | SDA_PIN_0 << 2 : SCL_PIN << 5 | SDA_PIN_1 << 2 );
|
sfr_mask_data(1, 0xfc, machine.sfp_port[slot].i2c_bus.scl << 5 | machine.sfp_port[slot].i2c_bus.sda << 2);
|
||||||
reg_write_m(RTL837X_REG_I2C_CTRL);
|
reg_write_m(RTL837X_REG_I2C_CTRL);
|
||||||
|
|
||||||
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
|
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
|
||||||
@@ -1009,6 +1009,59 @@ bool gpio_pin_test(uint8_t pin)
|
|||||||
return sfr_data[3-((pin >> 3) & 3)] & (1 << (pin & 7));
|
return sfr_data[3-((pin >> 3) & 3)] & (1 << (pin & 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gpio_mux_setup(uint8_t pin)
|
||||||
|
{
|
||||||
|
// Some GPIOs require setting MUX registers to enable GPIO
|
||||||
|
if (pin == 36) {
|
||||||
|
reg_bit_set(RTL837X_PIN_MUX_1, 30);
|
||||||
|
} else if ( pin == 50 ) {
|
||||||
|
// Bit 15-16 0b00 -> GPIO
|
||||||
|
reg_read_m(RTL837X_PIN_MUX_1);
|
||||||
|
sfr_mask_data(1, 0x80, 0x00);
|
||||||
|
sfr_mask_data(2, 0x01, 0x00);
|
||||||
|
reg_write_m(RTL837X_PIN_MUX_1);
|
||||||
|
} else if ( pin == 51 ) {
|
||||||
|
// Bit 17-18 0b00 -> GPIO
|
||||||
|
reg_read_m(RTL837X_PIN_MUX_1);
|
||||||
|
sfr_mask_data(2, 0x06, 0x00);
|
||||||
|
reg_write_m(RTL837X_PIN_MUX_1);
|
||||||
|
} else if ( pin == 54 ) {
|
||||||
|
reg_bit_clear(RTL837X_PIN_MUX_2, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup a GPIO pin as input
|
||||||
|
* pin: GPIO pin number 0-63
|
||||||
|
*/
|
||||||
|
void gpio_input_setup(uint8_t pin) {
|
||||||
|
gpio_mux_setup(pin);
|
||||||
|
reg_bit_clear(pin < 32 ? RTL837X_REG_GPIO_00_31_DIRECTION : RTL837X_REG_GPIO_32_63_DIRECTION, (pin % 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup a GPIO pin as output
|
||||||
|
* pin: GPIO pin number 0-63
|
||||||
|
*/
|
||||||
|
void gpio_output_setup(uint8_t pin) {
|
||||||
|
gpio_mux_setup(pin);
|
||||||
|
// Default output to low
|
||||||
|
reg_bit_clear(pin < 32 ? RTL837X_REG_GPIO_00_31_OUTPUT : RTL837X_REG_GPIO_32_63_OUTPUT, (pin % 32));
|
||||||
|
reg_bit_set(pin < 32 ? RTL837X_REG_GPIO_00_31_DIRECTION : RTL837X_REG_GPIO_32_63_DIRECTION, (pin % 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inititalize SFP GPIOs */
|
||||||
|
void setup_sfp_gpio(void)
|
||||||
|
{
|
||||||
|
for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) {
|
||||||
|
gpio_input_setup(machine.sfp_port[sfp].pin_detect);
|
||||||
|
gpio_input_setup(machine.sfp_port[sfp].pin_los);
|
||||||
|
if (machine.sfp_port[sfp].pin_tx_disable != 0xFF) {
|
||||||
|
gpio_output_setup(machine.sfp_port[sfp].pin_tx_disable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void handle_sfp(void)
|
void handle_sfp(void)
|
||||||
{
|
{
|
||||||
@@ -1538,7 +1591,6 @@ void led_config(void)
|
|||||||
reg_write_m(RTL837X_REG_LED3_0_SET1);
|
reg_write_m(RTL837X_REG_LED3_0_SET1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rtl8373_revision(void)
|
void rtl8373_revision(void)
|
||||||
{
|
{
|
||||||
reg_read_m(RTL837X_REG_CHIP_INFO);
|
reg_read_m(RTL837X_REG_CHIP_INFO);
|
||||||
@@ -1811,11 +1863,50 @@ void setup_i2c(void)
|
|||||||
|
|
||||||
REG_SET(RTL837X_REG_I2C_CTRL2, 0);
|
REG_SET(RTL837X_REG_I2C_CTRL2, 0);
|
||||||
|
|
||||||
// HW Control register, enable I2C?
|
// HW Control register, enable I2C depending on PIN configuration
|
||||||
reg_read_m(RTL837X_PIN_MUX_1);
|
reg_read_m(RTL837X_PIN_MUX_1);
|
||||||
sfr_mask_data(3, 0x20, 0x00); // Clear bit 29
|
for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) {
|
||||||
sfr_mask_data(0, 0x60, 0x40); // Set bits 5-6 to 0b10
|
const uint8_t scl_bus = machine.sfp_port[sfp].i2c_bus.scl;
|
||||||
reg_write_m(RTL837X_PIN_MUX_1);
|
const uint8_t sda_bus = machine.sfp_port[sfp].i2c_bus.sda;
|
||||||
|
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');
|
||||||
|
if (scl_bus == 3) {
|
||||||
|
// Bit 5-6 0b10 -> SCL (implies enabled SDA on bus 3)
|
||||||
|
sfr_mask_data(0, 0x60, 0x40);
|
||||||
|
} else if (scl_bus == 2) {
|
||||||
|
// Bit 15-16 0b01 -> SCL
|
||||||
|
sfr_mask_data(1, 0x80, 0x80);
|
||||||
|
sfr_mask_data(2, 0x01, 0x00);
|
||||||
|
} else if (scl_bus == 1) {
|
||||||
|
// Bit 11-12 0b01 -> SCL
|
||||||
|
sfr_mask_data(1, 0x18, 0x08);
|
||||||
|
} else if (scl_bus == 0) {
|
||||||
|
// Bit 7-8 0b01 -> SCL
|
||||||
|
sfr_mask_data(0, 0x80, 0x80);
|
||||||
|
sfr_mask_data(1, 0x01, 0x00);
|
||||||
|
} else {
|
||||||
|
print_string("Invalid SCL bus number: "); print_byte(scl_bus); write_char('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sda_bus == 4) {
|
||||||
|
// Bit 29 0b0 -> SDA
|
||||||
|
sfr_mask_data(3, 0x20, 0x00);
|
||||||
|
} else if (sda_bus == 3) {
|
||||||
|
// Bit 5-6 0b10 -> SDA (implies enabled SCL on bus 3)
|
||||||
|
sfr_mask_data(0, 0x60, 0x40);
|
||||||
|
} else if (sda_bus == 2) {
|
||||||
|
// Bit 17-18 0b01 -> SDA
|
||||||
|
sfr_mask_data(2, 0x06, 0x02);
|
||||||
|
} else if (sda_bus == 1) {
|
||||||
|
// Bit 13-14 0b01 -> SDA
|
||||||
|
sfr_mask_data(1, 0x60, 0x20);
|
||||||
|
} else if (sda_bus == 0) {
|
||||||
|
// Bit 9-10 0b01 -> SDA
|
||||||
|
sfr_mask_data(1, 0x06, 0x02);
|
||||||
|
} else {
|
||||||
|
print_string("Invalid SDA bus number: "); print_byte(sda_bus); write_char('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reg_write_m(RTL837X_PIN_MUX_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2009,6 +2100,7 @@ void bootloader(void)
|
|||||||
management_vlan = 0; // Disabled
|
management_vlan = 0; // Disabled
|
||||||
|
|
||||||
setup_i2c();
|
setup_i2c();
|
||||||
|
setup_sfp_gpio();
|
||||||
|
|
||||||
print_string(greeting);
|
print_string(greeting);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -142,7 +142,7 @@ static __xdata u8_t tmpage;
|
|||||||
void
|
void
|
||||||
uip_arp_init(void) __banked
|
uip_arp_init(void) __banked
|
||||||
{
|
{
|
||||||
print_string("uip_arp_init called");
|
print_string("uip_arp_init called\n");
|
||||||
for(uint8_t i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
for(uint8_t i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||||
memset(arp_table[i].ipaddr, 0, 4);
|
memset(arp_table[i].ipaddr, 0, 4);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user