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.
1. APIs

2. I2C messages Example
# ==========================================================================
# Easyi3C Tower USB to I3C Host Adapter
# --------------------------------------------------------------------------
# Copyright © 2026 by Easyi3C, Inc.
# All rights reserved.
# --------------------------------------------------------------------------
# ==========================================================================
import sys
from ezi3c.api import *
from ezi3c.protocol import WriteMsg, ReadMsg, IdleMsg
from ezi3c import utils
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, "Failed to set IO voltage"
try:
print("---------------------------------------------")
print(" Message test example: used JEDEC DDR5 TS ")
print("---------------------------------------------")
addr = 0x37
reg = 28
ez_ccc_rstdaa(ez)
print("> i2c Message write test ...")
wdata = 0xF0
msgs = [WriteMsg(addr, [reg, wdata])]
for msg in msgs:
print(msg)
result = ez_send_i2c_msgs(ez, msgs)
if not result.err == 0:
print("Failed to send msgs: err: {}".format(result.err))
else:
for i, rx in enumerate(result.rx_data):
print("Msg {}: rx_data: {}".format(i, utils.hex_string(rx)))
print("> i2c Message write read test ...")
rx_len = 1
msgs = [
WriteMsg(addr, reg, stop=False),
ReadMsg(addr, rx_len),
]
for msg in msgs:
print(msg)
result = ez_send_i2c_msgs(ez, msgs)
if not result.err == 0:
print("Failed to send msgs: err: {}".format(result.err))
else:
for i, rx in enumerate(result.rx_data):
print("Msg {}: rx_data: {}".format(i, utils.hex_string(rx)))
print("> i2c Message write read insert idle test ...")
rx_len = 1
duration = 10
msgs = [
WriteMsg(addr, reg, stop=False),
IdleMsg(duration),
ReadMsg(addr, rx_len),
]
for msg in msgs:
print(msg)
result = ez_send_i2c_msgs(ez, msgs)
if not result.err == 0:
print("Failed to send msgs: err: {}".format(result.err))
else:
for i, rx in enumerate(result.rx_data):
print("Msg {}: rx_data: {}".format(i, utils.hex_string(rx)))
finally:
ez_close(ez)3. I3C messages Example
# ==========================================================================
# Easyi3C Tower USB to I3C Host Adapter
# --------------------------------------------------------------------------
# Copyright © 2026 by Easyi3C, Inc.
# All rights reserved.
# --------------------------------------------------------------------------
# ==========================================================================
import sys
from ezi3c.api import *
from ezi3c import crc
from ezi3c.protocol import WriteMsg, ReadMsg, IdleMsg
from ezi3c import utils
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, "Failed to set IO voltage"
try:
print("---------------------------------------------")
print(" Message test example: used JEDEC DDR5 TS ")
print("---------------------------------------------")
addr = 0x37
reg = 28
ez_ccc_setaasa(ez)
print("> i3c Message write test ...")
wdata = 0xF0
msgs = [WriteMsg(addr, [reg, wdata])]
for msg in msgs:
print(msg)
result = ez_send_i3c_msgs(ez, msgs)
if not result.err == 0:
print("Failed to send msgs: err: {}".format(result.err))
else:
for i, rx in enumerate(result.rx_data):
print("Msg {}: rx_data: {}".format(i, utils.hex_string(rx)))
print("> i3c Message write read test ...")
rx_len = 1
msgs = [
WriteMsg(addr, reg, stop=False),
ReadMsg(addr, rx_len),
]
for msg in msgs:
print(msg)
result = ez_send_i3c_msgs(ez, msgs)
if not result.err == 0:
print("Failed to send msgs: err: {}".format(result.err))
else:
for i, rx in enumerate(result.rx_data):
print("Msg {}: rx_data: {}".format(i, utils.hex_string(rx)))
print("> i3c Message write read insert idle test ...")
rx_len = 1
duration = 10
msgs = [
WriteMsg(addr, reg, stop=False),
ReadMsg(addr, rx_len),
IdleMsg(duration),
WriteMsg(addr, reg, stop=False),
ReadMsg(addr, rx_len),
]
for msg in msgs:
print(msg)
result = ez_send_i3c_msgs(ez, msgs)
if not result.err == 0:
print("Failed to send msgs: err: {}".format(result.err))
else:
for i, rx in enumerate(result.rx_data):
print("Msg {}: rx_data: {}".format(i, utils.hex_string(rx)))
print("> Enable PEC ...")
BROADCAST = 0x7
ez_ccc_devctrl(ez, BROADCAST, 0, 0, 0, 0, [0x01 << 7])
print("> i3c Message write with PEC test ...")
wdata = 0x0
# Follow by JEDEC DDR5 Ts spec define
cmd = 0x0
pec_bytes = [addr << 1 | 0x00] + [reg, cmd, wdata]
pec_cal = crc.crc(pec_bytes)
msgs = [WriteMsg(addr, [reg, cmd, wdata, pec_cal])]
result = ez_send_i3c_msgs(ez, msgs)
if not result.err == 0:
print("Failed to send msgs: err: {}".format(result.err))
else:
for i, rx in enumerate(result.rx_data):
print("Msg {}: rx_data: {}".format(i, utils.hex_string(rx)))
print("> i3c Message write read with PEC test ...")
rx_len = 1
pec_count = 1
# Follow by JEDEC DDR5 Ts spec define
cmd = 1 << 4
pec_bytes = [addr << 1 | 0x00] + [reg] + [cmd]
pec_cal = crc.crc(pec_bytes)
msgs = [
WriteMsg(addr, [reg, cmd, pec_cal], stop=False),
ReadMsg(addr, rx_len + pec_count)
]
result = ez_send_i3c_msgs(ez, msgs)
if not result.err == 0:
print("Failed to send msgs: err: {}".format(result.err))
else:
for i, rx in enumerate(result.rx_data):
print("Msg {}: rx_data: {}".format(i, utils.hex_string(rx)))
# check pec value
pec_value = rx[1]
pec_bytes = [addr << 1 | 0x01] + [rx[0]]
pec_cal = crc.crc(pec_bytes)
if pec_value != pec_cal:
print(f"PEC mismatch: expected {pec_cal}, got {pec_value}.")
print("> Diable PEC ...")
print("> DEVCTRL CCC Broadcast with PEC ...")
# Follow by JEDEC DDR5 Ts spec define
addr_ccc = 0x7E
broadcast = 0x62
addrmask = 0x7
startoffset = 0x0
pecbl = 0x0
regmod = 0x0
data = addrmask << 5 | startoffset << 3 | pecbl << 1 | regmod
devid = 0x0
payload = [0]
pec_bytes = [broadcast] + [data] + [devid << 1] + payload
pec_cal = crc.crc(pec_bytes)
send_bytes = [broadcast] + [data] + [devid << 1] + payload + [pec_cal]
msgs = [WriteMsg(addr_ccc, send_bytes)]
result = ez_send_i3c_msgs(ez, msgs)
if not result.err == 0:
print("Failed to send msgs: err: {}".format(result.err))
else:
for i, rx in enumerate(result.rx_data):
print("Msg {}: rx_data: {}".format(i, utils.hex_string(rx)))
finally:
ez_close(ez)