Skip to main content

Serial Cables Atlas3 Python API

PyPI version Python versions License: MIT

A Python library for controlling the Serial Cables Atlas3 PCIe Gen6 Host Adapter Card (PCI6-AD-x16HI-BG6-144).

Features

  • Full Python API for all CLI commands
  • Type-safe with dataclasses and enums
  • Context manager support for automatic connection handling
  • Command-line interface included
  • Comprehensive error handling
  • PyPI installable

Hardware

The Atlas3 Host Adapter Card features the Broadcom PEX90144 PCIe Gen6 Switch supporting:

  • Up to 144 lanes and 72 ports
  • Five 16-lane downstream stations
  • PCIe Gen6 (64 GT/s) with FLIT mode
  • Ultra low latency with FLIT & FEC
  • Dynamic Port Reconfiguration (DPR)
  • Hot-plug support

Connectors

Connector Description Ports
CN1 PCIe Straddle mount (x16) Port 80
CN2 MCIO x8 (EXT upper) Ports 120-127
CN3 MCIO x8 (EXT lower) Ports 112-119
CN4 MCIO x8 (INT upper) Ports 136-143
CN5 MCIO x8 (INT lower) Ports 128-135
CN6 USB-C (SDB/SMART) -
CN7 USB-C (MCU CLI) -
CN9 12V 2x6 Power -

Installation

pip install serialcables-atlas3

Or install from source:

git clone https://github.com/serialcables/serialcables-atlas3.git
cd serialcables-atlas3
pip install -e .

Quick Start

Python API

from serialcables_atlas3 import Atlas3

# Connect to the Atlas3 card
with Atlas3("/dev/ttyUSB0") as card:
    # Get version information
    info = card.get_version()
    print(f"Model: {info.model}")
    print(f"MCU Version: {info.mcu_version}")
    
    # Get host card status
    status = card.get_host_card_info()
    print(f"Temperature: {status.thermal.switch_temperature_celsius}°C")
    print(f"Power: {status.power.load_power}W")
    
    # Get port status
    ports = card.get_port_status()
    for port in ports.ext_mcio_ports:
        if port.is_linked:
            print(f"Port {port.port_number}: {port.speed} x{port.width}")
    
    # Run built-in self-test
    bist = card.run_bist()
    print(f"BIST: {'PASS' if bist.all_passed else 'FAIL'}")

Command-Line Interface

# Show version information
atlas3-cli -p /dev/ttyUSB0 version

# Show host card status
atlas3-cli -p /dev/ttyUSB0 status

# Show port status
atlas3-cli -p /dev/ttyUSB0 ports

# Run BIST
atlas3-cli -p /dev/ttyUSB0 bist

# Set clock spread
atlas3-cli -p /dev/ttyUSB0 spread 1  # 2500PPM

# Reset a connector
atlas3-cli -p /dev/ttyUSB0 reset 0

# Output as JSON
atlas3-cli -p /dev/ttyUSB0 --json status

API Reference

Connection

from serialcables_atlas3 import Atlas3

# Manual connection management
card = Atlas3("/dev/ttyUSB0", auto_connect=False)
card.connect()
# ... use the card ...
card.disconnect()

# Context manager (recommended)
with Atlas3("/dev/ttyUSB0") as card:
    # ... use the card ...
    pass  # Automatically disconnects

# Find available devices
devices = Atlas3.find_devices()
print(devices)  # ['/dev/ttyUSB0', '/dev/ttyUSB1']

System Information

# Get version info (ver command)
info = card.get_version()
print(info.company)       # "Serial Cables"
print(info.model)         # "PCI6-AD-x16HI-BG6-144"
print(info.mcu_version)   # "0.2.3"
print(info.sbr_version)   # "0032A022"

# Get host card info (lsd command)
status = card.get_host_card_info()
print(status.thermal.switch_temperature_celsius)  # 46.0
print(status.fan.switch_fan_rpm)                  # 6456
print(status.voltages.voltage_1v5)                # 1.499
print(status.power.load_power)                    # 126.251

