SPI API

This page aggregates all C++ SPI-related public methods of the class CosmicSDK.

group CosmicSDK SPI API

Constants and APIs related to SPI operations.

Functions

uint16_t spiSetBusVoltage(uint16_t voltage_mV, bool persist = false)

Sets the SPI bus voltage.

Warning

On Supernova and Pulsar host adapters, the SPI interface shares the same voltage domain as I2C, UART and GPIOs. As a result, calling this method to set the SPI voltage will also affect the voltage of I2C, UART and GPIO interfaces. This must be taken into account when more than one interfaces are used simultaneously.

Parameters:
  • voltage_mV – Voltage in millivolts to set the SPI bus to. The valid values are 0 mV, and any value in the range 1200 to 3300 mV. The value 0mV deactivates the VTARG pin and turn offs the downstream devices.

  • persist – bool If true, the voltage setting will be persistent across power cycles. This ensures that any DUT connected to the SPI bus (e.g. via Pulsar or Supernova) will receive power immediately upon startup, without waiting for the host to issue the voltage set command. If false, the setting will only apply to the current session.

Return values:

FW_EXTERNAL_VOLTAGE_DETECTED – Firmware 4.7.0 and later: the port already carries a voltage from another source, so the rail is left off. Call spiUseExternalVoltage() to run from that supply. A persisted setpoint gets the same check at boot.

Returns:

The status code of the operation

uint16_t spiUseExternalVoltage(bool save = false)

Configures the SPI bus to use an externally supplied voltage.

Notify the host adapter that I2C/SPI/UART/GPIO bus voltage comes from an external supply.

Warning

On Supernova and Pulsar host adapters, the SPI interface shares the same voltage domain as I2C, UART and GPIOs. As a result, calling this method will also affect the voltage domain of I2C, UART and GPIO interfaces.

Parameters:

save – If true, stores the measured external voltage as the rail’s power-on setpoint: after a power cycle the adapter drives the rail itself at that voltage. It does not store “external”. If false, applies only to the current session.

Return values:
  • SUCCESS – Voltage domain successfully switched to external supply.

  • FW_VOLTAGE_OUT_OF_RANGE – The requested voltage is outside the valid range.

  • FW_VOLTAGE_ADJUSTMENT_FAILURE – The voltage could not be applied.

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiGetBusVoltage(uint16_t &externalVoltage_mV)

Reads the measured SPI bus voltage from the host adapter.

Warning

On Supernova and Pulsar host adapters, the SPI interface shares the same voltage domain as I2C, UART and GPIOs. As a result, this method returns the same voltage values as i2cGetBusVoltage, uartGetBusVoltage, and gpioGetVoltage.

Parameters:

externalVoltage_mV – Receives the voltage (in millivolts) measured on the VTARG pin for the I2C/SPI/UART/GPIO voltage domain.

Return values:
  • SUCCESS – Voltage measurements successfully retrieved.

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

  • SDK_ERROR_WRONG_RESPONSE – The host adapter answered with a response too short to hold the analog measurements, so no reading could be taken. externalVoltage_mV is left untouched. A firmware error reported in such a response is returned in its place.

uint16_t spiDeinit()

Deinitialize the SPI interface, releasing whichever role it holds.

Tears the interface down whether it was brought up as a controller or as a target, aborting any transfer still armed and emptying the FIFOs, and leaves it uninitialized so it can be brought up again as either role.

Note

  • This is the supported way out of SPI target mode. An interface that still holds a role refuses the other role’s init, so without this the only exit is a device reset.

  • The command reaches the firmware from v4.5.0 onwards; older firmware answers FW_UNSUPPORTED_COMMAND.

Return values:
  • SUCCESS – The interface was successfully deinitialized.

  • FW_INTERFACE_NOT_INITIALIZED – The interface holds no role, so there was nothing to release.

  • FW_UNSUPPORTED_COMMAND – The firmware predates the command.

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiControllerInit(SpiBitOrder bitOrder, SpiMode mode, SpiDataWidth dataWidth, SpiChipSelect chipSelect, SpiChipSelectPolarity chipSelectPol, uint32_t frequency)

