Skip to main content

Python bindings for SP1000G Logic Analyzer API

Project description

Ikalogic SP1000G Python Bindings

Python bindings for the Ikalogic SP1000G series logic analyzers.

Installation

pip install ikalogic-sp1000g

Supported Devices

  • SP1018G: 18 channels
  • SP1036G: 36 channels
  • SP1054G: 54 channels

Quick Start

Basic Example: Capturing a Clock Signal

This example shows how to capture and analyze a clock signal on channel 0:

from ikalogic import sp1000g
import time

# Create API instance for your device model
api = sp1000g.SP1000G(sp1000g.Model.SP1018G)

# Find and open device
api.create_device_list()
count = api.get_devices_count()
print(f"Found {count} device(s)")

if count > 0:
    api.device_open_first()
    
    # Get firmware version
    fpga_ver = f"{api.get_fpga_version_major()}.{api.get_fpga_version_minor()}"
    print(f"Firmware version: {fpga_ver}")

    # Configure capture settings
    settings = sp1000g.Settings()
    settings.sampling_depth = 1000000   # 1M samples total
    settings.post_trig_depth = 900000   # 900K samples after trigger
    settings.s_clk = 250000000          # 250 MHz sampling clock
    
    # Configure thresholds (in millivolts)
    # IMPORTANT: Must assign the whole array at once!
    settings.thresh_capture_mv = [1600, 1600, 1600, 1600, 1600, 1600]
    
    # Trigger configuration (no trigger - immediate capture)
    settings.trig_order = 3
    
    trigger_a = sp1000g.TriggerDescription()
    trigger_a.type = sp1000g.TriggerType.TRG_NOTRIG
    trigger_a.channel = -1
    
    trigger_b = sp1000g.TriggerDescription()
    trigger_b.type = sp1000g.TriggerType.TRG_NOTRIG
    trigger_b.channel = -1
    
    # Launch capture
    print("Launching capture...")
    api.launch_new_capture_simple_trigger(trigger_a, trigger_b, settings)

    # Wait for trigger
    while not api.get_triggered_flag():
        time.sleep(0.25)
    print("Triggered!")

    # Wait for capture complete
    while not api.get_capture_done_flag():
        time.sleep(0.1)
    print("Capture complete!")
    
    # Read transitions from channel 0
    api.trs_reset(0)
    prev_sample_index = 0
    
    print("\nFirst 20 transitions:")
    count = 0
    while api.trs_is_not_last(0) and count < 20:
        ch0 = api.trs_get_next(0)
        delta = ch0.sample_index - prev_sample_index
        time_us = (delta / settings.s_clk) * 1e6
        print(f"  {ch0.value}/{ch0.sample_index}/{delta} ({time_us:.3f} µs)")
        prev_sample_index = ch0.sample_index
        count += 1
    
    api.device_close()

Important Notes:

  • Array Properties: Settings arrays must be assigned as complete lists:

    # ✅ CORRECT
    settings.thresh_capture_mv = [1600, 1600, 1600, 1600, 1600, 1600]
    
    # ❌ WRONG - doesn't work!
    settings.thresh_capture_mv[0] = 1600
    
  • Transition Iterator: Use trs_reset(), trs_is_not_last(), and trs_get_next() to read transitions.

  • Sample Index: The sample_index field contains the absolute sample position of each transition.

API Reference

Main Class: SP1000G

Constructor

api = sp1000g.SP1000G(model)
  • model: One of sp1000g.Model.SP1018G, sp1000g.Model.SP1036G, or sp1000g.Model.SP1054G

Device Management Methods

create_device_list()

Create or update the list of SP1000G devices connected via USB.

api.create_device_list()

free_device_list()

Free memory used to store the device list.

api.free_device_list()

get_devices_count() -> int

Get the number of devices in the list.

count = api.get_devices_count()

get_device_descriptor(device_number) -> DeviceDescriptor

Get device information by index (0-based).

desc = api.get_device_descriptor(0)
print(f"Serial: {desc.serial_number}")
print(f"Description: {desc.description}")

device_open(descriptor)

Open a specific device using its descriptor.

desc = api.get_device_descriptor(0)
api.device_open(desc)

device_open_first()

Open the first available device in the list.

api.device_open_first()

device_close()

Close the currently open device.

api.device_close()

get_device_open_flag() -> bool

Check if a device is currently open.

