Skip to main content

SPI

The SPI (Serial Peripheral Interface) interface provides high-speed synchronous serial communication. Supports configurable clock speed, voltage levels from 1.6V to 5.0V, and SPI modes (0-3) for clock polarity and phase.

Only master mode

Please note that the AT1000 device only supports master mode for SPI communication. This means that it can initiate communication with slave devices, but it cannot act as a slave itself.

Multiplexing

Some interfaces share the same GPIO pins, so only one can be used at a time. Check out the multiplexing tables in the introduction for more details.

Quick Start​

The example code below shows how to enable the SPI bus, set the baud rate, and transmit/receive data.

Note about CS lines

CS lines are handled as regular I/Os. This means that you can use any free GPIO pin as a CS line. However, you need to manually control the CS line before and after the SPI transaction, as shown in the examples below.

import AT1000 from '@ikalogic/at1000';
let testers = await AT1000.findDevices(500); // Find the device with serial number 12345
let tester = testers[0]; // Target the first detected device
let spi = tester.com.spi(0); // Select the first SPI bus
var cs_pin = tester.gpio.digital(5); // GPIO 5 on master device
await cs_pin.configure_output({
voh: 3.3,
vol: 0,
vih: 1.2,
vil: 0.8,
value: true
}); // VIH = 3.3V, VIL = 0V, set to high level

// Enable SPI bus with a target VCC of 3.3V
// Effectively connecting the SPI pins the dedicated IO pins
await spi.configure({
vcc: 3.3,
baud_rate: 500000, // Initial baud rate of 500kHz
enabled: true
});

// Do an SPI transaction
await cs_pin.write(false); // Set CS line to low
let rx_data = await spi.trx([0xDE, 0xAD, 0xBE, 0xEF]); // Send and receive 4 data bytes
await cs_pin.write(true); // Set CS line to high
console.log('Received data:', rx_data);

API Reference​

Accessing SPI​

const spi = tester.com.spi(id);

Parameters:

  • id (number): The SPI interface identifier (0-based index)

Returns: Spi instance


Methods​

configure(config)​

Configures the SPI interface parameters without changing the enabled state.

await spi.configure({ 
baud_rate: 1000000,
vcc: 3.3,
mode: 0
});

Parameters:

  • config (SpiConfigPatch): Configuration object with optional properties:
    • enabled (boolean, optional): Enable or disable the interface
    • baud_rate (number, optional): SPI clock frequency in Hz (300 to 10000000)
    • vcc (number, optional): Logic level voltage in volts (1.6 to 5.0)
    • mode (number, optional): SPI mode (0, 1, 2, or 3)

SPI Modes:

  • Mode 0: CPOL=0, CPHA=0 (clock idle low, sample on rising edge)
  • Mode 1: CPOL=0, CPHA=1 (clock idle low, sample on falling edge)
  • Mode 2: CPOL=1, CPHA=0 (clock idle high, sample on falling edge)
  • Mode 3: CPOL=1, CPHA=1 (clock idle high, sample on rising edge)

Returns: Promise<SpiConfig> - The updated configuration

Exceptions:

  • Throws validation error if baud_rate is outside the range [300, 10000000]
  • Throws validation error if vcc is outside the range [1.6, 5.0]
  • Throws validation error if mode is outside the range [0, 3]

enable([config])​

Enables the SPI interface and optionally applies configuration.

await spi.enable({ 
baud_rate: 1000000,
vcc: 3.3,
mode: 0
});

Parameters:

  • config (SpiEnableConfig, optional): Optional configuration to apply:
    • baud_rate (number, optional): SPI clock frequency (300 to 10000000)
    • vcc (number, optional): Logic level voltage (1.6 to 5.0)
    • mode (number, optional): SPI mode (0-3)

Returns: Promise<SpiConfig> - The updated configuration with enabled: true

Exceptions:

  • Throws validation error if parameters are outside valid ranges

disable()​

Disables the SPI interface.

await spi.disable();

Returns: Promise<SpiConfig> - The updated configuration with enabled: false


trx(data)​

Transmits data over SPI and simultaneously receives the response (full-duplex).

// Send command and receive response
const response = await spi.trx([0x03, 0x00, 0x00, 0x00]);
console.log("Received:", response);

// Send string
const response2 = await spi.trx("READ");

Parameters:

  • data (SerialDataInput): Data to transmit, either:
    • string: Text data (max 1024 characters)
    • number[]: Byte array (each byte 0-255, max 1024 bytes)

Returns: Promise<SerialData> - Received data as byte array (number[])

Note: SPI is full-duplex, so data is received simultaneously with transmission. The response length equals the transmission length.

