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.
This commit is contained in:
d00f committed 2026-09-18 18:28:13 +02:00
1 parent a62866a93a
commit 48f28ae7ff
3 files changed
+47

No files matched your search

+28
View File
@@ -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) void parse_sdsget(void)
{ {
__xdata uint8_t sds_id, page, reg, hex_size; __xdata uint8_t sds_id, page, reg, hex_size;
@@ -1883,6 +1909,8 @@ void cmd_parser(void) __banked
parse_eee(); parse_eee();
} else if (cmd_compare(0, "bw")) { } else if (cmd_compare(0, "bw")) {
parse_bw(); parse_bw();
} else if (cmd_compare(0, "temp")) {
parse_temp();
} else if (cmd_compare(0, "version")) { } else if (cmd_compare(0, "version")) {
print_sw_version(); print_sw_version();
} else if (cmd_compare(0, "time")) { } else if (cmd_compare(0, "time")) {
+12
View File
@@ -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 void rtl8373_init(void) __banked
{ {
tm_init();
print_string("\nrtl8373_init called\n"); print_string("\nrtl8373_init called\n");
// r65d8:3ffbedff R65d8-3ffbedff // r65d8:3ffbedff R65d8-3ffbedff
@@ -191,6 +201,8 @@ void rtl8373_init(void) __banked
void rtl8372_init(void) __banked void rtl8372_init(void) __banked
{ {
tm_init();
print_string("\nrtl8372_init called\n"); print_string("\nrtl8372_init called\n");
sds_init(); sds_init();
+7
View File
@@ -9,6 +9,13 @@
#define RESET_SOC_BIT 0 #define RESET_SOC_BIT 0
#define RESET_NIC_BIT 2 #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 #define RTL837X_REG_HW_CONF 0x6040
// Bits 4 & 5: CLOCK DIVIDER from 125MHz for Timer // Bits 4 & 5: CLOCK DIVIDER from 125MHz for Timer