Blog
Technology Sharing
Tower I3C Host Adapter Usage Example (21)hits:10


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.



Testing DDR5 RCD based on Tower I3C Host Adapter (5)


2. Testing DDR5 RCD I3C Based on Tower I3C Host Adapter


Based on the JEDEC Spec I3C write and read formats excerpted in the previous section, we have summarized the following APIs specifically for DDR5 RCD I3C:

i3c_1.png

i3c_2.png


With our supported APIs, you can easily test DDR5 RCD I3C.


3. test environment setup


The test environment is set up using the Tower I3C Host Adapter as shown in the following figure:

tower.png


First, connect the Easyi3C Host I3C/I2C adapter to your computer using a USB Type-C cable, install the necessary USB drivers, and then connect it to the target using the cable provided by the manufacturer.


4. API Installation


from Official website Download the corresponding software package: Easyi3C Tower I3C Host Adapter DDR5 Device API.

Easyi3C provides a set of Python APIs for DDR5 devices. Users must install Python before using the API. Easyi3C supports Python versions 3.8 to 3.13.

Notes: The Easyi3C DDR5 device API is based on the Easyi3C standard API. Before installation, you must ensure that the standard Easyi3C API package is installed.

The Easyi3C DDR5 device API is provided as a Python wheel package. Its name is:

1.png


After installing Python on the user's computer, execute the following command to install the Easyi3C DDR5 device package API:

2.png


Notes: The red box indicates the corresponding Python version. For example, if your Python version is 3.8, you must install ddr5-xxx-cp38-cp38-win-amd64.whl.

The above commands are also used to upgrade to new versions of the API package.

To uninstall the package, please run:

3.png


5. I3C Test Reference Code:


Using the wheel package installed above, perform I3C protocol testing through the supported APIs.

# ==========================================================================
# Easyi3C Tower USB to I3C Host Adapter Interface Library
# --------------------------------------------------------------------------
# Copyright © 2026 by Easyi3C, Inc.
# All rights reserved.
# --------------------------------------------------------------------------
# ==========================================================================


import sys
from ezi3c.api import *

from ddr5 import Rcd
from ddr5 import Pmic0
import time
from ezi3c import crc

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"

hid = 7

pmic0 = Pmic0(ez, hid=hid)
rcd = Rcd(ez, hid=hid)

try:
    print("switch to i3c")
    rcd.disable_pec(send_ccc=True)
    rcd.switch_to_i3c(send_ccc=True)

    print("I3C Block Mode Read Test")
    channel = 0
    page = 3
    device_id_reg = 0x6c
    DEVICE_ID = (0x00, 0x51)
    ret, data = rcd.i3c_block_read(channel, page, device_id_reg)
    assert data[2:] == DEVICE_ID

    print("I3C Block Mode Read Test with PEC")
    rcd.enable_pec(send_ccc=True)  # I3C enable pec need send ccc devctrl
    ret, data = rcd.i3c_block_read(channel, page, device_id_reg)
    assert data[2:] == DEVICE_ID
    rcd.disable_pec(send_ccc=True)  # I3C disable pec need send ccc devctrl

    print("I3C Block Mode Read Test with PEC not internal pec check")
    rcd.enable_pec(send_ccc=True)  # I3C enable pec need send ccc devctrl
    ret, data = rcd.i3c_block_read(channel, page, device_id_reg, pec_check_internal=False)
    # pec_check_internal=False, data last Byte is pec valve, check read data pec value as follows:
    # Please see Jedec Rcd spec define.
    pec_value = data[-1]
    Byte_count = 5
    status = 1
    pec_bytes = [rcd.addr << 1 | 0x01] + [Byte_count] + [status] + list(data[0:4])
    pec_cal = crc.crc(pec_bytes)
    if pec_value != pec_cal:
        print(f"PEC mismatch: expected {pec_cal}, got {pec_value}.")
    assert data[2:4] == DEVICE_ID
    rcd.disable_pec(send_ccc=True)  # I3C disable pec need send ccc devctrl

    print("I3C Block Mode Write Byte Test")
    channel = 0
    page = 0
    reg = 0x40
    value = 0x50
    ret = rcd.i3c_block_write_byte(channel, page, reg, value)
    ret, data = rcd.i3c_block_read(channel, page, reg)
    assert value == data[3]

    print("I3C Block Mode Write Byte Test with PEC")
    rcd.enable_pec(send_ccc=True)     # I3C enable pec need send ccc devctrl
    value = 0x51
    ret = rcd.i3c_block_write_byte(channel, page, reg, value)
    ret, data = rcd.i3c_block_read(channel, page, reg)
    assert value == data[3]
    rcd.disable_pec(send_ccc=True)    # I3C enable pec need send ccc devctrl

    print("I3C Block Mode Write Word Test")
    value = 0x5152
    ret = rcd.i3c_block_write_word(channel, page, reg, value)
    ret, data = rcd.i3c_block_read(channel, page, reg)
    assert value == data[2] << 8 | data[3]

    print("I3C Block Mode Write Word Test with PEC")
    rcd.enable_pec(send_ccc=True)     # I3C enable pec need send ccc devctrl
    value = 0x5354
    ret = rcd.i3c_block_write_word(channel, page, reg, value)
    ret, data = rcd.i3c_block_read(channel, page, reg)
    assert value == data[2] << 8 | data[3]
    rcd.disable_pec(send_ccc=True)    # I3C enable pec need send ccc devctrl

    print("I3C Block Mode Write DWord Test")
    value = 0x55565758
    ret = rcd.i3c_block_write_dword(channel, page, reg, value)
    ret, data = rcd.i3c_block_read(channel, page, reg)
    assert value == data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]

    print("I3C Block Mode Write DWord Test with PEC")
    rcd.enable_pec(send_ccc=True)     # I3C enable pec need send ccc devctrl
    value = 0x50515253
    ret = rcd.i3c_block_write_dword(channel, page, reg, value)
    ret, data = rcd.i3c_block_read(channel, page, reg)
    assert value == data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]
    rcd.disable_pec(send_ccc=True)    # I3C enable pec need send ccc devctrl

    print("I3C Write Read with IBI header")
    channel = 0
    page = 0
    reg = 0x40
    value = 0x50
    ret = rcd.i3c_block_write_byte(channel, page, reg, value, with_ibi_header=True)
    ret, data = rcd.i3c_block_read(channel, page, reg, with_ibi_header=True)
    assert value == data[3]

    print("I3C Write with insert parity error")
    value = 0x51
    ret = rcd.i3c_block_write_byte(channel, page, reg, value, inject_parity_err=True)


finally:
    rcd.ccc_rstdaa()
    ez_close(ez)
    print("Adapter closed.")


6. Summary


Using the official API of the Tower I3C Host Adapter, engineers can easily test the RCD I3C protocol, perform many complex automated tests, and improve work efficiency.


Service Line:

Address:Silicon Valley
Email:support@easyi3c.com

Copyright © Easyi3C Co., LTD