From 48f28ae7ff9dde93ba0032339763036df0ab0832 Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Fri, 18 Sep 2026 18:28:13 +0200 Subject: [PATCH 1/2] temp: read the on-chip thermal sensor The chip has a pair of thermal meters and nothing was reading them. This adds a `temp` command that prints the current reading next to the one taken at power-on. The result register at 0x340 splits a 19 bit value across two fields: bits 18:3 live in the low 16 bits, bits 2:0 in bits 18:16, with the sign at bit 18, degrees in 17:10 and a fraction below. The nice part of that layout is that the degrees fall out of a shift of the low half, so the conversion stays 16 bit. The meter comes out of reset latched: the register keeps whatever was measured when the board powered up and then never moves. Four samples 40 s apart came back identical down to the raw ADC, and 0x340 matched the power-on register at 0x350. Clearing bit 2 of the control register at 0x338 during init is what makes it live. Measured on an SWTGW218AS: 58.7 to 59.5 C while running, with the power-on register still showing the 49.2 C it started from. For what it is worth, the scale lines up three ways: the threshold register reads -40 and +125, the slope from warm-up works out at 4450 LSB/C, and the slope between the two meters at 4388 LSB/C. We only read the meter that is up after boot. The other sits in reset with no coefficients, so it would just repeat its power-on value. Costs 231 bytes in BANK2. --- cmd_parser.c | 28 ++++++++++++++++++++++++++++ rtl837x_init.c | 12 ++++++++++++ rtl837x_regs.h | 7 +++++++ 3 files changed, 47 insertions(+) diff --git a/cmd_parser.c b/cmd_parser.c index d4c4df8b..2677fb5a 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -1157,6 +1157,32 @@ err: } +static void print_temperature(uint16_t reg) +{ + int16_t v; + + reg_read(reg); + v = SFR_DATA_U16; + if (v < 0) { + write_char('-'); + v = -v; + } + itoa(v >> 7); + write_char('.'); + itoa(((v & 0x7f) * 10) >> 7); + print_string(" C\n"); +} + + +void parse_temp(void) +{ + print_string("\nChip temperature: "); + print_temperature(RTL837X_TM_RESULT); + print_string("At power-on: "); + print_temperature(RTL837X_TM_RESULT_POWERON); +} + + void parse_sdsget(void) { __xdata uint8_t sds_id, page, reg, hex_size; @@ -1883,6 +1909,8 @@ void cmd_parser(void) __banked parse_eee(); } else if (cmd_compare(0, "bw")) { parse_bw(); + } else if (cmd_compare(0, "temp")) { + parse_temp(); } else if (cmd_compare(0, "version")) { print_sw_version(); } else if (cmd_compare(0, "time")) { diff --git a/rtl837x_init.c b/rtl837x_init.c index 6b24843b..5cb9df1a 100644 --- a/rtl837x_init.c +++ b/rtl837x_init.c @@ -92,8 +92,18 @@ void static sds_init(void) } +void static tm_init(void) +{ + reg_read_m(RTL837X_TM_CTRL2); + sfr_mask_data(0, TM_CTRL2_EN_LATCH, 0); + reg_write_m(RTL837X_TM_CTRL2); +} + + void rtl8373_init(void) __banked { + tm_init(); + print_string("\nrtl8373_init called\n"); // r65d8:3ffbedff R65d8-3ffbedff @@ -191,6 +201,8 @@ void rtl8373_init(void) __banked void rtl8372_init(void) __banked { + tm_init(); + print_string("\nrtl8372_init called\n"); sds_init(); diff --git a/rtl837x_regs.h b/rtl837x_regs.h index 37a7e99d..ba2d7eb1 100644 --- a/rtl837x_regs.h +++ b/rtl837x_regs.h @@ -9,6 +9,13 @@ #define RESET_SOC_BIT 0 #define RESET_NIC_BIT 2 +#define RTL837X_TM_CTRL2 0x0338 +#define TM_CTRL2_EN_LATCH 0x04 +#define RTL837X_TM_RESULT 0x0340 +#define RTL837X_TM_RESULT_POWERON 0x0350 +// Temperature: 19 bit value, bits 18:3 in the low 16 bits of the register, +// bits 2:0 in bits 18:16. Bit 18 signed, bits 17:10 degrees C, bits 9:0 fraction. + #define RTL837X_REG_HW_CONF 0x6040 // Bits 4 & 5: CLOCK DIVIDER from 125MHz for Timer From 52b1d1a4eaf98e92c17988a3f88f8d6d1bef18cb Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Fri, 18 Sep 2026 18:28:13 +0200 Subject: [PATCH 2/2] web: show the chip temperature in the System page The row sits between Hardware and Flash. The firmware sends the formatted string rather than the raw register, since the System table prints its values as they arrive. Costs 186 bytes in BANK1. --- html/app.js | 8 ++++---- httpd/page_impl.c | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/html/app.js b/html/app.js index 0a50b322..a58bdec4 100644 --- a/html/app.js +++ b/html/app.js @@ -15,7 +15,7 @@ c_full:"full",c_half:"half",c_devices:"devices",c_yes:"yes",c_no:"no", d_ports:"Ports",d_ports_h:"click a port for details",d_system:"System",d_traffic:"Traffic", d_traffic_h:"packets/s, live",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX bad",d_rxbad:"RX bad", i_host:"Hostname",i_ip:"IP address",i_mask:"Netmask",i_gw:"Gateway",i_mac:"MAC",i_fw:"Firmware", -i_built:"Built",i_hw:"Hardware",i_flash:"Flash",i_syslog:"Syslog", +i_built:"Built",i_hw:"Hardware",i_temp:"Temperature",i_flash:"Flash",i_syslog:"Syslog", p_state:"State",p_disabled:"disabled",p_up:"up",p_txgb:"TX good / bad",p_rxgb:"RX good / bad", p_pkts:"pkts",p_module:"Module",p_temp:"Temperature",p_vcc:"Vcc",p_txbias:"TX bias",p_txpower:"TX power", p_rxpower:"RX power",p_txfault:"TX fault",p_txdis:"TX disabled",p_rxlos:"RX LOS",p_adv:"Advertising", @@ -126,7 +126,7 @@ c_full:"全二重",c_half:"半二重",c_devices:"デバイス",c_yes:"はい",c_ d_ports:"ポート",d_ports_h:"ポートをクリックすると詳細を表示",d_system:"システム",d_traffic:"トラフィック", d_traffic_h:"パケット/秒、リアルタイム",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 異常",d_rxbad:"RX 異常", i_host:"ホスト名",i_ip:"IP アドレス",i_mask:"ネットマスク",i_gw:"ゲートウェイ",i_mac:"MAC",i_fw:"ファームウェア", -i_built:"ビルド日",i_hw:"ハードウェア",i_flash:"フラッシュ",i_syslog:"Syslog", +i_built:"ビルド日",i_hw:"ハードウェア",i_temp:"温度",i_flash:"フラッシュ",i_syslog:"Syslog", p_state:"状態",p_disabled:"無効",p_up:"アップ",p_txgb:"TX 正常 / 異常",p_rxgb:"RX 正常 / 異常", p_pkts:"pkts",p_module:"モジュール",p_temp:"温度",p_vcc:"電圧",p_txbias:"TX バイアス",p_txpower:"TX 電力", p_rxpower:"RX 電力",p_txfault:"TX 障害",p_txdis:"TX 無効",p_rxlos:"RX 信号ロス",p_adv:"アドバタイズ", @@ -237,7 +237,7 @@ c_full:"全双工",c_half:"半双工",c_devices:"台设备",c_yes:"是",c_no:" d_ports:"端口",d_ports_h:"点击端口查看详情",d_system:"系统",d_traffic:"流量", d_traffic_h:"包/秒,实时",d_txpps:"TX pps",d_rxpps:"RX pps",d_txbad:"TX 错误",d_rxbad:"RX 错误", i_host:"主机名",i_ip:"IP 地址",i_mask:"子网掩码",i_gw:"网关",i_mac:"MAC",i_fw:"固件", -i_built:"构建日期",i_hw:"硬件",i_flash:"Flash",i_syslog:"Syslog", +i_built:"构建日期",i_hw:"硬件",i_temp:"温度",i_flash:"Flash",i_syslog:"Syslog", p_state:"状态",p_disabled:"已禁用",p_up:"已连接",p_txgb:"TX 正常 / 错误",p_rxgb:"RX 正常 / 错误", p_pkts:"个包",p_module:"模块",p_temp:"温度",p_vcc:"供电电压",p_txbias:"TX 偏置电流",p_txpower:"TX 光功率", p_rxpower:"RX 光功率",p_txfault:"TX 故障",p_txdis:"TX 禁用",p_rxlos:"RX 信号丢失",p_adv:"通告能力", @@ -680,7 +680,7 @@ function portDetail(i){ function renderInfo(){ var m=[["i_host","hostname"],["i_ip","ip_address"],["i_mask","ip_netmask"], ["i_gw","ip_gateway"],["i_mac","mac_address"],["i_fw","sw_ver"],["i_built","build_date"], - ["i_hw","hw_ver"],["i_flash","flash_size"],["i_syslog","syslog_server"]]; + ["i_hw","hw_ver"],["i_temp","chip_temp"],["i_flash","flash_size"],["i_syslog","syslog_server"]]; var tb=$("sysinfo");tb.innerHTML=""; m.forEach(function(r){ var v=S.info[r[1]]; diff --git a/httpd/page_impl.c b/httpd/page_impl.c index cb11075c..148ccacb 100644 --- a/httpd/page_impl.c +++ b/httpd/page_impl.c @@ -117,6 +117,23 @@ void string_to_html(__code char *s) while (*s) char_to_html(*s++); } +static void temp_to_html(void) +{ + int16_t v; + + reg_read(RTL837X_TM_RESULT); + v = SFR_DATA_U16; + if (v < 0) { + char_to_html('-'); + v = -v; + } + itoa_html(v >> 7); + char_to_html('.'); + itoa_html(((v & 0x7f) * 10) >> 7); + char_to_html(' '); + char_to_html('C'); +} + uint16_t stat_content(void) { dbg_string("stat_content called\n"); @@ -262,6 +279,8 @@ void send_basic_info(void) slen += strtox(outbuf + slen, BUILD_DATE); slen += strtox(outbuf + slen, "\",\"hw_ver\":\""); slen += strtox(outbuf + slen, machine.machine_name); + slen += strtox(outbuf + slen, "\",\"chip_temp\":\""); + temp_to_html(); slen += strtox(outbuf + slen, "\",\"flash_size\":\""); string_to_html(get_flash_size_str());