sfp: move the I2C transfer to the banked pins module

sfp_read_reg() sat in rtlplayground.c, so it occupied the common 16 KB
window that every bank shares, even though nothing outside the SFP paths
calls it. That window is the tightest resource in the image:
SWTG024AS_V2_0 and SWTG024AS_A_2_0_1_5C_1SFP had 54 bytes left in it.

rtl837x_pins.c is already in BANK2 and already holds the I2C bus helpers
this function calls, so the transfer belongs there. The function moves
verbatim and becomes __banked; the prototype in rtl837x_common.h says so,
which is what keeps the callers in BANK1 and BANK2 honest.

No behaviour change. The common segment gains 200 bytes on every machine:
159 to 359 free on SWTGW218AS, 54 to 254 on the two variants above.
BANK1 +6 bytes, BANK2 +336. Built on sdcc 4.5.0.
This commit is contained in:
d00f
2026-08-24 02:34:39 +02:00
parent 1d1e33f4d5
commit 9a96c80af2
3 changed files with 45 additions and 40 deletions
+1 -1
View File
@@ -149,7 +149,7 @@ void sleep(uint16_t t);
void write_char_no_syslog(char c); void write_char_no_syslog(char c);
void write_char(char c); void write_char(char c);
void print_reg(uint16_t reg); void print_reg(uint16_t reg);
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg); uint8_t sfp_read_reg(uint8_t slot, uint8_t reg) __banked;
extern __xdata uint8_t sfp_i2c_fail; extern __xdata uint8_t sfp_i2c_fail;
void reg_bit_set(uint16_t reg_addr, char bit); void reg_bit_set(uint16_t reg_addr, char bit);
void reg_bit_clear(uint16_t reg_addr, char bit); void reg_bit_clear(uint16_t reg_addr, char bit);
+44
View File
@@ -1,6 +1,11 @@
#include "rtl837x_pins.h" #include "rtl837x_pins.h"
#include "rtl837x_common.h" #include "rtl837x_common.h"
#include "rtl837x_sfr.h"
#include "rtl837x_regs.h" #include "rtl837x_regs.h"
#include "machine.h"
extern __code const struct machine machine;
extern __xdata uint8_t sfr_data[4];
#pragma codeseg BANK2 #pragma codeseg BANK2
#pragma constseg BANK2 #pragma constseg BANK2
@@ -121,3 +126,42 @@ void gpio_output_setup(uint8_t pin, __xdata uint8_t initial_val) __banked{
reg_bit_set(gpio_direction_reg(pin), (pin % 32)); reg_bit_set(gpio_direction_reg(pin), (pin % 32));
} }
/*
* Read a register of the EEPROM via I2C
*/
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg) __banked
{
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
reg &= 0x7f;
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x51 >> 5, (0x51 << 3) & 0xff);
} else {
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x50 >> 5, (0x50 << 3) & 0xff);
}
reg_read_m(RTL837X_REG_I2C_CTRL);
sfr_mask_data(1, 0xfc, i2c_bus_from_scl_pin(machine.sfp_port[slot].i2c.scl) << 5 | i2c_bus_from_sda_pin(machine.sfp_port[slot].i2c.sda) << 2);
reg_write_m(RTL837X_REG_I2C_CTRL);
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
// Execute I2C Read
reg_bit_set(RTL837X_REG_I2C_CTRL, 0);
// Wait for execution to finish
do {
reg_read_m(RTL837X_REG_I2C_CTRL);
} while (sfr_data[3] & 0x1);
/* Bit 1 is the controller's own failure indication, which the vendor SDK
* looks at and this did not. Without it an unacknowledged address comes
* back as an ordinary byte and the caller cannot tell it from data. */
if (sfr_data[3] & 0x2) {
sfp_i2c_fail = 1;
return 0xff;
}
reg_read_m(RTL837X_REG_I2C_OUT);
return sfr_data[3];
}
-39
View File
@@ -1036,45 +1036,6 @@ void sds_config(uint8_t sds, uint8_t mode)
} }
/*
* Read a register of the EEPROM via I2C
*/
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
{
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
reg &= 0x7f;
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x51 >> 5, (0x51 << 3) & 0xff);
} else {
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x50 >> 5, (0x50 << 3) & 0xff);
}
reg_read_m(RTL837X_REG_I2C_CTRL);
sfr_mask_data(1, 0xfc, i2c_bus_from_scl_pin(machine.sfp_port[slot].i2c.scl) << 5 | i2c_bus_from_sda_pin(machine.sfp_port[slot].i2c.sda) << 2);
reg_write_m(RTL837X_REG_I2C_CTRL);
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
// Execute I2C Read
reg_bit_set(RTL837X_REG_I2C_CTRL, 0);
// Wait for execution to finish
do {
reg_read_m(RTL837X_REG_I2C_CTRL);
} while (sfr_data[3] & 0x1);
/* Bit 1 is the controller's own failure indication, which the vendor SDK
* looks at and this did not. Without it an unacknowledged address comes
* back as an ordinary byte and the caller cannot tell it from data. */
if (sfr_data[3] & 0x2) {
sfp_i2c_fail = 1;
return 0xff;
}
reg_read_m(RTL837X_REG_I2C_OUT);
return sfr_data[3];
}
/* /*
* Adds TX Header to uip_buf and calls nic_tx_packet to send the packet * Adds TX Header to uip_buf and calls nic_tx_packet to send the packet
* over the wire * over the wire