is_open = api.get_device_open_flag()

Version Information Methods

get_fpga_version_major() -> int

Get FPGA firmware major version number.

major = api.get_fpga_version_major()

get_fpga_version_minor() -> int

Get FPGA firmware minor version number.

minor = api.get_fpga_version_minor()

get_mcu_version_major() -> int

Get MCU firmware major version number.

major = api.get_mcu_version_major()

get_mcu_version_minor() -> int

Get MCU firmware minor version number.

minor = api.get_mcu_version_minor()

Capture Methods

launch_new_capture_simple_trigger(trigger, trigger_b, settings)

Launch a new capture with simple trigger configuration.

# Create trigger configurations
trigger_a = sp1000g.TriggerDescription()
trigger_a.type = sp1000g.TriggerType.TRG_RISING
trigger_a.channel = 0

trigger_b = sp1000g.TriggerDescription()
trigger_b.type = sp1000g.TriggerType.TRG_NOTRIG
trigger_b.channel = 0

# Create settings
settings = sp1000g.Settings()
settings.sampling_depth = 10000000
settings.post_trig_depth = 9000000
settings.s_clk = 250000000  # 250 MHz

# Set thresholds (one per threshold input, not per channel)
settings.thresh_capture_mv = [1650, 1650]  # 2 thresholds for SP1018G

# Launch capture
api.launch_new_capture_simple_trigger(trigger_a, trigger_b, settings)

get_config_done_flag() -> bool

Check if device configuration is complete.

while not api.get_config_done_flag():
    time.sleep(0.01)

get_triggered_flag() -> bool

Check if the device has triggered.

while not api.get_triggered_flag():
    time.sleep(0.01)

get_trigger_position() -> int

Get the trigger position in samples.

trig_pos = api.get_trigger_position()

get_available_samples() -> tuple[int, int]

Get available samples count.

Returns a tuple: (total_samples, post_trigger_samples)

total, post_trig = api.get_available_samples()
print(f"Total: {total}, Post-trigger: {post_trig}")

get_capture_done_flag() -> bool

Check if capture is complete and all data has been retrieved.

while not api.get_capture_done_flag():
    time.sleep(0.01)

get_ready_flag() -> bool

Check if device is ready (no operation in progress).

is_ready = api.get_ready_flag()

request_abort()

Request any pending operation to abort.

api.request_abort()

Transition Iterator Methods

These methods allow you to iterate through signal transitions on each channel.

trs_reset(channel_index)

Reset the transitions iterator for a specific channel to the beginning.

api.trs_reset(0)  # Reset iterator for channel 0

trs_before(channel_index, target_sample)

Position the transitions iterator before a specific sample number.

api.trs_before(0, 1000)  # Position before sample 1000 on channel 0

trs_get_next(channel_index) -> Transition

Get the next transition for a channel.

transition = api.trs_get_next(0)
print(f"Value: {transition.value}, Sample: {transition.sample_index}")

trs_get_previous(channel_index) -> Transition

Get the previous transition for a channel.

transition = api.trs_get_previous(0)

trs_is_not_last(channel_index) -> bool

Check if the current transition is not the last one.

while api.trs_is_not_last(0):
    trs = api.trs_get_next(0)
    # Process transition

Error Handling

get_last_error() -> ErrorCode

Get the last error code from internal threads.

err = api.get_last_error()
if err != sp1000g.ErrorCode.OK:
    print(f"Error: {err}")

Data Structures

DeviceDescriptor

Represents device information.

desc = sp1000g.DeviceDescriptor()
desc.serial_number = "SN12345"
desc.description = "My Device"

Attributes:

  • serial_number (str): Device serial number
  • description (str): Device description

TriggerDescription

Defines a trigger condition.

trigger = sp1000g.TriggerDescription()
trigger.type = sp1000g.TriggerType.TRG_RISING
trigger.channel = 0

Attributes:

  • type (TriggerType): Type of trigger
  • channel (int): Channel number for the trigger

Settings

Capture and device configuration.

settings = sp1000g.Settings()

Attributes:

Basic Capture Settings:

  • sampling_depth (int): Total number of samples to capture
  • post_trig_depth (int): Number of samples to capture after trigger
  • s_clk (int): State clock frequency in Hz
  • state_clk_mode (StateClkMode): State clock mode
  • state_clk_src (StateClkSource): State clock source
  • timebase_src (TimebaseClk): Timebase clock source