Initializes the SPI controller.

This function initializes the SPI peripheral and must be called successfully before any other SPI-related API is used.

Note

Parameters:
  • bitOrder – Bit transmission order (MSB-first or LSB-first). See SpiBitOrder for supported values.

  • mode – SPI clock mode (CPOL/CPHA configuration). See SpiMode for supported values.

  • dataWidth – Width of a single SPI data frame, in bits. See SpiDataWidth for supported values.

  • chipSelect – Chip select line to be used by the controller. See SpiChipSelect for supported values.

  • chipSelectPol – Polarity of the chip select signal (active high or low). See SpiChipSelectPolarity for supported values.

  • frequency – SPI clock frequency in Hertz. Valid range: 10000 (10 kHz) to 50000000 (50 MHz). The maximum frequency may vary depending on the USB host device model and hardware revision.

Return values:
  • SUCCESS – SPI interphase was successfully initialized.

  • FW_INTERFACE_ALREADY_INITIALIZED – The SPI interface has already been initialized.

  • FW_INVALID_PARAMETER – One or more configuration parameters are invalid or unsupported.

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiSetParameters(SpiBitOrder bitOrder, SpiMode mode, SpiDataWidth dataWidth, SpiChipSelect chipSelect, SpiChipSelectPolarity chipSelectPol, uint32_t frequency)

Sets the SPI bus parameters.

This function updates the SPI bus parameters after the SPI interface has been successfully initialized using spiControllerInit. It allows runtime reconfiguration of the SPI without requiring a full deinitialization or reinitialization of the peripheral.

Note

Parameters:
  • bitOrder – Bit transmission order (MSB-first or LSB-first). See SpiBitOrder for supported values.

  • mode – SPI clock mode (CPOL/CPHA configuration). See SpiMode for supported values.

  • dataWidth – Width of a single SPI data frame, in bits. See SpiDataWidth for supported values.

  • chipSelect – Chip select line to be used by the controller. See SpiChipSelect for supported values.

  • chipSelectPol – Polarity of the chip select signal (active high or low). See SpiChipSelectPolarity for supported values.

  • frequency – SPI clock frequency in Hertz. Valid range: 10000 (10 kHz) to 50000000 (50 MHz). The maximum frequency may vary depending on the USB host device model and hardware revision.

Return values:
  • SUCCESS – SPI parameters were successfully updated.

  • FW_INTERFACE_NOT_INITIALIZED – The SPI interface has not been initialized.

  • FW_INVALID_PARAMETER – One or more configuration parameters are invalid or unsupported.

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiTransfer(std::vector<uint8_t> &inData, std::vector<uint8_t> &outData, uint16_t transferLength)

Performs an SPI transfer.

Requests the host adapter to send data using the currently active SPI configuration (see spiControllerInit and spiSetParameters).

Note

Parameters:
  • inData – Buffer containing the data to be transmitted over SPI MOSI pin.

  • outData – Buffer where the received data through SPI MISO pin will be stored.

  • transferLength – Total length of the transfer in terms of frames or data units. Typically, the frame size is 8 bits, or in other words, 1 byte. It is worth mentioning that the transferLength can be equal or greater than the length of the inData buffer.

Return values:
  • SUCCESS – SPI message was successfully sent.

  • FW_INTERFACE_NOT_INITIALIZED – The UART interface has not been initialized.

  • FW_INVALID_PARAMETER – The transferLength is greater than te maximum SPI data length supported by the host device.

  • FW_UNHANDLED_ERROR – An unhandled error occurred while transferring SPI data.

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiWriteBulk(const std::vector<uint8_t> &data)

Writes a block of bytes to the downstream SPI device over the vendor bulk endpoint.

Unlike spiTransfer, whose payload travels inside the USB request and is therefore bounded by the request size, this call streams data over the vendor bulk OUT endpoint right after the command, so it is not bounded by the request size. This is the call to use when programming a flash device or moving any block larger than a single transfer frame. Any bytes clocked back from the downstream device (MISO) while writing are discarded; use spiReadBulk when the response matters.

