mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
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:
@@ -1,6 +1,11 @@
|
||||
#include "rtl837x_pins.h"
|
||||
#include "rtl837x_common.h"
|
||||
#include "rtl837x_sfr.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 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));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user