SANBlaze I3C Controller Platform
Version 1530 User Guide
Release Date: April 2026
Table of Contents
1. Introduction
V1530 fixes a critical SMBus multi-chunk read bug where mi commands requesting more
than 56 bytes via the SMBus path returned the first 56 bytes repeated to fill the
requested length. VPD Read (256 bytes) now returns complete, correct data via both
I3C and SMBus paths. This release also includes a coordinated update to the SANBlaze
i2c-tiny-usb kernel module required to support the fix.
All V1529 features and fixes are preserved and unchanged.
2. Installation
Package Contents
The release package i3c_v1530_release.gz contains firmware, tools, and documentation.
Extract with the -P flag to install system binaries:
mkdir /tmp/sb_i3c
cp i3c_v1530_release.gz /tmp/sb_i3c
cd /tmp/sb_i3c
tar -xzvPf i3c_v1530_release.gz
Key package contents:
Path |
Description |
|---|---|
|
Host CLI tool |
|
Firmware image (UF2 format) |
|
Bind device to i2c-tiny-usb driver |
|
Unbind device from driver |
|
Find device by slot |
|
List all I3C devices |
|
Firmware update utility |
|
Automated test suite |
After extraction, all tools are installed system-wide and available without a path prefix.
Firmware Update
sb_i3c_update -d <slot> /etc/iRiser/sanblaze_i3c_fw_v1530.uf2
The device reboots automatically. Wait 3 seconds before issuing commands.
Verify the update:
sb_i3c -d 2 status
# Expected output includes:
# Version: 1530
Hardware Requirement: Bus Termination
V1529 requires correct bus termination on the drive side of the I2C mux. A missing jumper on the drive-side mux leaves the bus unterminated, causing pattern-sensitive ACK failures that are difficult to distinguish from firmware bugs. Symptom: intermittent SMBus errors on specific byte values that pass consistently on the FT260 path.
Verify the drive-side mux jumper is installed before diagnosing SMBus reliability issues.
3. Quick Start
Discover and Configure Drive
# Reset bus and discover drive at address 0x1D
sb_i3c -d 2 targetreset
sleep 0.5
sb_i3c -d 2 entdaa 0x1d
# Enable IBI events (required for MCTP)
sb_i3c -d 2 enec 0x1d
# Set maximum write and read length to 69 (required before MCTP traffic)
sb_i3c -d 2 setmwl 0x1d 69
sb_i3c -d 2 setmrl 0x1d 69
# Verify drive is present
sb_i3c -d 2 getpid 0x1d
# Expected: PID: 0x02 0x02 0x16 0x00 0x12 0x34
Quick MCTP Health Check
# Buffer the Identify Controller command (2 MCTP packets)
sb_i3c -d 2 private_write --hold 0x1d \
0x01 0x00 0x00 0x8d 0x84 0x10 0x00 0x00 0x06 0x03 0x01 \
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 \
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 \
0x00 0x00 0x00 0x00 0x00 0x10 0x00 0x00 0x00 0x00 0x00 \
0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00 \
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 \
0x00 0x00 0xf2
sb_i3c -d 2 private_write --hold 0x1d \
0x01 0x00 0x00 0x5d 0x00 0x00 0x00 0x00 0x04 0x4d 0x64 0x69 0x7d
# Fire command and read response
sb_i3c -d 2 mctp_command 0x1d
# Expected: MCTP_COMMAND: 4445 total response bytes
# 65 decoded packets with serial number, model, firmware revision
4. Linux i2c-tools Interface
The SANBlaze I3C device presents a standard i2c-tiny-usb interface to Linux, enabling
use of standard i2c-tools (i2cdetect, i2cget, i2cset, i2ctransfer).
Finding Your Device
Use sb_i3c_find to discover the USB path, TTY, and I2C bus number for a slot:
sb_i3c_find -d 2
# USB Path: 1-5.2.7.4
# TTY: /dev/ttyACM6
# Version: 1530
# I2C Dev: /dev/i2c-15
Use sb_i3c_find_all to list all slots with I3C capability:
sb_i3c_find_all
# slot=2 usb=1-5.2.7.4 tty=/dev/ttyACM6 ver=1530 i2c=/dev/i2c-15
Driver Binding
If the i2c-tiny-usb driver is not automatically bound:
sb_i3c_bind -d 2 # Bind
sb_i3c_unbind -d 2 # Unbind
Common i2c-tools Commands
# Scan for devices on the TinyUSB I2C bus
i2cdetect -y 15
# Read a single byte from address 0x53
i2cget -y 15 0x53
# Write to address 0x71
i2cset -y 15 0x71 0x00
# Write-restart-read (required for devices that need an offset before reading)
i2ctransfer -y 15 w1@0x6a 0x00 r16
# Write multiple bytes
i2ctransfer -y 15 w4@0x24 0x01 0x02 0x03 0x04
Note: Devices that require a write-restart-read sequence will hold SDA low if a plain read is attempted without first writing the offset. Clear with:
sb_i3c -d 2 i3c_poll
5. IBI Behavior
IBI (In-Band Interrupt) is the I3C mechanism by which a target device signals the controller that it needs attention. Understanding IBI behavior is important for reliable operation.
When IBI Is Asserted
I3C targets commonly assert IBI after:
Initial power-on
First CCC command after a power cycle
Completion of certain operations (device-specific)
When IBI is asserted, the target holds SDA low. This is normal device behavior.
While IBI is pending, i2cdetect will show no devices — this does not indicate
a firmware problem.
Polling and Clearing IBI
sb_i3c -d 2 i3c_poll
Example output when IBI is pending:
IBI: 0xFF 0xFF 0xFF 0xFF ...
Example output when bus is clear:
No IBI Bytes Found
Poll until “No IBI Bytes Found” before proceeding with bus operations. After
clearing IBI, i2cdetect will show devices normally.
Quick Target Mode Verification
After firmware update, verify the local target is working:
sb_i3c -d 2 i3c_target_enable
sb_i3c -d 2 i3c_sdr_write 0x24 0xAA 0xBB 0xCC 0xDD
sb_i3c -d 2 i3c_data_read
# Expected: DATA(4): 0xAA 0xBB 0xCC 0xDD
6. MCTP Operations
Overview
MCTP (Management Component Transport Protocol) over I3C enables communication with drive management interfaces. The firmware supports three MCTP read paths with increasing levels of autonomy:
Path |
Command |
Use Case |
|---|---|---|
Manual |
private_write + i3c_poll + mctp_read |
Step-by-step debugging |
Autonomous |
mctp_command |
CLI-based testing and development |
Ring buffer |
mctp_to_ring |
Customer application integration |
Required before any MCTP traffic: After ENTDAA and ENEC, send SETMWL and SETMRL to establish the maximum transfer unit. Most I3C MCTP targets require this before accepting MCTP commands:
sb_i3c -d 2 setmwl 0x1d 69 sb_i3c -d 2 setmrl 0x1d 69
Multi-Packet MCTP over SMBus (V1529)
In I2C/SMBus mode, drives may return responses as multiple sequential SMBus frames,
each addressed to the local target (0x24). V1529 firmware ACKs all packets and
commits each complete frame to the ring buffer atomically. The mi tool reads packets
one at a time, using the MCTP SOM/EOM flags to determine when the response is complete.
Commands returning large responses (VPD Read, Identify Controller) will produce
multiple committed frames in sequence. The ring buffer reports 0 bytes until a complete
frame is committed; mi polls and reads each frame individually.
Manual Path (Debugging)
For detailed visibility into each phase:
# 1. Send MCTP command packets
sb_i3c -d 2 private_write --hold 0x1d <pkt1_bytes>
sb_i3c -d 2 private_write 0x1d <pkt2_bytes> # no --hold = fires burst
# 2. Poll for IBI (drive signals response ready)
sb_i3c -d 2 i3c_poll
# 3. Read all response packets
sb_i3c -d 2 mctp_read 0x1d
# Output: packet-by-packet hex dump with MCTP headers decoded
Autonomous Path (mctp_command)
Single command handles burst fire, IBI polling, and multi-packet read:
sb_i3c -d 2 private_write --hold 0x1d <pkt1_bytes>
sb_i3c -d 2 private_write --hold 0x1d <pkt2_bytes>
sb_i3c -d 2 mctp_command 0x1d
Ring Buffer Path (mctp_to_ring)
Routes the complete MCTP response into the target ring buffer for customer application integration:
sb_i3c -d 2 private_write --hold 0x1d <pkt1_bytes>
sb_i3c -d 2 private_write --hold 0x1d <pkt2_bytes>
sb_i3c -d 2 mctp_to_ring 0x1d
# Read via existing TARGET_CMD_DATA_READ path
sb_i3c -d 2 i3c_data_read
7. Private Transfers
I3C Private Transfers use a 0x7E broadcast + Repeated START preamble before the addressed transaction. Required for MCTP communication with most NVMe drives.
# Single private write
sb_i3c -d 2 private_write 0x1d 0x01 0x02 0x03 ...
# Buffered (held) private write for burst
sb_i3c -d 2 private_write --hold 0x1d 0x01 0x02 ...
# Private read
sb_i3c -d 2 private_read 0x1d 64
8. Burst Write System
The burst write system buffers multiple private_write --hold packets in firmware
and transmits them back-to-back as a single burst when mctp_command or mctp_to_ring
is called. This eliminates USB latency between packets and is required for multi-packet
MCTP commands.
# Buffer packet 1 (69 bytes) — not sent yet
sb_i3c -d 2 private_write --hold 0x1d <pkt1_bytes>
# Output: PRIVATE_WRITE HELD: 69 bytes to 0x1D
# Buffer packet 2 (13 bytes) — not sent yet
sb_i3c -d 2 private_write --hold 0x1d <pkt2_bytes>
# Output: PRIVATE_WRITE HELD: 13 bytes to 0x1D
# Fire all buffered packets in one burst
sb_i3c -d 2 mctp_command 0x1d
# or
sb_i3c -d 2 mctp_to_ring 0x1d
The burst buffer holds up to 512 bytes across multiple packets. Each packet is sent as a complete I3C Private Write transaction with START and STOP.
9. Ring Buffer Integration
Customer Application Flow
The ring buffer path (mctp_to_ring) is designed for production use. Customer
applications read MCTP data using the same TARGET_CMD_DATA_READ (0x52) USB
command they already use for target-mode data. No application code changes needed.
Driver integration steps:
Buffer MCTP packets via
HOST_CMD_I3C_SDR_WRITE_CHUNK(0x40) with HOLD flagTrigger
HOST_CMD_MCTP_TO_RING(0x62) — firmware runs entire bus transactionPoll
HOST_CMD_MCTP_TO_RING(0x62) IN until committed bytes > 0Read data via
TARGET_CMD_DATA_READ(0x52) — existing path
See the separate MCTP Ring Buffer Integration Guide for complete USB command details, byte-level packet formats, and error handling.
Ring Buffer Constraints
Buffer size: 8192 bytes
Reset at start of each mctp_to_ring command
Reports 0 bytes until entire response is committed (atomic visibility)
Data consumed on read (single-read semantics)
Backpressure NAK is disabled in I2C mode;
mipolling rate determines throughput
10. Diagnostics
PIO Dump
Comprehensive bus and PIO state machine diagnostic:
sb_i3c -d 2 pio_dump
Output includes:
Bus state: SDA/SCL levels and GPIO function assignments
PIO0 SM1 (Initiator): program counter, enabled, FIFO state, stall flags
PIO1 SM0 (Target): state and GPIO configuration
PIO2 SM0 (Target 0x7E): state for Private transfer monitoring
IRQ flags for all PIO blocks
Diagnosis line (e.g., “All OK - bus idle” or specific fault identification)
Disassembled PIO instructions at current program counter
The test suite automatically runs pio_dump on any test failure.
Debug Levels
sb_i3c -d 2 debug 0 # Quiet (default)
sb_i3c -d 2 debug 1 # Key events (MCTP packet summaries, IBI, errors)
sb_i3c -d 2 debug 2 # Verbose (ring buffer commits, PIO state, SMBus trim, linger)
Debug level 2 shows the full ring-buffer and SMBus path trace including:
[PIO] START/was_init, [XFER_END], [CCC] complete, [LINGER] SCL low,
[IRQ3], and SMBus trim events. Use level 2 when diagnosing SMBus frame
assembly or multi-packet MCTP issues.
Debug output goes to the USB CDC serial console (typically /dev/ttyACM0):
screen /dev/ttyACM0 115200
11. Command Reference
New in V1528 (carried forward)
Command |
Description |
|---|---|
|
I3C Private Write; –hold buffers for burst |
|
I3C Private Read (up to 128 bytes) |
|
Read all MCTP response packets from drive |
|
Burst fire + IBI poll + read (autonomous) |
|
Burst fire + IBI poll + read → ring buffer |
|
Force Private mode for all transfers |
|
PIO/bus diagnostic dump |
|
Set Maximum Write Length (CCC 0x89, direct, 2-byte BE) |
|
Set Maximum Read Length (CCC 0x8A, direct, 2-byte BE) |
|
Binary ring buffer read; pipe to |
Modified in V1528 (carried forward)
Command |
Change |
|---|---|
|
Writes to persistent storage only; applied by set_mode |
|
Writes to persistent storage only; applied by set_mode |
|
Reads and applies stored per-mode clock automatically |
Existing Commands (unchanged)
Command |
Description |
|---|---|
|
Firmware version and device info |
|
Reset I3C bus |
|
Dynamic address assignment |
|
Get Provisional ID |
|
Get Bus Characteristics Register |
|
Get Device Characteristics Register |
|
Get device status |
|
Enable events (IBI) |
|
Disable events |
|
Set debug level |
|
Read from target ring buffer |
|
SDR write |
|
SDR read |
|
Write-restart-read (no STOP between phases) |
|
Poll for IBI events |
|
Get error log |
|
Clear error log |
|
Scan for I2C devices |
|
Scan for I3C devices |
|
Set bus termination |
|
Set output drive strength (2–12 mA) |
|
Enable local target mode |
|
Disable local target mode |
|
Set local target address |
|
Show local target state |
|
Clear local target ring buffer |
12. Test Suite
Run the full test suite:
./sb_i3c_test.sh -d 2
Options:
./sb_i3c_test.sh -d 2 -t 41 # Run single test
./sb_i3c_test.sh -d 2 -t 30-52 # Run test range
./sb_i3c_test.sh -d 2 -v # Verbose output
./sb_i3c_test.sh -d 2 -N # Skip hardware init (caller ensures drive present)
V1530: TEST40 and TEST41 now run correctly on V1530 firmware. The version gate that previously skipped these tests on versions beyond V1529 has been updated. When
-Nis used,HAS_DRIVEdefaults to 1 and thei3c_capablecache is cleared, allowing I3C-mode tests to probe fresh rather than skip on a stale result.
MCTP Tests
Test |
Description |
|---|---|
38 |
SETMWL 69 — direct CCC 0x89 to drive after ENTDAA/ENEC |
39 |
SETMRL 69 — direct CCC 0x8A to drive after ENTDAA/ENEC |
41 |
MCTP 4K Identify via manual burst write + IBI + mctp_read |
50 |
MCTP discovery (Get Endpoint ID) via mctp_command |
51 |
MCTP 4K Identify via mctp_command (autonomous) |
52 |
MCTP 4K Identify via mctp_to_ring (ring buffer path) |
Test 52 verifies the complete customer path: burst write → mctp_to_ring → i3c_data_read → verify byte count → confirm ring drains to empty.
All MCTP tests (41–52) issue SETMWL/SETMRL 69 as part of their setup preamble.
13. Troubleshooting
Intermittent SMBus Errors on Specific Byte Values
If SMBus commands fail intermittently on byte values such as 0xD3, 0xF5, or 0xC1 (even-popcount bytes) but pass consistently on the FT260 path, suspect missing bus termination. Check the drive-side mux jumper. Unterminated bus causes pattern-sensitive ACK failures that mimic firmware bugs.
Drive Not Responding After MCTP Read
After a 4K MCTP transaction, the drive’s MCTP state machine is exhausted. Use double targetreset to recover:
sb_i3c -d 2 targetreset
sleep 0.5
sb_i3c -d 2 targetreset
sleep 0.5
sb_i3c -d 2 entdaa 0x1d
sb_i3c -d 2 enec 0x1d
sb_i3c -d 2 setmwl 0x1d 69
sb_i3c -d 2 setmrl 0x1d 69
I3C Tests Skipping Unexpectedly with -N Flag
If Python test wrappers show “Drive not available in I3C mode” when the drive is
present, the i3c_drive_unavailable flag file from a previous failed run may be
stale. The V1529 setup_i3c() fix clears this file automatically. If running an
older wrapper, clear manually:
rm -f /path/to/luns/1/i3c_drive_unavailable
rm -f /path/to/luns/1/i3c_drive_ready
i2cdetect Shows No Devices
Check for a pending IBI first — this is the most common cause:
sb_i3c -d 2 i3c_poll
# Poll repeatedly until: No IBI Bytes Found
If IBI is clear, check bus state:
sb_i3c -d 2 status
# Look for: Bus State: SDA=1, SCL=1 (both high = idle)
If the bus is stuck, power cycle the target device.
Bus Stuck After Operation
If SDA or SCL is held low after an operation:
sb_i3c -d 2 i3c_poll # Clear any pending IBI
sb_i3c -d 2 targetreset # Reset bus state
sb_i3c -d 2 pio_dump # Inspect PIO state if still stuck
Local Target Tests Fail
# Ensure target is enabled
sb_i3c -d 2 i3c_target_enable
# Verify target address
sb_i3c -d 2 i3c_target_set_addr 0x24
# Flush stale data from buffer
sb_i3c -d 2 i3c_target_buf_reset
MCTP_COMMAND Returns “No response data”
The CLI polls too fast before firmware finishes the bus transaction. V1528+ CLI includes automatic retry (100ms intervals, up to 30 seconds). If still failing, verify the drive was discovered and IBI enabled.
Short MCTP Response (< 4000 bytes)
Drive sent an error packet (SOM=EOM=1 in a single packet). Check byte 3 bit 6 for EOM flag. Common cause: drive MCTP state not reset from previous transaction.
Watchdog Reboot at Idle
V1528 resolved idle watchdog crashes present in intermediate builds. If this recurs, verify firmware version matches the release binary (not an intermediate build). Expected version: 1530.
PIO Dump Shows Stall
If pio_dump shows tx_stall=1 with tx_empty=0, the PIO state machine is
blocked waiting for the bus. Run targetreset to clear.
Error Log
Read and clear the firmware error log:
sb_i3c -d 2 i3c_err_get # Read error log
sb_i3c -d 2 i3c_err_clear # Clear after review
14. Support
When reporting an issue, please include:
Firmware version:
sb_i3c -d <slot> statusTest script output if applicable
Error log:
sb_i3c -d <slot> i3c_err_getPIO dump if bus behavior is unexpected:
sb_i3c -d <slot> pio_dumpDebug level 2 log from ttyACM if SMBus frame assembly is suspected
The exact command sequence that reproduces the issue
Whether the issue reproduces on the FT260 path (slot 2 vs slot 1)
SANBlaze Technology Inc. — Confidential Copyright 2024-2026 SANBlaze