See also

The four checks every bulk call makes before it moves a byte.

Note

  • Requires the vendor bulk transport to be usable; see isBulkTransportAvailable and getBulkCapabilities. Otherwise returns SDK_ERROR_BULK_UNAVAILABLE.

  • The allowed size of data is capped by the connected device’s advertised ceiling for CMD_SPI_CONTROLLER_WRITE_BULK (see BulkCapabilities::maxPayloadFor), not by the compile-time SPI_BULK_MAX_PAYLOAD constant, which is only an upper bound.

Parameters:

data – Bytes to clock out. Must be non-empty and within the device’s advertised ceiling for this command.

Return values:
  • SUCCESS – The bytes were written and acknowledged by the firmware.

  • SDK_ERROR_BULK_UNAVAILABLE – The vendor bulk transport is not usable, or the connected device does not advertise support for this command.

  • SDK_ERROR_WRONG_REQUEST – data is empty or larger than the device’s advertised ceiling.

  • SDK_ERROR_TIMEOUT – The operation timed out, either waiting for the firmware reply or while streaming data over the bulk endpoint. The reply wait is the SDK timeout plus the bus time at the last clock set for this bus.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiReadBulk(const std::vector<uint8_t> &commandBytes, std::vector<uint8_t> &outData, uint16_t readLength)

Sends a short command and reads a large block back over the vendor bulk endpoint.

Chip select is held across both phases: commandBytes is sent inside the request, then chip select stays asserted while readLength bytes are clocked in and streamed back over the vendor bulk IN endpoint. Only that data phase is written to outData, so the caller does not have to skip its own command bytes. This is the call to use when reading a large block from a downstream flash or memory-mapped device.

See also

The four checks every bulk call makes before it moves a byte.

Note

  • Requires the vendor bulk transport to be usable; see isBulkTransportAvailable and getBulkCapabilities. Otherwise returns SDK_ERROR_BULK_UNAVAILABLE.

  • The allowed value of readLength is capped by the connected device’s advertised ceiling for CMD_SPI_CONTROLLER_READ_BULK (see BulkCapabilities::maxPayloadFor), not by the compile-time SPI_BULK_MAX_PAYLOAD constant, which is only an upper bound.

Parameters:
  • commandBytes – Command and address bytes (e.g. a read opcode plus an address), sent inside the request itself. May be empty if the downstream device needs no command phase.

  • outData – Receives the readLength bytes read back; resized to that length on success, cleared on failure.

  • readLength – Data bytes to read. Must be non-zero and within the device’s advertised ceiling.

Return values:
  • SUCCESS – The bytes were read into outData.

  • SDK_ERROR_BULK_UNAVAILABLE – The vendor bulk transport is not usable, or the connected device does not advertise support for this command.

  • SDK_ERROR_WRONG_REQUEST – readLength is zero or larger than the device’s advertised ceiling.

  • SDK_ERROR_TIMEOUT – The operation timed out, either waiting for the firmware reply or while collecting the payload from the bulk endpoint. The reply wait is the SDK timeout plus the bus time at the last clock set for this bus.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiTransferBulk(const std::vector<uint8_t> &inData, std::vector<uint8_t> &outData, uint16_t transferLength)

Full-duplex transfer whose received bytes return over the vendor bulk endpoint.

The same transaction spiTransfer performs – inData is clocked out while transferLength bytes are clocked in, chip select asserted across the whole transfer – except that the received bytes come back on the vendor bulk IN endpoint instead of inside the reply. That is the only difference, and it is what lifts the reply’s size limit: a transfer can return up to the device’s advertised ceiling rather than MAX_SPI_TRANSFER_LENGTH.

Use this when a full-duplex device has to see its bytes and answer in the same transaction and the answer is large. When the two directions can be split, spiWriteBulk and spiReadBulk each get the whole staging pool for the side carrying real data, and spiWriteBulk is the only one of the three that can send more than MAX_SPI_TRANSFER_LENGTH.

