SANBlaze I3C Controller Platform

V1534 Release Notes

Release Date: September 2026


Overview

V1534’s headline capability is surviving a live NVMe firmware update. When a drive is sent a Firmware Activate command it reports More Processing Required, drops off the bus to apply the image, and rejoins some seconds later - often in a different state than it left. Earlier releases lost the drive across that window: the link went quiet and the host could not recover it without operator intervention. V1534 keeps watch across the reboot and brings the drive back automatically, so a firmware update completes end to end without a manual re-enumeration or a power cycle.

The recovery is built on a host-armed device-presence poller and a set of wake-and-re-enumerate steps that handle the several ways a drive can come back: still in I2C-passive mode, back in I3C but with its dynamic address dropped, or back believing it still owns its old address and ignoring normal traffic. Each of these is detected and handled without host involvement beyond arming the poller once.

V1534 also fixes I3C enumeration at 12.5 MHz on risers whose signal path bypasses the level shifters (the iRiser6i on the SBExpress-6SA), hardens the I2C receive timing across the full 100 kHz / 400 kHz / 1 MHz range, and restores live on-the-wire GETPID reads while keeping the status command silent on the bus.

V1534 preserves the V1531/V1532 read contract, ring buffer frame format, and command surface. Existing host code runs unchanged, the default bus speed and default behavior are unchanged, and I3C data-phase behavior is unchanged.

This release supersedes V1532 and folds in the intermediate V1533 recovery work.


What’s New

Live firmware update (LFU) survival

A drive that is sent an NVMe Firmware Activate goes offline to apply the image and rejoins the bus afterward. V1534 keeps the controller-to-drive link alive across that reboot and re-establishes the drive automatically.

The mechanism is a device-presence poller the host arms once, before starting the update:

(
: ${SLOT:?Set your slot number with SLOT=N first}
# Arm the poller on the drive's dynamic address, then start the update.
sb_i3c -d $SLOT poll_on 0x1d
# ... issue the NVMe Firmware Activate as usual ...
)

Once armed, the poller is silent while the drive is present and answering. When the drive departs (the response ring goes empty across the reboot window), the poller begins waking it, brings it back, and returns to its idle armed state - ready for the next update. It stays armed until explicitly turned off:

sb_i3c -d $SLOT poll_off

The poller retains the drive’s dynamic address independently of the enumeration table, so it can direct a wake to the correct address even after the drive has dropped off the bus. No host polling loop, no manual re-enumeration, and no power cycle is required to complete the update.

Automatic recovery across all drive come-back modes

A drive returning from a firmware reboot can rejoin in more than one state. V1534 detects and handles each:

  • I2C-passive. The drive reverts to behaving as an I2C target and will not rejoin the I3C bus until it observes an I3C frame. The poller issues a directed GETSTATUS to the drive’s retained address; that frame re-arms the drive’s Hot-Join, the drive rejoins, and the controller re-assigns its address automatically.

  • Rejoined without an address. The drive Hot-Joins on its own; the controller’s existing autonomous Hot-Join handling assigns the dynamic address.

  • Rejoined but unresponsive (address retained). The drive comes back believing it still owns its old address and ignores the directed GETSTATUS. After several unanswered attempts the poller escalates to a bus reset (RSTDAA) followed by a fresh enumeration (ENTDAA), which forces the drive to surrender the stale address and take it again. The reset and the enumeration are issued as separate bus operations so the drive settles between them.

Throughout recovery, if the drive delivers any data to the ring, the poller treats it as alive and stops escalating - so a normal, self-recovering update is never disturbed by a redundant reset.

Autonomous Hot-Join enable/disable control

A new command gates autonomous Hot-Join handling:

sb_i3c -d $SLOT hot_join 1   # enable (default) - auto-ENTDAA on a Hot-Join
sb_i3c -d $SLOT hot_join 0   # disable - ignore Hot-Join requests

The default is enabled, matching prior behavior. Disabling it is useful for controlled bring-up and for hosts that drive enumeration explicitly. The current setting is reported by the status command.

I3C 12.5 MHz enumeration on level-shifter-bypassed risers

On risers whose signal path bypasses the level shifters (the iRiser6i on the SBExpress-6SA), I3C enumeration failed at 12.5 MHz: ENTDAA found no targets and the drive never came up, although the same firmware enumerated cleanly at 12.5 MHz on the iRiser6SE. Data transfer to an already-addressed drive was not affected; only the address-assignment phase failed.

