DebugProbe SPI

The SPI controller on the Binho Atira debug probe: the hostadapter-shaped surface (spiControllerInit / spiSetParameters / spiTransfer), the thin wire verbs for HID commands 0x70–0x7A, the SPI NOR flash library (spiFlash*) and the bulk transport policy (spiFlashProgramFast).

Parity is with the fw-hostadapters SPI interface at develop-4.5.0. Two deviations are named: chip selects 1–3 are in the parameter space but answer NOT_SUPPORTED unless a board routes the pin, and the 1024-byte transfer is reached by chunking under one chip-select envelope. Bus voltage (spiSetBusVoltage) is a hostadapter power-rail feature Atira does not have.

Results are CosmicSDK codes, checked against SUCCESS like any CosmicSDK call: the firmware’s status translated into FW_*, an SDK_ERROR_* code, or an DEBUGPROBE_FLASH_* verdict. The translation table is on spiControllerInit.

The types these methods take (SpiParams, SpiStatus, SpiListEntry, FlashParams, SpiFlashProgress, …) are declared in include/debugprobe/Spi.hpp, SpiFlash.hpp and SpiBulkTransport.hpp; this reference does not render them yet.

group DebugProbe SPI API

The SPI controller on Atira (fw-atira #151): thin wire verbs, the hostadapter-shaped surface, the SPI NOR flash library, and the bulk transport.

Parity is with the fw-hostadapters SPI interface at develop-4.5.0 (SPI_CONTROLLER_INIT/SET_PARAMETERS/GET_PARAMETERS/TRANSFER, SPI_DEINIT). Two named deviations: CHIP_SELECT_1..3 are in the parameter space but answer NOT_SUPPORTED unless a board routes the pin; and the 1024-byte MAX_SPI_TRANSFER_LENGTH is reached by chunking under one chip-select envelope rather than in one request. Bus voltage (spiSetBusVoltage) is a hostadapter power-rail feature Atira does not have — a named non-conformance.

Results are CosmicSDK codes, checked against SUCCESS like any CosmicSDK call: the firmware’s own FW_* status (FW_RESOURCE_BUSY when the pin group is held), an SDK_ERROR_* code, or an DEBUGPROBE_FLASH_* verdict. Since fw-atira v1.0 the firmware sends CosmicSDK codes as a 16-bit status; the SDK refuses to connect to an older image. lastFirmwareStatus() returns the raw status for support.

Functions

uint16_t spiDeinit()

SPI_DEINIT — close the session, releasing a held chip select; idempotent.

uint16_t spiGetParameters(SpiParams &out)

SPI_GET_PARAMS — the open session’s parameters.

uint16_t spiTransferChunk(uint8_t flags, const std::vector<uint8_t> &tx, uint16_t transferLen, std::vector<uint8_t> &rx)

SPI_TRANSFER — one report: ≤56 tx / ≤58 clocked bytes; the flags open, continue or close the CS envelope.

uint16_t spiCsRelease()

SPI_CS release — end a held envelope without clocking.

uint16_t spiGetStatus(SpiStatus &out)

SPI_GET_STATUS — session state, params, and the live hash/list limits; answers without a session.

uint16_t spiHashStart(uint8_t algorithm = kSpiHashAlgCrc32)

SPI_HASH_START — reset the on-probe CRC-32 (algorithm 0 = zlib’s).

uint16_t spiHashUpdate(uint16_t n)

SPI_HASH_UPDATE — clock n dummy bytes into the running hash as a middle chunk of the held envelope.

uint16_t spiHashFinish(SpiHashDigest &out)

SPI_HASH_FINISH — collect the digest and clear the running state.

uint16_t spiTransferList(const std::vector<SpiListEntry> &entries, SpiListResult &out)

SPI_XFER_LIST — run a transaction list; out is filled on firmware-error paths too.

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

SPI_INIT with CosmicSDK’s argument list — the hostadapter-shaped entry point (spiControllerInit in CosmicSDK.hpp).

Parity is with fw-hostadapters develop-4.5.0; the two named deviations are CS1–CS3 (in the enum, FW_FEATURE_NOT_SUPPORTED_BY_HARDWARE unless a board routes the pin) and the 1024-byte transfer being chunked under one CS by spiTransfer.

Results are CosmicSDK codes; fw-atira v1.0 sends them as-is (cosmicStatus, protocol.hpp; the raw value is lastFirmwareStatus()):

CosmicSDK code

value

when

SUCCESS

0x0000

FW_UNSUPPORTED_COMMAND

0x0001

no SPI block in the image

FW_INVALID_PARAMETER

0x0004

a parameter out of range

FW_FEATURE_NOT_SUPPORTED_BY_HARDWARE

0x0005

an unrouted chip select, or a dead controller

FW_INTERFACE_ALREADY_INITIALIZED

0x0007

a session is already open

FW_UNHANDLED_ERROR

0x000C

FW_RESOURCE_BUSY

0x000E

the pin group is held by DAP/RTT/UPDI/ICSP, or the bulk transport owns the session

a value the firmware does not declare

SDK_ERROR_UNEXPECTED_RESPONSE (0x6000)

Parameters:
  • bitOrder – MSB or LSB first (definitions.h SpiBitOrder).

  • mode – SPI mode 0..3 (clock polarity and phase).

  • dataWidth – 8- or 16-bit frames; at 16 bits every transfer length must be even and the flash library refuses the session.

  • chipSelect – One index is native, and which one depends on the board: CS2 (J4 pin 9) on Atira Rev A/B, CS0 on the FRDM kits. The others answer FW_FEATURE_NOT_SUPPORTED_BY_HARDWARE unless a board routes the pin.

  • chipSelectPol – Active-low or active-high chip select.

  • frequency – SCK in Hz; the firmware bounds it to 1 kHz .. 8 MHz on Rev A/B (12 MHz on the FRDM kits) and answers FW_INVALID_PARAMETER above.

Return values:
  • SUCCESS – the session is open.

  • FW_INTERFACE_ALREADY_INITIALIZED – a session is already open.

  • FW_RESOURCE_BUSY – the pin group is held, or the bulk transport owns the session; GET_PIN_STATUS says who.

  • FW_FEATURE_NOT_SUPPORTED_BY_HARDWARE – the chip select has no routed pin.

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

SPI_SET_PARAMS with CosmicSDK’s argument list (spiSetParameters in CosmicSDK.hpp).

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

One logical transfer of transferLength bytes (1..1024) under one chip-select envelope, chunked over HID reports invisibly: inData first, dummy zeros for the rest, every clocked byte in outData — CosmicSDK’s spiTransfer semantics.

uint16_t spiFlashDetect(const FlashParams *override, FlashParams &out)

JEDEC names the NOR part, SFDP supplies the numbers, override (nullptr for none) wins after the liveness check.

uint16_t spiFlashGetParams(FlashParams &out)

The detected part’s parameters.

uint16_t spiFlashRelease()

Forget the detected part (confirming a deferred page program first); the SPI session stays open.

uint16_t spiFlashRead(uint32_t addr, uint32_t n, std::vector<uint8_t> &out, const SpiFlashProgress &progress = {})

Read n bytes from addr, windowed to the 1024-byte transfer bound.

uint16_t spiFlashSectorErase(uint32_t addr)

One sector erase at a sector-aligned addr.

uint16_t spiFlashEraseRange(uint32_t addr, uint32_t n, const SpiFlashProgress &progress = {})

Erase every sector overlapping [addr, addr+n) with the largest aligned granularity; the footprint equals sector-at-a-time and chip erase is never selected.

uint16_t spiFlashChipErase()

Erase the whole part — explicit by design.

uint16_t spiFlashProgram(uint32_t addr, const std::vector<uint8_t> &data, const SpiFlashProgress &progress = {})

Program data at addr, split on page boundaries, through the transaction list when the probe advertises it. Erase is not implied.

uint16_t spiFlashHash(uint32_t addr, uint32_t n, uint32_t &crc32, const SpiFlashProgress &progress = {})

CRC-32 of a span computed on the probe (DEBUGPROBE_FLASH_NO_HASH when the image does not advertise it).

uint16_t spiFlashVerifyFast(uint32_t addr, const std::vector<uint8_t> &data, bool &matches, const SpiFlashProgress &progress = {})

Pass/fail verify via the probe hash — cannot name a byte.

uint16_t spiFlashVerify(uint32_t addr, const std::vector<uint8_t> &data, std::optional<uint32_t> &mismatch, const SpiFlashProgress &progress = {})

Verify a span: the hash for pass/fail when available, read-back to name the first differing byte otherwise.

uint16_t spiFlashBlankCheck(uint32_t addr, uint32_t n, std::optional<uint32_t> &firstDirty)

Whether [addr, addr+n) is all 0xFF; firstDirty receives the first non-blank address.

uint16_t spiBulkAvailable(bool &available)

Whether this board’s SPI vendor bulk interface can be opened from here (false on images without it, and on Windows until fw-atira ships the MSOSv2 subset).

uint16_t spiFlashProgramFast(uint32_t addr, const std::vector<uint8_t> &data, bool &usedBulk, const SpiFlashProgress &progress = {})

spiFlashProgram with the transport policy: over the bulk interface when it opens (the HID session is handed over and taken back), the HID list path otherwise; usedBulk says which.

uint16_t spiFlashGetLastBulkStats(SpiFlashBulkStats &out)

Counters of the last bulk program: page envelopes, previous-page polls that hit their bound, extra lists.