# Get complete system info (sysinfo command)
sysinfo = card.get_system_info()

Port Status

# Get port status (showport command)
ports = card.get_port_status()
print(ports.chip_version)  # "A0"

for port in ports.ext_mcio_ports:
    print(f"Port {port.port_number}:")
    print(f"  Station: {port.station_name}")      # "Stn7", "Stn8"
    print(f"  Connector: {port.connector}")       # "Con00", "Con01"
    print(f"  Status: {port.status_str}")         # "Active", "Degraded", "Idle"
    print(f"  Linked: {port.is_linked}")          # True if width > 0
    if port.is_linked:
        print(f"  Speed: {port.speed}")           # "Gen4", "Gen5", "Gen6"
        print(f"  Width: x{port.width}")          # 4, 8, 16
    print(f"  Max: {port.max_speed_str}")         # "Gen6 x4", "Gen6 x16"

# Check for degraded links
degraded = [p for p in ports.ext_mcio_ports if p.is_degraded]

# Check for linked ports
linked = [p for p in ports.int_mcio_ports if p.is_linked]

Error Counters

# Get error counters (counters command)
counters = card.get_error_counters()
print(f"Total errors: {counters.total_errors}")

for c in counters.counters:
    if c.has_errors:
        print(f"Port {c.port_number}:")
        print(f"  Bad TLP: {c.bad_tlp}")
        print(f"  Bad DLLP: {c.bad_dllp}")
        print(f"  Flit Error: {c.flit_error}")

# Query specific port
port_32 = counters.get_port(32)
if port_32:
    print(f"Port 32 total errors: {port_32.total_errors}")

# Get only ports with errors
for port in counters.ports_with_errors:
    print(f"Port {port.port_number}: {port.total_errors} errors")

# Serialize to JSON
json_str = counters.to_json(indent=2)

# Convert to dictionary
data = counters.to_dict()

# Convert to pandas DataFrame (requires pandas)
df = counters.to_dataframe()
errors_df = df[df['has_errors'] == True]

# Clear error counters
card.clear_error_counters()

Diagnostics

# Run BIST (bist command)
result = card.run_bist()
print(f"All passed: {result.all_passed}")

for device in result.devices:
    print(f"{device.channel} {device.device_name}: {device.status}")

Configuration

from serialcables_atlas3 import OperationMode, SpreadMode

# Mode configuration (setmode/showmode commands)
current_mode = card.get_mode()
print(f"Current mode: {current_mode.value}")  # 1, 2, 3, or 4

card.set_mode(OperationMode.MODE_1)  # Common clock, precoding enabled
# Note: Requires controller reset to take effect

# Clock spread (spread command)
spread = card.get_spread_status()
print(f"Spread enabled: {spread.enabled}")

card.set_spread(SpreadMode.DOWN_2500PPM)  # -0.25% spread
card.set_spread("off")  # Disable spread

# Clock output (clk command)
clk = card.get_clock_status()
print(f"Straddle clock: {'enabled' if clk.straddle_enabled else 'disabled'}")

card.set_clock_output(True)   # Enable clock output
card.set_clock_output(False)  # Disable clock output

# Flit mode (flit command)
flit = card.get_flit_status()
print(f"Station 2 flit disable: {flit.station2}")

card.set_flit_mode("all", False)  # Enable flit on all stations
card.set_flit_mode(2, True)       # Disable flit on station 2

# SDB routing (sdb command)
card.set_sdb_target("usb")  # Route to USB for SwitchCLID/ARCTIC
card.set_sdb_target("mcu")  # Route to MCU for normal operation

Reset Commands

# Reset connector (conrst command)
card.reset_connector(0)      # Reset CON0 (EXT MCIO upper)
card.reset_connector("all")  # Reset all connectors

# Reset MCU (reset command)
card.reset_mcu()

Register Access

# Read registers (dr command)
dump = card.read_register(0x60800000, count=16)
for addr, value in sorted(dump.values.items()):
    print(f"0x{addr:08X}: 0x{value:08X}")