Trigger Settings:

  • trig_order (int): Trigger order
  • t_clk (list[int]): Trigger clock frequencies (length = TRIG_ENGINES_COUNT = 2)

Threshold and Power Settings:

  • thresh_capture_mv (list[int]): Capture thresholds in millivolts (length = THRESHOLDS_COUNT = 6)
  • vcc_gen_mv (list[int]): Generated VCC in millivolts (length = THRESHOLDS_COUNT = 6)

⚠️ IMPORTANT: Array properties must be assigned as complete lists, not element-by-element:

# ✅ CORRECT
settings.thresh_capture_mv = [1600, 1600, 1600, 1600, 1600, 1600]

# ❌ WRONG - This does NOT work!
settings.thresh_capture_mv[0] = 1600  # Creates a temporary copy, doesn't modify settings
settings.thresh_capture_mv[1] = 1600  # Creates another temporary copy, changes are lost

This applies to all array properties: t_clk, thresh_capture_mv, vcc_gen_mv, io_type, io_pull, oci_clk_out_enable, and oci_clk_out_freq.

I/O Configuration:

  • io_type (list[IOType]): I/O type for each channel (length = CHANNELS_COUNT)
  • io_pull (list[Pull]): Pull resistor for each channel (length = CHANNELS_COUNT)

External Trigger:

  • ext_trig_50r (bool): Enable 50Ω termination on external trigger input
  • ext_in_threshold_mv (int): External input threshold in millivolts
  • ext_trig_out_polarity (int): External trigger output polarity

On-Chip Instrumentation (OCI) Clock:

  • oci_clk_out_enable (list[list[bool]]): Enable OCI clocks (GROUPS_COUNT x OCI_CLOCK_COUNT)
  • oci_clk_out_freq (list[list[int]]): OCI clock frequencies (GROUPS_COUNT x OCI_CLOCK_COUNT)

Example:

settings = sp1000g.Settings()
settings.sampling_depth = 10000000
settings.post_trig_depth = 5000000
settings.s_clk = 100000000

# Set trigger clocks
settings.t_clk = [100000000, 100000000]

# Set thresholds
settings.thresh_capture_mv = [1650, 1650, 1650]
settings.vcc_gen_mv = [3300, 3300, 3300]

# Configure I/O (example for first 3 channels)
settings.io_type = [sp1000g.IOType.IO_IN] * sp1000g.CHANNELS_COUNT
settings.io_pull = [sp1000g.Pull.PULL_DOWN] * sp1000g.CHANNELS_COUNT

Transition

Represents a signal transition on a channel.

# Get transition from iterator
transition = api.trs_get_next(0)
print(f"Value: {transition.value}")
print(f"Sample: {transition.sample_index}")

Attributes:

  • value (int): Signal value at this transition (0 or 1)
  • sample_index (int): Absolute sample index where this transition occurred

Note: The sample_index is the absolute position in the capture buffer, not a delta from the previous transition. To calculate the time between transitions:

prev_sample = 0
while api.trs_is_not_last(0):
    trs = api.trs_get_next(0)
    delta = trs.sample_index - prev_sample
    time_us = (delta / sampling_freq) * 1e6
    print(f"Transition at {trs.sample_index}: value={trs.value}, "
          f"delta={delta} samples ({time_us:.3f} µs)")
    prev_sample = trs.sample_index

Enumerations

Model

Device models.

  • SP1018G - 18 channels
  • SP1036G - 36 channels
  • SP1054G - 54 channels

TriggerType

Trigger types.

  • TRG_NOTRIG - No trigger
  • TRG_RISING - Rising edge
  • TRG_FALLING - Falling edge
  • TRG_CHANGE - Any edge (rising or falling)
  • TRG_EXT_RISING - External trigger rising edge
  • TRG_EXT_FALLING - External trigger falling edge

ErrorCode

