Serial Cables Atlas3 Python API
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
- Website: https://serialcables.com
- Email: support@serialcables.com
- Address: 8811 American Way, Suite 110, Englewood, CO 80107
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)
| File | Size | Uploaded | |
|---|---|---|---|
| serialcables_atlas3-0.1.5.tar.gz | 31.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|