# Write register (mw command)
card.write_register(0xFFF0017C, 0xFFFFFFFF)

# Read port registers (dp command)
port_dump = card.read_port_registers(32)  # Golden finger port

# Read flash (df command)
flash = card.read_flash(0x400, count=16)

I2C Access

# Read from I2C device (iicwr command)
result = card.i2c_read(
    address=0xD4,
    connector=2,
    channel="a",
    read_bytes=8,
    register=0
)
print([hex(b) for b in result.data])

# Write to I2C device (iicw command)
card.i2c_write(
    address=0xD4,
    connector=2,
    channel="a",
    data=[0xFF]
)

Connector and Port Mapping

Station Connector Ports Description
STN2 - 32 Golden Finger (Upstream)
STN5 CON4 80 PCIe Straddle
STN7 CON0 112-118 EXT MCIO upper
STN7 CON1 120-126 EXT MCIO lower
STN8 CON2 128-134 INT MCIO upper
STN8 CON3 136-142 INT MCIO lower

LED Indicators

Status LEDs

LED Color Description
SLED1 Red System error
SLED2 Green Heartbeat (blinking = managed FW running)
SLED3 Green MCU status (blinking = MCU running)

Link Speed LEDs (Blue)

Blink Rate Speed
0.25 Hz Gen1 (2.5 GT/s)
0.5 Hz Gen2 (5.0 GT/s)
1.0 Hz Gen3 (8.0 GT/s)
2.0 Hz Gen4 (16.0 GT/s)
4.0 Hz Gen5 (32.0 GT/s)
Always on Gen6 (64.0 GT/s)

Error Handling

from serialcables_atlas3 import (
    Atlas3,
    Atlas3Error,
    ConnectionError,
    CommandError,
    TimeoutError,
    InvalidParameterError,
)

try:
    with Atlas3("/dev/ttyUSB0") as card:
        card.set_mode(5)  # Invalid mode
except InvalidParameterError as e:
    print(f"Invalid parameter: {e}")
except ConnectionError as e:
    print(f"Connection failed: {e}")
except TimeoutError as e:
    print(f"Command timed out: {e}")
except CommandError as e:
    print(f"Command failed: {e}")
except Atlas3Error as e:
    print(f"Atlas3 error: {e}")

Development

# Clone the repository
git clone https://github.com/serialcables/serialcables-atlas3.git
cd serialcables-atlas3

# Install in development mode with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black src tests
isort src tests

# Type checking
mypy src

# Lint
ruff check src tests

License

MIT License - see LICENSE for details.

Support

Related Products

  • PCI6-AD-x16HI-BG6-144: Gen6 x16 – 4, x8 MCIO Host Card w/ 1x16 Straddle Mount Connector (A0 144-lane Switch)8-bay E3 passive JBOF

Metadata

Release files for serialcables-atlas3 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for serialcables-atlas3 0.1.5
File Size Uploaded
serialcables_atlas3-0.1.5.tar.gz 31.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for serialcables-atlas3 0.1.5
File Interpreter ABI Platform
serialcables_atlas3-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 58.0 kB

Release files / serialcables_atlas3-0.1.5.tar.gz

Download URL serialcables_atlas3-0.1.5.tar.gz
Size 31.3 kB
Tags Source
SHA-256 checksum
How to use checksums
49b699fc08cba1f09d3805e89b9f108ebbd6d47d2496cc6f6454552302f94d66
BLAKE2b-256 checksum
How to use checksums
71d6ad36ee8fadfd4f9e1060bb6fcadeb195dcd2baccccb81a6d9f6657ee67a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.3

Release files / serialcables_atlas3-0.1.5-py3-none-any.whl

Download URL serialcables_atlas3-0.1.5-py3-none-any.whl
Size 26.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17264e6952fe8c185257add742d02ec037a3e7d54936d72a28028c2ac52f58d3
BLAKE2b-256 checksum
How to use checksums
eff040fc2f4f36a76ad341efe5e414ef65287a34e47606b35ca51ec001e5fc22
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.3

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page