Error codes.

  • OK - Success
  • HW_ERRORS - Hardware error
  • NOT_SUPPORTED - Unsupported command
  • DEVICE_NOT_OPEN - Device not open
  • DEVICE_NOT_FOUND - Device not found
  • INVALID_SERIAL - Invalid serial number
  • INVALID_CONFIG - Invalid configuration
  • INVALID_ARGUMENT - Invalid argument
  • BUSY - Device busy
  • ABORTED - Operation aborted
  • POWER_FAILURE - Power failure
  • PLL_FAILURE - PLL failure
  • FLUSH_TIMEOUT - Flush timeout
  • NOT_RESPONDING - Device not responding
  • NO_DATA - No data available
  • FIRMWARE_ERROR - Firmware error
  • FIRM_UPDT_FAILED - Firmware update failed
  • DATA_NOT_ALIGNED - Data not aligned
  • DEVICE_FORGED - Device forged
  • HARDWARE_FAULT - Hardware fault
  • UNKNOWN_ERROR - Unknown error
  • USB_ERRORS - USB error
  • USB3_ERRORS - USB3 error
  • NOT_IMPLEMENTED - Not implemented

Pull

Pull resistor configuration.

  • PULL_DOWN - Pull-down resistor
  • PULL_UP - Pull-up resistor

IOType

I/O type configuration.

  • IO_IN - Input
  • IO_PP - Push-Pull output
  • IO_OD - Open-Drain output

StateClkMode

State clock mode.

  • SCLK_DISABLE - Disabled
  • SCLK_RISING - Rising edge
  • SCLK_FALLING - Falling edge
  • SCLK_DUAL - Dual edge

StateClkSource

State clock source.

  • SCLK_CH9 - Channel 9
  • SCLK_CH18 - Channel 18

TimebaseClk

Timebase clock source.

  • TIMEBASE_INTERNAL - Internal timebase
  • TIMEBASE_EXTERNAL - External timebase

Constants

These constants are available as module attributes:

sp1000g.GROUPS_COUNT         # Number of channel groups
sp1000g.CHANNELS_COUNT       # Total number of channels (model-dependent)
sp1000g.TRIG_ENGINES_COUNT   # Number of trigger engines (2)
sp1000g.THRESHOLDS_COUNT     # Number of threshold inputs (3)
sp1000g.MAX_TRIG_STEPS_COUNT # Maximum trigger steps
sp1000g.OCI_CLOCK_COUNT      # Number of OCI clocks per group

Complete Example

import time
from ikalogic import sp1000g

# Create API instance
api = sp1000g.SP1000G(sp1000g.Model.SP1054G)

try:
    # Find and open device
    api.create_device_list()
    count = api.get_devices_count()
    print(f"Found {count} device(s)")
    
    if count == 0:
        print("No devices found!")
        exit(1)
    
    # Open first device
    api.device_open_first()
    print("Device opened")
    
    # Get version info
    fpga_ver = f"{api.get_fpga_version_major()}.{api.get_fpga_version_minor()}"
    mcu_ver = f"{api.get_mcu_version_major()}.{api.get_mcu_version_minor()}"
    print(f"FPGA: {fpga_ver}, MCU: {mcu_ver}")
    
    # Configure capture
    settings = sp1000g.Settings()
    settings.sampling_depth = 1000000
    settings.post_trig_depth = 500000
    settings.s_clk = 100000000  # 100 MHz
    settings.t_clk = [100000000, 100000000]
    settings.thresh_capture_mv = [1650, 1650, 1650]
    settings.vcc_gen_mv = [3300, 3300, 3300]
    settings.io_type = [sp1000g.IOType.IO_IN] * sp1000g.CHANNELS_COUNT
    settings.io_pull = [sp1000g.Pull.PULL_DOWN] * sp1000g.CHANNELS_COUNT
    
    # Configure trigger - rising edge on channel 0
    trigger_a = sp1000g.TriggerDescription()
    trigger_a.type = sp1000g.TriggerType.TRG_RISING
    trigger_a.channel = 0
    
    trigger_b = sp1000g.TriggerDescription()
    trigger_b.type = sp1000g.TriggerType.TRG_NOTRIG
    trigger_b.channel = 0
    
    # Launch capture
    print("Launching capture...")
    api.launch_new_capture_simple_trigger(trigger_a, trigger_b, settings)
    
    # Wait for configuration
    while not api.get_config_done_flag():
        time.sleep(0.01)
    print("Configuration done")
    
    # Wait for trigger
    print("Waiting for trigger...")
    while not api.get_triggered_flag():
        time.sleep(0.01)
    print("Triggered!")
    
    # Wait for capture complete
    while not api.get_capture_done_flag():
        time.sleep(0.01)
    print("Capture complete")
    
    # Get trigger info
    trig_pos = api.get_trigger_position()
    total, post = api.get_available_samples()
    print(f"Trigger at sample {trig_pos}")
    print(f"Captured {total} samples ({post} post-trigger)")
    
    # Read transitions on channel 0
    print("\nFirst 10 transitions on channel 0:")
    api.trs_reset(0)
    count = 0
    while api.trs_is_not_last(0) and count < 10:
        trs = api.trs_get_next(0)
        print(f"  Sample {trs.sample_index}: {trs.value}")
        count += 1
    