Exceptions:

  • Throws validation error if string exceeds 1024 characters
  • Throws validation error if array exceeds 1024 elements
  • Throws validation error if any byte value is outside the range [0, 255]

Types​

SpiConfig​

Complete configuration object returned by configuration methods.

{
enabled: boolean,
baud_rate: number, // 300 to 10000000
vcc: number, // 1.6 to 5.0
mode: number // 0, 1, 2, or 3
}

SpiConfigPatch​

Partial configuration for the configure() method. All properties are optional.

{
enabled?: boolean,
baud_rate?: number, // 300 to 10000000
vcc?: number, // 1.6 to 5.0
mode?: number // 0, 1, 2, or 3
}

SpiEnableConfig​

Optional configuration for the enable() method.

{
baud_rate?: number, // 300 to 10000000
vcc?: number, // 1.6 to 5.0
mode?: number // 0, 1, 2, or 3
}

SerialDataInput​

Input data type for transmission.

string | number[]
  • string: Maximum 1024 characters
  • number[]: Maximum 1024 elements, each byte in range [0, 255]

SerialData​

Output data type, always returned as a byte array.

number[]  // Array of bytes (0-255)

Usage Example​

import AT1000 from '@ikalogic/at1000';

// Find and connect to device
const devices = await AT1000.findDevices(500);
const tester = devices[0];

// Access SPI interface 0
const spi = tester.com.spi(0);

// Enable with 1 MHz clock, 3.3V logic, Mode 0
await spi.enable({
baud_rate: 1000000,
vcc: 3.3,
mode: 0
});

// Read from SPI device (e.g., read 4 bytes from address 0x1000)
const readCmd = [0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
const response = await spi.trx(readCmd);
console.log("Data:", response.slice(4)); // Skip command bytes

// Disable interface
await spi.disable();

Common Patterns​

Reading from SPI Flash​

// Configure for typical SPI flash (Mode 0, 3.3V, 10 MHz)
await spi.enable({
baud_rate: 10000000,
vcc: 3.3,
mode: 0
});

// Read JEDEC ID (0x9F command)
const jedecCmd = [0x9F, 0x00, 0x00, 0x00];
const jedecId = await spi.trx(jedecCmd);
console.log("Manufacturer:", jedecId[1].toString(16));
console.log("Device ID:", jedecId[2].toString(16), jedecId[3].toString(16));

// Read 256 bytes from address 0x000000
const readCmd = [0x03, 0x00, 0x00, 0x00, ...new Array(256).fill(0)];
const data = await spi.trx(readCmd);
const pageData = data.slice(4); // Skip 4 command bytes

SPI Sensor Communication​

// Configure for sensor (e.g., accelerometer)
await spi.enable({
baud_rate: 5000000,
vcc: 3.3,
mode: 3 // Some sensors use Mode 3
});

// Read register 0x0F (WHO_AM_I)
const whoAmI = await spi.trx([0x8F, 0x00]); // 0x80 = read bit
console.log("Device ID:", whoAmI[1].toString(16));

// Write to register 0x20
await spi.trx([0x20, 0x47]); // Write 0x47 to register 0x20

// Read multiple registers (burst read)
const burst = await spi.trx([0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
const values = burst.slice(1); // Skip command byte

Mode Selection Guide​

// Mode 0 (most common): Flash memory, SD cards, many sensors
await spi.configure({ mode: 0 });

// Mode 1: Some LCD controllers
await spi.configure({ mode: 1 });

// Mode 2: Rare, some specialized devices
await spi.configure({ mode: 2 });

// Mode 3: Some accelerometers, gyroscopes
await spi.configure({ mode: 3 });

Multi-Byte Transfer​

// Prepare large data transfer
const txData = new Array(1024).fill(0).map((_, i) => i & 0xFF);

// Send and receive
const rxData = await spi.trx(txData);

// Process response
console.log(`Transferred ${rxData.length} bytes`);

Voltage Level Configuration​

// 5V logic devices
await spi.configure({ vcc: 5.0 });

// 3.3V logic devices (most common)
await spi.configure({ vcc: 3.3 });

// 1.8V logic devices
await spi.configure({ vcc: 1.8 });

Notes​

  • SPI is a full-duplex protocol: data is transmitted and received simultaneously
  • The chip select (CS) signal must be managed manually using GPIO pins
  • MOSI (Master Out Slave In): Data from AT1000 to device
  • MISO (Master In Slave Out): Data from device to AT1000
  • SCK (Serial Clock): Clock signal generated by AT1000
  • Response length always equals transmission length (SPI characteristic)