mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Fix I2C access code
While the current implementation works for what it is actually used, it is broken when trying to do larger transfers. The length field in the control register has a size of 4 bits. In every transfer, length+1 bytes are read. Thus, each transfer is limited to a maximum of 16 bytes. Add a check for the length, and write the correct value to the register. Also update the loop in "sfp_send_data" to properly increment the output register. Remove the unused special case for a length of 128 bytes.
This commit is contained in:
+8
-7
@@ -175,11 +175,15 @@ void send_sfp_info(uint8_t sfp)
|
|||||||
|
|
||||||
void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len)
|
void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len)
|
||||||
{
|
{
|
||||||
|
// maximum supported transfer size is 16 bytes
|
||||||
|
if (len > 16)
|
||||||
|
return;
|
||||||
|
|
||||||
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
|
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
|
||||||
reg &= 0x7f;
|
reg &= 0x7f;
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | len & 0xf, 0x51 >> 5, (0x51 << 3) & 0xff);
|
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | (len - 1) & 0xf, 0x51 >> 5, (0x51 << 3) & 0xff);
|
||||||
} else {
|
} else {
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | len & 0xf, 0x50 >> 5, (0x50 << 3) & 0xff);
|
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | (len - 1) & 0xf, 0x50 >> 5, (0x50 << 3) & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||||
@@ -196,12 +200,9 @@ 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);
|
||||||
} while (sfr_data[3] & 0x1);
|
} while (sfr_data[3] & 0x1);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < len & 0xf; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
if (!(i & 0x3))
|
if (!(i & 0x3))
|
||||||
reg_read_m(RTL837X_REG_I2C_OUT + (i >> 2));
|
reg_read_m(RTL837X_REG_I2C_OUT + i);
|
||||||
if (len & 0x80)
|
|
||||||
char_to_html(sfr_data[3 - (i & 0x3)]);
|
|
||||||
else
|
|
||||||
byte_to_html(sfr_data[3 - (i & 0x3)]);
|
byte_to_html(sfr_data[3 - (i & 0x3)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -832,9 +832,9 @@ uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
|
|||||||
{
|
{
|
||||||
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
|
if (reg & 0x80) { // Configure SFP readings address (0x51) as I2C device address
|
||||||
reg &= 0x7f;
|
reg &= 0x7f;
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 1, 0x51 >> 5, (0x51 << 3) & 0xff);
|
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 0, 0x51 >> 5, (0x51 << 3) & 0xff);
|
||||||
} else {
|
} else {
|
||||||
REG_WRITE(RTL837X_REG_I2C_CTRL, 0x00, 0x1 << (I2C_MEM_ADDR_WIDTH-16) | 1, 0x50 >> 5, (0x50 << 3) & 0xff);
|
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);
|
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||||
|
|||||||
Reference in New Issue
Block a user