finally:
    # Clean up
    if api.get_device_open_flag():
        api.device_close()
        print("\nDevice closed")

Requirements

  • Python 3.7+
  • Supported platforms:
    • Linux x86_64 (manylinux2014)
    • Windows x64
    • macOS (Intel and Apple Silicon)

Linux Dependencies

Usually pre-installed, but if needed:

sudo apt-get install libusb-1.0-0 libudev1

License

Copyright (c) 2023-2025 IKALOGIC SAS

See LICENSE file for details.


Support

For support, please visit ikalogic.com or contact support@ikalogic.com.

Supported Devices

  • SP1018G: 18 channels, 1 GHz sampling
  • SP1036G: 36 channels, 1 GHz sampling
  • SP1054G: 54 channels, 1 GHz sampling

Basic Usage

Device Management

# Create device list
api.create_device_list()

# Get number of devices
count = api.get_devices_count()

# Get device info
for i in range(count):
    desc = api.get_device_descriptor(i)
    print(f"Device {i}: {desc.serial_number}")

# Open device
api.device_open_first()  # or api.device_open(index)

# Check if open
if api.get_device_open_flag():
    print("Device is open")

# Close device
api.device_close()

Capture Configuration

# Create settings
settings = sp1000g.Settings()
settings.sampling_depth = 1000000      # Total samples
settings.post_trig_depth = 900000      # Samples after trigger
settings.s_clk = 250000000             # 250 MHz sampling

# Set thresholds (mV) - one per channel
settings.thresh_capture_mv = [1650] * 18  # For SP1018G

# Apply settings
api.apply_settings(settings)

Triggering

# Simple trigger
trigger = sp1000g.TriggerDescription()
trigger.type = sp1000g.TriggerType.TRG_RISING
trigger.channel = 0

api.launch_new_capture_simple_trigger(trigger, settings, 0, True, 0, 0, 0)

# Wait for capture
while not api.is_capture_complete():
    time.sleep(0.1)

Reading Data

# Reset transition iterator
api.trs_reset(0)

# Read transitions
while api.trs_is_not_last(0):
    trs = api.trs_get_next(0)
    print(f"Sample {trs.sample_index}: Channel {trs.channel} = {trs.value}")

API Reference

Classes

  • SP1000G(model) - Main API class
  • Settings - Capture configuration
  • TriggerDescription - Trigger configuration
  • DeviceDescriptor - Device information
  • Transition - Signal transition data

Enums

  • Model - Device models (SP1018G, SP1054G, SP1108G)
  • TriggerType - Trigger types (RISING, FALLING, ANY_EDGE, etc.)
  • DeviceState - Device states

Requirements

  • Python 3.7+
  • Linux x86_64
  • libusb-1.0 (usually pre-installed)
  • libudev (usually pre-installed)

License

See LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ikalogic_sp1000g-0.1.13-cp312-cp312-win_amd64.whl (1.4 MB view details)

Uploaded CPython 3.12Windows x86-64

File details

Details for the file ikalogic_sp1000g-0.1.13-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for ikalogic_sp1000g-0.1.13-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 0d46b5634016e58056a2d7e78e94e358e7e6f8e024c1f3d4a23f1dc0fda46da8
MD5 9a49195a0c1615d6b0991339ef238635
BLAKE2b-256 ef06fab24f59befa28e988c18fa607ca2ff5fea9c615916031ed051eeaea51e7

See more details on using hashes here.

File details

Details for the file ikalogic_sp1000g-0.1.13-cp312-cp312-manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ikalogic_sp1000g-0.1.13-cp312-cp312-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7a58f36e63994887033f48eaaea56704a2a9845fad43cb918908cee214027179
MD5 abc71b113f51f609d0fc90fa571756db
BLAKE2b-256 09cf0d68f4fd7fae6a4fbf3f238c10fd8a220fbf361c1304c9dcebd3a2bd374d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page