SoC typically include an embedded sensor device for monitoring the temperature. This device is also known as the thermal diode. Thermal diodes are commonly used in CPUs and GPUs. They are simple, reliable and allow remote monitoring of the die temperature. The diode is forward biased with a fixed current running throw it (1uA – 100uA). Any variation in temperature causes the voltage to vary accordingly, this allows us to extrapolate the temperature by measuring the voltage.
ADT7473 chips offer a solution for reading the temperature and returning it as a digital value in degrees Celsius. This and other capabilities such as controlling up to 4 fans and other thermal protection features. Also worth noting, ADT7473 supports I2C serial bus interface, which will be the way to configure and read the values.
For more information about ADT7473 see datasheet.
ADT7473 in PCB design
The following is a board schematic created in KiCad, showing a typical connection of ADT7473 for thermal monitoring purposes.
Reading temperature over I2C bus
To read the temperature from the ADT7473 device you need read/write access to the I2C bus. Typically this is another master I2C device on the board.
We will assume that you have such a device, as well as, an API that allows you to perform read/write on the bus.
def read_i2c(dev_add: int, reg_addr: int): def write_i2c(dev_add: int, reg_addr: int, data: int):
The following function will set the temperature offset to -10 degrees, return the the temperature value and the extended resolution in degrees Celsius.
def read_adt7473(offset=0xf6): """ @inuput: offset -> temperature offset in 8bit two's compliment format default value = 0xf6 = -10 """ dev_add = 0x2d temp_read_addr = 0x25 # 0x27 for remote 2 temp_offset_addr = 0x70 # 0x72 for remote 2 write_i2c(dev_add, temp_offset_addr, offset) # to read the value after the decimal point we will read bits <3:2> # for remote 2 we need to extract bits <7:6> extended_resolution = read_i2c(devadd, 0x77) extended_resolution = (extended_resolution >> 2) & 0x3 remote_offset_63 = read_i2c(devadd, temp_read_addr) return (remote_offset_63 - 64) + 0.25 * ext_res