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] 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