mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
sfp: notice when an I2C read fails
sfp_read_reg() waited for the transfer to finish and then read the output register whatever the outcome, so an address nothing acknowledged came back as an ordinary byte and no caller could tell it apart from data. The vendor SDK looks at bit 1 of the control register for exactly this, and we did not. A failure now sets sfp_i2c_fail and the read returns 0xff, which is already the value sfp_apply_quirks() reads as either a failed transfer or a voltage the spec does not allow, so that test starts being true when it should be. The insertion path and the sfp command clear the flag first and say so afterwards, rather than presenting the bytes as though they came from the module. What this deliberately does not do is act on the failure. Skipping sds_config() when the rate read failed is the obvious next step, but a module that raises the bit spuriously would then never be configured at all, which is worse than what happens today, and I have no way to judge how often the bit is right. That decision belongs with someone holding the board. It also leaves the other half of the rewrite alone, reading and writing up to sixteen bytes per transaction. doc/sfp.md describes only the single byte path and does not name a length field, and guessing at a register I cannot test is how the last attempt at this function went wrong. 40 bytes of the common segment, 51 of BANK2 and 1 of xdata, nothing in BANK1 or internal RAM. Built for SWTGW218AS and KP_9000_6XHML_X2 on sdcc 4.5.0. Not tested on hardware: shorting the clock line, as in #342, should now print the failure line instead of a plausible looking byte.
This commit is contained in:
@@ -150,6 +150,7 @@ void write_char_no_syslog(char c);
|
||||
void write_char(char c);
|
||||
void print_reg(uint16_t reg);
|
||||
uint8_t sfp_read_reg(uint8_t slot, uint8_t reg);
|
||||
extern __xdata uint8_t sfp_i2c_fail;
|
||||
void reg_bit_set(uint16_t reg_addr, char bit);
|
||||
void reg_bit_clear(uint16_t reg_addr, char bit);
|
||||
uint8_t reg_bit_test(uint16_t reg_addr, char bit);
|
||||
|
||||
Reference in New Issue
Block a user