See also

The four checks every bulk call makes before it moves a byte.

Note

  • Requires the vendor bulk transport to be usable; see isBulkTransportAvailable and getBulkCapabilities. Otherwise returns SDK_ERROR_BULK_UNAVAILABLE.

  • inData rides inside the request, so it is bounded by MAX_SPI_TRANSFER_LENGTH and not by the advertised ceiling, which describes the returning half.

  • If transferLength exceeds inData.size(), the extra clocks send zeros, exactly as spiTransfer does.

Parameters:
  • inData – Bytes to clock out, sent inside the request. May be empty. At most MAX_SPI_TRANSFER_LENGTH bytes.

  • outData – Receives the bytes the device announced; resized on success, cleared on failure.

  • transferLength – Bytes to clock and read back. Must be non-zero and within the device’s advertised ceiling for CMD_SPI_CONTROLLER_TRANSFER_BULK.

Return values:
  • SUCCESS – The bytes were read into outData.

  • SDK_ERROR_BULK_UNAVAILABLE – The vendor bulk transport is not usable, or the connected device does not advertise support for this command.

  • SDK_ERROR_WRONG_REQUEST – transferLength is zero or above the advertised ceiling, or inData is longer than MAX_SPI_TRANSFER_LENGTH.

  • SDK_ERROR_WRONG_RESPONSE – The reply was too short to carry the announced length.

  • SDK_ERROR_TIMEOUT – The operation timed out, either waiting for the firmware reply or while collecting the payload from the bulk endpoint. The reply wait is the SDK timeout plus the bus time at the last clock set for this bus.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiTargetInit(SpiMode mode, SpiBitOrder bitOrder, SpiChipSelect chipSelect, SpiChipSelectPolarity chipSelectPol, SpiTargetModel model, SpiTargetEngine engine, uint32_t &memorySize)

Enters SPI target (slave) mode.

Arms the device as an SPI target backed by an arena drawn from the shared bulk-staging pool. An external controller clocks bytes against that arena while the firmware services the chip-select-framed transactions autonomously. The model selects how the clocked byte stream is interpreted; engine selects the MEMORY-model service path (ignored by FLASH/REGISTER_MAP). Preload defaults with spiTargetWriteMemory and read back the controller’s writes with spiTargetReadMemory.

Parameters:
  • mode – SPI mode 0..3 (CPOL/CPHA); must match the controller. See SpiMode.

  • bitOrder – MSB-first or LSB-first. See SpiBitOrder.

  • chipSelect – Which SSEL line the target answers on; reported in notifications. See SpiChipSelect.

  • chipSelectPol – Chip-select active polarity. See SpiChipSelectPolarity.

  • model – Emulation model presented on the bus. See SpiTargetModel.

  • engine – MEMORY service engine. See SpiTargetEngine.

  • memorySize – On success, receives the arena capacity in bytes (32 KB on Supernova, 16 KB on Pulsar). Set to 0 when the result is not SUCCESS.

Return values:
  • SUCCESS – The device entered target mode.

  • FW_INTERFACE_ALREADY_INITIALIZED – Already in target mode; use spiTargetSetParameters instead. memorySize is left at 0.

  • FW_SPI_TARGET_STAGING_UNAVAILABLE – The bulk-staging pool could not be acquired for the arena.

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiTargetSetParameters(SpiMode mode, SpiBitOrder bitOrder, SpiChipSelect chipSelect, SpiChipSelectPolarity chipSelectPol, SpiTargetModel model, SpiTargetEngine engine, uint32_t &memorySize)

Reconfigures the active SPI target in place.

Re-arms the target with a new mode, chip select, or model without discarding the arena contents. This is the idempotent way to re-run configuration (unlike spiTargetInit, which returns FW_INTERFACE_ALREADY_INITIALIZED when already in target mode).

