Target Mode

In target mode the host adapter stops driving the bus and answers on it instead: an external controller reads and writes a memory arena on the adapter, and the firmware services those transactions on its own. Your application preloads the arena, reads back what the controller wrote, and is told about each completed transaction through a notification.

Protocol

Enter / reconfigure

Arena access

Leave

I2C

i2cTargetInit, i2cTargetSetParameters

i2cTargetWriteMemory, i2cTargetReadMemory (bulk)

i2cDeinit(bus)

SPI

spiTargetInit, spiTargetSetParameters

spiTargetWriteMemory, spiTargetReadMemory (bulk)

spiDeinit()

I3C

i3cTargetInit, i3cTargetSetParameters

i3cTargetWriteMemory, i3cTargetReadMemory (HID)

i3cControllerInit

Each has the same name, prefixed with CosmicSDK_, in the C API.

I2C and SPI target

  • The arena is drawn from the shared bulk-staging pool; i2cTargetInit and spiTargetInit return its size in memorySize (32 KB on Supernova, 16 KB on Pulsar).

  • Arena access uses the bulk transport, so the host must be able to claim the vendor endpoints (see Bulk Transfers). Without them, *TargetWriteMemory and *TargetReadMemory return SDK_ERROR_BULK_UNAVAILABLE (0xC000); entering and configuring target mode still works.

  • Models. I2C: I2C_TARGET_MODEL_MEMORY (flat, auto-incrementing), I2C_TARGET_MODEL_EEPROM (24Cxx-style page wrap, busy timing, write protect; see i2cTargetSetEepromConfig) and I2C_TARGET_MODEL_REGISTER_MAP (per-region access policies; see i2cTargetSetRegisterRegion). SPI: SPI_TARGET_MODEL_MEMORY, SPI_TARGET_MODEL_FLASH (25-series command set; see spiTargetSetFlashConfig) and SPI_TARGET_MODEL_REGISTER_MAP.

  • Leaving. A bus that holds one role refuses the other role’s init. i2cDeinit(bus) and spiDeinit() release whichever role is held, so the interface can be initialized again as either one. They need firmware 4.5.0 or newer; older firmware answers FW_UNSUPPORTED_COMMAND, and the only way out is resetDevice().

I3C target

  • Supernova only. Needs firmware 4.1.1 or newer.

  • The arena is I3C_TARGET_MEMORY_SIZE (1024 bytes). It fits in a HID request, so i3cTargetWriteMemory / i3cTargetReadMemory do not use the bulk transport and work on every host.

  • i3cTargetInit switches the adapter from controller to target by itself and never answers FW_INTERFACE_ALREADY_INITIALIZED: a second call re-runs the whole target init.

  • Leaving. There is no I3C deinit call. i3cControllerInit switches back from target to controller in place; it answers FW_INTERFACE_ALREADY_INITIALIZED only when the controller role is already up. While the target role is held, controller commands answer FW_INVALID_COMMAND.

  • Target-initiated In-Band Interrupts are not implemented by the firmware yet.

Bus-event notifications

Each transaction a controller completes against the target raises a notification: NOTIF_I2C_TARGET_BUS_EVENT, NOTIF_SPI_TARGET_BUS_EVENT or NOTIF_I3C_TARGET_BUS_EVENT. The I2C and SPI events carry metadata only — the event kind, the address or chip select, the arena offset and the length; read the bytes themselves back with *TargetReadMemory. The I3C event also points at the bytes transferred, valid only during the callback.

Warning

The notification callback runs on the SDK’s receive thread, the same thread that delivers every command reply. Do not call *TargetReadMemory — or any other blocking SDK method — from inside the callback: it waits for a reply only that thread can deliver, so it waits out the full timeout, and forever with the default timeout of -1. Copy the event, return, and read the arena from your own thread.

Examples

examples/blocking_api/i2c_target/, examples/blocking_api/spi_target/ and examples/blocking_api/i3c_target/, in C and C++. The Python, Java and C# bindings carry the same three examples. See Examples.