124 lines
3.6 KiB
Python
124 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Configuration file for VNA data acquisition system
|
|
"""
|
|
|
|
import glob
|
|
import logging
|
|
from pathlib import Path
|
|
import serial.tools.list_ports
|
|
|
|
# Base directory for VNA system
|
|
BASE_DIR = Path(__file__).parent.parent
|
|
|
|
# Serial communication settings
|
|
DEFAULT_BAUD_RATE = 115200
|
|
DEFAULT_PORT = "/dev/ttyACM0"
|
|
|
|
# VNA device identification
|
|
VNA_VID = 0x0483 # STMicroelectronics
|
|
VNA_PID = 0x5740 # STM32 Virtual ComPort
|
|
VNA_MANUFACTURER = "STMicroelectronics"
|
|
VNA_PRODUCT = "STM32 Virtual ComPort"
|
|
RX_TIMEOUT = 5.0
|
|
TX_CHUNK_SIZE = 64 * 1024
|
|
|
|
# Sweep detection and parsing constants
|
|
SWEEP_CMD_LEN = 515
|
|
SWEEP_CMD_PREFIX = bytes([0xAA, 0x00, 0xDA])
|
|
MEAS_HEADER_LEN = 21
|
|
MEAS_CMDS_PER_SWEEP = 17
|
|
EXPECTED_POINTS_PER_SWEEP = 1000
|
|
|
|
# Buffer settings
|
|
SWEEP_BUFFER_MAX_SIZE = 100 # Maximum number of sweeps to store in circular buffer
|
|
SERIAL_BUFFER_SIZE = 512 * 1024
|
|
|
|
# Log file settings
|
|
BIN_INPUT_FILE_PATH = "./vna_system/binary_input/current_input.bin" # Symbolic link to the current log file
|
|
|
|
# Binary log format constants
|
|
MAGIC = b"VNALOG1\n"
|
|
DIR_TO_DEV = 0x01 # '>'
|
|
DIR_FROM_DEV = 0x00 # '<'
|
|
|
|
# File I/O settings
|
|
FILE_CHUNK_SIZE = 256 * 1024
|
|
SERIAL_PEEK_SIZE = 32
|
|
|
|
# Timeout settings
|
|
SERIAL_IDLE_TIMEOUT = 0.5
|
|
SERIAL_DRAIN_DELAY = 0.05
|
|
SERIAL_DRAIN_CHECK_DELAY = 0.01
|
|
SERIAL_CONNECT_DELAY = 0.01
|
|
|
|
|
|
def find_vna_port():
|
|
"""
|
|
Automatically find VNA device port.
|
|
|
|
Returns:
|
|
str: Port path (e.g., '/dev/ttyACM1') or None if not found
|
|
"""
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Method 1: Use pyserial port detection by VID/PID
|
|
try:
|
|
ports = list(serial.tools.list_ports.comports())
|
|
|
|
logger.debug(f"Found {len(ports)} serial ports")
|
|
|
|
for port in ports:
|
|
logger.debug(f"Checking port {port.device}")
|
|
|
|
# Check by VID/PID
|
|
if port.vid == VNA_VID and port.pid == VNA_PID:
|
|
logger.debug(f"Found VNA device by VID/PID at {port.device}")
|
|
return port.device
|
|
|
|
# Fallback: Check by manufacturer/product strings
|
|
if (port.manufacturer and VNA_MANUFACTURER.lower() in port.manufacturer.lower() and
|
|
port.description and VNA_PRODUCT.lower() in port.description.lower()):
|
|
logger.debug(f"Found VNA device by description at {port.device}")
|
|
return port.device
|
|
|
|
except Exception as e:
|
|
logger.warning(f"Error during VID/PID port detection: {e}")
|
|
|
|
# Method 2: Search ttyACM devices (Linux-specific)
|
|
try:
|
|
acm_ports = glob.glob('/dev/ttyACM*')
|
|
logger.debug(f"Found ACM ports: {acm_ports}")
|
|
|
|
if acm_ports:
|
|
# Sort to get consistent ordering (ttyACM0, ttyACM1, etc.)
|
|
acm_ports.sort()
|
|
logger.info(f"Using first available ACM port: {acm_ports[0]}")
|
|
return acm_ports[0]
|
|
|
|
except Exception as e:
|
|
logger.warning(f"Error during ACM port detection: {e}")
|
|
|
|
# Method 3: Fallback to default
|
|
logger.warning(f"VNA device not found, using default port: {DEFAULT_PORT}")
|
|
return DEFAULT_PORT
|
|
|
|
|
|
def get_vna_port():
|
|
"""
|
|
Get VNA port, trying auto-detection first, then falling back to default.
|
|
|
|
Returns:
|
|
str: Port path to use for VNA connection
|
|
"""
|
|
logger = logging.getLogger(__name__)
|
|
|
|
try:
|
|
port = find_vna_port()
|
|
if port and port != DEFAULT_PORT:
|
|
logger.info(f"Auto-detected VNA port: {port}")
|
|
return port
|
|
except Exception as e:
|
|
logger.error(f"Port detection failed: {e}")
|
|
logger.info(f"Using default port: {DEFAULT_PORT}")
|
|
return DEFAULT_PORT |