Parameters:
  • mode – SPI mode 0..3 (CPOL/CPHA); must match the controller. See SpiMode.

  • bitOrder – MSB-first or LSB-first. See SpiBitOrder.

  • chipSelect – Which SSEL line the target answers on; reported in notifications. See SpiChipSelect.

  • chipSelectPol – Chip-select active polarity. See SpiChipSelectPolarity.

  • model – Emulation model presented on the bus. See SpiTargetModel.

  • engine – MEMORY service engine. See SpiTargetEngine.

  • memorySize – On success, receives the arena capacity in bytes. Set to 0 when the result is not SUCCESS.

Return values:
  • SUCCESS – The target was reconfigured.

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiTargetSetFlashConfig(uint8_t addressBytes, uint16_t pageSize, uint32_t writeCycle_us, uint8_t idLength, const uint8_t id[8], uint8_t flags)

Configures the FLASH emulation model (SPI target).

Valid only while the active model is SPI_TARGET_MODEL_FLASH. Sets the address width, the page-program wrap granularity, the program busy timing, and the JEDEC id reported by RDID.

Parameters:
  • addressBytes – Address width in bytes: 2 or 3.

  • pageSize – Page-program wrap granularity. Must be a power of two.

  • writeCycle_us – Program time in microseconds; a program stays WIP-busy for this long.

  • idLength – Number of valid JEDEC id bytes in id (0..8).

  • id – JEDEC id bytes reported by RDID (0x9F). Always eight bytes on the wire; only the first idLength are used.

  • flags – Config flags. Bit 0 = require WEL before program; other bits reserved (send 0).

Return values:
  • SUCCESS – The configuration was applied.

  • FW_SPI_TARGET_WRONG_MODEL – The active model is not FLASH.

  • FW_SPI_TARGET_INVALID_CONFIG – The configuration is invalid (e.g., pageSize is not a power of two).

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiTargetWriteMemory(uint16_t memoryAddress, const std::vector<uint8_t> &data)

Preloads the SPI target arena over the vendor bulk endpoint.

Sends the command, then streams data on the vendor OUT endpoint. Requires the vendor bulk transport to be claimed and the firmware to advertise the command; otherwise returns SDK_ERROR_BULK_UNAVAILABLE.

See also

The four checks every bulk call makes before it moves a byte.

Parameters:
  • memoryAddress – Arena offset to start writing at.

  • data – Bytes to store; 1 to SPI_BULK_MAX_PAYLOAD.

Return values:
  • SUCCESS – The arena was written.

  • SDK_ERROR_BULK_UNAVAILABLE – The vendor bulk transport is not usable (not claimed, or unsupported by the firmware).

  • SDK_ERROR_WRONG_REQUEST – data is empty or larger than the bulk ceiling.

  • FW_SPI_TARGET_SURPASSED_MEMORY_SIZE – memoryAddress + data.size() exceeds the arena.

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.

uint16_t spiTargetReadMemory(uint16_t memoryAddress, uint16_t length, std::vector<uint8_t> &outData)

Reads the SPI target arena back over the vendor bulk endpoint.

Sends the command, reads the reply (which echoes the length), resizes outData to the announced count, then collects the payload from the vendor IN endpoint. Requires the vendor bulk transport to be claimed and the firmware to advertise the command; otherwise returns SDK_ERROR_BULK_UNAVAILABLE.

See also

The four checks every bulk call makes before it moves a byte.

Parameters:
  • memoryAddress – Arena offset to start reading from.

  • length – Bytes to read; 1 to SPI_BULK_MAX_PAYLOAD.

  • outData – Receives the bytes read; resized to the announced length. Cleared on timeout.

Return values:
  • SUCCESS – The arena was read.

  • SDK_ERROR_BULK_UNAVAILABLE – The vendor bulk transport is not usable (not claimed, or unsupported by the firmware).

  • SDK_ERROR_WRONG_REQUEST – length is zero or larger than the bulk ceiling.

  • FW_SPI_TARGET_SURPASSED_MEMORY_SIZE – memoryAddress + length exceeds the arena.

  • SDK_ERROR_TIMEOUT – The operation timed out.

  • SDK_ERROR_DISCONNECT – The device was disconnected or became unavailable during the operation.