SANBlaze I3C Controller Platform

Version 1528 User Guide

Release Date: March 2026


Table of Contents

  1. Introduction

  2. Installation

  3. Quick Start

  4. Linux i2c-tools Interface

  5. IBI Behavior

  6. MCTP Operations

  7. Private Transfers

  8. Burst Write System

  9. Ring Buffer Integration

  10. Diagnostics

  11. Command Reference

  12. Test Suite

  13. Troubleshooting

  14. Support


1. Introduction

V1528 adds complete MCTP over I3C support for drive health monitoring. The firmware can send multi-packet MCTP commands to MCTP capable drives, read full 4096-byte Identify Controller responses, and route data into the ring buffer for seamless customer application integration.


2. Installation

Package Contents

The release package i3c_v1528_release.gz contains firmware, tools, and documentation. Extract with the -P flag to install system binaries:

mkdir /tmp/sb_i3c
cp i3c_v1528_release.gz /tmp/sb_i3c
cd /tmp/sb_i3c
tar -xzvPf i3c_v1528_release.gz

Key package contents:

Path

Description

sb_i3c

Host CLI tool

sanblaze_firmware.uf2

Firmware image (UF2 format)

tools/sb_i3c_bind

Bind device to i2c-tiny-usb driver

tools/sb_i3c_unbind

Unbind device from driver

tools/sb_i3c_find

Find device by slot

tools/sb_i3c_find_all

List all I3C devices

tools/sb_i3c_update

Firmware update utility

tools/sb_i3c_test

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_v1528.uf2

The device reboots automatically. Wait 3 seconds before issuing commands.

Verify the update:

sb_i3c -d 2 status
# Expected output includes:
#   Version: 1528

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:  1528
#   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=1528  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

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

Output includes decoded MCTP packets with SOM/EOM flags, sequence numbers, tag values, hex dump, and ASCII representation. The Identify Controller response contains the drive serial number, model number, and firmware revision in ASCII.

Ring Buffer Path (mctp_to_ring)

Routes the response into the target ring buffer for customer applications:

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
# Output: MCTP_TO_RING: 4445 bytes committed to ring buffer

# Read from ring buffer (customer application path)
sb_i3c -d 2 i3c_data_read
# Output: DATA(4445): 0x01 0x00 0x00 0x85 ...

# Ring is empty after read
sb_i3c -d 2 i3c_data_read
# Output: DATA(0):

The ring buffer reports 0 bytes until the entire MCTP response is committed. Customer applications using TARGET_CMD_DATA_READ (0x52) require no changes.

MCTP Discovery (Get Endpoint ID)

Smaller single-packet command to verify MCTP connectivity:

sb_i3c -d 2 private_write --hold 0x1d \
  0x01 0x00 0x00 0xcd 0x84 0x08 0x00 0x00 0x00 0x00 0x00 \
  0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xe2 0x00 \
  0x06 0x07 0x55
sb_i3c -d 2 mctp_command 0x1d

Drive Recovery Between MCTP Commands

After a 4K MCTP read, the drive’s MCTP state machine requires a reset:

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

7. Private Transfers

I3C Private Transfers use a 0x7E broadcast address with Restart preamble, required for MCTP capable drives.

Private Write

# Single write (sent immediately)
sb_i3c -d 2 private_write 0x1d 0x01 0x02 0x03

# Buffered write (held for burst, see Section 5)
sb_i3c -d 2 private_write --hold 0x1d 0x01 0x02 0x03

Payloads larger than 56 bytes are automatically chunked across multiple USB transfers and reassembled by firmware. The 69-byte MCTP packets are sent as two USB chunks (56 + 13 bytes).

Private Read

sb_i3c -d 2 private_read 0x1d 69

Reads up to 128 bytes per transfer (up from 56 bytes in V1527).

Force Private Mode

Forces all transfers to use Private framing regardless of command type:

sb_i3c -d 2 private_force on     # Enable
sb_i3c -d 2 private_force off    # Disable

8. Burst Write System

The burst system buffers multiple packets in firmware and fires them back-to-back with proper STOP separation, eliminating USB latency between packets.

How It Works

# 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:

  1. Buffer MCTP packets via HOST_CMD_I3C_SDR_WRITE_CHUNK (0x40) with HOLD flag

  2. Trigger HOST_CMD_MCTP_TO_RING (0x62) — firmware runs entire bus transaction

  3. Poll HOST_CMD_MCTP_TO_RING (0x62) IN until committed bytes > 0

  4. Read 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)


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 (per-byte tracing, PIO state transitions)

Debug output goes to the USB CDC serial console (typically /dev/ttyACM0):

screen /dev/ttyACM0 115200

11. Command Reference

New in V1528

Command

Description

private_write [--hold] <da7> <bytes>

I3C Private Write; –hold buffers for burst

private_read <da7> <nbytes>

I3C Private Read (up to 128 bytes)

mctp_read <da7> [pkt_size]

Read all MCTP response packets from drive

mctp_command <da7> [pkt_size]

Burst fire + IBI poll + read (autonomous)

mctp_to_ring <da7> [pkt_size]

Burst fire + IBI poll + read → ring buffer

private_force <on|off>

Force Private mode for all transfers

pio_dump

PIO/bus diagnostic dump

setmwl <da7> <bytes>

Set Maximum Write Length (CCC 0x89, direct, 2-byte BE)

setmrl <da7> <bytes>

Set Maximum Read Length (CCC 0x8A, direct, 2-byte BE)

i3c_data_dump [N]

Binary ring buffer read; pipe to hexdump -C -v for inspection

Modified in V1528

Command

Change

i2c_clk <khz>

Writes to persistent storage only; applied by set_mode

i3c_clk <khz>

Writes to persistent storage only; applied by set_mode

set_mode <i2c|i3c>

Reads and applies stored per-mode clock automatically

Existing Commands (unchanged from V1527)

Command

Description

status

Firmware version and device info

targetreset

Reset I3C bus

entdaa <da7>

Dynamic address assignment

getpid <da7>

Get Provisional ID

getbcr <da7>

Get Bus Characteristics Register

getdcr <da7>

Get Device Characteristics Register

getstatus <da7>

Get device status

enec <da7>

Enable events (IBI)

disec <da7>

Disable events

debug <0|1|2>

Set debug level

i3c_data_read [nbytes]

Read from target ring buffer

i3c_sdr_write <da7> <bytes>

SDR write

i3c_sdr_read <da7> <nbytes>

SDR read

i3c_sdr_writeread <da7> <byte> <len>

Write-restart-read (no STOP between phases)

i3c_poll

Poll for IBI events

i3c_err_get

Get error log

i3c_err_clear

Clear error log

scan_i2c

Scan for I2C devices

scan_i3c

Scan for I3C devices

set_termination <0-3>

Set bus termination

set_drive_strength <mA>

Set output drive strength (2–12 mA)

i3c_target_enable

Enable local target mode

i3c_target_disable

Disable local target mode

i3c_target_set_addr <addr>

Set local target address

i3c_target_status

Show local target state

i3c_target_buf_reset

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

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

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

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).

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> status

  • Test script output if applicable

  • Error log: sb_i3c -d <slot> i3c_err_get

  • PIO dump if bus behavior is unexpected: sb_i3c -d <slot> pio_dump

  • The exact command sequence that reproduces the issue


SANBlaze Technology Inc. — Confidential Copyright 2024-2026 SANBlaze