mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Merge pull request #183 from janh/fix-i2c-and-sfp-ddm
Fix I2C access and SFP diagnostic monitoring in web interface
This commit is contained in:
+85
-5
@@ -40,6 +40,82 @@ function drawPorts() {
|
||||
}
|
||||
}
|
||||
|
||||
function parseUint16(val) {
|
||||
return parseInt(val, 16) & 0xffff;
|
||||
}
|
||||
|
||||
function parseInt16(val) {
|
||||
let valInt = parseInt(val, 16);
|
||||
let num = valInt & 0x7fff;
|
||||
if (valInt & 0x8000) {
|
||||
return num - 0x8000;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
function applyCalibrationSlopeOffset(val, cal) {
|
||||
if (typeof cal !== 'string') {
|
||||
return val;
|
||||
}
|
||||
if (cal.startsWith("0x")) {
|
||||
cal = cal.substring(2);
|
||||
}
|
||||
if (cal.length != 8) {
|
||||
return val;
|
||||
}
|
||||
let slope = parseUint16(cal.substring(0, 4)) / 256;
|
||||
let offset = parseInt16(cal.substring(4, 8));
|
||||
return slope * val + offset;
|
||||
}
|
||||
|
||||
function applyRxPowerCalibration(val, cal) {
|
||||
if (typeof cal !== 'string') {
|
||||
return val;
|
||||
}
|
||||
if (cal.startsWith("0x")) {
|
||||
cal = cal.substring(2);
|
||||
}
|
||||
if (cal.length != 40) {
|
||||
return val;
|
||||
}
|
||||
let bytes = cal.match(/.{1,2}/g).map(function (x) { return parseInt(x, 16); });
|
||||
let view = new DataView(new Uint8Array(bytes).buffer);
|
||||
return view.getFloat32(0) * Math.pow(val, 4)
|
||||
+ view.getFloat32(4) * Math.pow(val, 3)
|
||||
+ view.getFloat32(8) * Math.pow(val, 2)
|
||||
+ view.getFloat32(12) * val
|
||||
+ view.getFloat32(16);
|
||||
}
|
||||
|
||||
function decodeSfpTemp(val, cal) {
|
||||
let temp = parseInt16(val);
|
||||
return applyCalibrationSlopeOffset(temp, cal) / 256;
|
||||
}
|
||||
|
||||
function decodeSfpVcc(val, cal) {
|
||||
let vcc = parseUint16(val);
|
||||
return applyCalibrationSlopeOffset(vcc, cal) / 10000;
|
||||
}
|
||||
|
||||
function decodeSfpTxBias(val, cal) {
|
||||
let bias = parseUint16(val);
|
||||
return applyCalibrationSlopeOffset(bias, cal) / 500;
|
||||
}
|
||||
|
||||
function decodeSfpTxPower(val, cal) {
|
||||
let txPower = parseUint16(val);
|
||||
return applyCalibrationSlopeOffset(txPower, cal) / 10000;
|
||||
}
|
||||
|
||||
function decodeSfpRxPower(val, cal) {
|
||||
let rxPower = parseUint16(val);
|
||||
return applyRxPowerCalibration(rxPower, cal) / 10000;
|
||||
}
|
||||
|
||||
function convertPowerTodBm(val) {
|
||||
return 10 * Math.log10(val);
|
||||
}
|
||||
|
||||
function update(callback) {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
@@ -98,13 +174,17 @@ function update(callback) {
|
||||
iHTML += "<tr><td>Model</td><td>:</td><td>" + p.sfp_model + "</td></tr>";
|
||||
iHTML += "<tr><td>Serial</td><td>:</td><td>" + p.sfp_serial + "</td></tr>";
|
||||
if (hasExtendedStatus) {
|
||||
iHTML += "<tr><td>Temp</td><td>:</td><td>" + (Number(p.sfp_temp) >> 8) + "." + ((Number(p.sfp_temp) & 0xff)/256.0 * 100).toFixed(0) + " ℃</td></tr>";
|
||||
iHTML += "<tr><td>Vcc</td><td>:</td><td>" + (Number(p.sfp_vcc) / 10000.0).toFixed(2) + " V</td></tr>";
|
||||
let txPower = decodeSfpTxPower(p.sfp_txpower, p.sfp_txpower_cal);
|
||||
let txPowerdBm = convertPowerTodBm(txPower);
|
||||
let rxPower = decodeSfpRxPower(p.sfp_rxpower, p.sfp_rxpower_cal);
|
||||
let rxPowerdBm = convertPowerTodBm(rxPower);
|
||||
iHTML += "<tr><td>Temp</td><td>:</td><td>" + decodeSfpTemp(p.sfp_temp, p.sfp_temp_cal).toFixed(2) + " ℃</td></tr>";
|
||||
iHTML += "<tr><td>Vcc</td><td>:</td><td>" + decodeSfpVcc(p.sfp_vcc, p.sfp_vcc_cal).toFixed(2) + " V</td></tr>";
|
||||
iHTML += "<tr><td>TX-Fault</td><td>:</td><td>" + (Boolean(Number(p.sfp_state) & 0x4)) + "</td></tr>";
|
||||
iHTML += "<tr><td>TX-Disabled</td><td>:</td><td>" + (Boolean(Number(p.sfp_state) & 0x80)) + "</td></tr>";
|
||||
iHTML += "<tr><td>TX-Bias</td><td>:</td><td>" + (Number(p.sfp_txbias) / 500.0).toFixed(1) + " mA</td></tr>";
|
||||
iHTML += "<tr><td>TX-Power</td><td>:</td><td>" + (Number(p.sfp_txpower) / 10.0).toFixed(0) + " mW</td></tr>";
|
||||
iHTML += "<tr><td>RX-Power</td><td>:</td><td>" + (Number(p.sfp_rxpower) / 10.0).toFixed(0) + " mW</td></tr>";
|
||||
iHTML += "<tr><td>TX-Bias</td><td>:</td><td>" + decodeSfpTxBias(p.sfp_txbias, p.sfp_txbias_cal).toFixed(1) + " mA</td></tr>";
|
||||
iHTML += "<tr><td>TX-Power</td><td>:</td><td>" + txPower.toFixed(3) + " mW / " + txPowerdBm.toFixed(2) + " dBm</td></tr>";
|
||||
iHTML += "<tr><td>RX-Power</td><td>:</td><td>" + rxPower.toFixed(3) + " mW / " + rxPowerdBm.toFixed(2) + " dBm</td></tr>";
|
||||
}
|
||||
// Not all devices & modules have LOS pin...
|
||||
const rx_los_pin = p.sfp_los !== null ? Boolean(Number(p.sfp_los)) : null;
|
||||
|
||||
+22
-9
@@ -175,11 +175,15 @@ void send_sfp_info(uint8_t sfp)
|
||||
|
||||
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
|
||||
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 {
|
||||
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);
|
||||
@@ -196,13 +200,10 @@ void sfp_send_data(uint8_t slot, uint8_t reg, uint8_t len)
|
||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||
} 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))
|
||||
reg_read_m(RTL837X_REG_I2C_OUT + (i >> 2));
|
||||
if (len & 0x80)
|
||||
char_to_html(sfr_data[3 - (i & 0x3)]);
|
||||
else
|
||||
byte_to_html(sfr_data[3 - (i & 0x3)]);
|
||||
reg_read_m(RTL837X_REG_I2C_OUT + i);
|
||||
byte_to_html(sfr_data[3 - (i & 0x3)]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,7 +641,6 @@ void send_status(void)
|
||||
slen += strtox(outbuf + slen,",\"sfp_options\":\"0x");
|
||||
byte_to_html(sfp_options[machine.is_sfp[i]-1]);
|
||||
if (sfp_options[machine.is_sfp[i]-1] & 0x40) {
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 92, 1);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_temp\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 224, 2);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_vcc\":\"0x");
|
||||
@@ -651,6 +651,19 @@ void send_status(void)
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 230, 2);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_rxpower\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 232, 2);
|
||||
if (sfp_options[machine.is_sfp[i]-1] & 0x10) {
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_temp_cal\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 212, 4);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_vcc_cal\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 216, 4);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_txbias_cal\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 204, 4);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_txpower_cal\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 208, 4);
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_rxpower_cal\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 184, 16);
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 200, 4);
|
||||
}
|
||||
slen += strtox(outbuf + slen,"\",\"sfp_state\":\"0x");
|
||||
sfp_send_data(machine.is_sfp[i] - 1, 238, 1);
|
||||
}
|
||||
|
||||
+2
-2
@@ -892,9 +892,9 @@ 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) | 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 {
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user