Easyi3C is a leading supplier of embedded system tools that simplify the development and debugging of various communication protocols. The company offers a range of products designed to help engineers and developers use I3C/I2C , USB and MIPI, JEDEC, MCTP and other protocols more efficiently.
The TS (temperature sensor) chip is an important chip in DDR5, as shown in the picture above.
DDR5 mainstream chips are equipped with two TS ( Temperature Sensor ) chips, located on both sides of the DIMM board.
Compliant with JEDEC specifications;
supports I²C and I3C serial bus interfaces;
supports PEC (Packet Error Check) and parity functions;
supports bus reset function;
supports in-band interrupt (IBI).
Package: 6-pin WLCSP
RDIMM and LRDIMM memory modules for DDR5 servers
As a slave device of the SPD Hub, the TS can operate on I2C buses with clock frequencies up to 1MHz and I3C buses up to 12.5MHz. The server CPU can communicate with the TS via the SPD Hub to achieve temperature management of the memory modules.
As introduced above, testing the communication of the TS chip on DDR5 memory under I3C is an important new requirement. The added I3C testing brings many new requirements, such as testing CCC commands, IBI, and PEC, etc. The Tower I3C Host Adapter can easily meet these testing needs. We can perform debugging and verification using diagrams similar to the one shown below, easily verifying the chip's various functions, providing timely feedback to design and development teams, and shortening the chip development cycle.
To facilitate testing of DDR5 devices, we have provided dedicated APIs for DDR5 TS, encapsulating complex protocols within these APIs for easy user adoption. Our APIs fully comply with the JEDEC JESD403-1 standard. The relevant APIs are as follows:
For more detailed information, please log in.Easyi3CVisit the official website to download and learn more for free.
Using the APIs provided above, we can build automated test scripts to meet different needs, making it convenient to test various functions. Below is a code example:
# ==========================================================================
# --------------------------------------------------------------------------
# Copyright © 2025 by Easyi3C, Inc.
# All rights reserved.
# --------------------------------------------------------------------------
# ==========================================================================
import sys
from ezi3c.api import *
from ezi3c.utils import hex_string
from ddr5 import Ts0
from ddr5 import Ts1
ez = ez_open()
if not ez:
print("Cannot open Adapter")
sys.exit(-1)
clk = ez_set_bus_clk_freq(ez, 1000, 4000)
print("Cur Clk Freq: {}".format(clk))
ret = ez_set_io_voltage(ez, 1.0)
assert ret == 0, "Faield to set IO voltage"
ts0 = Ts0(ez, hid=0x00)
ts1 = Ts1(ez, hid=0x00)
reg = 28
try:
print("**************************")
print("**TS0 test: LID is : 0x2**")
print("**************************")
ret = ts0.ccc_rstdaa()
assert ret == 0, "Failed to reset DAA: addr:{:02X}".format(ts0.addr)
ret, data = ts0.i2c_read_reg(0, 2)
assert ret == 0 and data == (0x51, 0x11), "Failed to read TS data: addr:{:02X}".format(ts0.addr)
print("TS Data: {}".format(hex_string(data)))
ts0.switch_to_i3c(send_ccc=True)
ret, data = ts0.i3c_read_reg(0, 2)
assert ret == 0 and data == (0x51, 0x11), "Failed to read TS data in I3C mode: addr:{:02X}".format(ts0.addr)
ret = ts0.i3c_write_reg(reg, 0xC0)
assert ret == 0, "Failed to write to TS register: addr:{:02X}".format(ts0.addr)
ret, data = ts0.i3c_read_reg(reg, 1)
assert ret == 0 and data == 0xC0, "Failed to read TS register after write: addr:{:02X}".format(ts0.addr)
print("write read with IBI header")
ret = ts0.i3c_write_reg(reg, 0xb0, with_ibi_header=True)
assert ret == 0, "Failed to write to TS register: addr:{:02X}".format(ts0.addr)
ret, data = ts0.i3c_read_reg(reg, 1, with_ibi_header=True)
assert ret == 0 and data == 0xb0, "Failed to read TS register after write: addr:{:02X}".format(ts0.addr)
print("Inject parity error test")
ret = ts0.i3c_write_reg(28, 0xF0, inject_parity_err=True)
ret, data = ts0.i3c_read_reg(28, 1)
assert ret == 0 and data == 0xb0, "Failed to read TS register after write: addr:{:02X}".format(ts0.addr)
ret = ts0.i3c_write_reg(28, 0xF0)
assert ret == 0, "Failed to write to TS register: addr:{:02X}".format(ts0.addr)
ret, data = ts0.i3c_read_reg(28, 1)
assert ret == 0 and data == 0xF0, "Failed to read TS register after write: addr:{:02X}".format(ts0.addr)
print("Enable PEC then read write register test")
ret = ts0.enable_pec(send_ccc=True)
assert ret == 0, "Failed to enable PEC: addr:{:02X}".format(ts0.addr)
ret, data = ts0.i3c_read_reg(0, 1)
assert ret == 0 and data == 0x51, "Failed to read TS data in I3C mode with PEC: addr:{:02X}".format(ts0.addr)
print("PEC inject error")
ret, data = ts0.i3c_read_reg(0, 1, inject_pec_err=True)
assert data is None
ret = ts0.i3c_write_reg(28, 0xF0)
assert ret == 0, "Failed to write to TS register: addr:{:02X}".format(ts0.addr)
ret, data = ts0.i3c_read_reg(28, 1)
assert ret == 0 and data == 0xF0, "Failed to read TS register after write: addr:{:02X}".format(ts0.addr)
ret, data = ts0.ccc_getstatus()
assert ret == 0, "Failed to get CCC status: addr:{:02X}".format(ts0.addr)
print("CCC Status: {}".format(hex_string(data)))
ret, data = ts0.ccc_devcap()
assert ret == 0 and data == (0x04, 0x00), "Failed to get Device Capabilities: addr:{:02X}".format(ts0.addr)
print("Device Capabilities: {}".format(hex_string(data)))
print("Disable PEC")
ret = ts0.disable_pec(send_ccc=True)
assert ret == 0, "Failed to enable PEC: addr:{:02X}".format(ts0.addr)
print("**************************")
print("**TS1 test: LID is : 0x6**")
print("**************************")
ret = ts1.ccc_rstdaa()
assert ret == 0, "Failed to reset DAA: addr:{:02X}".format(ts1.addr)
ret, data = ts1.i2c_read_reg(0, 2)
assert ret == 0 and data == (0x51, 0x11), "Failed to read TS data: addr:{:02X}".format(ts1.addr)
print("TS Data: {}".format(hex_string(data)))
ts0.switch_to_i3c(send_ccc=True)
ret, data = ts1.i3c_read_reg(0, 2)
assert ret == 0 and data == (0x51, 0x11), "Failed to read TS data in I3C mode: addr:{:02X}".format(ts1.addr)
ret = ts1.i3c_write_reg(reg, 0xC0)
assert ret == 0, "Failed to write to TS register: addr:{:02X}".format(ts1.addr)
ret, data = ts1.i3c_read_reg(reg, 1)
assert ret == 0 and data == 0xC0, "Failed to read TS register after write: addr:{:02X}".format(ts1.addr)
print("write read with IBI header")
ret = ts1.i3c_write_reg(reg, 0xb0, with_ibi_header=True)
assert ret == 0, "Failed to write to TS register: addr:{:02X}".format(ts1.addr)
ret, data = ts1.i3c_read_reg(reg, 1, with_ibi_header=True)
assert ret == 0 and data == 0xb0, "Failed to read TS register after write: addr:{:02X}".format(ts1.addr)
print("Inject parity error test")
ret = ts1.i3c_write_reg(28, 0xF0, inject_parity_err=True)
ret, data = ts1.i3c_read_reg(28, 1)
assert ret == 0 and data == 0xb0, "Failed to read TS register after write: addr:{:02X}".format(ts1.addr)
ret = ts1.i3c_write_reg(28, 0xF0)
assert ret == 0, "Failed to write to TS register: addr:{:02X}".format(ts1.addr)
ret, data = ts1.i3c_read_reg(28, 1)
assert ret == 0 and data == 0xF0, "Failed to read TS register after write: addr:{:02X}".format(ts1.addr)
print("Enable PEC then read write register test")
ret = ts1.enable_pec(send_ccc=True)
assert ret == 0, "Failed to enable PEC: addr:{:02X}".format(ts1.addr)
ret, data = ts1.i3c_read_reg(0, 1)
assert ret == 0 and data == 0x51, "Failed to read TS data in I3C mode with PEC: addr:{:02X}".format(ts1.addr)
print("PEC inject error")
ret, data = ts1.i3c_read_reg(0, 1, inject_pec_err=True)
assert data == None
ret = ts1.i3c_write_reg(28, 0xF0)
assert ret == 0, "Failed to write to TS register: addr:{:02X}".format(ts1.addr)
ret, data = ts1.i3c_read_reg(28, 1)
assert ret == 0 and data == 0xF0, "Failed to read TS register after write: addr:{:02X}".format(ts1.addr)
ret, data = ts1.ccc_getstatus()
assert ret == 0, "Failed to get CCC status: addr:{:02X}".format(ts1.addr)
print("CCC Status: {}".format(hex_string(data)))
ret, data = ts1.ccc_devcap()
assert ret == 0 and data == (0x04, 0x00), "Failed to get Device Capabilities: addr:{:02X}".format(ts1.addr)
print("Device Capabilities: {}".format(hex_string(data)))
print("Disable PEC")
ret = ts1.disable_pec(send_ccc=True)
assert ret == 0, "Failed to enable PEC: addr:{:02X}".format(ts1.addr)
finally:
ts1.ccc_rstdaa()
ez_close(ez)
print("Adapter closed.")Based on our Tower I3C Host Adapter, DDR5 TS can be tested very easily, meeting complex testing needs, building automated testing environments, and shortening the time to market for chips.