The address-less setup phases of I3C - the wake broadcast, the Hot-Join address read, ENTDAA, and target reset - run in the bus’s slower open-drain mode, which is inherently more sensitive to edge rate than the push-pull data phase. On the direct-signal-path riser those open-drain edges could not be read reliably at 12.5 MHz. V1534 runs those setup phases at a reduced clock while leaving the data phase at the configured rate, matching how I3C separates open-drain arbitration from push-pull data. Enumeration and sustained 12.5 MHz data both now hold on the 6i; the 6SE is unaffected.

Verified on the iRiser6i / 6SA with a Samsung drive: 10 of 10 enumerations succeeded at 12.5 MHz with correct BCR and PID each time, followed by a full 4.25 MB firmware image download at 12.5 MHz.

I2C receive timing hardened across all speeds

The multi-packet MCTP receive path introduced in V1532 carried timing constants tuned for 100 kHz. Under systematic qualification, the extremes of the supported I2C range showed failures that the middle rate did not - a signature of fixed time constants rather than signal integrity. V1534 scales the receive and end-of-transaction timing to the configured bus speed and gates the receive engine’s recovery on the detected bus boundary rather than a fixed schedule.

Qualification now passes clean across the full matrix:

Mode Speed MCTP short MCTP long (4K Identify)
I2C 100 kHz Pass Pass
I2C 400 kHz Pass Pass
I2C 1 MHz Pass Pass
I3C 4 MHz Pass Pass
I3C 8 MHz Pass Pass
I3C 12.5 MHz Pass Pass

GETPID returns to the wire by default

GETPID had been changed to read from a cached value so that the frequently polled status command would not place a GETPID transaction on the bus each time. That silenced status but also stopped GETPID from ever performing a live read.

V1534 restores the original behavior for direct callers: getpid (and every caller other than status) performs a live GETPID on the wire and returns the drive’s current PID. The status command alone reads from the cache and remains silent on the bus. A live read refreshes the cache, so status continues to report the current value.


What’s Fixed

Drive lost across a firmware update

Sending a Firmware Activate left the drive unreachable after it rebooted: the link went quiet and only a manual re-enumeration or power cycle recovered it. See “Live firmware update (LFU) survival” and “Automatic recovery across all drive come-back modes” above. This is the primary fix in V1534.

I3C enumeration failed at 12.5 MHz on bypassed-shifter risers

ENTDAA found no targets at 12.5 MHz on the iRiser6i / 6SA. Fixed by running the open-drain setup phases at a reduced clock. See “I3C 12.5 MHz enumeration on level-shifter-bypassed risers” above.

I2C failures at the speed extremes

I2C traffic failed at 100 kHz (long transfers) and 1 MHz (short and long) while 400 kHz passed. Fixed by scaling the receive timing to the bus speed. See “I2C receive timing hardened across all speeds” above.

GETPID never reached the wire

A caller needing a live PID read got the cached value instead. Fixed with a cache-versus-wire selection; status uses the cache, all other callers go to the wire. See “GETPID returns to the wire by default” above.

Non-ASCII characters in tool output

Status and informational strings contained Unicode punctuation (em dashes and similar) that rendered as garbage once the output left a UTF-8 terminal - in the HTML qualification report, in logs viewed under other encodings, and in scraped command output. All firmware and host CLI strings are now plain ASCII.


Known Limitations

After I3C enumeration, a drive’s I2C side goes quiet until a power cycle

Once a drive has been enumerated on the I3C bus (via ENTDAA or SETDASA), it operates as an I3C device and its I2C-side functions - including an on-board EEPROM at its I2C address - stop answering. RSTDAA does not restore the I2C side; only a power cycle does. A test or workflow that switches to I3C and then expects plain I2C access to the same drive must power-cycle the drive back to I2C first. This is drive behavior, exposed by mode switching, not a controller defect.

I3C 12.5 MHz is platform- and setup-dependent

12.5 MHz enumeration and data are validated on the iRiser6SE and, with the open-drain setup-clock fix, on the iRiser6i / 6SA. The reliable maximum clock is setup-dependent - cabling, bus loading, riser signal path, and any inline instrumentation all affect it. Prefer a moderate clock with margin over the highest that appears to work; marginal signal integrity can produce a hard hang rather than a clean error. Validate enumeration at a candidate clock before relying on it.

