|
|
|
@ -131,7 +131,8 @@ class Session(QObject):
|
|
|
|
self.session_profile_id: Optional[int] = None
|
|
|
|
self.session_profile_id: Optional[int] = None
|
|
|
|
|
|
|
|
|
|
|
|
# Hardware ports (managed by this class)
|
|
|
|
# Hardware ports (managed by this class)
|
|
|
|
self.uart_port: Optional[UARTPort] = None
|
|
|
|
self.uart_command_port: Optional[UARTPort] = None # For sending commands (TX/RX)
|
|
|
|
|
|
|
|
self.uart_logger_port: Optional[UARTPort] = None # For telemetry packets (RX only, optional)
|
|
|
|
self.i2c_handle: Optional[I2CHandle] = None
|
|
|
|
self.i2c_handle: Optional[I2CHandle] = None
|
|
|
|
self.packet_config: Optional[PacketConfig] = None
|
|
|
|
self.packet_config: Optional[PacketConfig] = None
|
|
|
|
|
|
|
|
|
|
|
|
@ -184,7 +185,7 @@ class Session(QObject):
|
|
|
|
profile_name,
|
|
|
|
profile_name,
|
|
|
|
uart_command_port, uart_command_baud, uart_command_data_bits,
|
|
|
|
uart_command_port, uart_command_baud, uart_command_data_bits,
|
|
|
|
uart_command_stop_bits, uart_command_parity, uart_command_timeout_ms,
|
|
|
|
uart_command_stop_bits, uart_command_parity, uart_command_timeout_ms,
|
|
|
|
uart_logger_port, uart_logger_baud, uart_logger_data_bits,
|
|
|
|
uart_logger_enable, uart_logger_port, uart_logger_baud, uart_logger_data_bits,
|
|
|
|
uart_logger_stop_bits, uart_logger_parity, uart_logger_timeout_ms,
|
|
|
|
uart_logger_stop_bits, uart_logger_parity, uart_logger_timeout_ms,
|
|
|
|
uart_logger_packet_detect_enable, uart_logger_packet_detect_start,
|
|
|
|
uart_logger_packet_detect_enable, uart_logger_packet_detect_start,
|
|
|
|
uart_logger_packet_detect_length, uart_logger_packet_detect_end,
|
|
|
|
uart_logger_packet_detect_length, uart_logger_packet_detect_end,
|
|
|
|
@ -210,22 +211,23 @@ class Session(QObject):
|
|
|
|
'uart_command_parity': row[5],
|
|
|
|
'uart_command_parity': row[5],
|
|
|
|
'uart_command_timeout_ms': row[6],
|
|
|
|
'uart_command_timeout_ms': row[6],
|
|
|
|
# UART Logger interface
|
|
|
|
# UART Logger interface
|
|
|
|
'uart_logger_port': row[7],
|
|
|
|
'uart_logger_enable': bool(row[7]) if row[7] is not None else True,
|
|
|
|
'uart_logger_baud': row[8],
|
|
|
|
'uart_logger_port': row[8],
|
|
|
|
'uart_logger_data_bits': row[9],
|
|
|
|
'uart_logger_baud': row[9],
|
|
|
|
'uart_logger_stop_bits': row[10],
|
|
|
|
'uart_logger_data_bits': row[10],
|
|
|
|
'uart_logger_parity': row[11],
|
|
|
|
'uart_logger_stop_bits': row[11],
|
|
|
|
'uart_logger_timeout_ms': row[12],
|
|
|
|
'uart_logger_parity': row[12],
|
|
|
|
|
|
|
|
'uart_logger_timeout_ms': row[13],
|
|
|
|
# Packet detection
|
|
|
|
# Packet detection
|
|
|
|
'packet_detect_enable': row[13],
|
|
|
|
'packet_detect_enable': row[14],
|
|
|
|
'packet_detect_start': row[14],
|
|
|
|
'packet_detect_start': row[15],
|
|
|
|
'packet_detect_length': row[15],
|
|
|
|
'packet_detect_length': row[16],
|
|
|
|
'packet_detect_end': row[16],
|
|
|
|
'packet_detect_end': row[17],
|
|
|
|
# I2C configuration
|
|
|
|
# I2C configuration
|
|
|
|
'i2c_port': row[17],
|
|
|
|
'i2c_port': row[18],
|
|
|
|
'i2c_slave_address': row[18],
|
|
|
|
'i2c_slave_address': row[19],
|
|
|
|
'i2c_slave_read_register': row[19],
|
|
|
|
'i2c_slave_read_register': row[20],
|
|
|
|
'i2c_slave_read_length': row[20]
|
|
|
|
'i2c_slave_read_length': row[21]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# ===================================================================
|
|
|
|
# ===================================================================
|
|
|
|
@ -233,7 +235,7 @@ class Session(QObject):
|
|
|
|
# ===================================================================
|
|
|
|
# ===================================================================
|
|
|
|
|
|
|
|
|
|
|
|
cursor = self.db_conn.execute("""
|
|
|
|
cursor = self.db_conn.execute("""
|
|
|
|
SELECT profile_name, command_sequence, description
|
|
|
|
SELECT profile_name, command_sequence, description, print_command_rx
|
|
|
|
FROM session_profiles
|
|
|
|
FROM session_profiles
|
|
|
|
WHERE profile_id = ?
|
|
|
|
WHERE profile_id = ?
|
|
|
|
""", (session_profile_id,))
|
|
|
|
""", (session_profile_id,))
|
|
|
|
@ -246,6 +248,7 @@ class Session(QObject):
|
|
|
|
self.session_profile_id = session_profile_id
|
|
|
|
self.session_profile_id = session_profile_id
|
|
|
|
profile_name = row[0]
|
|
|
|
profile_name = row[0]
|
|
|
|
command_sequence_json = row[1]
|
|
|
|
command_sequence_json = row[1]
|
|
|
|
|
|
|
|
self.print_command_rx = bool(row[3]) if len(row) > 3 else False
|
|
|
|
|
|
|
|
|
|
|
|
# Parse JSON command sequence
|
|
|
|
# Parse JSON command sequence
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
@ -319,8 +322,8 @@ class Session(QObject):
|
|
|
|
Open UART and I2C ports based on interface configuration.
|
|
|
|
Open UART and I2C ports based on interface configuration.
|
|
|
|
|
|
|
|
|
|
|
|
This method:
|
|
|
|
This method:
|
|
|
|
1. Opens UART logger port (for packet detection)
|
|
|
|
1. Opens UART Command port (TX/RX - for sending commands, always needed)
|
|
|
|
2. Starts UART reader thread
|
|
|
|
2. Opens UART Logger port (RX - for telemetry, optional)
|
|
|
|
3. Opens I2C port (for angle readings)
|
|
|
|
3. Opens I2C port (for angle readings)
|
|
|
|
4. Creates PacketConfig from interface profile
|
|
|
|
4. Creates PacketConfig from interface profile
|
|
|
|
|
|
|
|
|
|
|
|
@ -329,44 +332,104 @@ class Session(QObject):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
# ===================================================================
|
|
|
|
# ===================================================================
|
|
|
|
# 1. Open UART Logger Port (for packet detection)
|
|
|
|
# 1. Open UART Command Port (TX/RX - ALWAYS NEEDED)
|
|
|
|
# ===================================================================
|
|
|
|
# ===================================================================
|
|
|
|
|
|
|
|
|
|
|
|
# Create UART config (only device and baudrate are required)
|
|
|
|
# Create UART command config
|
|
|
|
uart_config = UARTConfig(
|
|
|
|
cmd_uart_config = UARTConfig(
|
|
|
|
device=self.interface_config['uart_logger_port'],
|
|
|
|
device=self.interface_config['uart_command_port'],
|
|
|
|
baudrate=self.interface_config['uart_logger_baud']
|
|
|
|
baudrate=self.interface_config['uart_command_baud']
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# Create UART port
|
|
|
|
# Create UART command port
|
|
|
|
status, self.uart_port = uart_create(uart_config)
|
|
|
|
status, self.uart_command_port = uart_create(cmd_uart_config)
|
|
|
|
|
|
|
|
|
|
|
|
if status != UARTStatus.OK or self.uart_port is None:
|
|
|
|
if status != UARTStatus.OK or self.uart_command_port is None:
|
|
|
|
self.error_occurred.emit(f"Failed to create UART port")
|
|
|
|
self.error_occurred.emit(f"Failed to create UART command port")
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
# Open UART port
|
|
|
|
# Open UART command port
|
|
|
|
status = uart_open(self.uart_port)
|
|
|
|
status = uart_open(self.uart_command_port)
|
|
|
|
|
|
|
|
|
|
|
|
if status != UARTStatus.OK:
|
|
|
|
if status != UARTStatus.OK:
|
|
|
|
self.error_occurred.emit(f"Failed to open UART port {uart_config.device}")
|
|
|
|
self.error_occurred.emit(f"Failed to open UART command port {cmd_uart_config.device}")
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
# Start UART reader thread
|
|
|
|
# Start UART command reader thread
|
|
|
|
status = uart_start_reader(self.uart_port)
|
|
|
|
status = uart_start_reader(self.uart_command_port)
|
|
|
|
if status != UARTStatus.OK:
|
|
|
|
if status != UARTStatus.OK:
|
|
|
|
uart_close(self.uart_port)
|
|
|
|
uart_close(self.uart_command_port)
|
|
|
|
self.uart_port = None
|
|
|
|
self.uart_command_port = None
|
|
|
|
self.error_occurred.emit("Failed to start UART reader")
|
|
|
|
self.error_occurred.emit("Failed to start UART command reader")
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
self.status_changed.emit(f"UART opened: {uart_config.device}")
|
|
|
|
self.status_changed.emit(f"UART Command opened: {cmd_uart_config.device}")
|
|
|
|
|
|
|
|
|
|
|
|
# ===================================================================
|
|
|
|
# ===================================================================
|
|
|
|
# 2. Create PacketConfig from interface profile
|
|
|
|
# 2. Open UART Logger Port (RX - OPTIONAL)
|
|
|
|
|
|
|
|
# ===================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.interface_config['uart_logger_enable']:
|
|
|
|
|
|
|
|
# Logger enabled - open logger port
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Create UART logger config
|
|
|
|
|
|
|
|
log_uart_config = UARTConfig(
|
|
|
|
|
|
|
|
device=self.interface_config['uart_logger_port'],
|
|
|
|
|
|
|
|
baudrate=self.interface_config['uart_logger_baud']
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Create UART logger port
|
|
|
|
|
|
|
|
status, self.uart_logger_port = uart_create(log_uart_config)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if status != UARTStatus.OK or self.uart_logger_port is None:
|
|
|
|
|
|
|
|
self.error_occurred.emit(f"Failed to create UART logger port")
|
|
|
|
|
|
|
|
# Close command port before returning
|
|
|
|
|
|
|
|
uart_stop_reader(self.uart_command_port)
|
|
|
|
|
|
|
|
uart_close(self.uart_command_port)
|
|
|
|
|
|
|
|
self.uart_command_port = None
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Open UART logger port
|
|
|
|
|
|
|
|
status = uart_open(self.uart_logger_port)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if status != UARTStatus.OK:
|
|
|
|
|
|
|
|
self.error_occurred.emit(f"Failed to open UART logger port {log_uart_config.device}")
|
|
|
|
|
|
|
|
# Close command port before returning
|
|
|
|
|
|
|
|
uart_stop_reader(self.uart_command_port)
|
|
|
|
|
|
|
|
uart_close(self.uart_command_port)
|
|
|
|
|
|
|
|
self.uart_command_port = None
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Start UART logger reader thread
|
|
|
|
|
|
|
|
status = uart_start_reader(self.uart_logger_port)
|
|
|
|
|
|
|
|
if status != UARTStatus.OK:
|
|
|
|
|
|
|
|
uart_close(self.uart_logger_port)
|
|
|
|
|
|
|
|
self.uart_logger_port = None
|
|
|
|
|
|
|
|
# Close command port before returning
|
|
|
|
|
|
|
|
uart_stop_reader(self.uart_command_port)
|
|
|
|
|
|
|
|
uart_close(self.uart_command_port)
|
|
|
|
|
|
|
|
self.uart_command_port = None
|
|
|
|
|
|
|
|
self.error_occurred.emit("Failed to start UART logger reader")
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.status_changed.emit(f"UART Logger opened: {log_uart_config.device}")
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
# Logger disabled - skip logger port
|
|
|
|
|
|
|
|
self.uart_logger_port = None
|
|
|
|
|
|
|
|
self.status_changed.emit("UART Logger disabled (command port only)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ===================================================================
|
|
|
|
|
|
|
|
# 3. Create PacketConfig from interface profile
|
|
|
|
# ===================================================================
|
|
|
|
# ===================================================================
|
|
|
|
|
|
|
|
|
|
|
|
if self.interface_config['packet_detect_enable']:
|
|
|
|
# Check if print_command_rx is enabled (session profile override)
|
|
|
|
|
|
|
|
if hasattr(self, 'print_command_rx') and self.print_command_rx:
|
|
|
|
|
|
|
|
# Force packet detection OFF - just print TX/RX to data monitor
|
|
|
|
|
|
|
|
self.packet_config = PacketConfig(enable=False)
|
|
|
|
|
|
|
|
elif not self.interface_config['uart_logger_enable']:
|
|
|
|
|
|
|
|
# Logger disabled - no packet detection
|
|
|
|
|
|
|
|
self.packet_config = PacketConfig(enable=False)
|
|
|
|
|
|
|
|
elif self.interface_config['packet_detect_enable']:
|
|
|
|
# Parse hex markers
|
|
|
|
# Parse hex markers
|
|
|
|
start_marker = bytes.fromhex(
|
|
|
|
start_marker = bytes.fromhex(
|
|
|
|
self.interface_config['packet_detect_start'].replace(' ', '')
|
|
|
|
self.interface_config['packet_detect_start'].replace(' ', '')
|
|
|
|
@ -387,7 +450,7 @@ class Session(QObject):
|
|
|
|
self.packet_config = PacketConfig(enable=False)
|
|
|
|
self.packet_config = PacketConfig(enable=False)
|
|
|
|
|
|
|
|
|
|
|
|
# ===================================================================
|
|
|
|
# ===================================================================
|
|
|
|
# 3. Open I2C Port (optional - for angle readings)
|
|
|
|
# 4. Open I2C Port (optional - for angle readings)
|
|
|
|
# ===================================================================
|
|
|
|
# ===================================================================
|
|
|
|
|
|
|
|
|
|
|
|
if self.interface_config['i2c_port']:
|
|
|
|
if self.interface_config['i2c_port']:
|
|
|
|
@ -444,7 +507,11 @@ class Session(QObject):
|
|
|
|
# 2. Create PacketConfig from interface profile
|
|
|
|
# 2. Create PacketConfig from interface profile
|
|
|
|
# ===================================================================
|
|
|
|
# ===================================================================
|
|
|
|
|
|
|
|
|
|
|
|
if self.interface_config['packet_detect_enable']:
|
|
|
|
# Check if print_command_rx is enabled (session profile override)
|
|
|
|
|
|
|
|
if hasattr(self, 'print_command_rx') and self.print_command_rx:
|
|
|
|
|
|
|
|
# Force packet detection OFF - just print TX/RX to data monitor
|
|
|
|
|
|
|
|
self.packet_config = PacketConfig(enable=False)
|
|
|
|
|
|
|
|
elif self.interface_config['packet_detect_enable']:
|
|
|
|
# Parse hex markers
|
|
|
|
# Parse hex markers
|
|
|
|
start_marker = bytes.fromhex(
|
|
|
|
start_marker = bytes.fromhex(
|
|
|
|
self.interface_config['packet_detect_start'].replace(' ', '')
|
|
|
|
self.interface_config['packet_detect_start'].replace(' ', '')
|
|
|
|
@ -509,12 +576,19 @@ class Session(QObject):
|
|
|
|
Ensures clean shutdown of hardware interfaces.
|
|
|
|
Ensures clean shutdown of hardware interfaces.
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
# Close UART
|
|
|
|
# Close UART Command port
|
|
|
|
if self.uart_port:
|
|
|
|
if self.uart_command_port:
|
|
|
|
uart_stop_reader(self.uart_port)
|
|
|
|
uart_stop_reader(self.uart_command_port)
|
|
|
|
uart_close(self.uart_port)
|
|
|
|
uart_close(self.uart_command_port)
|
|
|
|
self.uart_port = None
|
|
|
|
self.uart_command_port = None
|
|
|
|
self.status_changed.emit("UART closed")
|
|
|
|
self.status_changed.emit("UART Command closed")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Close UART Logger port
|
|
|
|
|
|
|
|
if self.uart_logger_port:
|
|
|
|
|
|
|
|
uart_stop_reader(self.uart_logger_port)
|
|
|
|
|
|
|
|
uart_close(self.uart_logger_port)
|
|
|
|
|
|
|
|
self.uart_logger_port = None
|
|
|
|
|
|
|
|
self.status_changed.emit("UART Logger closed")
|
|
|
|
|
|
|
|
|
|
|
|
# Close I2C
|
|
|
|
# Close I2C
|
|
|
|
if self.i2c_handle:
|
|
|
|
if self.i2c_handle:
|
|
|
|
@ -659,7 +733,8 @@ class Session(QObject):
|
|
|
|
run_no=cmd_index,
|
|
|
|
run_no=cmd_index,
|
|
|
|
command_id=cmd['command_id'],
|
|
|
|
command_id=cmd['command_id'],
|
|
|
|
command_hex=cmd['hex_string'],
|
|
|
|
command_hex=cmd['hex_string'],
|
|
|
|
uart_port=self.uart_port,
|
|
|
|
uart_command_port=self.uart_command_port,
|
|
|
|
|
|
|
|
uart_logger_port=self.uart_logger_port,
|
|
|
|
i2c_port=self.i2c_handle, # Note: run.py calls it i2c_port but it's actually I2CHandle
|
|
|
|
i2c_port=self.i2c_handle, # Note: run.py calls it i2c_port but it's actually I2CHandle
|
|
|
|
packet_config=self.packet_config,
|
|
|
|
packet_config=self.packet_config,
|
|
|
|
stop_timeout_ms=5000,
|
|
|
|
stop_timeout_ms=5000,
|
|
|
|
|