Python API for Serial Cables Atlas3 PCIe Gen6 Host Adapter Card
Project description
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.negotiated_speed.value} x{port.negotiated_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}")
print(f" Status: {port.status.value}") # "Active", "Degraded", or "Idle"
if port.is_linked:
print(f" Speed: {port.negotiated_speed.value}") # "Gen6"
print(f" Width: x{port.negotiated_width}")
print(f" Max: {port.max_speed.value} x{port.max_width}")
# Check for degraded links
degraded = [p for p in ports.ext_mcio_ports if p.is_degraded]
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}")
# 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
- PCI5-ENC8-E3-08: Gen6 PCIe 8-bay E3 passive JBOF
- PCI6-AD-MX8-X16: MCIO x8 to PCIe x16 adapter
- MCIO6-8X-2X8B: MCIO x8 Y-cables
- MCIO6-8X-EDSFFX2-1X4: MCIO x8 to 2x EDSFF cables
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file serialcables_atlas3-0.1.0.tar.gz.
File metadata
- Download URL: serialcables_atlas3-0.1.0.tar.gz
- Upload date:
- Size: 29.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2944e6b95166df822868d976baf76b7b78da631a38fd852a3d9ef311ab71456d
|
|
| MD5 |
12c9399ed63fa1500c2a083a94f55243
|
|
| BLAKE2b-256 |
760245ba387ea45086938bdc179e3e9a1de5a398262c52d418909a82a6d9d98f
|
File details
Details for the file serialcables_atlas3-0.1.0-py3-none-any.whl.
File metadata
- Download URL: serialcables_atlas3-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62807560ea4bd24d32a26dc5328478735a854cec309642bcbe8fe84c05840bf1
|
|
| MD5 |
dd78578720c3a8faf7e7a7350185d0ae
|
|
| BLAKE2b-256 |
869d3e822bcdaf9c551f85b435eb01e95c301f4131b3cb57b6bd36ce4d5ffb62
|