SETDASA to the controller’s own target NAKs at 12.5 MHz

A SETDASA directed at the controller’s own local target address is NAK’d when the I3C clock is set to 12.5 MHz; it succeeds at the default 8 MHz. This is a pre-existing condition, present in prior firmware, and affects only the local target-mode self-test path, not drive enumeration or data transfer.

1 MHz support is drive-dependent

Not every drive that accepts a 1 MHz Configuration Set operates correctly at that rate. Confirm with a short traffic run after setting the speed, not with the Configuration Get read-back alone. All drives tested operate correctly at 100 kHz and 400 kHz. Use 400 kHz for data transfer; 1 MHz is suitable for speed validation and for drives confirmed to support it.

Bus speed is not preserved across a power cycle

Both the controller and the drive return to their default speed after a power cycle. Re-apply both settings as part of bring-up; setting only one leaves the two mismatched, which presents as a bus that enumerates but cannot carry traffic.

FW download throughput and I3C clock

A full 4.25 MB image downloads in roughly 80 seconds with per-chunk validation enabled. The per-packet cost is dominated by host/USB transfer overhead rather than the I3C wire, so the I3C clock rate has little effect on total download time. Select the I3C clock for reliability, not speed. See User Guide section 7 for the procedure to choose a clock on a given setup.

HDR-DDR mode not supported

V1534 operates in SDR mode only. HDR-DDR is scheduled for a future release.


Compatibility

Firmware

  • Runs on all iRiser hardware supported by V1531/V1532 - no hardware requirement changes.

  • Validated on the iRiser6SE and the iRiser6i (SBExpress-6SA).

  • No new memory or resource requirements.

Host CLI (sb_i3c)

  • Adds three commands: poll_on, poll_off, hot_join. No existing command was removed or changed in signature.

  • getpid behavior is restored to a live wire read (its pre-cache behavior); status is unchanged and remains silent on the bus.

Ring buffer and host read path

  • Frame format is unchanged: one framed entry per transaction, one entry per read, in arrival order.

  • A stale or late response carrying a prior request’s tag is now dropped rather than delivered against a new request; this is internal and requires no host change.

  • The USB command set is compatible; new control requests were added for the poller and Hot-Join control and do not affect existing requests.

  • No host or driver change is required to receive multi-packet messages or to benefit from LFU survival beyond arming the poller.

Test suite (sb_i3c_test)

  • Update EXPECTED_VERSION to 1534 and include 1534 in ACCEPTED_VERSIONS.

  • All prior tests run unchanged. The EEPROM read test now power-cycles a drive back to I2C mode if a preceding I3C test left it enumerated (see the I2C-side limitation above).

Existing customer workflows

  • V1531/V1532 host code runs without modification.

  • I3C data-phase behavior is unchanged.

  • Default bus speed is unchanged at 100 kHz. Higher speeds are opt-in.

  • The device-presence poller is off unless armed; a workflow that does not arm it sees prior behavior.


Upgrade Path

Standard firmware update:

sb_i3c_update -d $SLOT /etc/iRiser/sanblaze_i3c_fw_v1534.uf2

Then re-run device discovery:

sb_i3c_find_all

Host-side device information - including reported firmware version - is discovered at boot and cached. After updating firmware in place, refresh the cache so host software selects V1534 behavior:

Discovered devices:
slot=2  usb=1-5.2.7.4  tty=/dev/ttyACM3  ver=1534  i2c=/dev/i2c-2

Confirm ver= matches the firmware just installed before running traffic against the device.

No configuration migration is required. Persistent settings (clock frequencies in /tmp/NVMe/iRiser/<slot>/) are format-compatible.


Support

For questions, defect reports, or feature requests, contact SANBlaze support with the output of:

sb_i3c -d $SLOT status
sb_i3c -d $SLOT i3c_err_get
cat /tmp/NVMe/iRiser/$SLOT/i3c_*

For LFU/recovery issues, also capture the poller state and a debug log across the update window:

sb_i3c -d $SLOT status | grep -i poll

The V1534 firmware version string is V1534. Confirm with:

sb_i3c -d $SLOT status | grep Version