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.
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.
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.
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.
- NodeJS
- Python
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);
from ikalogic_at1000 import AT1000
testers = await AT1000.find_devices(500) # Find the device with serial number 12345
tester = testers[0] # Target the first detected device
spi = tester.com.spi(0) # Select the first SPI bus
cs_pin = tester.gpio.digital(5) # GPIO 5 on master device
await cs_pin.config_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
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
print(f"Received data: {rx_data}")
API Reference​
Accessing SPI​
- NodeJS
- Python
const spi = tester.com.spi(id);
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.
- NodeJS
- Python
await spi.configure({
baud_rate: 1000000,
vcc: 3.3,
mode: 0
});
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 interfacebaud_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_rateis outside the range [300, 10000000] - Throws validation error if
vccis outside the range [1.6, 5.0] - Throws validation error if
modeis outside the range [0, 3]
enable([config])​
Enables the SPI interface and optionally applies configuration.
- NodeJS
- Python
await spi.enable({
baud_rate: 1000000,
vcc: 3.3,
mode: 0
});
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.
- NodeJS
- Python
await spi.disable();
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).
- NodeJS
- Python
// 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");
# Send command and receive response
response = await spi.trx([0x03, 0x00, 0x00, 0x00])
print(f"Received: {response}")
# Send string
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 charactersnumber[]: 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​
- NodeJS
- Python
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();
from ikalogic_at1000 import AT1000
import asyncio
# Find and connect to device
devices = await AT1000.find_devices(500)
tester = devices[0]
# Access SPI interface 0
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)
read_cmd = [0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
response = await spi.trx(read_cmd)
print(f"Data: {response[4:]}") # Skip command bytes
# Disable interface
await spi.disable()
Common Patterns​
Reading from SPI Flash​
- NodeJS
- Python
// 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
# 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)
jedec_cmd = [0x9F, 0x00, 0x00, 0x00]
jedec_id = await spi.trx(jedec_cmd)
print(f"Manufacturer: {jedec_id[1]:02x}")
print(f"Device ID: {jedec_id[2]:02x} {jedec_id[3]:02x}")
# Read 256 bytes from address 0x000000
read_cmd = [0x03, 0x00, 0x00, 0x00] + [0x00] * 256
data = await spi.trx(read_cmd)
page_data = data[4:] # Skip 4 command bytes
SPI Sensor Communication​
- NodeJS
- Python
// 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
# 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)
who_am_i = await spi.trx([0x8F, 0x00]) # 0x80 = read bit
print(f"Device ID: {who_am_i[1]:02x}")
# Write to register 0x20
await spi.trx([0x20, 0x47]) # Write 0x47 to register 0x20
# Read multiple registers (burst read)
burst = await spi.trx([0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
values = burst[1:] # Skip command byte
Mode Selection Guide​
- NodeJS
- Python
// 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 });
# 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​
- NodeJS
- Python
// 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`);
# Prepare large data transfer
tx_data = [i & 0xFF for i in range(1024)]
# Send and receive
rx_data = await spi.trx(tx_data)
# Process response
print(f"Transferred {len(rx_data)} bytes")
Voltage Level Configuration​
- NodeJS
- Python
// 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 });
# 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)