From 9153362979669f0109bb44b148dab1d159378172 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Mon, 13 Apr 2026 17:48:25 +0200 Subject: [PATCH 01/19] add AUTO serial connection --- README.md | 14 +- doc/gui_qt.md | 7 +- doc/gui_web.md | 8 +- mchplnet | 2 +- pyx2cscope/examples/can_demo.py | 2 - .../gui/qt/controllers/connection_manager.py | 7 +- pyx2cscope/gui/qt/tabs/setup_tab.py | 2 + pyx2cscope/gui/web/app.py | 2 + pyx2cscope/gui/web/static/js/script.js | 2 + pyx2cscope/gui/web/templates/setup.html | 1 + tests/test_can_reconnection.py | 323 ++++++++++++++++++ tests/test_pyx2cscope_class.py | 8 +- tests/utils/serial_stub.py | 4 +- 13 files changed, 364 insertions(+), 18 deletions(-) create mode 100644 tests/test_can_reconnection.py diff --git a/README.md b/README.md index 512538b9..4893b17a 100644 --- a/README.md +++ b/README.md @@ -40,12 +40,16 @@ To execute the Browser based version type: ```py from pyx2cscope.x2cscope import X2CScope -# initialize the X2CScope class with serial port, by default baud rate is 115200 -x2c_scope = X2CScope(port="COM8") -# instead of loading directly the elf file, we can import it after instantiating the X2CScope class -x2c_scope.import_variables(r"..\..\tests\data\qspin_foc_same54.elf") +# Option 1: Default UART with Auto-detect COM port (recommended for single device) +x2c_scope = X2CScope(elf_file="path/to/firmware.elf") -# Collect some variables. +# Option 2: Specify COM port explicitly +# x2c_scope = X2CScope(port="COM8", elf_file="path/to/firmware.elf") + +# Or import variables after instantiation +# x2c_scope.import_variables(r"..\..\tests\data\qspin_foc_same54.elf") + +# Collect some variables speed_reference = x2c_scope.get_variable("motor.apiData.velocityReference") speed_measured = x2c_scope.get_variable("motor.apiData.velocityMeasured") diff --git a/doc/gui_qt.md b/doc/gui_qt.md index b3f8fd66..4b330eb4 100644 --- a/doc/gui_qt.md +++ b/doc/gui_qt.md @@ -41,9 +41,14 @@ The Setup tab is where you configure the connection to your microcontroller. ### UART Settings -- **Port**: Select the COM port from the dropdown. Use the refresh button to update available ports. +- **Port**: Select the COM port from the dropdown. + - **AUTO**: Automatically detects the first available LNet device (recommended for single device). + - **Specific Port**: Choose a specific COM port (COM1, COM3, etc.) for manual connection. + - **Refresh Button**: Updates the list of available ports. - **Baud Rate**: Select the baud rate (38400, 115200, 230400, 460800, 921600). +> **Tip**: When using AUTO mode, the system will scan available COM ports and connect to the first device that responds to the LNet protocol. This is useful when the exact port number is unknown or when working across different machines. + ### TCP/IP Settings - **Host**: Enter the IP address or hostname of the target device. diff --git a/doc/gui_web.md b/doc/gui_web.md index 4fecbd7d..8afd0fb7 100644 --- a/doc/gui_web.md +++ b/doc/gui_web.md @@ -63,8 +63,12 @@ Select the communication interface type: When Serial is selected: -1. **UART Dropdown** - Select the COM port from the available ports list -2. **Refresh Button** - Click to rescan for available COM ports +1. **UART Dropdown** - Select the COM port: + - **AUTO (Auto-detect)**: Automatically scans and connects to the first available LNet device (recommended for single device). + - **Specific Port**: Choose a specific COM port (COM1, COM3, etc.) for manual connection. +2. **Refresh Button** - Click to rescan for available COM ports. + +> **Tip**: The AUTO option is useful when you don't know the exact COM port or when working across different machines. The system will test each available port and connect to the first one that responds to the LNet protocol. ### TCP/IP Configuration diff --git a/mchplnet b/mchplnet index f425fb20..1f442e6a 160000 --- a/mchplnet +++ b/mchplnet @@ -1 +1 @@ -Subproject commit f425fb205c4158903bbc20fbded73d6733c9f2fa +Subproject commit 1f442e6a854fa5c639d25b99fb0e0d430c552893 diff --git a/pyx2cscope/examples/can_demo.py b/pyx2cscope/examples/can_demo.py index 31c7d449..42ff1917 100644 --- a/pyx2cscope/examples/can_demo.py +++ b/pyx2cscope/examples/can_demo.py @@ -1,11 +1,9 @@ """Demo scripting for user to get started with CAN interface.""" import time -from mchplnet.interfaces.factory import InterfaceType from pyx2cscope.utils import get_can_config, get_elf_file_path from pyx2cscope.x2cscope import X2CScope - # Check if x2cscope was injected by the Scripting tab, otherwise create our own if globals().get("x2cscope") is None: # Get configuration from config.ini diff --git a/pyx2cscope/gui/qt/controllers/connection_manager.py b/pyx2cscope/gui/qt/controllers/connection_manager.py index 6a1adec2..3ef7e829 100644 --- a/pyx2cscope/gui/qt/controllers/connection_manager.py +++ b/pyx2cscope/gui/qt/controllers/connection_manager.py @@ -248,7 +248,12 @@ def disconnect(self) -> bool: True if disconnection successful, False otherwise. """ try: - # X2CScope handles closing the serial connection + # Get current x2cscope instance and properly disconnect it + x2cscope = self._app_state.x2cscope + if x2cscope: + x2cscope.disconnect() + + # Clear the x2cscope instance self._app_state.set_x2cscope(None) logging.info("Disconnected from device") self.connection_changed.emit(False) diff --git a/pyx2cscope/gui/qt/tabs/setup_tab.py b/pyx2cscope/gui/qt/tabs/setup_tab.py index d0d3f861..56d68f63 100644 --- a/pyx2cscope/gui/qt/tabs/setup_tab.py +++ b/pyx2cscope/gui/qt/tabs/setup_tab.py @@ -392,6 +392,8 @@ def elf_file_path(self, path: str): def set_ports(self, ports: list): """Set available COM ports.""" self._port_combo.clear() + # Add AUTO option first for auto-detection + self._port_combo.addItem("AUTO") self._port_combo.addItems(ports) def set_connected(self, connected: bool): diff --git a/pyx2cscope/gui/web/app.py b/pyx2cscope/gui/web/app.py index 3f876550..6750dd40 100644 --- a/pyx2cscope/gui/web/app.py +++ b/pyx2cscope/gui/web/app.py @@ -169,6 +169,8 @@ def connect(): return jsonify({"status": "error", "msg": str(e)}), 401 except ValueError as e: return jsonify({"status": "error", "msg": str(e)}), 401 + except TimeoutError as e: + return jsonify({"status": "error", "msg": str(e)}), 401 return jsonify({"status": "error", "msg": "Interface argument or import file invalid."}), 400 diff --git a/pyx2cscope/gui/web/static/js/script.js b/pyx2cscope/gui/web/static/js/script.js index ece9b28f..eaea6516 100644 --- a/pyx2cscope/gui/web/static/js/script.js +++ b/pyx2cscope/gui/web/static/js/script.js @@ -55,6 +55,8 @@ function load_uart() { uart = $('#port'); uart.empty(); uart.append(''); + // Add AUTO option for auto-detection + uart.append($('').val('AUTO').html('AUTO (Auto-detect)')); data.forEach(function(item) { uart.append($('').val(item).html(item)); }); diff --git a/pyx2cscope/gui/web/templates/setup.html b/pyx2cscope/gui/web/templates/setup.html index 38117e19..66102411 100644 --- a/pyx2cscope/gui/web/templates/setup.html +++ b/pyx2cscope/gui/web/templates/setup.html @@ -16,6 +16,7 @@
diff --git a/tests/test_can_reconnection.py b/tests/test_can_reconnection.py new file mode 100644 index 00000000..7a6eb6d3 --- /dev/null +++ b/tests/test_can_reconnection.py @@ -0,0 +1,323 @@ +"""Tests for CAN interface reconnection bug fix. + +This test suite verifies that the CAN interface can be properly disconnected +and reconnected multiple times without errors, preventing the regression of +the "PCAN Channel has not been initialized" bug. +""" + +import os +from unittest.mock import MagicMock, patch + +import pytest + +# Set headless mode before importing Qt modules +os.environ["QT_QPA_PLATFORM"] = "offscreen" + +from mchplnet.interfaces.can import LNetCan +from pyx2cscope.x2cscope import X2CScope +from tests import data + + +@pytest.fixture +def mock_can_bus(): + """Create a mock CAN bus for testing.""" + with patch('can.interface.Bus') as mock_bus_class: + mock_bus_instance = MagicMock() + mock_bus_instance._is_shutdown = False + mock_bus_instance.recv = MagicMock(return_value=None) + mock_bus_instance.send = MagicMock() + mock_bus_instance.shutdown = MagicMock() + mock_bus_class.return_value = mock_bus_instance + yield mock_bus_class, mock_bus_instance + + +class TestCANReconnection: + """Test CAN interface reconnection scenarios.""" + + elf_file = os.path.join( + os.path.dirname(data.__file__), "mc_foc_sl_fip_dspic33ck_mclv48v300w.elf" + ) + + def test_can_interface_start_cleans_up_existing_bus(self, mock_can_bus): + """Test that start() properly cleans up an existing bus before creating a new one.""" + mock_bus_class, mock_bus_instance = mock_can_bus + + # Create CAN interface + can_interface = LNetCan( + bustype="pcan_usb", + channel=1, + baud_rate=500000, + id_tx=0x110, + id_rx=0x100, + ) + + # Start the interface (first time) + can_interface.start() + assert mock_bus_class.call_count == 1 + assert can_interface.bus is not None + + # Start again without stopping (simulates reconnection attempt) + can_interface.start() + + # Verify shutdown was called on the old bus + assert mock_bus_instance.shutdown.called + # Verify a new bus was created (total 2 calls) + assert mock_bus_class.call_count == 2 + + def test_can_interface_stop_clears_bus_reference(self, mock_can_bus): + """Test that stop() properly clears the bus reference.""" + mock_bus_class, mock_bus_instance = mock_can_bus + + can_interface = LNetCan( + bustype="pcan_usb", + channel=1, + baud_rate=500000, + ) + + # Start and stop + can_interface.start() + assert can_interface.bus is not None + + can_interface.stop() + + # Verify shutdown was called and bus is None + assert mock_bus_instance.shutdown.called + assert can_interface.bus is None + + def test_can_interface_multiple_reconnections(self, mock_can_bus): + """Test multiple connect-disconnect-reconnect cycles.""" + mock_bus_class, mock_bus_instance = mock_can_bus + + can_interface = LNetCan( + bustype="pcan_usb", + channel=1, + baud_rate=500000, + ) + + # Perform 3 connect-disconnect cycles + for i in range(3): + # Start + can_interface.start() + assert can_interface.bus is not None + assert mock_bus_class.call_count == i + 1 + + # Stop + can_interface.stop() + assert can_interface.bus is None + assert mock_bus_instance.shutdown.call_count == i + 1 + + # Verify we can start again after all cycles + can_interface.start() + assert can_interface.bus is not None + assert mock_bus_class.call_count == 4 + + def test_can_interface_stop_handles_shutdown_error(self, mock_can_bus): + """Test that stop() handles errors during bus shutdown gracefully.""" + mock_bus_class, mock_bus_instance = mock_can_bus + + # Make shutdown raise an exception + mock_bus_instance.shutdown.side_effect = Exception("Shutdown error") + + can_interface = LNetCan( + bustype="pcan_usb", + channel=1, + baud_rate=500000, + ) + + can_interface.start() + assert can_interface.bus is not None + + # Stop should not raise exception even if shutdown fails + can_interface.stop() + + # Bus should still be set to None + assert can_interface.bus is None + + def test_x2cscope_disconnect_calls_interface_stop(self, mock_can_bus): + """Test that X2CScope.disconnect() properly calls interface.stop().""" + mock_bus_class, mock_bus_instance = mock_can_bus + + # Mock the read/write methods to avoid actual CAN communication + with patch('mchplnet.interfaces.can.LNetCan.read') as mock_read, \ + patch('mchplnet.interfaces.can.LNetCan.write'): + + # Mock read to return valid LNet DeviceInfo frame + # Frame structure (49+ bytes): + # SYN(0x55), SIZE, NODE, SERVICE_ID, STATUS, + # MONITOR_VER(2), APP_VER(2), PROCESSOR_ID(2), + # MONITOR_DATE(9), MONITOR_TIME(4), APP_DATE(9), APP_TIME(4), + # DSP_STATE(1), EVENT_TYPE(2), EVENT_ID(4), TABLE_STRUCT_ADD(4) + device_info_frame = bytearray( + b'\x55\x2E\x01\x11\x00' # SYN, SIZE(46 data bytes), NODE, SERVICE_ID, STATUS + b'\x01\x00' # Monitor version (little-endian) + b'\x01\x00' # App version (little-endian) + b'\x10\x82' # Processor ID 0x8210 (16-bit generic dsPIC) + b'01/01/2024' # Monitor date (9 bytes) + b'1200' # Monitor time (4 bytes) + b'01/01/2024' # App date (9 bytes) + b'1200' # App time (4 bytes) + b'\x01' # DSP state (0x01 = Application runs on target) + b'\x00\x00' # Event type (2 bytes) + b'\x00\x00\x00\x00' # Event ID (4 bytes) + b'\x00\x00\x00\x00' # Table struct address (4 bytes) + b'\x00' # CRC + ) + # Mock LoadParameters frame (simpler, just status response) + load_param_frame = bytearray(b'\x55\x00\x01\x12\x00\x00') + # Mock LoadScopeData frame + load_scope_frame = bytearray(b'\x55\x08\x01\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') + + # Return different frames for each call + mock_read.side_effect = [device_info_frame, load_param_frame, load_scope_frame] + + # Create X2CScope with CAN interface + x2cscope = X2CScope( + elf_file=self.elf_file, + bustype="pcan_usb", + channel=1, + baud_rate=500000, + ) + + # Verify interface was started + assert mock_bus_class.called + + # Disconnect + x2cscope.disconnect() + + # Verify shutdown was called + assert mock_bus_instance.shutdown.called + + def test_qt_connection_manager_disconnect_calls_x2cscope_disconnect(self, mock_can_bus): + """Test that Qt ConnectionManager properly calls x2cscope.disconnect().""" + from PyQt5.QtCore import QCoreApplication + from pyx2cscope.gui.qt.controllers.connection_manager import ConnectionManager + from pyx2cscope.gui.qt.models.app_state import AppState + + # Create Qt application if it doesn't exist + app = QCoreApplication.instance() + if app is None: + app = QCoreApplication([]) + + try: + _, mock_bus_instance = mock_can_bus + + # Create app state and connection manager + app_state = AppState() + conn_manager = ConnectionManager(app_state) + + # Mock read/write to avoid actual CAN communication + with patch('mchplnet.interfaces.can.LNetCan.read') as mock_read, \ + patch('mchplnet.interfaces.can.LNetCan.write'): + + # Mock read to return valid LNet frames + device_info_frame = bytearray( + b'\x55\x2E\x01\x11\x00' # SYN, SIZE(46 data bytes), NODE, SERVICE_ID, STATUS + b'\x01\x00' # Monitor version (little-endian) + b'\x01\x00' # App version (little-endian) + b'\x10\x82' # Processor ID 0x8210 (16-bit generic dsPIC) + b'01/01/2024' # Monitor date (9 bytes) + b'1200' # Monitor time (4 bytes) + b'01/01/2024' # App date (9 bytes) + b'1200' # App time (4 bytes) + b'\x01' # DSP state (0x01 = Application runs on target) + b'\x00\x00' # Event type (2 bytes) + b'\x00\x00\x00\x00' # Event ID (4 bytes) + b'\x00\x00\x00\x00' # Table struct address (4 bytes) + b'\x00' # CRC + ) + load_param_frame = bytearray(b'\x55\x00\x01\x12\x00\x00') + # Return frames for connection (2 calls: device_info and load_parameters) + mock_read.side_effect = [ + device_info_frame, + load_param_frame, + ] + + # Connect via CAN + success = conn_manager.connect_can( + elf_file=self.elf_file, + bus_type="USB", + channel=1, + baudrate="500K", + mode="Standard", + tx_id="110", + rx_id="100", + ) + + assert success is True + assert app_state.is_connected() + + # Disconnect + conn_manager.disconnect() + + # Verify x2cscope was properly disconnected + assert not app_state.is_connected() + assert app_state.x2cscope is None + # Verify bus shutdown was called + assert mock_bus_instance.shutdown.called + + finally: + # Clean up Qt application + if app: + app.quit() + + +class TestCANInterfaceStartupCleanup: + """Test CAN interface cleanup on startup.""" + + def test_start_with_none_bus_creates_new_bus(self, mock_can_bus): + """Test that start() creates a bus when bus is None.""" + mock_bus_class, _ = mock_can_bus + + can_interface = LNetCan(bustype="pcan_usb", channel=1) + assert can_interface.bus is None + + can_interface.start() + + assert can_interface.bus is not None + assert mock_bus_class.call_count == 1 + + def test_start_with_existing_bus_stops_first(self, mock_can_bus): + """Test that start() stops existing bus before creating new one.""" + mock_bus_class, mock_bus_instance = mock_can_bus + + can_interface = LNetCan(bustype="pcan_usb", channel=1) + + # First start + can_interface.start() + first_bus = can_interface.bus + assert first_bus is not None + + # Second start without stopping + can_interface.start() + + # Verify old bus was shut down + assert mock_bus_instance.shutdown.called + # Verify new bus was created + assert mock_bus_class.call_count == 2 + + def test_is_open_returns_false_when_bus_is_none(self): + """Test that is_open() returns False when bus is None.""" + can_interface = LNetCan(bustype="pcan_usb", channel=1) + assert can_interface.bus is None + assert can_interface.is_open() is False + + def test_is_open_returns_true_when_bus_is_active(self, mock_can_bus): + """Test that is_open() returns True when bus is active.""" + mock_bus_class, mock_bus_instance = mock_can_bus + + can_interface = LNetCan(bustype="pcan_usb", channel=1) + can_interface.start() + + assert can_interface.is_open() is True + + def test_is_open_returns_false_when_bus_is_shutdown(self, mock_can_bus): + """Test that is_open() returns False when bus is shutdown.""" + mock_bus_class, mock_bus_instance = mock_can_bus + + can_interface = LNetCan(bustype="pcan_usb", channel=1) + can_interface.start() + + # Simulate bus shutdown + mock_bus_instance._is_shutdown = True + + assert can_interface.is_open() is False diff --git a/tests/test_pyx2cscope_class.py b/tests/test_pyx2cscope_class.py index 4615fd97..b0effb79 100644 --- a/tests/test_pyx2cscope_class.py +++ b/tests/test_pyx2cscope_class.py @@ -53,8 +53,8 @@ def test_missing_interface(self, mocker): def test_missing_com_port(self, mocker): """Check class behavior in case of non COM-Port initialization. - A com-port must not be provided, in this case, the default COM1 - is used but a warning is generated on the console. + A com-port must not be provided, in this case, AUTO detection + is attempted but a warning is generated on the console. """ fake_serial(mocker, 16) with warnings.catch_warnings(record=True) as w: @@ -67,7 +67,7 @@ def test_missing_com_port(self, mocker): # Verify the warning was raised assert len(w) == 2 # noqa: PLR2004 assert issubclass(w[-1].category, Warning) is True - assert "No port provided, using default COM1" in str(w[-1].message) + assert "No port provided, will attempt auto-detection" in str(w[-1].message) # Clean up scope.disconnect() @@ -75,6 +75,6 @@ def test_missing_com_port(self, mocker): def test_wrong_com_port(self): """Check handling of a non-existent COM-PORT input.""" with pytest.raises( - RuntimeError, match=r"Failed to retrieve device information" + Exception, match=r"could not open port 'COM0'" ): X2CScope(elf_file=self.elf_file, port="COM0") diff --git a/tests/utils/serial_stub.py b/tests/utils/serial_stub.py index 0e329028..cce6300a 100644 --- a/tests/utils/serial_stub.py +++ b/tests/utils/serial_stub.py @@ -85,9 +85,9 @@ def __init__(self, uc_width=BIT_LENGTH_16): def lnet_serial_start(self): """Mocker for the start interface function. - As we are dealing with no real device, we just return. + As we are dealing with no real device, we just return True. """ - return + return True def _get_ram(self): """Handle a get_ram request.""" From 968419517a25d6e388e6ff3b0cfc6d220b581a79 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Mon, 13 Apr 2026 18:10:23 +0200 Subject: [PATCH 02/19] add help tab --- pyx2cscope/gui/qt/main_window.py | 5 + pyx2cscope/gui/qt/tabs/help_tab.py | 255 +++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+) create mode 100644 pyx2cscope/gui/qt/tabs/help_tab.py diff --git a/pyx2cscope/gui/qt/main_window.py b/pyx2cscope/gui/qt/main_window.py index c9490c49..d2827186 100644 --- a/pyx2cscope/gui/qt/main_window.py +++ b/pyx2cscope/gui/qt/main_window.py @@ -24,6 +24,7 @@ from pyx2cscope.gui.qt.controllers.config_manager import ConfigManager from pyx2cscope.gui.qt.controllers.connection_manager import ConnectionManager from pyx2cscope.gui.qt.models.app_state import AppState +from pyx2cscope.gui.qt.tabs.help_tab import HelpTab from pyx2cscope.gui.qt.tabs.scope_view_tab import ScopeViewTab from pyx2cscope.gui.qt.tabs.scripting_tab import ScriptingTab from pyx2cscope.gui.qt.tabs.setup_tab import SetupTab @@ -181,6 +182,10 @@ def _setup_ui(self): # noqa: PLR0915 self._scripting_tab = ScriptingTab(self._app_state, self) self._tab_widget.addTab(self._scripting_tab, "Scripting") + # Tab 4: Help + self._help_tab = HelpTab(self) + self._tab_widget.addTab(self._help_tab, "Help") + # Set initial view (Both selected) self._on_view_toggle_changed() diff --git a/pyx2cscope/gui/qt/tabs/help_tab.py b/pyx2cscope/gui/qt/tabs/help_tab.py new file mode 100644 index 00000000..33478b2c --- /dev/null +++ b/pyx2cscope/gui/qt/tabs/help_tab.py @@ -0,0 +1,255 @@ +"""Help tab for the Qt GUI application.""" + +import platform +import subprocess +import sys +from PyQt5.QtCore import QUrl +from PyQt5.QtWidgets import ( + QGroupBox, + QHBoxLayout, + QLabel, + QPushButton, + QTextEdit, + QVBoxLayout, + QWidget, +) +from PyQt5.QtGui import QFont, QDesktopServices + +import pyx2cscope + + +class HelpTab(QWidget): + """Help tab containing links to GitHub, release notes, and version info.""" + + def __init__(self, parent=None): + """Initialize the help tab.""" + super().__init__(parent) + self._setup_ui() + + def _setup_ui(self): + """Set up the user interface.""" + layout = QVBoxLayout(self) + layout.setContentsMargins(20, 20, 20, 20) + layout.setSpacing(20) + + # Title + title_label = QLabel("Help & Support") + title_font = QFont() + title_font.setPointSize(14) + title_font.setBold(True) + title_label.setFont(title_font) + title_label.setStyleSheet("margin-bottom: 10px;") + layout.addWidget(title_label) + + # GitHub Issues Section + github_group = QGroupBox("Report Issues & Request Features") + github_layout = QVBoxLayout(github_group) + + github_info = QLabel( + "If you encounter bugs, have feature requests, or need help, " + "please open an issue on our GitHub repository." + ) + github_info.setWordWrap(True) + github_info.setStyleSheet("color: #666; margin-bottom: 10px;") + github_layout.addWidget(github_info) + + github_button_layout = QHBoxLayout() + + self.github_issues_btn = QPushButton("Open GitHub Issues") + self.github_issues_btn.clicked.connect(self._open_github_issues) + self.github_issues_btn.setStyleSheet( + "QPushButton { background-color: #0078d4; color: white; padding: 8px 16px; border-radius: 4px; }" + "QPushButton:hover { background-color: #106ebe; }" + ) + github_button_layout.addWidget(self.github_issues_btn) + + self.github_repo_btn = QPushButton("Visit Repository") + self.github_repo_btn.clicked.connect(self._open_github_repo) + self.github_repo_btn.setStyleSheet( + "QPushButton { background-color: #28a745; color: white; padding: 8px 16px; border-radius: 4px; }" + "QPushButton:hover { background-color: #218838; }" + ) + github_button_layout.addWidget(self.github_repo_btn) + github_button_layout.addStretch() + + github_layout.addLayout(github_button_layout) + layout.addWidget(github_group) + + # Release Notes Section + release_group = QGroupBox("Release Notes & Documentation") + release_layout = QVBoxLayout(release_group) + + release_info = QLabel( + "View the latest release notes, changelog, and documentation." + ) + release_info.setWordWrap(True) + release_info.setStyleSheet("color: #666; margin-bottom: 10px;") + release_layout.addWidget(release_info) + + release_button_layout = QHBoxLayout() + + self.release_notes_btn = QPushButton("View Release Notes") + self.release_notes_btn.clicked.connect(self._open_release_notes) + self.release_notes_btn.setStyleSheet( + "QPushButton { background-color: #17a2b8; color: white; padding: 8px 16px; border-radius: 4px; }" + "QPushButton:hover { background-color: #138496; }" + ) + release_button_layout.addWidget(self.release_notes_btn) + + self.documentation_btn = QPushButton("Documentation") + self.documentation_btn.clicked.connect(self._open_documentation) + self.documentation_btn.setStyleSheet( + "QPushButton { background-color: #6f42c1; color: white; padding: 8px 16px; border-radius: 4px; }" + "QPushButton:hover { background-color: #5a32a3; }" + ) + release_button_layout.addWidget(self.documentation_btn) + release_button_layout.addStretch() + + release_layout.addLayout(release_button_layout) + layout.addWidget(release_group) + + # Software Versions Section + version_group = QGroupBox("Software Versions") + version_layout = QVBoxLayout(version_group) + + version_info = QLabel("Current software and dependency versions:") + version_info.setStyleSheet("color: #666; margin-bottom: 10px;") + version_layout.addWidget(version_info) + + self.version_text = QTextEdit() + self.version_text.setReadOnly(True) + self.version_text.setMaximumHeight(200) + self.version_text.setStyleSheet( + "QTextEdit { background-color: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 10px; }" + ) + self._populate_version_info() + version_layout.addWidget(self.version_text) + + # Copy version info button + copy_layout = QHBoxLayout() + self.copy_version_btn = QPushButton("Copy Version Info") + self.copy_version_btn.clicked.connect(self._copy_version_info) + self.copy_version_btn.setStyleSheet( + "QPushButton { background-color: #6c757d; color: white; padding: 6px 12px; border-radius: 4px; }" + "QPushButton:hover { background-color: #5a6268; }" + ) + copy_layout.addWidget(self.copy_version_btn) + copy_layout.addStretch() + version_layout.addLayout(copy_layout) + + layout.addWidget(version_group) + + # Additional Resources + resources_group = QGroupBox("Additional Resources") + resources_layout = QVBoxLayout(resources_group) + + resources_text = QLabel( + "For additional support and community discussion:\n" + "· Check the examples directory for usage examples\n" + "· Review the README file for installation instructions\n" + "· Join our community discussions on GitHub" + ) + resources_text.setWordWrap(True) + resources_text.setStyleSheet("color: #666; line-height: 1.5;") + resources_layout.addWidget(resources_text) + + layout.addWidget(resources_group) + + # Add stretch to push everything to the top + layout.addStretch() + + def _open_github_issues(self): + """Open GitHub issues page in default browser.""" + url = QUrl("https://github.com/X2Cscope/pyx2cscope/issues") + QDesktopServices.openUrl(url) + + def _open_github_repo(self): + """Open GitHub repository page in default browser.""" + url = QUrl("https://github.com/X2Cscope/pyx2cscope") + QDesktopServices.openUrl(url) + + def _open_release_notes(self): + """Open GitHub releases page in default browser.""" + url = QUrl("https://github.com/X2Cscope/pyx2cscope/releases") + QDesktopServices.openUrl(url) + + def _open_documentation(self): + """Open documentation in default browser.""" + url = QUrl("https://x2cscope.github.io/pyx2cscope/") + QDesktopServices.openUrl(url) + + def _populate_version_info(self): + """Populate the version information text area.""" + version_info = [] + + # Main application version + version_info.append(f"pyX2Cscope: {pyx2cscope.__version__}") + + # mchplnet version (important dependency) + try: + import mchplnet + version_info.append(f"mchplnet: {mchplnet.__version__}") + except ImportError: + version_info.append("mchplnet: Not installed") + + # Python version + version_info.append(f"Python: {sys.version}") + + # Platform info + version_info.append(f"Platform: {platform.platform()}") + version_info.append(f"Architecture: {platform.architecture()[0]}") + version_info.append(f"Processor: {platform.processor()}") + + # PyQt version + try: + from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR + version_info.append(f"Qt: {QT_VERSION_STR}") + version_info.append(f"PyQt5: {PYQT_VERSION_STR}") + except ImportError: + version_info.append("PyQt5: Not available") + + # Try to get other dependency versions + dependencies = [ + ("numpy", "numpy"), + ("matplotlib", "matplotlib"), + ("serial", "pyserial"), # pyserial is imported as 'serial' + ("elftools", "elftools") + ] + + for import_name, display_name in dependencies: + try: + module = __import__(import_name) + if display_name == "pyserial": + version = getattr(module, "VERSION", "Unknown") + else: + version = getattr(module, "__version__", "Unknown") + version_info.append(f"{display_name}: {version}") + except ImportError: + version_info.append(f"{display_name}: Not installed") + + self.version_text.setPlainText("\n".join(version_info)) + + def _copy_version_info(self): + """Copy version information to clipboard.""" + from PyQt5.QtWidgets import QApplication + clipboard = QApplication.clipboard() + clipboard.setText(self.version_text.toPlainText()) + + # Show brief confirmation by changing button text temporarily + original_text = self.copy_version_btn.text() + self.copy_version_btn.setText("Copied!") + self.copy_version_btn.setStyleSheet( + "QPushButton { background-color: #28a745; color: white; padding: 6px 12px; border-radius: 4px; }" + ) + + # Reset button after 2 seconds + from PyQt5.QtCore import QTimer + QTimer.singleShot(2000, lambda: self._reset_copy_button(original_text)) + + def _reset_copy_button(self, original_text): + """Reset the copy button text and style.""" + self.copy_version_btn.setText(original_text) + self.copy_version_btn.setStyleSheet( + "QPushButton { background-color: #6c757d; color: white; padding: 6px 12px; border-radius: 4px; }" + "QPushButton:hover { background-color: #5a6268; }" + ) From b3e0bda31c23290e3323342aa7dbce5ae2b0a45a Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Tue, 14 Apr 2026 11:28:49 +0200 Subject: [PATCH 03/19] enhance help tab --- pyx2cscope/gui/qt/tabs/help_tab.py | 210 ++++++++++++----------------- 1 file changed, 88 insertions(+), 122 deletions(-) diff --git a/pyx2cscope/gui/qt/tabs/help_tab.py b/pyx2cscope/gui/qt/tabs/help_tab.py index 33478b2c..f63cb8a0 100644 --- a/pyx2cscope/gui/qt/tabs/help_tab.py +++ b/pyx2cscope/gui/qt/tabs/help_tab.py @@ -32,17 +32,33 @@ def _setup_ui(self): layout.setContentsMargins(20, 20, 20, 20) layout.setSpacing(20) - # Title - title_label = QLabel("Help & Support") - title_font = QFont() - title_font.setPointSize(14) - title_font.setBold(True) - title_label.setFont(title_font) - title_label.setStyleSheet("margin-bottom: 10px;") - layout.addWidget(title_label) + # Release Notes Section + release_group = QGroupBox("Release Notes and Documentation") + release_layout = QVBoxLayout(release_group) + + release_info = QLabel( + "View the latest release notes, changelog, and documentation." + ) + release_info.setWordWrap(True) + release_info.setStyleSheet("color: #666; margin-bottom: 10px;") + release_layout.addWidget(release_info) + + release_button_layout = QHBoxLayout() + + self.release_notes_btn = QPushButton("View Release Notes") + self.release_notes_btn.clicked.connect(self._open_release_notes) + release_button_layout.addWidget(self.release_notes_btn) + + self.documentation_btn = QPushButton("Documentation") + self.documentation_btn.clicked.connect(self._open_documentation) + release_button_layout.addWidget(self.documentation_btn) + release_button_layout.addStretch() + + release_layout.addLayout(release_button_layout) + layout.addWidget(release_group) # GitHub Issues Section - github_group = QGroupBox("Report Issues & Request Features") + github_group = QGroupBox("Report Issues and Request Features") github_layout = QVBoxLayout(github_group) github_info = QLabel( @@ -54,60 +70,19 @@ def _setup_ui(self): github_layout.addWidget(github_info) github_button_layout = QHBoxLayout() - + self.github_issues_btn = QPushButton("Open GitHub Issues") self.github_issues_btn.clicked.connect(self._open_github_issues) - self.github_issues_btn.setStyleSheet( - "QPushButton { background-color: #0078d4; color: white; padding: 8px 16px; border-radius: 4px; }" - "QPushButton:hover { background-color: #106ebe; }" - ) github_button_layout.addWidget(self.github_issues_btn) self.github_repo_btn = QPushButton("Visit Repository") self.github_repo_btn.clicked.connect(self._open_github_repo) - self.github_repo_btn.setStyleSheet( - "QPushButton { background-color: #28a745; color: white; padding: 8px 16px; border-radius: 4px; }" - "QPushButton:hover { background-color: #218838; }" - ) github_button_layout.addWidget(self.github_repo_btn) github_button_layout.addStretch() - + github_layout.addLayout(github_button_layout) layout.addWidget(github_group) - # Release Notes Section - release_group = QGroupBox("Release Notes & Documentation") - release_layout = QVBoxLayout(release_group) - - release_info = QLabel( - "View the latest release notes, changelog, and documentation." - ) - release_info.setWordWrap(True) - release_info.setStyleSheet("color: #666; margin-bottom: 10px;") - release_layout.addWidget(release_info) - - release_button_layout = QHBoxLayout() - - self.release_notes_btn = QPushButton("View Release Notes") - self.release_notes_btn.clicked.connect(self._open_release_notes) - self.release_notes_btn.setStyleSheet( - "QPushButton { background-color: #17a2b8; color: white; padding: 8px 16px; border-radius: 4px; }" - "QPushButton:hover { background-color: #138496; }" - ) - release_button_layout.addWidget(self.release_notes_btn) - - self.documentation_btn = QPushButton("Documentation") - self.documentation_btn.clicked.connect(self._open_documentation) - self.documentation_btn.setStyleSheet( - "QPushButton { background-color: #6f42c1; color: white; padding: 8px 16px; border-radius: 4px; }" - "QPushButton:hover { background-color: #5a32a3; }" - ) - release_button_layout.addWidget(self.documentation_btn) - release_button_layout.addStretch() - - release_layout.addLayout(release_button_layout) - layout.addWidget(release_group) - # Software Versions Section version_group = QGroupBox("Software Versions") version_layout = QVBoxLayout(version_group) @@ -118,25 +93,20 @@ def _setup_ui(self): self.version_text = QTextEdit() self.version_text.setReadOnly(True) - self.version_text.setMaximumHeight(200) + self.version_text.setMaximumHeight(250) self.version_text.setStyleSheet( - "QTextEdit { background-color: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 10px; }" + "QTextEdit { " + "background-color: #f8f9fa; " + "border: 1px solid #dee2e6; " + "border-radius: 4px; " + "padding: 10px; " + "font-family: 'Consolas', 'Courier New', monospace; " + "font-size: 10pt; " + "}" ) self._populate_version_info() version_layout.addWidget(self.version_text) - # Copy version info button - copy_layout = QHBoxLayout() - self.copy_version_btn = QPushButton("Copy Version Info") - self.copy_version_btn.clicked.connect(self._copy_version_info) - self.copy_version_btn.setStyleSheet( - "QPushButton { background-color: #6c757d; color: white; padding: 6px 12px; border-radius: 4px; }" - "QPushButton:hover { background-color: #5a6268; }" - ) - copy_layout.addWidget(self.copy_version_btn) - copy_layout.addStretch() - version_layout.addLayout(copy_layout) - layout.addWidget(version_group) # Additional Resources @@ -144,13 +114,14 @@ def _setup_ui(self): resources_layout = QVBoxLayout(resources_group) resources_text = QLabel( - "For additional support and community discussion:\n" - "· Check the examples directory for usage examples\n" - "· Review the README file for installation instructions\n" - "· Join our community discussions on GitHub" + "For additional support and resources:\n" + "• Check the examples directory for usage examples\n" + "• Review the README file for installation instructions\n" + "• Join our community discussions on GitHub\n" + "• Visit the documentation for detailed guides" ) resources_text.setWordWrap(True) - resources_text.setStyleSheet("color: #666; line-height: 1.5;") + resources_text.setStyleSheet("color: #666; line-height: 1.8; padding: 5px;") resources_layout.addWidget(resources_text) layout.addWidget(resources_group) @@ -181,41 +152,42 @@ def _open_documentation(self): def _populate_version_info(self): """Populate the version information text area.""" version_info = [] - - # Main application version + + # Application Versions Section + version_info.append("=== Application ===") version_info.append(f"pyX2Cscope: {pyx2cscope.__version__}") - + + # Core Dependencies Section + version_info.append("\n=== Core Dependencies ===") + # mchplnet version (important dependency) try: import mchplnet version_info.append(f"mchplnet: {mchplnet.__version__}") - except ImportError: + except (ImportError, AttributeError): version_info.append("mchplnet: Not installed") - - # Python version - version_info.append(f"Python: {sys.version}") - - # Platform info - version_info.append(f"Platform: {platform.platform()}") - version_info.append(f"Architecture: {platform.architecture()[0]}") - version_info.append(f"Processor: {platform.processor()}") - - # PyQt version - try: - from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR - version_info.append(f"Qt: {QT_VERSION_STR}") - version_info.append(f"PyQt5: {PYQT_VERSION_STR}") - except ImportError: - version_info.append("PyQt5: Not available") - + + # mchplnet dependencies + mchplnet_deps = [ + ("can", "python-can"), + ] + + for import_name, display_name in mchplnet_deps: + try: + module = __import__(import_name) + version = getattr(module, "__version__", "Unknown") + version_info.append(f"{display_name}: {version}") + except (ImportError, AttributeError): + version_info.append(f"{display_name}: Not installed") + # Try to get other dependency versions dependencies = [ ("numpy", "numpy"), - ("matplotlib", "matplotlib"), + ("matplotlib", "matplotlib"), ("serial", "pyserial"), # pyserial is imported as 'serial' - ("elftools", "elftools") + ("elftools", "pyelftools") ] - + for import_name, display_name in dependencies: try: module = __import__(import_name) @@ -224,32 +196,26 @@ def _populate_version_info(self): else: version = getattr(module, "__version__", "Unknown") version_info.append(f"{display_name}: {version}") - except ImportError: + except (ImportError, AttributeError): version_info.append(f"{display_name}: Not installed") - - self.version_text.setPlainText("\n".join(version_info)) - def _copy_version_info(self): - """Copy version information to clipboard.""" - from PyQt5.QtWidgets import QApplication - clipboard = QApplication.clipboard() - clipboard.setText(self.version_text.toPlainText()) - - # Show brief confirmation by changing button text temporarily - original_text = self.copy_version_btn.text() - self.copy_version_btn.setText("Copied!") - self.copy_version_btn.setStyleSheet( - "QPushButton { background-color: #28a745; color: white; padding: 6px 12px; border-radius: 4px; }" - ) - - # Reset button after 2 seconds - from PyQt5.QtCore import QTimer - QTimer.singleShot(2000, lambda: self._reset_copy_button(original_text)) - - def _reset_copy_button(self, original_text): - """Reset the copy button text and style.""" - self.copy_version_btn.setText(original_text) - self.copy_version_btn.setStyleSheet( - "QPushButton { background-color: #6c757d; color: white; padding: 6px 12px; border-radius: 4px; }" - "QPushButton:hover { background-color: #5a6268; }" - ) + # GUI Framework Section + version_info.append("\n=== GUI Framework ===") + try: + from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR + version_info.append(f"Qt: {QT_VERSION_STR}") + version_info.append(f"PyQt5: {PYQT_VERSION_STR}") + except ImportError: + version_info.append("PyQt5: Not available") + + # System Information Section + version_info.append("\n=== System Information ===") + version_info.append(f"Python: {sys.version.split()[0]}") # Show version without extra info + version_info.append(f"Platform: {platform.platform()}") + version_info.append(f"Architecture: {platform.architecture()[0]}") + + processor = platform.processor() + if processor: # Only show if available + version_info.append(f"Processor: {processor}") + + self.version_text.setPlainText("\n".join(version_info)) From 3c731d30e902e292e4ffbacbb47b226e7071fb51 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Tue, 14 Apr 2026 11:49:14 +0200 Subject: [PATCH 04/19] adding versions to web gui --- pyproject.toml | 1 + pyx2cscope/gui/web/app.py | 39 +++++++ .../gui/web/templates/welcome_content.html | 105 +++++++++++++----- requirements.txt | Bin 472 -> 346 bytes 4 files changed, 117 insertions(+), 28 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c7aa18dd..9d34b844 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ PyQt5 = "^5.15.9" pyqtgraph = "^0.13.7" mchplnet = "0.4.2" flask = "^3.0.3" +flask-socketio = "^5.3.4" [tool.ruff] line-length = 120 diff --git a/pyx2cscope/gui/web/app.py b/pyx2cscope/gui/web/app.py index 6750dd40..53edf176 100644 --- a/pyx2cscope/gui/web/app.py +++ b/pyx2cscope/gui/web/app.py @@ -39,6 +39,7 @@ def create_app(): app.add_url_rule("/", view_func=index) app.add_url_rule("/serial-ports", view_func=list_serial_ports) app.add_url_rule("/local-ips", view_func=get_local_ips) + app.add_url_rule("/version-info", view_func=get_version_info) app.add_url_rule("/connect", view_func=connect, methods=["POST"]) app.add_url_rule("/disconnect", view_func=disconnect) app.add_url_rule("/is-connected", view_func=is_connected) @@ -92,6 +93,44 @@ def get_local_ips(): return jsonify({"ips": ips}) +def get_version_info(): + """Return version information for all dependencies. + + call {server_url}/version-info to execute. + """ + import importlib.metadata + versions = {} + + def get_package_version(package_name, module_name=None, attr_name='__version__'): + """Get version from package metadata or module attribute.""" + try: + # Try importlib.metadata first (standard way) + return importlib.metadata.version(package_name) + except Exception: + # Fall back to module attribute + if module_name: + try: + module = __import__(module_name) + return getattr(module, attr_name, 'Unknown') + except (ImportError, AttributeError): + pass + return 'Not installed' + + # Web interface dependencies + versions['flask'] = get_package_version('flask', 'flask') + versions['flask_socketio'] = get_package_version('flask-socketio', 'flask_socketio') + versions['mchplnet'] = get_package_version('mchplnet', 'mchplnet') + versions['python_can'] = get_package_version('python-can', 'can') + + # Core dependencies + versions['numpy'] = get_package_version('numpy', 'numpy') + versions['matplotlib'] = get_package_version('matplotlib', 'matplotlib') + versions['pyserial'] = get_package_version('pyserial', 'serial', 'VERSION') + versions['pyelftools'] = get_package_version('pyelftools', 'elftools') + + return jsonify(versions) + + def connect(): """Connect pyX2CScope using arguments coming from the web. diff --git a/pyx2cscope/gui/web/templates/welcome_content.html b/pyx2cscope/gui/web/templates/welcome_content.html index c25ad4d1..47a877c4 100644 --- a/pyx2cscope/gui/web/templates/welcome_content.html +++ b/pyx2cscope/gui/web/templates/welcome_content.html @@ -1,34 +1,83 @@ - -
Getting Started
+ +
+ +
+
Getting Started
-
-
settings Setup
-

Configure your interface, upload an ELF file, and click "Connect" to start monitoring your device.

-
+
+
settings Setup
+

Configure your interface, upload an ELF file, and click "Connect" to start monitoring your device.

+
-
Available Views
-
-
-
visibility Watch View
-

Monitor and interact with variables in real-time.

-
-
-
show_chart Scope View
-

Visualize variable data over time with oscilloscope-style charts.

-
-
-
dashboard Dashboard
-

Create custom layouts with interactive widgets and gauges.

+
Available Views
+
+
visibility Watch View
+

Monitor and interact with variables in real-time.

+
+
+
show_chart Scope View
+

Visualize variable data over time with oscilloscope-style charts.

+
+
+
dashboard Dashboard
+

Create custom layouts with interactive widgets and gauges.

+
+
+
code Scripting
+

Execute Python scripts with access to x2cscope.

+
+ +
Tips
+
    +
  • qr_code_2 Click QR code icons to generate scannable links for mobile access
  • +
  • open_in_new Click open icons to launch views in separate windows
  • +
  • help_outline Click the help icon in the header to toggle this card
  • +
-
-
code Scripting
-

Execute Python scripts with access to x2cscope.

+ + +
+
Software Versions
+
+
+

Application:

+
    +
  • pyX2Cscope: {{ version }}
  • +
+

Web Interface Dependencies:

+
    +
  • Flask: Loading...
  • +
  • Flask-SocketIO: Loading...
  • +
  • mchplnet: Loading...
  • +
  • python-can: Loading...
  • +
+

Core Dependencies:

+
    +
  • numpy: Loading...
  • +
  • matplotlib: Loading...
  • +
  • pyserial: Loading...
  • +
  • pyelftools: Loading...
  • +
+
+
-
Tips
-
    -
  • qr_code_2 Click QR code icons to generate scannable links for mobile access
  • -
  • open_in_new Click open icons to launch views in separate windows
  • -
  • help_outline Click the help icon in the header to toggle this card
  • -
+ diff --git a/requirements.txt b/requirements.txt index d9a6c9536004e3d7cdeb925bb6efa79969d13224..1cc3c318136e3eb8182075a1ff0f48b110c9e004 100644 GIT binary patch delta 14 Wcmcb?e2a+tp>sX delta 135 zcmcb`bc0#p|Gxr;N`_*FRE8pkOol{;9ELguTLxnWJqA+-UIs3PiA?XJK`KfZG8pn1 z@)&f1D)Si9fok)BtW2Po9ZJqqmQ=nRNAU2x#Iv)W3 C4;#1u From 19d97dddf424174819006c90ced692d207deeb32 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Tue, 14 Apr 2026 13:32:17 +0200 Subject: [PATCH 05/19] update mchplnet 0.5.0, pyX2C 0.7.0 --- mchplnet | 2 +- pyproject.toml | 4 ++-- pyx2cscope/__init__.py | 4 ++-- requirements.txt | Bin 346 -> 346 bytes tests/test_install.py | 11 +++++++++-- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/mchplnet b/mchplnet index 1f442e6a..a1b9669e 160000 --- a/mchplnet +++ b/mchplnet @@ -1 +1 @@ -Subproject commit 1f442e6a854fa5c639d25b99fb0e0d430c552893 +Subproject commit a1b9669e222f8c3a6cfc3f2ee90d3e46a36f17b4 diff --git a/pyproject.toml b/pyproject.toml index 9d34b844..78c9b8e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "pyx2cscope" -version = "0.6.2" +version = "0.7.0" description = "python implementation of X2Cscope" authors = [ "Yash Agarwal", @@ -33,7 +33,7 @@ numpy = "^1.26.0" matplotlib = "^3.7.2" PyQt5 = "^5.15.9" pyqtgraph = "^0.13.7" -mchplnet = "0.4.2" +mchplnet = "0.5.0" flask = "^3.0.3" flask-socketio = "^5.3.4" diff --git a/pyx2cscope/__init__.py b/pyx2cscope/__init__.py index 465d8ef3..79b0e20e 100644 --- a/pyx2cscope/__init__.py +++ b/pyx2cscope/__init__.py @@ -1,11 +1,11 @@ """This module contains the pyx2cscope package. -Version: 0.6.2 +Version: 0.7.0 """ import logging -__version__ = "0.6.2" +__version__ = "0.7.0" def set_logger( level: int = logging.ERROR, diff --git a/requirements.txt b/requirements.txt index 1cc3c318136e3eb8182075a1ff0f48b110c9e004..f9e7311086ccb8df4b9601b3a09d06ad7e6dd669 100644 GIT binary patch delta 17 Ycmcb`bc<;N2P3N~gC2vyWL`#J04wVQ_y7O^ delta 17 Ycmcb`bc<;N2P3NqgC2v?WL`#J04wYR`2YX_ diff --git a/tests/test_install.py b/tests/test_install.py index 95e36364..7e2039b6 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -1,6 +1,8 @@ """Integration test to check if after install, PyX2CScope outputs the expected behavior.""" import os +import subprocess +import sys import pyx2cscope from mchplnet.services.frame_device_info import DeviceInfo @@ -48,8 +50,13 @@ def test_x2cscope_install_serial_32(mocker): def test_x2cscope_install_script_bin(): """Test if the script scripts/pyx2cscope executable is installed correctly.""" - result = os.popen("pyx2cscope -v").read().split(" ")[1].strip("\n") - assert result == pyx2cscope.__version__, "x2cscope script not working" + result = subprocess.run( + [sys.executable, "-m", "pyx2cscope", "-v"], + capture_output=True, + text=True, + ) + version = result.stdout.strip().split(" ")[-1].strip() + assert version == pyx2cscope.__version__, "x2cscope script not working" # def test_web_x2cscope_install(): From 7ebca22e3dcc41e8bc08a57d65bc57d40630a490 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Tue, 14 Apr 2026 13:55:28 +0200 Subject: [PATCH 06/19] ruff and tests ok --- mchplnet | 2 +- pyx2cscope/gui/qt/tabs/help_tab.py | 207 +++++++++++++---------------- tests/test_can_reconnection.py | 85 +----------- tests/test_install.py | 2 +- tests/test_qt_gui.py | 88 +++++++++++- 5 files changed, 185 insertions(+), 199 deletions(-) diff --git a/mchplnet b/mchplnet index a1b9669e..fea6eefb 160000 --- a/mchplnet +++ b/mchplnet @@ -1 +1 @@ -Subproject commit a1b9669e222f8c3a6cfc3f2ee90d3e46a36f17b4 +Subproject commit fea6eefbef72780a101f7283ebb2c0c3dfe33c74 diff --git a/pyx2cscope/gui/qt/tabs/help_tab.py b/pyx2cscope/gui/qt/tabs/help_tab.py index f63cb8a0..1b60e57a 100644 --- a/pyx2cscope/gui/qt/tabs/help_tab.py +++ b/pyx2cscope/gui/qt/tabs/help_tab.py @@ -1,9 +1,10 @@ """Help tab for the Qt GUI application.""" import platform -import subprocess import sys + from PyQt5.QtCore import QUrl +from PyQt5.QtGui import QDesktopServices from PyQt5.QtWidgets import ( QGroupBox, QHBoxLayout, @@ -13,7 +14,6 @@ QVBoxLayout, QWidget, ) -from PyQt5.QtGui import QFont, QDesktopServices import pyx2cscope @@ -32,64 +32,71 @@ def _setup_ui(self): layout.setContentsMargins(20, 20, 20, 20) layout.setSpacing(20) - # Release Notes Section - release_group = QGroupBox("Release Notes and Documentation") - release_layout = QVBoxLayout(release_group) + layout.addWidget(self._create_release_group()) + layout.addWidget(self._create_github_group()) + layout.addWidget(self._create_version_group()) + layout.addWidget(self._create_resources_group()) + layout.addStretch() - release_info = QLabel( - "View the latest release notes, changelog, and documentation." - ) - release_info.setWordWrap(True) - release_info.setStyleSheet("color: #666; margin-bottom: 10px;") - release_layout.addWidget(release_info) + def _create_release_group(self): + """Create the Release Notes and Documentation group box.""" + group = QGroupBox("Release Notes and Documentation") + group_layout = QVBoxLayout(group) - release_button_layout = QHBoxLayout() + info = QLabel("View the latest release notes, changelog, and documentation.") + info.setWordWrap(True) + info.setStyleSheet("color: #666; margin-bottom: 10px;") + group_layout.addWidget(info) + + button_layout = QHBoxLayout() self.release_notes_btn = QPushButton("View Release Notes") self.release_notes_btn.clicked.connect(self._open_release_notes) - release_button_layout.addWidget(self.release_notes_btn) + button_layout.addWidget(self.release_notes_btn) self.documentation_btn = QPushButton("Documentation") self.documentation_btn.clicked.connect(self._open_documentation) - release_button_layout.addWidget(self.documentation_btn) - release_button_layout.addStretch() + button_layout.addWidget(self.documentation_btn) + button_layout.addStretch() - release_layout.addLayout(release_button_layout) - layout.addWidget(release_group) + group_layout.addLayout(button_layout) + return group - # GitHub Issues Section - github_group = QGroupBox("Report Issues and Request Features") - github_layout = QVBoxLayout(github_group) + def _create_github_group(self): + """Create the Report Issues and Request Features group box.""" + group = QGroupBox("Report Issues and Request Features") + group_layout = QVBoxLayout(group) - github_info = QLabel( + info = QLabel( "If you encounter bugs, have feature requests, or need help, " "please open an issue on our GitHub repository." ) - github_info.setWordWrap(True) - github_info.setStyleSheet("color: #666; margin-bottom: 10px;") - github_layout.addWidget(github_info) + info.setWordWrap(True) + info.setStyleSheet("color: #666; margin-bottom: 10px;") + group_layout.addWidget(info) - github_button_layout = QHBoxLayout() + button_layout = QHBoxLayout() self.github_issues_btn = QPushButton("Open GitHub Issues") self.github_issues_btn.clicked.connect(self._open_github_issues) - github_button_layout.addWidget(self.github_issues_btn) + button_layout.addWidget(self.github_issues_btn) self.github_repo_btn = QPushButton("Visit Repository") self.github_repo_btn.clicked.connect(self._open_github_repo) - github_button_layout.addWidget(self.github_repo_btn) - github_button_layout.addStretch() + button_layout.addWidget(self.github_repo_btn) + button_layout.addStretch() - github_layout.addLayout(github_button_layout) - layout.addWidget(github_group) + group_layout.addLayout(button_layout) + return group - # Software Versions Section - version_group = QGroupBox("Software Versions") - version_layout = QVBoxLayout(version_group) + def _create_version_group(self): + """Create the Software Versions group box.""" + group = QGroupBox("Software Versions") + group_layout = QVBoxLayout(group) - version_info = QLabel("Current software and dependency versions:") - version_info.setStyleSheet("color: #666; margin-bottom: 10px;") - version_layout.addWidget(version_info) + info = QLabel("Current software and dependency versions:") + info.setStyleSheet("color: #666; margin-bottom: 10px;") + group_layout.addWidget(info) self.version_text = QTextEdit() self.version_text.setReadOnly(True) @@ -105,117 +112,81 @@ def _setup_ui(self): "}" ) self._populate_version_info() - version_layout.addWidget(self.version_text) - - layout.addWidget(version_group) + group_layout.addWidget(self.version_text) + return group - # Additional Resources - resources_group = QGroupBox("Additional Resources") - resources_layout = QVBoxLayout(resources_group) + def _create_resources_group(self): + """Create the Additional Resources group box.""" + group = QGroupBox("Additional Resources") + group_layout = QVBoxLayout(group) - resources_text = QLabel( + text = QLabel( "For additional support and resources:\n" "• Check the examples directory for usage examples\n" "• Review the README file for installation instructions\n" "• Join our community discussions on GitHub\n" "• Visit the documentation for detailed guides" ) - resources_text.setWordWrap(True) - resources_text.setStyleSheet("color: #666; line-height: 1.8; padding: 5px;") - resources_layout.addWidget(resources_text) - - layout.addWidget(resources_group) - - # Add stretch to push everything to the top - layout.addStretch() + text.setWordWrap(True) + text.setStyleSheet("color: #666; line-height: 1.8; padding: 5px;") + group_layout.addWidget(text) + return group def _open_github_issues(self): """Open GitHub issues page in default browser.""" - url = QUrl("https://github.com/X2Cscope/pyx2cscope/issues") - QDesktopServices.openUrl(url) + QDesktopServices.openUrl(QUrl("https://github.com/X2Cscope/pyx2cscope/issues")) def _open_github_repo(self): """Open GitHub repository page in default browser.""" - url = QUrl("https://github.com/X2Cscope/pyx2cscope") - QDesktopServices.openUrl(url) + QDesktopServices.openUrl(QUrl("https://github.com/X2Cscope/pyx2cscope")) def _open_release_notes(self): """Open GitHub releases page in default browser.""" - url = QUrl("https://github.com/X2Cscope/pyx2cscope/releases") - QDesktopServices.openUrl(url) + QDesktopServices.openUrl(QUrl("https://github.com/X2Cscope/pyx2cscope/releases")) def _open_documentation(self): """Open documentation in default browser.""" - url = QUrl("https://x2cscope.github.io/pyx2cscope/") - QDesktopServices.openUrl(url) + QDesktopServices.openUrl(QUrl("https://x2cscope.github.io/pyx2cscope/")) + + @staticmethod + def _get_module_version(import_name, version_attr="__version__"): + """Return the version string for a module, or 'Not installed' on failure.""" + try: + module = __import__(import_name) + return getattr(module, version_attr, "Unknown") + except ImportError: + return "Not installed" def _populate_version_info(self): """Populate the version information text area.""" - version_info = [] + lines = [] - # Application Versions Section - version_info.append("=== Application ===") - version_info.append(f"pyX2Cscope: {pyx2cscope.__version__}") + lines.append("=== Application ===") + lines.append(f"pyX2Cscope: {pyx2cscope.__version__}") - # Core Dependencies Section - version_info.append("\n=== Core Dependencies ===") + lines.append("\n=== Core Dependencies ===") + lines.append(f"mchplnet: {self._get_module_version('mchplnet')}") + lines.append(f"python-can: {self._get_module_version('can')}") + lines.append(f"numpy: {self._get_module_version('numpy')}") + lines.append(f"matplotlib: {self._get_module_version('matplotlib')}") + lines.append(f"pyserial: {self._get_module_version('serial', 'VERSION')}") + lines.append(f"pyelftools: {self._get_module_version('elftools')}") - # mchplnet version (important dependency) - try: - import mchplnet - version_info.append(f"mchplnet: {mchplnet.__version__}") - except (ImportError, AttributeError): - version_info.append("mchplnet: Not installed") - - # mchplnet dependencies - mchplnet_deps = [ - ("can", "python-can"), - ] - - for import_name, display_name in mchplnet_deps: - try: - module = __import__(import_name) - version = getattr(module, "__version__", "Unknown") - version_info.append(f"{display_name}: {version}") - except (ImportError, AttributeError): - version_info.append(f"{display_name}: Not installed") - - # Try to get other dependency versions - dependencies = [ - ("numpy", "numpy"), - ("matplotlib", "matplotlib"), - ("serial", "pyserial"), # pyserial is imported as 'serial' - ("elftools", "pyelftools") - ] - - for import_name, display_name in dependencies: - try: - module = __import__(import_name) - if display_name == "pyserial": - version = getattr(module, "VERSION", "Unknown") - else: - version = getattr(module, "__version__", "Unknown") - version_info.append(f"{display_name}: {version}") - except (ImportError, AttributeError): - version_info.append(f"{display_name}: Not installed") - - # GUI Framework Section - version_info.append("\n=== GUI Framework ===") + lines.append("\n=== GUI Framework ===") try: - from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR - version_info.append(f"Qt: {QT_VERSION_STR}") - version_info.append(f"PyQt5: {PYQT_VERSION_STR}") + from PyQt5.QtCore import PYQT_VERSION_STR, QT_VERSION_STR + lines.append(f"Qt: {QT_VERSION_STR}") + lines.append(f"PyQt5: {PYQT_VERSION_STR}") except ImportError: - version_info.append("PyQt5: Not available") + lines.append("PyQt5: Not available") - # System Information Section - version_info.append("\n=== System Information ===") - version_info.append(f"Python: {sys.version.split()[0]}") # Show version without extra info - version_info.append(f"Platform: {platform.platform()}") - version_info.append(f"Architecture: {platform.architecture()[0]}") + lines.append("\n=== System Information ===") + lines.append(f"Python: {sys.version.split()[0]}") + lines.append(f"Platform: {platform.platform()}") + lines.append(f"Architecture: {platform.architecture()[0]}") processor = platform.processor() - if processor: # Only show if available - version_info.append(f"Processor: {processor}") + if processor: + lines.append(f"Processor: {processor}") - self.version_text.setPlainText("\n".join(version_info)) + self.version_text.setPlainText("\n".join(lines)) diff --git a/tests/test_can_reconnection.py b/tests/test_can_reconnection.py index 7a6eb6d3..deb46c87 100644 --- a/tests/test_can_reconnection.py +++ b/tests/test_can_reconnection.py @@ -10,13 +10,14 @@ import pytest -# Set headless mode before importing Qt modules -os.environ["QT_QPA_PLATFORM"] = "offscreen" - from mchplnet.interfaces.can import LNetCan from pyx2cscope.x2cscope import X2CScope from tests import data +EXPECTED_BUS_CALLS_AFTER_RECONNECT = 2 +RECONNECT_CYCLES = 3 +EXPECTED_BUS_CALLS_AFTER_CYCLES = RECONNECT_CYCLES + 1 + @pytest.fixture def mock_can_bus(): @@ -62,7 +63,7 @@ def test_can_interface_start_cleans_up_existing_bus(self, mock_can_bus): # Verify shutdown was called on the old bus assert mock_bus_instance.shutdown.called # Verify a new bus was created (total 2 calls) - assert mock_bus_class.call_count == 2 + assert mock_bus_class.call_count == EXPECTED_BUS_CALLS_AFTER_RECONNECT def test_can_interface_stop_clears_bus_reference(self, mock_can_bus): """Test that stop() properly clears the bus reference.""" @@ -109,7 +110,7 @@ def test_can_interface_multiple_reconnections(self, mock_can_bus): # Verify we can start again after all cycles can_interface.start() assert can_interface.bus is not None - assert mock_bus_class.call_count == 4 + assert mock_bus_class.call_count == EXPECTED_BUS_CALLS_AFTER_CYCLES def test_can_interface_stop_handles_shutdown_error(self, mock_can_bus): """Test that stop() handles errors during bus shutdown gracefully.""" @@ -187,78 +188,6 @@ def test_x2cscope_disconnect_calls_interface_stop(self, mock_can_bus): # Verify shutdown was called assert mock_bus_instance.shutdown.called - def test_qt_connection_manager_disconnect_calls_x2cscope_disconnect(self, mock_can_bus): - """Test that Qt ConnectionManager properly calls x2cscope.disconnect().""" - from PyQt5.QtCore import QCoreApplication - from pyx2cscope.gui.qt.controllers.connection_manager import ConnectionManager - from pyx2cscope.gui.qt.models.app_state import AppState - - # Create Qt application if it doesn't exist - app = QCoreApplication.instance() - if app is None: - app = QCoreApplication([]) - - try: - _, mock_bus_instance = mock_can_bus - - # Create app state and connection manager - app_state = AppState() - conn_manager = ConnectionManager(app_state) - - # Mock read/write to avoid actual CAN communication - with patch('mchplnet.interfaces.can.LNetCan.read') as mock_read, \ - patch('mchplnet.interfaces.can.LNetCan.write'): - - # Mock read to return valid LNet frames - device_info_frame = bytearray( - b'\x55\x2E\x01\x11\x00' # SYN, SIZE(46 data bytes), NODE, SERVICE_ID, STATUS - b'\x01\x00' # Monitor version (little-endian) - b'\x01\x00' # App version (little-endian) - b'\x10\x82' # Processor ID 0x8210 (16-bit generic dsPIC) - b'01/01/2024' # Monitor date (9 bytes) - b'1200' # Monitor time (4 bytes) - b'01/01/2024' # App date (9 bytes) - b'1200' # App time (4 bytes) - b'\x01' # DSP state (0x01 = Application runs on target) - b'\x00\x00' # Event type (2 bytes) - b'\x00\x00\x00\x00' # Event ID (4 bytes) - b'\x00\x00\x00\x00' # Table struct address (4 bytes) - b'\x00' # CRC - ) - load_param_frame = bytearray(b'\x55\x00\x01\x12\x00\x00') - # Return frames for connection (2 calls: device_info and load_parameters) - mock_read.side_effect = [ - device_info_frame, - load_param_frame, - ] - - # Connect via CAN - success = conn_manager.connect_can( - elf_file=self.elf_file, - bus_type="USB", - channel=1, - baudrate="500K", - mode="Standard", - tx_id="110", - rx_id="100", - ) - - assert success is True - assert app_state.is_connected() - - # Disconnect - conn_manager.disconnect() - - # Verify x2cscope was properly disconnected - assert not app_state.is_connected() - assert app_state.x2cscope is None - # Verify bus shutdown was called - assert mock_bus_instance.shutdown.called - - finally: - # Clean up Qt application - if app: - app.quit() class TestCANInterfaceStartupCleanup: @@ -293,7 +222,7 @@ def test_start_with_existing_bus_stops_first(self, mock_can_bus): # Verify old bus was shut down assert mock_bus_instance.shutdown.called # Verify new bus was created - assert mock_bus_class.call_count == 2 + assert mock_bus_class.call_count == EXPECTED_BUS_CALLS_AFTER_RECONNECT def test_is_open_returns_false_when_bus_is_none(self): """Test that is_open() returns False when bus is None.""" diff --git a/tests/test_install.py b/tests/test_install.py index 7e2039b6..8470bcb5 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -53,7 +53,7 @@ def test_x2cscope_install_script_bin(): result = subprocess.run( [sys.executable, "-m", "pyx2cscope", "-v"], capture_output=True, - text=True, + text=True, check=False, ) version = result.stdout.strip().split(" ")[-1].strip() assert version == pyx2cscope.__version__, "x2cscope script not working" diff --git a/tests/test_qt_gui.py b/tests/test_qt_gui.py index e2682761..76bed478 100644 --- a/tests/test_qt_gui.py +++ b/tests/test_qt_gui.py @@ -10,13 +10,28 @@ """ import os -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch import pytest # Set headless mode before importing Qt modules os.environ["QT_QPA_PLATFORM"] = "offscreen" +from tests import data + + +@pytest.fixture +def mock_can_bus(): + """Create a mock CAN bus for testing.""" + with patch('can.interface.Bus') as mock_bus_class: + mock_bus_instance = MagicMock() + mock_bus_instance._is_shutdown = False + mock_bus_instance.recv = MagicMock(return_value=None) + mock_bus_instance.send = MagicMock() + mock_bus_instance.shutdown = MagicMock() + mock_bus_class.return_value = mock_bus_instance + yield mock_bus_class, mock_bus_instance + class TestAppStateModel: """Tests for AppState model.""" @@ -388,6 +403,77 @@ def test_stop_polling(self, data_poller): assert data_poller._running is False +class TestCANConnectionManager: + """Tests for ConnectionManager CAN connect/disconnect cycle.""" + + elf_file = os.path.join( + os.path.dirname(data.__file__), "mc_foc_sl_fip_dspic33ck_mclv48v300w.elf" + ) + + def test_qt_connection_manager_disconnect_calls_x2cscope_disconnect(self, mock_can_bus): + """Test that Qt ConnectionManager properly calls x2cscope.disconnect().""" + from unittest.mock import patch + + from PyQt5.QtCore import QCoreApplication + + from pyx2cscope.gui.qt.controllers.connection_manager import ConnectionManager + from pyx2cscope.gui.qt.models.app_state import AppState + + app = QCoreApplication.instance() + if app is None: + app = QCoreApplication([]) + + try: + _, mock_bus_instance = mock_can_bus + + app_state = AppState() + conn_manager = ConnectionManager(app_state) + + device_info_frame = bytearray( + b'\x55\x2E\x01\x11\x00' + b'\x01\x00' + b'\x01\x00' + b'\x10\x82' + b'01/01/2024' + b'1200' + b'01/01/2024' + b'1200' + b'\x01' + b'\x00\x00' + b'\x00\x00\x00\x00' + b'\x00\x00\x00\x00' + b'\x00' + ) + load_param_frame = bytearray(b'\x55\x00\x01\x12\x00\x00') + + with patch('mchplnet.interfaces.can.LNetCan.read') as mock_read, \ + patch('mchplnet.interfaces.can.LNetCan.write'): + mock_read.side_effect = [device_info_frame, load_param_frame] + + success = conn_manager.connect_can( + elf_file=self.elf_file, + bus_type="USB", + channel=1, + baudrate="500K", + mode="Standard", + tx_id="110", + rx_id="100", + ) + + assert success is True + assert app_state.is_connected() + + conn_manager.disconnect() + + assert not app_state.is_connected() + assert app_state.x2cscope is None + assert mock_bus_instance.shutdown.called + + finally: + if app: + app.quit() + + class TestSignalSlotConnections: """Tests for signal/slot connections.""" From ddc3b468a1d13d642614e4aa404cb664609eb92b Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Tue, 14 Apr 2026 14:14:39 +0200 Subject: [PATCH 07/19] fix test wrong com port --- tests/test_pyx2cscope_class.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_pyx2cscope_class.py b/tests/test_pyx2cscope_class.py index b0effb79..46428066 100644 --- a/tests/test_pyx2cscope_class.py +++ b/tests/test_pyx2cscope_class.py @@ -74,7 +74,5 @@ def test_missing_com_port(self, mocker): def test_wrong_com_port(self): """Check handling of a non-existent COM-PORT input.""" - with pytest.raises( - Exception, match=r"could not open port 'COM0'" - ): + with pytest.raises(Exception, match=r"could not open port '?COM0'?"): X2CScope(elf_file=self.elf_file, port="COM0") From 89db7e7f64b11699cfb5662adeb2623cb98b18f3 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Tue, 14 Apr 2026 16:14:09 +0200 Subject: [PATCH 08/19] including jupyter notebook example --- pyx2cscope/examples/notebooks/README.md | 60 ++ .../examples/notebooks/mcaf_hil_example.ipynb | 592 ++++++++++++++++++ 2 files changed, 652 insertions(+) create mode 100644 pyx2cscope/examples/notebooks/README.md create mode 100644 pyx2cscope/examples/notebooks/mcaf_hil_example.ipynb diff --git a/pyx2cscope/examples/notebooks/README.md b/pyx2cscope/examples/notebooks/README.md new file mode 100644 index 00000000..b0425aa5 --- /dev/null +++ b/pyx2cscope/examples/notebooks/README.md @@ -0,0 +1,60 @@ +# pyX2Cscope — Jupyter Notebook Examples + +Interactive notebooks for exploring and controlling Microchip embedded targets using pyX2Cscope. + +## Available Notebooks + +| Notebook | Description | +|---|---| +| [mcaf_hil_example.ipynb](mcaf_hil_example.ipynb) | Hardware-in-the-Loop test with MCAF motor firmware: ramp speed, capture phase currents, calculate RMS values | + +--- + +## How to Run + +### 1. Install pyX2Cscope + +If you haven't already: + +```bash +pip install pyx2cscope +``` + +### 2. Install Jupyter + +```bash +pip install jupyterlab +``` + +### 3. Launch Jupyter + +From this folder: + +```bash +jupyter lab +``` + +A browser window will open. Click the notebook you want to run. + +### 4. Configure the notebook + +Each notebook has a **Configuration** cell near the top. At minimum you need to set: + +- `SERIAL_PORT` — the COM port your board is connected to (e.g. `"COM3"` on Windows, `"/dev/ttyUSB0"` on Linux/macOS). Set to `"AUTO"` to let pyX2Cscope detect it automatically. +- `ELF_FILE` — the full path to the `.elf` file matching the firmware flashed on your board. + +### 5. Run the cells + +Use **Shift+Enter** to run one cell at a time, or **Run → Run All Cells** from the menu to execute the full notebook. + +> **Tip:** Always run the final cleanup cell before closing the notebook. It stops the motor and restores the hardware UI. + +--- + +## Requirements + +- Python 3.10 or newer +- pyX2Cscope (`pip install pyx2cscope`) +- `notebook` or `jupyterlab` +- A Microchip board running compatible firmware, connected via USB/serial +- The matching `.elf` file for the firmware on your board diff --git a/pyx2cscope/examples/notebooks/mcaf_hil_example.ipynb b/pyx2cscope/examples/notebooks/mcaf_hil_example.ipynb new file mode 100644 index 00000000..57e32734 --- /dev/null +++ b/pyx2cscope/examples/notebooks/mcaf_hil_example.ipynb @@ -0,0 +1,592 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# MCAF Hardware-in-the-Loop (HiL) Example\n", + "\n", + "This notebook demonstrates how to use **pyX2Cscope** to control and monitor a BLDC motor running\n", + "[MCAF (Motor Control Application Framework)](https://www.microchip.com/en-us/solutions/technologies/motor-control-and-drive/motorbench-development-suite)\n", + "firmware on a Microchip device.\n", + "\n", + "### What this notebook does\n", + "\n", + "1. Connects to the target via serial (UART)\n", + "2. Disables the hardware UI so the script has exclusive control\n", + "3. Stops any running motor\n", + "4. Ramps the motor to **700 RPM**, measures the time to reach that speed, then captures phase currents with the scope\n", + "5. Arms the scope on `velocityMeasured`, ramps to **1400 RPM**, and plots the speed ramp curve (~60 ms)\n", + "6. Captures phase currents at 1400 RPM and calculates RMS values\n", + "7. Stops the motor and returns control to the hardware UI\n", + "\n", + "### Hardware used in this test\n", + "\n", + "| Component | Description |\n", + "|---|---|\n", + "| [MCLV-48V-300W Inverter Board (EV18H47A)](https://www.microchip.com/en-us/development-tool/ev18h47a) | Motor control inverter board (low-voltage, up to 48 V / 300 W) |\n", + "| [dsPIC33CK Low Voltage Motor Control (LVMC) Board (EV62P66A)](https://www.microchip.com/en-us/development-tool/ev62p66a) | Digital controller board with dsPIC33CK DSC |\n", + "| ACT 42BLF02 | BLDC motor |\n", + "\n", + "The firmware was generated with [MotorBench Development Suite (MCAF)](https://www.microchip.com/en-us/solutions/technologies/motor-control-and-drive/motorbench-development-suite).\n", + "\n", + "### Prerequisites\n", + "\n", + "- The hardware listed above, connected via USB/serial\n", + "- The matching `.elf` file for the firmware flashed on the controller board\n", + "- pyX2Cscope installed: `pip install pyx2cscope`\n", + "\n", + "> **Note:** The variable names used here (`motor.apiData.velocityReference`, etc.) are specific to MCAF.\n", + "> Use `x2c_scope.list_variables()` to browse the variables available in your firmware." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1 — Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "from pyx2cscope.x2cscope import X2CScope" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2 — Configuration\n", + "\n", + "Set the serial port and the path to the ELF file for your board.\n", + "\n", + "| Setting | Description |\n", + "|---|---|\n", + "| `SERIAL_PORT` | COM port on Windows (`\"COM3\"`) or device path on Linux/macOS (`\"/dev/ttyUSB0\"`). Use `\"AUTO\"` to let pyX2Cscope detect the port automatically. |\n", + "| `ELF_FILE` | Full path to the `.elf` file matching the firmware on your board. |" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "SERIAL_PORT = \"AUTO\" # or e.g. \"COM3\" / \"/dev/ttyUSB0\"\n", + "ELF_FILE = r\"C:\\Users\\M71906\\Projects\\pyx2c_training\\mb_foc_dspic.X\\dist\\default\\production\\mb_foc_dspic.X.production.elf\" # <-- update this path\n", + "\n", + "# Speed thresholds — MCAF stores speed as RPM * 10\n", + "TARGET_SPEED_1_RPM = 7000 # represents 700.0 RPM\n", + "TARGET_SPEED_2_RPM = 14000 # represents 1400.0 RPM" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3 — Connect to the target" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connected to: {'processor_id': '__GENERIC_MICROCHIP_DSPIC__', 'uc_width': '16-bit', 'date': 'Sep132024', 'time': '1516', 'AppVer': 2048, 'dsp_state': 'Application runs on target'}\n" + ] + } + ], + "source": [ + "x2c_scope = X2CScope(port=SERIAL_PORT, elf_file=ELF_FILE)\n", + "\n", + "device_info = x2c_scope.get_device_info()\n", + "print(\"Connected to:\", device_info)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Browse available variables (optional)\n", + "\n", + "Run this cell to see all variables exposed by the firmware." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "19215 variables available\n" + ] + }, + { + "data": { + "text/plain": [ + "['app.hardwareUiEnabled',\n", + " 'app.motorDirection',\n", + " 'app.motorVelocityCommand',\n", + " 'app.motorVelocityCommandMaximum',\n", + " 'app.motorVelocityCommandMinimum',\n", + " 'bPreCleared',\n", + " 'calibOffset',\n", + " 'compilationDate.date',\n", + " 'compilationDate.date[0]',\n", + " 'compilationDate.date[10]',\n", + " 'compilationDate.date[1]',\n", + " 'compilationDate.date[2]',\n", + " 'compilationDate.date[3]',\n", + " 'compilationDate.date[4]',\n", + " 'compilationDate.date[5]',\n", + " 'compilationDate.date[6]',\n", + " 'compilationDate.date[7]',\n", + " 'compilationDate.date[8]',\n", + " 'compilationDate.date[9]',\n", + " 'compilationDate.time']" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "variables = x2c_scope.list_variables()\n", + "print(f\"{len(variables)} variables available\")\n", + "variables[:20] # show first 20" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4 — Take control: disable hardware UI and stop the motor" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hardware UI disabled\n", + "Stop request sent\n" + ] + } + ], + "source": [ + "# Disable the hardware UI so this script has exclusive control\n", + "hardware_ui_enabled = x2c_scope.get_variable(\"app.hardwareUiEnabled\")\n", + "hardware_ui_enabled.set_value(0)\n", + "print(\"Hardware UI disabled\")\n", + "\n", + "# Stop the motor (in case it is already running)\n", + "stop_motor_request = x2c_scope.get_variable(\"motor.apiData.stopMotorRequest\")\n", + "stop_motor_request.set_value(1)\n", + "print(\"Stop request sent\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5 — Ramp to 700 RPM and measure time to reach speed" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Motor started, target: 700 RPM\n", + "Reached 700 RPM in 0.69 s\n" + ] + } + ], + "source": [ + "velocity_reference = x2c_scope.get_variable(\"motor.apiData.velocityReference\")\n", + "velocity_reference.set_value(TARGET_SPEED_1_RPM)\n", + "\n", + "run_motor_request = x2c_scope.get_variable(\"motor.apiData.runMotorRequest\")\n", + "run_motor_request.set_value(1)\n", + "print(f\"Motor started, target: {TARGET_SPEED_1_RPM / 10:.0f} RPM\")\n", + "\n", + "speed_measured = x2c_scope.get_variable(\"motor.apiData.velocityMeasured\")\n", + "start_time = time.time()\n", + "while speed_measured.get_value() < TARGET_SPEED_1_RPM:\n", + " time.sleep(0.05)\n", + "time_to_speed_1 = time.time() - start_time\n", + "\n", + "print(f\"Reached {TARGET_SPEED_1_RPM / 10:.0f} RPM in {time_to_speed_1:.2f} s\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6 — Capture phase currents at 700 RPM with the scope" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RMS current at 700 RPM: Ia=18.858 A Ib=17.568 A avg=18.213 A\n" + ] + } + ], + "source": [ + "time.sleep(2) # let the motor settle\n", + "\n", + "phase_current_a = x2c_scope.get_variable(\"motor.iabc.a\")\n", + "phase_current_b = x2c_scope.get_variable(\"motor.iabc.b\")\n", + "x2c_scope.add_scope_channel(phase_current_a)\n", + "x2c_scope.add_scope_channel(phase_current_b)\n", + "\n", + "x2c_scope.request_scope_data()\n", + "while not x2c_scope.is_scope_data_ready():\n", + " time.sleep(0.1)\n", + "\n", + "scope_data_1 = x2c_scope.get_scope_channel_data()\n", + "current_a_1 = np.array(scope_data_1[\"motor.iabc.a\"])\n", + "current_b_1 = np.array(scope_data_1[\"motor.iabc.b\"])\n", + "\n", + "rms_a_1 = np.sqrt(np.mean(current_a_1 ** 2)) * 0.1\n", + "rms_b_1 = np.sqrt(np.mean(current_b_1 ** 2)) * 0.1\n", + "avg_current_1 = (rms_a_1 + rms_b_1) / 2\n", + "\n", + "print(f\"RMS current at {TARGET_SPEED_1_RPM / 10:.0f} RPM: Ia={rms_a_1:.3f} A Ib={rms_b_1:.3f} A avg={avg_current_1:.3f} A\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot phase currents at 700 RPM" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAGGCAYAAABmGOKbAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuNSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/xnp5ZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOydB3gbVdaGP/de48QpTu+9kgQCgVQglNDLwsLSFpYOS1l2/4Wl97J0WHrvNaRDSEhIQnrvzY4Tx713W/9zZuZKV6MZaSSNytj3fZ7Esqwykq7u3HPPd74TYbPZbBAIBAKBQCAQCAQCgUBgOpHmP6RAIBAIBAKBQCAQCAQCQgTdAoFAIBAIBAKBQCAQBAgRdAsEAoFAIBAIBAKBQBAgRNAtEAgEAoFAIBAIBAJBgBBBt0AgEAgEAoFAIBAIBAFCBN0CgUAgEAgEAoFAIBAECBF0CwQCgUAgEAgEAoFAECBE0C0QCAQCgUAgEAgEAkGAEEG3QCAQCAQCgUAgEAgEAUIE3QKBQCAIK9577z1ERERg7dq1oT4UgUAgEAgEAr8RQbdAIBAIghpMs3/x8fEYMGAAbr75Zhw7dgxtgX379uH6669Hnz59pNeXmpqKSZMm4b///S/q6upgVebOnYv//Oc/IXnuxx57DN99951PY0z97+OPP3a6fX5+Pi666CKkp6dLn9Xs2bOxf/9+zcd+++23MXjwYOlz7d+/P1566SWfjik6OhrdunXDX/7yF+n51ZxyyilOt8/MzMRxxx2Hd955B62trfbb0f3p73TcWmNrz5499sd45plnDB2rQCAQCAJDdIAeVyAQCAQCTR566CH07t0b9fX1WL58OV577TUpqNu6dSsSExNhVX766SdceOGFiIuLwxVXXIFhw4ahsbFReo133303tm3bhjfffBNWhD6fV155JSSBNwXdF1xwAc455xyPt508eTI+/PBDl+uff/55bNq0CdOmTbNfV11djSlTpqCiogL//Oc/ERMTI93u5JNPxsaNG9GhQwf7bd944w3ccMMNOP/883HnnXfit99+w6233ora2lrce++9Xo/7VatWScE4jQ0a9xTI8+Tk5ODxxx+XLhcVFeGDDz7ANddcg927d+OJJ56w344CeDqGH3/8Udo84KENBnpcej6BQCAQhBibQCAQCARB4N1337XRaWfNmjVO1995553S9Z988onb24Uz+/fvtyUnJ9sGDRpkO3LkiMvf9+zZY3vhhRdMea7q6mrN61tbW221tbW2QHDTTTdJn0koSEpKsl155ZU+35/ek5SUFNuMGTOcrn/yySel1/THH3/Yr9uxY4ctKirKdt999zndv0OHDrYzzjjD6f6XXXaZdGylpaVun19vPN97773S9Z9//rnT9SeffLJt6NChTtfV1NTYcnJypOdrbGyUrqP3hH6fOXOm7ZxzznF53v79+9vOP/986Tmefvppt8coEAgEgsAi5OUCgUAgCClTp06Vfh44cMDp+oaGBimr2LFjRyQlJeHcc8+Vsn4833//Pc444wx07dpVyjD37dsXDz/8MFpaWlyktpSl7Ny5s5T9o0ziJZdcImU5eT766COMHTsWCQkJkqyXbpOXl+fxNTz11FNS5pQkyF26dHH5e79+/XDbbbdJlw8ePChJfinTqYau57PJdJmu2759O/70pz8hIyMDJ554ovS3Xr164cwzz8SCBQswbtw46ZgpI0uUl5fj9ttvR/fu3aX3hZ7/ySefdJIns+Mg6TFl4Om9o9uSlHnNmjVOMmbKcrPjY/8Yn332mfSepaSkSFLn4cOHS3J6T9DznnDCCVJGmY6dHuOrr75yeT9qamrw/vvv25+XjscbKAtcVVWFyy67zOl6ei56rfSPMWjQICkb/sUXX9ivW7JkCUpKSnDjjTc63f+mm26Sjo0UDr5w0kkn2UsSPEEKkIkTJ0rPp/4O0LiYN2+e9Jkz6POjMU9/EwgEAkHoEfJygUAgEIQUFnTwcl7illtukYLMBx54QAoQX3jhBan++/PPP7ffhgLX5ORkKTinn7/88gvuv/9+VFZW4umnn5ZuQxLvU089VQri6TEp8KZa2jlz5kiBSlpamnS7Rx99FP/+978lme61114rBTdUt0uS5Q0bNkh1v+4CO6rjpiAyEJBsneqISWpts1HyUmbXrl249NJLpTry6667DgMHDpTkxiSRptdI1/fo0QO///477rvvPhw9elR6H3k++eQTKSil21JQSxsI5513nlTbTJJruv7IkSNYtGiRi3SbrqPnp0CVgnpix44dWLFihX2TQQ8KzM8++2wpGKbPiIJ3ep30udBGCkHPR5/F+PHj8de//lW6jjYHvIFk1hTU02ti0ObD5s2bcfXVV7vcnp5r4cKF0ntCGwn02RO0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2GAYxl9IVXfuuedKpnu02cu4w/Jyi5Cfny/tRmtdh+n7goKCqJ0XEzmuu+46fPXVV5g/fz66d+/ueJw+fyo/qKio8Dg26Kve2BHPMdaE5OOlpaU45phjpJ1jui1cuBDPPfecdJ92inlstF/IaXjw4MEujw0aNEhyq1d/vt7mFfpKY0wNOduTGy2PD+tCHQoo2/373/9eKi+56KKLcOONN0rdMggeG4wgVGOB55rYD7j37NkjJQFElpvgseGEg26LQHLA0aNHSzVY6iwGfT9u3LionhsTXmjXkALuTz/9FD/88IObBIfGRWJiosvYoDoYWliLsUFf161b53LhExdG7aKcsQ5TpkyRPlfKUokbZTZJIiru89hov1AZira9INXwFhUVSffpWkILGvX4IMkx1dmpxwdt2tAGj4CuQzT/UE0nY03q6uqkmko1tLFPnyvBY4MRhGos0DHUfooCNPVcM2DAgJiRD7fngJtayH333XdSe0o1PDZUqEzVGAu0DCO3yDfffFNyA7ziiiuklmFq12Em9rj66qulVh0LFiywHzx40HGrq6tzaQtFbcR++OEHqS3UuHHjpJu2LdT06dOltmNz5syxd+zYkdtCxSBq93KCx0b7hVxkExISpPZQ27Zts7/77rv2tLQ0+zvvvOPSCojmkc8//9y+du1a+29+8xvdVkCjRo2S2o4tWrRIcsrntlDW5o9//KO9W7dujpZh1A6IWgXeeuutjmN4bLSvDhjUMpJuFBo8/fTT0n3hQB2KsUCO59QW6qKLLpLaQtGalq5HsdYWqj2NjaamJql9XPfu3aX1g3qNqnYi57Ehw0G3xXj++eelBTT166YWYtTzjolt6CKnd6Pe3QKa+K655hqp5QJdqH77299KFz01u3fvtp9yyilS70NaXN1888325ubmKPyPmEgG3Tw22jdffvmltKlCG7YDBw60v/rqqy7PUzuge+65R1rw0DFTpkyxb9myxeWYsrIyaYFEfZypldyll14qLcQY61JVVSVdJ2g9kZKSYu/du7fUi1e9UOax0X6YP3++7jqDNmdCORaoxze1MaTXoE0fCuYZ644N2rDztEalnxPw2JCJo3/UmW+GYRiGYRiGYRiGYUID13QzDMMwDMMwDMMwTJjgoJthGIZhGIZhGIZhwgQH3QzDMAzDMAzDMAwTJjjoZhiGYRiGYRiGYZgwwUE3wzAMwzAMwzAMw4QJDroZhmEYhmEYhmEYJkxw0M0wDMMwDMMwDMMwYYKDboZhGIZhGIZhGIYJExx0MwzDMAwTVuLi4vDZZ59F+zQYhmEYJipw0M0wDMMwMcDhw4dx9dVXo0ePHkhOTkZBQQFmzJiBn3/+OdqnxjAMwzDtmoRonwDDMAzDMMFz1llnoampCW+99RZ69+6NkpISfP/99ygrK4v2qTEMwzBMu4Yz3QzDMAxjcSoqKvDTTz/hsccew+TJk1FUVITjjjsOd9xxB8444wzpmKeffhrDhg1Deno6CgsLcc0116CmpsbxGm+++SZycnLw1VdfYcCAAUhLS8PZZ5+Nuro6KZDv2bMncnNzcf3116O1tdXxc/T4gw8+iPPPP1967W7duuGFF17wer7FxcU499xzpd+Xl5eH3/zmN9i9e3cY3yGGYRiGiR4cdDMMwzCMxcnIyJBuVDfd2Nioe4zNZsNzzz2HDRs2SEH0Dz/8gFtvvdXlGAqw6Zj33nsPc+bMwYIFC/Db3/4Ws2fPlm5vv/02XnnlFXz00UcuP/fEE09gxIgRWLVqFW6//XbccMMNmDdvnu55NDc3S7L3zMxMaaOA5O907jNnzpQy9QzDMAwTa8TZ7XZ7tE+CYRiGYZjg+Pjjj3H55Zejvr4exxxzDCZOnIjf//73GD58uO7xFDhfddVVOHLkiCPTfemll2L79u3o06eP9Bg9T4E2SdUpMCYoOKbs9ssvvyx9T/cHDRqEb775xvHa9HurqqqkQF0YqX366ac488wz8c477+Dvf/87Nm3aJD1OULBNWW/aNJg+fXqY3ymGYRiGiSyc6WYYhmGYGKnpPnDgAL744gspMKYsNQXfFEwT3333HaZMmSLJvynLfNFFF0n13pTdFpCkXATcROfOnaWgWgTc4rHS0lKX3z1u3Di37ymo1mPNmjVSYE/nIDL0JDFvaGjAjh07QvZ+MAzDMIxZYCM1hmEYhokRUlJSMG3aNOl2zz334M9//jPuu+8+TJo0Caeddprkbv7QQw9JQe6iRYtw2WWXSVlmCraJxMREl9ejTLTeY21tbQGfI9WRjx49Gu+++67bcx07dgz4dRmGYRjGrHDQzTAMwzAxyuDBgyXJ9ooVK6RA+amnnpJqu4kPPvggZL/n119/dfueJOd6UPb9/fffR6dOnZCVlRWyc2AYhmEYs8LycoZhGIaxOCQTP/nkk6V66bVr12LXrl348MMP8fjjj0vO4H379pUMzJ5//nns3LlTqtMWNdmhgMzQ6Hdt3bpVci6n301manpceOGFyM/Pl86LjNToXEkKT67o+/btC9k5MQzDMIxZ4Ew3wzAMw1gcqoseO3YsnnnmGakumgJsagtGxmp33nknUlNTpZZh1FKM2ohNmDABjzzyCC6++OKQ/P6bb74Zy5cvx/333y9lr+l3kUO5HiRl//HHH3Hbbbfhd7/7Haqrq6U6c6o358w3wzAME4uweznDMAzDMAFDRmv/93//J90YhmEYhnGH5eUMwzAMwzAMwzAMEyY46GYYhmEYhmEYhmGYMMHycoZhGIZhGIZhGIYJE5zpZhiGYRiGYRiGYZgwwUE3wzAMwzAMwzAMw4QJDroZhmEYhmEYhmEYJkxw0M0wDMMwDMMwDMMwYYKDboZhGIZhGIZhGIYJExx0MwzDMAzDMAzDMEyY4KCbYRiGYRiGYRiGYcIEB90MwzAMwzAMwzAMEyY46GYYhmEYhmEYhmEYhIf/B98PZ1bQrgYDAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(10, 4))\n", + "ax.plot(current_a_1 * 0.1, label=\"Phase A\")\n", + "ax.plot(current_b_1 * 0.1, label=\"Phase B\")\n", + "ax.set_title(f\"Phase Currents at {TARGET_SPEED_1_RPM / 10:.0f} RPM\")\n", + "ax.set_xlabel(\"Sample\")\n", + "ax.set_ylabel(\"Current (A)\")\n", + "ax.legend()\n", + "ax.grid(True)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7 — Capture speed ramp: 700 → 1400 RPM\n", + "\n", + "Add `motor.apiData.velocityMeasured` as a scope channel, arm the scope, **then** command the speed\n", + "change so the ramp is captured in the buffer. The scope window is set to cover ~100 ms\n", + "(sample time factor 0, firmware sample period ≈ 50 µs)." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Scope window: 122.5 ms\n", + "Target speed changed to 1400 RPM — waiting for scope capture…\n", + "Captured 2450 samples over 122.5 ms\n" + ] + } + ], + "source": [ + "SCOPE_SAMPLE_TIME_US = 50 # firmware interrupt period in µs — adjust if needed\n", + "\n", + "# Add speed as a scope channel (replaces current channels for this capture)\n", + "x2c_scope.clear_all_scope_channel()\n", + "x2c_scope.add_scope_channel(speed_measured)\n", + "\n", + "# Set sample time factor (0 = every firmware tick, gives the finest resolution)\n", + "x2c_scope.set_sample_time(0)\n", + "\n", + "# Compute the total scope window so we can build the time axis later\n", + "scope_window_ms = x2c_scope.get_scope_sample_time(SCOPE_SAMPLE_TIME_US)\n", + "print(f\"Scope window: {scope_window_ms:.1f} ms\")\n", + "\n", + "# Arm the scope FIRST, then trigger the speed change\n", + "x2c_scope.request_scope_data()\n", + "velocity_reference.set_value(TARGET_SPEED_2_RPM)\n", + "print(f\"Target speed changed to {TARGET_SPEED_2_RPM / 10:.0f} RPM — waiting for scope capture…\")\n", + "\n", + "while not x2c_scope.is_scope_data_ready():\n", + " time.sleep(0.05)\n", + "\n", + "ramp_data = x2c_scope.get_scope_channel_data()\n", + "ramp_speed_raw = np.array(ramp_data[\"motor.apiData.velocityMeasured\"])\n", + "ramp_speed_rpm = ramp_speed_raw / 10 # convert to RPM\n", + "n_samples = len(ramp_speed_rpm)\n", + "ramp_time_ms = np.linspace(0, scope_window_ms, n_samples)\n", + "\n", + "print(f\"Captured {n_samples} samples over {scope_window_ms:.1f} ms\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot speed ramp (700 → 1400 RPM)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAGGCAYAAABmGOKbAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuNSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/xnp5ZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB6B0lEQVR4nO3dB3hU1daA4ZXeC733LtIERRSx0PGqIBYUFQXBAngVf/ViQbGh6LWAvesVECs2RBBQelWkiog0KaGT3ud/1g5nmBoSSDKTyff6jJM552Rmn5kNzDpr7b2DbDabTQAAAAAAQIkLLvmnBAAAAAAAiqAbAAAAAIBSQtANAAAAAEApIegGAAAAAKCUEHQDAAAAAFBKCLoBAAAAACglBN0AAAAAAJQSgm4AAAAAAEoJQTcAAAAAAKWEoBsAUCEFBQXJY4895utmAACAAEfQDQA4ZevWrZOrrrpKGjRoIJGRkVKnTh3p2bOnTJ48WQLB9u3bTXBu3YKDg6Vy5crSt29fWbp0qQSSn3/+2elcXW9PPfWU0/FHjx6VESNGSLVq1SQmJkYuvvhi+fXXXz0+9zfffCNnnXWW6SP169eXRx99VHJzc6Wsvf7663L11VebNug53XzzzUX6veHDh5vj//Wvf53W+RXnPXN10UUXOX0eUVFR0rZtW3nppZckPz+/0H4bEhJi2jVgwABZs2aN07HWMbfeeqvH133ooYfsxxw8eLBIbQUAOAt1eQwAQJEsWbLEBA36ZV6Dkpo1a8quXbtk2bJl8vLLL8vo0aMlUFx33XXSr18/ycvLkz///FNee+01c+4rV66UNm3aSCBo1aqV/O9//3Pbrttmz54tvXr1sm/TIO/SSy+V33//Xe677z6pWrWqeU80MFy9erU0a9bMfuwPP/wg/fv3N/v0YoxeqHnyySdl//79JgguS88++6ykpKTIOeecI3v37i3S76xatUo++OADE1B7UtTzK8575k3dunVlwoQJ5mcNgKdOnSr33HOPHDhwwO2iiGu/3bRpk2mPtlf/jLZv395+nJ7bF198YdoTHh7u9BzTpk0z+zMzM4v0fgEAPLABAHAK+vXrZ6tWrZrtyJEjbvuSkpJs/k7/CXz00UcLPWbbtm3muOeee85p+w8//GC233HHHbZA17RpU1uzZs2ctk2fPt2c/2effWbftn//fltiYqLtuuuuczr2jDPOsLVr186Wk5Nj3/bQQw/ZgoKCbJs2bbKVpe3bt9vy8/PNzzExMbYhQ4YUerwe26VLF9vQoUNtDRo0sF166aVuxxT1/Irznnly4YUX2lq3bu20LSMjw7QrLi7Olpube9J++80335jtI0aMsG/Tx/3797cFBwfbZsyY4XT84sWLzf6BAwea+wMHDpy0nQAAd5SXAwBOydatW6V169aSmJjotq969epOj7U0ddSoUTJlyhRp0aKFyZx17NhRFixY4Pa7u3fvlqFDh0qNGjUkIiLCvMZ7773ndlxWVpYp423atKk5rl69enL//feb7a7HaTZQS3rj4uLk8ssvl3/++ee0zv2CCy6wvweO3n//fbnkkkvM+WubzjjjDI/Z3IYNG5pSZS3p7tSpkykV1oy5PlZffvmleWy9T7/99pvT72tZdGxsrPz999/Su3dvU6pcu3Ztefzxx/ViutOxmtH9448/JCcnp9jnuWLFCvnrr79k8ODBTts///xz8/lceeWV9m36/l5zzTXy9ddf2z+DjRs3mpuWVIeGniiuu/POO0079XnKkg6D0L5YVJrlX79+vccscnHPr6jvWXFo/zj77LNN9l4z6yejfVNt27bNabsOC+nWrZvJnDvSP6/aD88888xitw0AcAJBNwDglAMYLYvVoKQofvnlF7n77rvlhhtuMMHhoUOHpE+fPk6/n5SUJOeee6789NNPJkjXMnUNqocNG2bGrjqW6mrw/Pzzz8tll11mynq1xPfFF1+Ua6+91ul1dayq/q6WRz/zzDMSFhZmynxPh46ZVZUqVXLargG2vi8PPvig/Pe//zUXAjQAe/XVV92eQ4PZ66+/3rRfS4aPHDliftZARy8S6Ps0fvx4E9hrYOY6bldLhvX900Bu4sSJJjjXixB6czR27FhTOq4XM4pL26Jcg269CKBjmHWMuyMt205PTzcl+NZxSi8sONILBFoq7Xoxobjefvttefjhh6U0aCD7wAMPmM9Sh054UpzzK+p7VlzW+G1PF79cWReJqlSp4rZP++K3334rqamp5rGOSf/ss8/MdgDAafKQ/QYA4KRmz55tCwkJMTctwb3//vttP/74oy07O9vtWP3nRm+rVq2yb9uxY4ctMjLSNmDAAPu2YcOG2WrVqmU7ePCg0+8PGjTIlpCQYEtPTzeP//e//5ly2IULFzod98Yb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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(10, 4))\n", + "ax.plot(ramp_time_ms, ramp_speed_rpm, color=\"tab:blue\")\n", + "ax.axhline(TARGET_SPEED_1_RPM / 10, color=\"gray\", linestyle=\"--\", linewidth=0.8, label=f\"Start: {TARGET_SPEED_1_RPM / 10:.0f} RPM\")\n", + "ax.axhline(TARGET_SPEED_2_RPM / 10, color=\"green\", linestyle=\"--\", linewidth=0.8, label=f\"Target: {TARGET_SPEED_2_RPM / 10:.0f} RPM\")\n", + "ax.set_title(f\"Speed Ramp: {TARGET_SPEED_1_RPM / 10:.0f} → {TARGET_SPEED_2_RPM / 10:.0f} RPM\")\n", + "ax.set_xlabel(\"Time (ms)\")\n", + "ax.set_ylabel(\"Speed (RPM)\")\n", + "ax.legend()\n", + "ax.grid(True)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8 — Capture phase currents at 1400 RPM" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RMS current at 1400 RPM: Ia=25.176 A Ib=22.583 A avg=23.880 A\n" + ] + } + ], + "source": [ + "time.sleep(2) # let the motor settle at the new speed\n", + "\n", + "# Switch scope channels back to phase currents\n", + "x2c_scope.clear_all_scope_channel()\n", + "x2c_scope.add_scope_channel(phase_current_a)\n", + "x2c_scope.add_scope_channel(phase_current_b)\n", + "\n", + "x2c_scope.request_scope_data()\n", + "while not x2c_scope.is_scope_data_ready():\n", + " time.sleep(0.1)\n", + "\n", + "scope_data_2 = x2c_scope.get_scope_channel_data()\n", + "current_a_2 = np.array(scope_data_2[\"motor.iabc.a\"])\n", + "current_b_2 = np.array(scope_data_2[\"motor.iabc.b\"])\n", + "\n", + "rms_a_2 = np.sqrt(np.mean(current_a_2 ** 2)) * 0.1\n", + "rms_b_2 = np.sqrt(np.mean(current_b_2 ** 2)) * 0.1\n", + "avg_current_2 = (rms_a_2 + rms_b_2) / 2\n", + "\n", + "print(f\"RMS current at {TARGET_SPEED_2_RPM / 10:.0f} RPM: Ia={rms_a_2:.3f} A Ib={rms_b_2:.3f} A avg={avg_current_2:.3f} A\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot phase currents at 1400 RPM" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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HDhQdP/mVuaxY8eK8d7cui3jLuVyws3i4+NFUi0n3PJj58+fd/rsrKysGvc5qXZn7969IrHnbZBb6LmLeVlZGf3++++q7Q8AAABvgYnUAAAAmomAgAC66667xGXOnDn02GOP0bx58+iOO+6ge+65R8xuvnDhQpHkbt26lSZOnChamTnZZmaz2en9uCXa3WNVVVWN3kYeR96tWzdaunRpjediY2Mb/b4AAADeCkk3AABAM9WuXTvRZXvXrl0iUX799dfF2G72+eefq/Y5P/30U4373OXcHW59X758OcXFxVFYWJhq2wAAAOCt0L0cAABA57ib+J133inGS+/bt49yc3Ppiy++oFdffVXMDN66dWsxgdnbb79Nx48fF+O05THZauDJ0Pizjhw5ImYu58/mydTcGTNmDMXExIjt4onUeFu5KzzPin769GnVtgkAAMBboKUbAABA53hcdM+ePenNN98U46I5weZlwXhitRdeeIECAwPFkmG8pBgvI9avXz9atGgRjRs3TpXPnz59Ou3cuZPmz58vWq/5s3iGcne4K/vmzZtpxowZ9MADD1BxcbEYZ87jzdHyDQAAzRFmLwcAAIBG44nWnn76aXEBAACAmtC9HAAAAAAAAEAjSLoBAAAAAAAANILu5QAAAAAAAAAaQUs3AAAAAAAAgEaQdAMAAAAAAABoBEk3AAAAAAAAgEaQdAMAAAAAAABoBEk3AAAAAAAAgEaQdAMAAAAAAABoBEk3AAAAAAAAgEaQdAMAAAAAAABoBEk3AAAAAAAAAGnj/wHlPwymU7yUrAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(10, 4))\n", + "ax.plot(current_a_2 * 0.1, label=\"Phase A\")\n", + "ax.plot(current_b_2 * 0.1, label=\"Phase B\")\n", + "ax.set_title(f\"Phase Currents at {TARGET_SPEED_2_RPM / 10:.0f} RPM\")\n", + "ax.set_xlabel(\"Sample\")\n", + "ax.set_ylabel(\"Current (A)\")\n", + "ax.legend()\n", + "ax.grid(True)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 9 — Summary" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "==================================================\n", + "HiL Test Summary\n", + "==================================================\n", + "Time to reach 700 RPM : 0.69 s\n", + "Avg RMS current @ 700 RPM : 18.213 A\n", + "Speed ramp scope window : 122.5 ms\n", + "Avg RMS current @ 1400 RPM : 23.880 A\n" + ] + } + ], + "source": [ + "print(\"=\" * 50)\n", + "print(\"HiL Test Summary\")\n", + "print(\"=\" * 50)\n", + "print(f\"Time to reach {TARGET_SPEED_1_RPM / 10:.0f} RPM : {time_to_speed_1:.2f} s\")\n", + "print(f\"Avg RMS current @ {TARGET_SPEED_1_RPM / 10:.0f} RPM : {avg_current_1:.3f} A\")\n", + "print(f\"Speed ramp scope window : {scope_window_ms:.1f} ms\")\n", + "print(f\"Avg RMS current @ {TARGET_SPEED_2_RPM / 10:.0f} RPM : {avg_current_2:.3f} A\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 10 — Stop the motor and restore hardware UI\n", + "\n", + "> **Always run this cell** before closing the notebook to return control to the hardware UI." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Motor stopped\n", + "Hardware UI re-enabled\n", + "Disconnected\n" + ] + } + ], + "source": [ + "stop_motor_request.set_value(1)\n", + "print(\"Motor stopped\")\n", + "\n", + "hardware_ui_enabled.set_value(1)\n", + "print(\"Hardware UI re-enabled\")\n", + "\n", + "x2c_scope.disconnect()\n", + "print(\"Disconnected\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From c864020265da7f48c7503a0398ca9a2d38fe0aeb Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Wed, 15 Apr 2026 11:21:11 +0200 Subject: [PATCH 09/19] fixed sample_time UIX: start at 1 --- doc/example.md | 2 +- doc/scripting.rst | 87 ++++++++++++++++++- pyx2cscope/gui/qt/models/app_state.py | 4 +- pyx2cscope/gui/qt/tabs/scope_view_tab.py | 16 ++-- pyx2cscope/gui/web/scope.py | 3 +- .../gui/web/static/js/dashboard_view.js | 8 +- pyx2cscope/gui/web/static/js/scope_view.js | 6 +- .../web/static/widgets/plot_scope/widget.js | 8 +- .../static/widgets/scope_control/widget.js | 10 +-- .../gui/web/templates/sample_control.html | 2 +- pyx2cscope/gui/web/ws_handlers.py | 2 +- pyx2cscope/x2cscope.py | 7 +- tests/test_pyx2cscope_class.py | 16 ++++ tests/test_web_gui.py | 12 ++- 14 files changed, 145 insertions(+), 38 deletions(-) diff --git a/doc/example.md b/doc/example.md index 9ae83c11..61a16cef 100644 --- a/doc/example.md +++ b/doc/example.md @@ -217,7 +217,7 @@ variables = [ for var in variables: x2c_scope.add_scope_channel(x2c_scope.get_variable(var)) -x2c_scope.set_sample_time(0) +x2c_scope.set_sample_time(1) # Create the plot plt.ion() # Turn on interactive mode diff --git a/doc/scripting.rst b/doc/scripting.rst index 492c9bc1..700395fd 100644 --- a/doc/scripting.rst +++ b/doc/scripting.rst @@ -484,6 +484,26 @@ TriggerConfig needs some parameters like the variable and some trigger values li * Trigger_delay: Value > 0 Pre-trigger, Value < 0 Post trigger * Trigger_Edge: Rising (1) or Falling (0) +Data resolution +^^^^^^^^^^^^^^^ + +The scope sampling resolution can be adjusted with ``set_sample_time()``. + +.. code-block:: python + + x2c_scope.set_sample_time(sample_time) + +``sample_time`` starts at ``1`` in the pyX2Cscope API and interfaces: + +* ``1``: take every sample +* ``2``: take every second sample +* ``3``: take every third sample + +Higher values increase the total captured time window, but reduce the time resolution of the acquired data. +In other words, the scope skips more firmware samples before storing the next point in the scope buffer. + +Internally, LNET uses a 0-based value, but pyX2Cscope exposes this parameter as 1-based in the API and interfaces. + Additional information on how to change triggers, clear and change sample time, may be found on the API documentation. @@ -492,7 +512,7 @@ Utility Functions The ``pyx2cscope.utils`` module provides helper functions for managing configuration settings used in examples and scripts. These utilities simplify the process of specifying ELF file paths -and COM ports without hardcoding them into your scripts. +and communication parameters without hardcoding them into your scripts. Configuration File (config.ini) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -512,7 +532,16 @@ default placeholder values that you should update with your actual settings: [HOST_IP] host_ip = your_host_ip -After the file is created, edit it to specify your actual ELF file path and COM port. + [CAN] + bustype = pcan_usb + channel = 1 + baud_rate = 500000 + id_tx = 0x110 + id_rx = 0x100 + mode = standard + +After the file is created, edit it to specify your actual ELF path and the connection settings +needed for Serial, TCP/IP, or CAN. Available Functions ^^^^^^^^^^^^^^^^^^^ @@ -553,13 +582,33 @@ Retrieves the host IP address for TCP/IP connections: if host: x2cscope = X2CScope(host=host, tcp_port=12666, elf_file="firmware.elf") +**get_can_config()** + +Retrieves the CAN interface configuration from the ``[CAN]`` section in ``config.ini``: + +.. code-block:: python + + from pyx2cscope.utils import get_can_config + + can_config = get_can_config() + x2cscope = X2CScope(elf_file="firmware.elf", **can_config) + +The returned dictionary contains these parameters: + +* ``bustype`` +* ``channel`` +* ``baud_rate`` +* ``id_tx`` +* ``id_rx`` +* ``mode`` + Example Usage ^^^^^^^^^^^^^ The utility functions are particularly useful in example scripts where you want to avoid -hardcoding paths: +hardcoding paths and interface settings: .. code-block:: python @@ -577,6 +626,38 @@ hardcoding paths: # Initialize X2CScope with configured values x2cscope = X2CScope(port=port, elf_file=elf_path) +For CAN, the same approach can be used with the CAN configuration block: + +.. code-block:: python + + from pyx2cscope import X2CScope + from pyx2cscope.utils import get_can_config, get_elf_file_path + + elf_path = get_elf_file_path() + can_config = get_can_config() + + if not elf_path: + print("Please configure config.ini with your ELF file path") + exit(1) + + x2cscope = X2CScope(elf_file=elf_path, **can_config) + +For TCP/IP, the host address can also be loaded from the configuration file: + +.. code-block:: python + + from pyx2cscope import X2CScope + from pyx2cscope.utils import get_elf_file_path, get_host_address + + elf_path = get_elf_file_path() + host = get_host_address() + + if not elf_path or not host: + print("Please configure config.ini with your ELF file path and host IP") + exit(1) + + x2cscope = X2CScope(elf_file=elf_path, host=host) + .. note:: The utility functions return an empty string if the configuration contains placeholder diff --git a/pyx2cscope/gui/qt/models/app_state.py b/pyx2cscope/gui/qt/models/app_state.py index d185ff61..0bd6ebfe 100644 --- a/pyx2cscope/gui/qt/models/app_state.py +++ b/pyx2cscope/gui/qt/models/app_state.py @@ -134,7 +134,7 @@ def __init__(self, parent=None): # Scope state self._scope_active: bool = False self._scope_single_shot: bool = False - self._sample_time_factor: int = 0 + self._sample_time_factor: int = 1 self._scope_sample_time_us: int = 50 self._real_sample_time: float = 0.0 @@ -642,7 +642,7 @@ def sample_time_factor(self) -> int: @sample_time_factor.setter def sample_time_factor(self, value: int): self._mutex.lock() - self._sample_time_factor = value + self._sample_time_factor = 1 if value < 1 else value self._mutex.unlock() @property diff --git a/pyx2cscope/gui/qt/tabs/scope_view_tab.py b/pyx2cscope/gui/qt/tabs/scope_view_tab.py index d653eb11..9b5b75cd 100644 --- a/pyx2cscope/gui/qt/tabs/scope_view_tab.py +++ b/pyx2cscope/gui/qt/tabs/scope_view_tab.py @@ -6,8 +6,8 @@ import numpy as np import pyqtgraph as pg from PyQt5 import QtCore -from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot -from PyQt5.QtGui import QColor, QIcon, QPixmap +from PyQt5.QtCore import QRegExp, Qt, pyqtSignal, pyqtSlot +from PyQt5.QtGui import QColor, QIcon, QPixmap, QRegExpValidator from PyQt5.QtWidgets import ( QCheckBox, QComboBox, @@ -125,10 +125,8 @@ def _create_trigger_group(self) -> QGroupBox: # Sample time factor grid.addWidget(QLabel("Sample Time Factor"), 1, 0) - self._sample_time_factor_edit = QSpinBox() - self._sample_time_factor_edit.setMinimum(0) - self._sample_time_factor_edit.setMaximum(30) - self._sample_time_factor_edit.setValue(0) + self._sample_time_factor_edit = QLineEdit("1") + self._sample_time_factor_edit.setValidator(QRegExpValidator(QRegExp("[1-9][0-9]*"))) grid.addWidget(self._sample_time_factor_edit, 1, 1) # Scope sample time @@ -341,7 +339,7 @@ def _start_sampling(self): logging.debug(f"Added scope channel: {var_name}") # Set sample time - sample_time_factor = self._sample_time_factor_edit.value() + sample_time_factor = int(self._sample_time_factor_edit.text() or "1") x2cscope.set_sample_time(sample_time_factor) # Get real sample time @@ -502,7 +500,7 @@ def get_config(self) -> dict: "trigger_delay": self._trigger_delay_combo.currentText(), "trigger_edge": self._trigger_edge_combo.currentText(), "trigger_mode": self._trigger_mode_combo.currentText(), - "sample_time_factor": str(self._sample_time_factor_edit.value()), + "sample_time_factor": self._sample_time_factor_edit.text() or "1", "single_shot": self._single_shot_checkbox.isChecked(), } @@ -541,5 +539,5 @@ def load_config(self, config: dict): self._trigger_delay_combo.setCurrentText(config.get("trigger_delay", "0")) self._trigger_edge_combo.setCurrentText(config.get("trigger_edge", "Rising")) self._trigger_mode_combo.setCurrentText(config.get("trigger_mode", "Disable")) - self._sample_time_factor_edit.setValue(int(config.get("sample_time_factor", "0"))) + self._sample_time_factor_edit.setText(config.get("sample_time_factor", "1") or "1") self._single_shot_checkbox.setChecked(config.get("single_shot", False)) diff --git a/pyx2cscope/gui/web/scope.py b/pyx2cscope/gui/web/scope.py index f105ffec..df79b7aa 100644 --- a/pyx2cscope/gui/web/scope.py +++ b/pyx2cscope/gui/web/scope.py @@ -22,7 +22,7 @@ def __init__(self): self.scope_vars = [] self.scope_trigger = False self.scope_burst = False - self.scope_sample_time = 0 + self.scope_sample_time = 1 self.scope_time_sampling = 50e-3 self.dashboard_vars = {} # {var_name: Variable object} @@ -346,6 +346,7 @@ def scope_set_sample(self, trigger_action, sample_time, sample_freq): """ if self.x2c_scope is None: return + sample_time = 1 if sample_time < 1 else sample_time with self._lock: if self.scope_sample_time != sample_time: self.scope_sample_time = sample_time diff --git a/pyx2cscope/gui/web/static/js/dashboard_view.js b/pyx2cscope/gui/web/static/js/dashboard_view.js index ab46cc90..60e21f23 100644 --- a/pyx2cscope/gui/web/static/js/dashboard_view.js +++ b/pyx2cscope/gui/web/static/js/dashboard_view.js @@ -171,8 +171,8 @@ function updateScopeControlSampleState(data) { // Update sample time/freq if elements exist const sampleTimeEl = document.getElementById('scopeCtrlSampleTime'); const sampleFreqEl = document.getElementById('scopeCtrlSampleFreq'); - if (sampleTimeEl && data.sampleTime) sampleTimeEl.value = data.sampleTime; - if (sampleFreqEl && data.sampleFreq) sampleFreqEl.value = data.sampleFreq; + if (sampleTimeEl && data.sampleTime !== undefined) sampleTimeEl.value = data.sampleTime; + if (sampleFreqEl && data.sampleFreq !== undefined) sampleFreqEl.value = data.sampleFreq; // Update button states const widgetEl = document.getElementById(`dashboard-widget-${widget.id}`); @@ -245,7 +245,7 @@ function syncScopeControlToBackend() { const scopeControlWidget = dashboardWidgets.find(w => w.type === 'scope_control'); if (scopeControlWidget) { // Sync sample control settings - const sampleTime = scopeControlWidget.sampleTime !== undefined ? scopeControlWidget.sampleTime : 0; + const sampleTime = scopeControlWidget.sampleTime !== undefined ? scopeControlWidget.sampleTime : 1; const sampleFreq = scopeControlWidget.sampleFreq || 20; const sampleFormData = `triggerAction=off&sampleTime=${sampleTime}&sampleFreq=${sampleFreq}`; scopeSocket.emit('update_sample_control', sampleFormData); @@ -1068,4 +1068,4 @@ function handleDashboardFileImport(e) { }; reader.readAsText(file); } -} \ No newline at end of file +} diff --git a/pyx2cscope/gui/web/static/js/scope_view.js b/pyx2cscope/gui/web/static/js/scope_view.js index 06e452bd..607b1433 100644 --- a/pyx2cscope/gui/web/static/js/scope_view.js +++ b/pyx2cscope/gui/web/static/js/scope_view.js @@ -47,12 +47,12 @@ socket_sv.on("sample_control_updated", function(response) { }); } // Handle sampleTime input - if (response.data.sampleTime) { + if (response.data.sampleTime !== undefined) { const sampleTimeInput = document.getElementById('sampleTime'); sampleTimeInput.value = response.data.sampleTime; } // Handle sampleFreq input - if (response.data.sampleFreq) { + if (response.data.sampleFreq !== undefined) { const sampleFreqInput = document.getElementById('sampleFreq'); sampleFreqInput.value = response.data.sampleFreq; } @@ -493,4 +493,4 @@ $(document).ready(function () { } ] }); -}); \ No newline at end of file +}); diff --git a/pyx2cscope/gui/web/static/widgets/plot_scope/widget.js b/pyx2cscope/gui/web/static/widgets/plot_scope/widget.js index 930cfdfa..885da1fc 100644 --- a/pyx2cscope/gui/web/static/widgets/plot_scope/widget.js +++ b/pyx2cscope/gui/web/static/widgets/plot_scope/widget.js @@ -215,13 +215,13 @@ function refreshPlotScopeWidget(widget, widgetEl) { function generateTimeLabels(numSamples) { // Get sample time and frequency from scope control widget const scopeControlWidget = dashboardWidgets.find(w => w.type === 'scope_control'); - const sampleTime = scopeControlWidget?.sampleTime !== undefined ? scopeControlWidget.sampleTime : 0; + const sampleTime = scopeControlWidget?.sampleTime !== undefined ? scopeControlWidget.sampleTime : 1; const sampleFreq = scopeControlWidget?.sampleFreq || 20; // in KHz - // Calculate time per sample: (1 / freq_Hz) * (sampleTime + 1) - // sampleTime is a skip factor: 0 = every sample, 1 = every 2nd sample, etc. + // Calculate time per sample: (1 / freq_Hz) * sampleTime + // sampleTime is user-facing: 1 = every sample, 2 = every 2nd sample, etc. // freq is in KHz, so freq_Hz = sampleFreq * 1000 - const timePerSampleUs = (1 / (sampleFreq * 1000)) * (sampleTime + 1) * 1000000; // in microseconds + const timePerSampleUs = (1 / (sampleFreq * 1000)) * sampleTime * 1000000; // in microseconds const totalTimeUs = (numSamples - 1) * timePerSampleUs; // Determine best unit based on total time diff --git a/pyx2cscope/gui/web/static/widgets/scope_control/widget.js b/pyx2cscope/gui/web/static/widgets/scope_control/widget.js index 6fc87ecb..eeee6e96 100644 --- a/pyx2cscope/gui/web/static/widgets/scope_control/widget.js +++ b/pyx2cscope/gui/web/static/widgets/scope_control/widget.js @@ -17,7 +17,7 @@ function handleScopeControlAction(action) { scopeControlState = action; // Get current settings from the widget - const sampleTime = document.getElementById('scopeCtrlSampleTime')?.value || 0; + const sampleTime = document.getElementById('scopeCtrlSampleTime')?.value || 1; const sampleFreq = document.getElementById('scopeCtrlSampleFreq')?.value || 20; // Send to scope-view namespace @@ -80,7 +80,7 @@ function updateScopeControlTrigger(widgetId) { function updateScopeSampleSettings(widgetId) { if (isDashboardEditMode) return; - const sampleTime = document.getElementById('scopeCtrlSampleTime')?.value || 0; + const sampleTime = document.getElementById('scopeCtrlSampleTime')?.value || 1; const sampleFreq = document.getElementById('scopeCtrlSampleFreq')?.value || 20; // Store values in all scope_control widgets for persistence @@ -107,7 +107,7 @@ function createScopeControlWidget(widget) { const triggerLevel = widget.triggerLevel || 0; const triggerDelay = widget.triggerDelay || 0; const triggerVar = widget.triggerVar || ''; - const sampleTime = widget.sampleTime !== undefined ? widget.sampleTime : 0; + const sampleTime = widget.sampleTime !== undefined ? widget.sampleTime : 1; const sampleFreq = widget.sampleFreq || 20; // Build trigger variable options from scope-view variables @@ -145,7 +145,7 @@ function createScopeControlWidget(widget) {
@@ -246,7 +246,7 @@ function getScopeControlConfig(editWidget) { } function saveScopeControlConfig(widget) { - widget.sampleTime = widget.sampleTime !== undefined ? widget.sampleTime : 0; + widget.sampleTime = widget.sampleTime !== undefined ? widget.sampleTime : 1; widget.sampleFreq = widget.sampleFreq || 20; widget.triggerMode = widget.triggerMode || '0'; widget.triggerEdge = widget.triggerEdge || '1'; diff --git a/pyx2cscope/gui/web/templates/sample_control.html b/pyx2cscope/gui/web/templates/sample_control.html index 1781a878..851cfcd9 100644 --- a/pyx2cscope/gui/web/templates/sample_control.html +++ b/pyx2cscope/gui/web/templates/sample_control.html @@ -15,7 +15,7 @@
- +
diff --git a/pyx2cscope/gui/web/ws_handlers.py b/pyx2cscope/gui/web/ws_handlers.py index e536743d..6fdc91b2 100644 --- a/pyx2cscope/gui/web/ws_handlers.py +++ b/pyx2cscope/gui/web/ws_handlers.py @@ -169,7 +169,7 @@ def handle_update_sample_control(data): """ data = {k: v[0] if v else '' for k, v in parse_qs(data).items()} trigger_action = data.get('triggerAction', 'off') - sample_time = int(data.get('sampleTime', 0)) + sample_time = max(int(data.get('sampleTime', 1)), 1) sample_freq = float(data.get('sampleFreq', 20)) web_scope.scope_set_sample(trigger_action, sample_time, sample_freq) emit("sample_control_updated", { diff --git a/pyx2cscope/x2cscope.py b/pyx2cscope/x2cscope.py index 293425ca..5af2ed58 100644 --- a/pyx2cscope/x2cscope.py +++ b/pyx2cscope/x2cscope.py @@ -256,13 +256,14 @@ def set_sample_time(self, sample_time: int): """Define the resolution how the samples will be buffered at the internal buffer. This can be used to extend total sampling time at the cost of resolution. - 0 = every sample, 1 = every 2nd sample, 2 = every 3rd sample … + In the pyX2Cscope API, values start at 1, while LNET uses a 0-based pre-scaler. + 1 = every sample, 2 = every 2nd sample, 3 = every 3rd sample ... Args: sample_time (int): The sample time factor. """ - sample_time = 0 if sample_time < 0 else sample_time - self.scope_setup.set_sample_time_factor(sample_time) + sample_time = 1 if sample_time < 1 else sample_time + self.scope_setup.set_sample_time_factor(sample_time - 1) def set_scope_state(self, scope_state: int): """Set the state of the scope. diff --git a/tests/test_pyx2cscope_class.py b/tests/test_pyx2cscope_class.py index 46428066..315d1991 100644 --- a/tests/test_pyx2cscope_class.py +++ b/tests/test_pyx2cscope_class.py @@ -76,3 +76,19 @@ def test_wrong_com_port(self): """Check handling of a non-existent COM-PORT input.""" with pytest.raises(Exception, match=r"could not open port '?COM0'?"): X2CScope(elf_file=self.elf_file, port="COM0") + + def test_set_sample_time_uses_user_facing_factor(self, mocker): + """Check sample time values are translated from 1-based API to 0-based LNET.""" + fake_serial(mocker, 16) + scope = X2CScope(elf_file=self.elf_file, port="COM1") + try: + scope.set_sample_time(1) + assert scope.scope_setup.sample_time_factor == 0 + + scope.set_sample_time(3) + assert scope.scope_setup.sample_time_factor == 2 + + scope.set_sample_time(0) + assert scope.scope_setup.sample_time_factor == 0 + finally: + scope.disconnect() diff --git a/tests/test_web_gui.py b/tests/test_web_gui.py index 69b44683..713dcf17 100644 --- a/tests/test_web_gui.py +++ b/tests/test_web_gui.py @@ -313,7 +313,7 @@ def test_scope_trigger_defaults(self, web_scope): def test_scope_sample_time_default(self, web_scope): """Test scope sample time default.""" - assert web_scope.scope_sample_time == 0 + assert web_scope.scope_sample_time == 1 class TestWebScopeVariableManagement: @@ -405,6 +405,16 @@ def test_remove_scope_var(self, web_scope_connected): web_scope_connected.remove_scope_var("test_var") assert len(web_scope_connected.scope_vars) == 0 + def test_scope_sample_time_uses_user_facing_values(self, web_scope_connected): + """Test web scope clamps sample time to user-facing 1-based values.""" + web_scope_connected.x2c_scope.get_scope_sample_time.return_value = 2.5 + web_scope_connected.scope_sample_time = 2 + + web_scope_connected.scope_set_sample("off", 0, 20) + + assert web_scope_connected.scope_sample_time == 1 + web_scope_connected.x2c_scope.set_sample_time.assert_called_once_with(1) + class TestWebScopeScaledValue: """Tests for WebScope scaled value calculation.""" From 19006a367f8074b27a4fe2a08a96d4cc819ca8ba Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Wed, 15 Apr 2026 14:27:16 +0200 Subject: [PATCH 10/19] import/export SFRs --- pyx2cscope/variable/variable_factory.py | 55 +++++++++++++++++++++---- pyx2cscope/x2cscope.py | 4 +- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/pyx2cscope/variable/variable_factory.py b/pyx2cscope/variable/variable_factory.py index 1fa11699..b654c0c5 100644 --- a/pyx2cscope/variable/variable_factory.py +++ b/pyx2cscope/variable/variable_factory.py @@ -3,6 +3,7 @@ import logging import os import pickle +from typing import Optional from dataclasses import asdict from enum import Enum @@ -100,7 +101,7 @@ def set_lnet_interface(self, lnet: LNet): """ self.l_net = lnet - def _build_export_file_name(self, filename: str = None, ext: FileType= FileType.YAML): + def _build_export_file_name(self, filename: Optional[str] = None, ext: FileType= FileType.YAML): if filename is None: if self.parser.elf_path is not None: # get the elf_file name without extension @@ -110,7 +111,33 @@ def _build_export_file_name(self, filename: str = None, ext: FileType= FileType. return os.path.splitext(filename)[0] + ext.value - def export_variables(self, filename: str = None, ext: FileType = FileType.YAML, items=None): + def _resolve_export_item(self, item): + """Resolve an export item to VariableInfo and its target map kind.""" + if isinstance(item, tuple) and len(item) == 2: + name, sfr = item + if isinstance(name, str): + return self.parser.get_var_info(name, sfr=bool(sfr)), bool(sfr) + return None, bool(sfr) + + if isinstance(item, Variable): + item = item.info.name + + if isinstance(item, VariableInfo): + if self.parser.register_map.get(item.name) == item: + return item, True + if self.parser.variable_map.get(item.name) == item: + return item, False + return item, item.name in self.parser.register_map + + if isinstance(item, str): + if item in self.parser.variable_map: + return self.parser.variable_map.get(item), False + if item in self.parser.register_map: + return self.parser.register_map.get(item), True + + return None, False + + def export_variables(self, filename: Optional[str] = None, ext: FileType = FileType.YAML, items=None): """Store the variables registered on the elf file to a pickle file. Args: @@ -122,13 +149,17 @@ def export_variables(self, filename: str = None, ext: FileType = FileType.YAML, raise ValueError("Elf file is not yet supported as export format...") filename = self._build_export_file_name(filename, ext) - export_dict = {} + export_dict = {"variables": {}, "registers": {}} if items: for item in items: - variable_name = item.info.name if isinstance(item, Variable) else item - export_dict[variable_name] = self.parser.variable_map.get(variable_name) + variable_info, is_register = self._resolve_export_item(item) + if variable_info is None: + continue + target_key = "registers" if is_register else "variables" + export_dict[target_key][variable_info.name] = variable_info else: - export_dict = self.parser.variable_map + export_dict["variables"] = dict(self.parser.variable_map) + export_dict["registers"] = dict(self.parser.register_map) if ext is FileType.PICKLE: with open(filename, 'wb') as file: @@ -156,15 +187,23 @@ def import_variables(self, filename: str): # clear any previous loaded variable self.parser.variable_map.clear() + self.parser.register_map.clear() if ext is FileType.ELF: self.parser = GenericParser(filename) if ext is FileType.PICKLE: with open(filename, 'rb') as file: - self.parser.variable_map = pickle.load(file) + imported_data = pickle.load(file) if ext is FileType.YAML: with open(filename, 'r') as file: - self.parser.variable_map = yaml.load(file, Loader=yaml.FullLoader) + imported_data = yaml.load(file, Loader=yaml.FullLoader) + + if ext is not FileType.ELF: + if isinstance(imported_data, dict) and "variables" in imported_data: + self.parser.variable_map = imported_data.get("variables", {}) or {} + self.parser.register_map = imported_data.get("registers", {}) or {} + else: + self.parser.variable_map = imported_data or {} logging.debug(f"Variables loaded from {filename}") diff --git a/pyx2cscope/x2cscope.py b/pyx2cscope/x2cscope.py index 5af2ed58..9f31f1ed 100644 --- a/pyx2cscope/x2cscope.py +++ b/pyx2cscope/x2cscope.py @@ -9,7 +9,7 @@ import logging from dataclasses import dataclass from numbers import Number -from typing import Dict, List +from typing import Dict, List, Optional from mchplnet.interfaces.abstract_interface import Interface from mchplnet.interfaces.factory import InterfaceFactory, InterfaceType @@ -156,7 +156,7 @@ def get_variable_raw(self, variable_info: VariableInfo) -> Variable: """ return self.variable_factory.get_variable_raw(variable_info) - def export_variables(self, filename: str = None, ext: FileType = FileType.YAML, items=None): + def export_variables(self, filename: Optional[str] = None, ext: FileType = FileType.YAML, items=None): """Store the variables registered on the elf file to a pickle file. Args: From c4ba5ee65100cef1f353a081594815dba2f83caa Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Wed, 15 Apr 2026 14:27:38 +0200 Subject: [PATCH 11/19] export variables on QT and Web --- doc/gui_qt.md | 9 +- doc/gui_web.md | 11 ++- doc/scripting.rst | 4 + .../gui/qt/controllers/config_manager.py | 12 +-- .../gui/qt/controllers/connection_manager.py | 21 +++-- pyx2cscope/gui/qt/main_window.py | 36 ++++++- pyx2cscope/gui/qt/models/app_state.py | 54 +++++++++++ pyx2cscope/gui/qt/tabs/setup_tab.py | 21 +++-- pyx2cscope/gui/web/app.py | 43 ++++++++- pyx2cscope/gui/web/scope.py | 54 +++++++++-- pyx2cscope/gui/web/static/js/script.js | 25 ++++- pyx2cscope/gui/web/templates/index.html | 2 +- pyx2cscope/gui/web/templates/navbar.html | 5 +- pyx2cscope/gui/web/templates/setup.html | 4 +- .../gui/web/templates/welcome_content.html | 8 +- tests/test_parser.py | 23 +++++ tests/test_qt_gui.py | 51 ++++++++++ tests/test_web_gui.py | 94 +++++++++++++++++++ 18 files changed, 434 insertions(+), 43 deletions(-) diff --git a/doc/gui_qt.md b/doc/gui_qt.md index 4b330eb4..e4d803ef 100644 --- a/doc/gui_qt.md +++ b/doc/gui_qt.md @@ -30,7 +30,7 @@ The Setup tab is where you configure the connection to your microcontroller. ### Connection Settings -1. **ELF File**: Click "Select ELF file" to choose the ELF file of the project your microcontroller is programmed with. +1. **Select File**: Click `ELF / YML / PKL` to load variable information. Supported formats are `.elf`, `.yml`, and `.pkl`. 2. **Interface**: Select the communication interface: - **UART**: Serial communication @@ -132,6 +132,13 @@ mapped to its fixed hardware address. From that point it behaves exactly like an variable — values can be read, polled live (WatchView), or captured as a scope channel (ScopeView). +### Export Variables + +The **Export Variables** button in the Data Views toolbar allows you to: +- Export only the variables currently selected in WatchView and ScopeView. +- Save the selection as `.yml` or `.pkl`. +- Preserve SFR selections in the exported file too. + ### Save and Load Config The **Save Config** and **Load Config** buttons allow you to: diff --git a/doc/gui_web.md b/doc/gui_web.md index 8afd0fb7..f5192d26 100644 --- a/doc/gui_web.md +++ b/doc/gui_web.md @@ -95,11 +95,18 @@ When CAN is selected: > **Note**: CAN interface requires vendor-specific drivers to be installed. See the API documentation for driver requirements. -### ELF File Selection +### Variable File Selection -Select an ELF file (or PKL/YML import file) containing the variable information from your firmware. +Select a variable file containing the variable information for your firmware. Supported formats: `.elf`, `.pkl`, `.yml` +### Export Variables + +After connecting, click the export icon in the header to export the variables currently used in +Watch View, Scope View, and Dashboard. + +Choose either `.yml` or `.pkl`. SFR selections are preserved in the exported file too. + ### Connecting Click the **Connect** button to establish communication with the target device. diff --git a/doc/scripting.rst b/doc/scripting.rst index 700395fd..6c329c6b 100644 --- a/doc/scripting.rst +++ b/doc/scripting.rst @@ -357,6 +357,10 @@ It is possible to export selected variables or the whole list of variables. Having the exported file (yml or pickle) it is possible to import it back to the X2CScope object. YML is human readable and can be edited with any text editor, while pickle is a binary file and can be used to store the variables in a more secure way. +Exported files preserve both firmware variables and SFR entries. If a selected list contains SFRs, +they are stored in the register section of the export file and can be imported again with +``get_variable("NAME", sfr=True)``. + See the example below: .. literalinclude:: ../pyx2cscope/examples/export_import_variables.py diff --git a/pyx2cscope/gui/qt/controllers/config_manager.py b/pyx2cscope/gui/qt/controllers/config_manager.py index e0bc1e50..307d89ef 100644 --- a/pyx2cscope/gui/qt/controllers/config_manager.py +++ b/pyx2cscope/gui/qt/controllers/config_manager.py @@ -129,7 +129,7 @@ def validate_elf_file(self, elf_path: str) -> bool: return os.path.exists(elf_path) def prompt_for_elf_file(self) -> Optional[str]: - """Prompt user to select an ELF file. + """Prompt user to select an ELF file or import. Returns: Selected file path, or None if cancelled. @@ -139,9 +139,9 @@ def prompt_for_elf_file(self) -> Optional[str]: file_path, _ = QFileDialog.getOpenFileName( self._parent, - "Select ELF File", + "Select ELF File or Import", last_dir, - "ELF Files (*.elf);;All Files (*)", + "Variable Files (*.elf *.yml *.pkl);;ELF Files (*.elf);;YAML Files (*.yml);;Pickle Files (*.pkl);;All Files (*)", ) if file_path: @@ -151,7 +151,7 @@ def prompt_for_elf_file(self) -> Optional[str]: return file_path if file_path else None def show_file_not_found_warning(self, file_path: str): - """Show a warning dialog for missing ELF file. + """Show a warning dialog for a missing ELF/import file. Args: file_path: The path that was not found. @@ -159,8 +159,8 @@ def show_file_not_found_warning(self, file_path: str): QMessageBox.warning( self._parent, "File Not Found", - f"The ELF file '{file_path}' does not exist.\n\n" - "Please select a valid ELF file.", + f"The ELF/import file '{file_path}' does not exist.\n\n" + "Please select a valid ELF file or import.", ) @staticmethod diff --git a/pyx2cscope/gui/qt/controllers/connection_manager.py b/pyx2cscope/gui/qt/controllers/connection_manager.py index 3ef7e829..13112e5f 100644 --- a/pyx2cscope/gui/qt/controllers/connection_manager.py +++ b/pyx2cscope/gui/qt/controllers/connection_manager.py @@ -1,7 +1,6 @@ """Connection management for the X2CScope device.""" import logging - import serial.tools.list_ports from PyQt5.QtCore import QObject, pyqtSignal @@ -46,6 +45,12 @@ def refresh_ports(self) -> list: self.ports_refreshed.emit(ports) return ports + def _create_x2cscope(self, variable_file: str, **kwargs) -> X2CScope: + """Create an X2CScope instance and load variables from the selected file.""" + x2cscope = X2CScope(**kwargs) + x2cscope.import_variables(variable_file) + return x2cscope + def connect_uart(self, port: str, baud_rate: int, elf_file: str) -> bool: """Connect to the device via UART. @@ -58,9 +63,9 @@ def connect_uart(self, port: str, baud_rate: int, elf_file: str) -> bool: True if connection successful, False otherwise. """ try: - x2cscope = X2CScope( + x2cscope = self._create_x2cscope( + elf_file, port=port, - elf_file=elf_file, baud_rate=baud_rate, ) @@ -92,10 +97,10 @@ def connect_tcp(self, host: str, tcp_port: int, elf_file: str) -> bool: True if connection successful, False otherwise. """ try: - x2cscope = X2CScope( + x2cscope = self._create_x2cscope( + elf_file, host=host, tcp_port=tcp_port, - elf_file=elf_file, ) self._app_state.elf_file = elf_file @@ -168,8 +173,8 @@ def connect_can( # Map mode to standard/extended mode_str = 'extended' if is_extended else 'standard' - x2cscope = X2CScope( - elf_file=elf_file, + x2cscope = self._create_x2cscope( + elf_file, bustype=bustype, channel=channel, baud_rate=baud_value, @@ -214,7 +219,7 @@ def connect(self, elf_file: str, **params) -> bool: return False if not elf_file: - self.error_occurred.emit("No ELF file selected.") + self.error_occurred.emit("No ELF file or import selected.") return False interface = params.get("interface", "UART") diff --git a/pyx2cscope/gui/qt/main_window.py b/pyx2cscope/gui/qt/main_window.py index d2827186..dc3b00cd 100644 --- a/pyx2cscope/gui/qt/main_window.py +++ b/pyx2cscope/gui/qt/main_window.py @@ -7,6 +7,7 @@ from PyQt5.QtCore import QSettings, Qt from PyQt5.QtWidgets import ( QApplication, + QFileDialog, QHBoxLayout, QLabel, QMainWindow, @@ -133,13 +134,18 @@ def _setup_ui(self): # noqa: PLR0915 top_bar_layout.addStretch() - # Save/Load buttons + # Save/Load/Export buttons + self._export_variables_button = QPushButton("Export Variables") + self._export_variables_button.setFixedSize(120, 28) + self._export_variables_button.setEnabled(False) + self._export_variables_button.clicked.connect(self._export_selected_variables) self._save_button = QPushButton("Save Config") self._save_button.setFixedSize(100, 28) self._save_button.clicked.connect(self._save_config) self._load_button = QPushButton("Load Config") self._load_button.setFixedSize(100, 28) self._load_button.clicked.connect(self._load_config) + top_bar_layout.addWidget(self._export_variables_button) top_bar_layout.addWidget(self._save_button) top_bar_layout.addWidget(self._load_button) data_views_layout.addLayout(top_bar_layout) @@ -235,7 +241,7 @@ def _on_ports_refreshed(self, ports: list): self._setup_tab.set_ports(ports) def _on_elf_file_selected(self, file_path: str): - """Handle ELF file selection from setup tab.""" + """Handle variable file selection from setup tab.""" self._settings.setValue("elf_file_path", file_path) def _on_connect_clicked(self): @@ -249,7 +255,7 @@ def _on_connect_clicked(self): if not elf_path: self._setup_tab.set_loading(False) - self._show_error("Please select an ELF file first.") + self._show_error("Please select an ELF file or import first.") return # Get connection parameters based on selected interface @@ -272,6 +278,7 @@ def _on_connect_clicked(self): def _on_connection_changed(self, connected: bool): """Handle connection state change.""" self._setup_tab.set_connected(connected) + self._export_variables_button.setEnabled(connected) # Update tabs self._scope_view_tab.on_connection_changed(connected) @@ -362,6 +369,29 @@ def _save_config(self): ) self._config_manager.save_config(config) + def _export_selected_variables(self): + """Export variables currently selected in WatchView and ScopeView.""" + source_path = self._setup_tab.elf_file_path or self._settings.value("elf_file_path", "", type=str) + default_name = os.path.splitext(os.path.basename(source_path))[0] if source_path else "variables_list" + export_dir = self._settings.value("variable_export_dir", "", type=str) + default_path = os.path.join(export_dir, default_name + ".yml") if export_dir else default_name + ".yml" + + file_path, _ = QFileDialog.getSaveFileName( + self, + "Export Selected Variables", + default_path, + "YAML Files (*.yml);;Pickle Files (*.pkl)", + ) + if not file_path: + return + + self._settings.setValue("variable_export_dir", os.path.dirname(file_path)) + try: + self._app_state.export_selected_variables(file_path) + QMessageBox.information(self, "Export Complete", f"Variables exported to:\n{file_path}") + except Exception as e: + self._show_error(str(e)) + def _load_config(self): # noqa: PLR0912, PLR0915 """Load configuration from file.""" config = self._config_manager.load_config() diff --git a/pyx2cscope/gui/qt/models/app_state.py b/pyx2cscope/gui/qt/models/app_state.py index 0bd6ebfe..60f60ca7 100644 --- a/pyx2cscope/gui/qt/models/app_state.py +++ b/pyx2cscope/gui/qt/models/app_state.py @@ -11,6 +11,7 @@ from PyQt5.QtCore import QMutex, QObject, pyqtSignal +from pyx2cscope.variable.variable_factory import FileType from pyx2cscope.x2cscope import TriggerConfig, X2CScope @@ -198,6 +199,59 @@ def get_sfr_list(self) -> List[str]: finally: self._mutex.unlock() + def export_variables(self, filename: str): + """Export the currently loaded variable database to a YML or PKL file.""" + self._mutex.lock() + try: + if not self._x2cscope: + raise RuntimeError("No variables are loaded.") + + extension = filename.lower().rsplit(".", maxsplit=1)[-1] if "." in filename else "" + if extension == "yml": + file_type = FileType.YAML + elif extension == "pkl": + file_type = FileType.PICKLE + else: + raise ValueError("Supported export formats are .yml and .pkl.") + + self._x2cscope.export_variables(filename, ext=file_type) + finally: + self._mutex.unlock() + + def export_selected_variables(self, filename: str): + """Export only variables currently selected in the watch and scope views.""" + self._mutex.lock() + try: + if not self._x2cscope: + raise RuntimeError("No variables are loaded.") + + extension = filename.lower().rsplit(".", maxsplit=1)[-1] if "." in filename else "" + if extension == "yml": + file_type = FileType.YAML + elif extension == "pkl": + file_type = FileType.PICKLE + else: + raise ValueError("Supported export formats are .yml and .pkl.") + + seen_items = set() + selected_vars = [] + selected_vars.extend((var.name, var.sfr) for var in self._watch_vars if var.name and var.name != "None") + selected_vars.extend((var.name, var.sfr) for var in self._live_watch_vars if var.name and var.name != "None") + selected_vars.extend((channel.name, channel.sfr) for channel in self._scope_channels if channel.name and channel.name != "None") + + for name, sfr in selected_vars: + key = (name, sfr) + if key in seen_items: + continue + seen_items.add(key) + + if not seen_items: + raise RuntimeError("No variables are selected in WatchView or ScopeView.") + + self._x2cscope.export_variables(filename, ext=file_type, items=list(seen_items)) + finally: + self._mutex.unlock() + def update_device_info(self) -> Optional[DeviceInfo]: """Fetch and update device info (thread-safe).""" self._mutex.lock() diff --git a/pyx2cscope/gui/qt/tabs/setup_tab.py b/pyx2cscope/gui/qt/tabs/setup_tab.py index 56d68f63..1b1b6605 100644 --- a/pyx2cscope/gui/qt/tabs/setup_tab.py +++ b/pyx2cscope/gui/qt/tabs/setup_tab.py @@ -33,7 +33,7 @@ class SetupTab(QWidget): - UART settings (Port, Baud Rate) - TCP/IP settings (IP Address, Port) - CAN settings (Bus Type, Channel, Baudrate, Mode, Tx-ID, Rx-ID) - - ELF file selection + - File selection (.elf, .yml, .pkl) - Device info display """ @@ -73,7 +73,7 @@ def _setup_ui(self): # noqa: PLR0915 left_layout = QVBoxLayout() left_layout.setAlignment(Qt.AlignTop) - # === Connection Settings Group (ELF file + Interface selection) === + # === Connection Settings Group (file + interface selection) === connection_group = QGroupBox("Connection Settings") connection_layout = QGridLayout() connection_layout.setSpacing(8) @@ -83,9 +83,9 @@ def _setup_ui(self): # noqa: PLR0915 row = 0 - # ELF file selection - connection_layout.addWidget(QLabel("ELF File:"), row, 0, Qt.AlignRight) - self._elf_button = QPushButton("Select ELF file") + # Variable source selection + connection_layout.addWidget(QLabel("Select File:"), row, 0, Qt.AlignRight) + self._elf_button = QPushButton("ELF / YML / PKL") self._elf_button.setFixedWidth(200) self._elf_button.clicked.connect(self._on_select_elf) connection_layout.addWidget(self._elf_button, row, 1, 1, 2) @@ -241,6 +241,7 @@ def _setup_ui(self): # noqa: PLR0915 can_layout.addWidget(self._can_rx_id_edit, can_row, 1) left_layout.addWidget(self._can_group) + left_layout.addStretch() main_layout.addLayout(left_layout) @@ -311,15 +312,15 @@ def _on_interface_changed(self, interface: str): self._can_group.show() def _on_select_elf(self): - """Handle ELF file selection.""" + """Handle variable file selection.""" # Get last directory from settings last_dir = self._settings.value("elf_file_dir", "", type=str) file_path, _ = QFileDialog.getOpenFileName( self, - "Select ELF File", + "Select File", last_dir, - "ELF Files (*.elf);;All Files (*.*)", + "Variable Files (*.elf *.yml *.pkl);;ELF Files (*.elf);;YAML Files (*.yml);;Pickle Files (*.pkl);;All Files (*.*)", ) if file_path: self._elf_file_path = file_path @@ -375,12 +376,12 @@ def refresh_btn(self) -> QPushButton: @property def elf_file_path(self) -> str: - """Get the selected ELF file path.""" + """Get the selected file path.""" return self._elf_file_path @elf_file_path.setter def elf_file_path(self, path: str): - """Set the ELF file path.""" + """Set the selected file path.""" self._elf_file_path = path if path: basename = os.path.basename(path) diff --git a/pyx2cscope/gui/web/app.py b/pyx2cscope/gui/web/app.py index 53edf176..6cfcb2f5 100644 --- a/pyx2cscope/gui/web/app.py +++ b/pyx2cscope/gui/web/app.py @@ -6,15 +6,17 @@ import logging import os import socket +import tempfile import webbrowser import serial.tools.list_ports -from flask import Flask, jsonify, render_template, request +from flask import Flask, Response, jsonify, render_template, request from pyx2cscope import __version__, set_logger from pyx2cscope.gui import web from pyx2cscope.gui.web.scope import web_scope from pyx2cscope.gui.web.ws_handlers import socketio +from pyx2cscope.variable.variable_factory import FileType set_logger(logging.ERROR) @@ -45,6 +47,7 @@ def create_app(): app.add_url_rule("/is-connected", view_func=is_connected) app.add_url_rule("/variables", view_func=variables_autocomplete, methods=["POST", "GET"]) app.add_url_rule("/variables/all", view_func=get_variables, methods=["POST", "GET"]) + app.add_url_rule("/variables/export", view_func=export_variables, methods=["GET"]) socketio.init_app(app) @@ -260,6 +263,44 @@ def get_variables(): return jsonify({"items": items}) +def export_variables(): + """Export the currently loaded variable database as YML or PKL.""" + if not web_scope.is_connected() or web_scope.x2c_scope is None: + return jsonify({"status": "error", "msg": "No variables are loaded."}), 400 + + ext = request.args.get("ext", "yml").lower() + if ext == "yml": + file_type = FileType.YAML + mimetype = "application/x-yaml" + elif ext == "pkl": + file_type = FileType.PICKLE + mimetype = "application/octet-stream" + else: + return jsonify({"status": "error", "msg": "Supported export formats are yml and pkl."}), 400 + + temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=file_type.value) + temp_file.close() + try: + selected_items = web_scope.get_selected_variables() + if not selected_items: + return jsonify({"status": "error", "msg": "No variables are selected in WatchView, ScopeView, or Dashboard."}), 400 + + web_scope.x2c_scope.export_variables(temp_file.name, ext=file_type, items=selected_items) + with open(temp_file.name, "rb") as file: + data = file.read() + finally: + if os.path.exists(temp_file.name): + os.remove(temp_file.name) + + return Response( + data, + mimetype=mimetype, + headers={ + "Content-disposition": f"attachment; filename={web_scope.get_export_filename(file_type.value)}" + }, + ) + + def open_browser(host="localhost", web_port=5000): """Open a new browser pointing to the Flask server. diff --git a/pyx2cscope/gui/web/scope.py b/pyx2cscope/gui/web/scope.py index df79b7aa..3c9b87ce 100644 --- a/pyx2cscope/gui/web/scope.py +++ b/pyx2cscope/gui/web/scope.py @@ -5,6 +5,7 @@ """ import numbers import time +from pathlib import Path from pyx2cscope.gui.web import extensions from pyx2cscope.x2cscope import TriggerConfig, X2CScope @@ -24,6 +25,7 @@ def __init__(self): self.scope_burst = False self.scope_sample_time = 1 self.scope_time_sampling = 50e-3 + self.variables_file = "" self.dashboard_vars = {} # {var_name: Variable object} self.dashboard_rate = 1.0 # Fixed at 1 second for dashboard polling @@ -32,7 +34,7 @@ def __init__(self): self.x2c_scope :X2CScope | None = None self._lock = extensions.create_lock() - def _get_watch_variable_as_dict(self, variable, value=None): + def _get_watch_variable_as_dict(self, variable, sfr=False, value=None): primitive = variable.__class__.__name__.lower().replace("variable", "") if value is None: with self._lock: @@ -47,9 +49,10 @@ def _get_watch_variable_as_dict(self, variable, value=None): "offset": 0, "scaled_value": value, "remove": 0, + "sfr": bool(sfr), } - def _get_scope_variable_as_dict(self, variable): + def _get_scope_variable_as_dict(self, variable, sfr=False): colors = [ "#FF0000", "#00FF00", @@ -68,6 +71,7 @@ def _get_scope_variable_as_dict(self, variable): "gain": 1, "offset": 0, "remove": 0, + "sfr": bool(sfr), } @staticmethod @@ -151,7 +155,7 @@ def add_watch_var(self, var, sfr: bool = False): if not any(_data["variable"].info.name == var for _data in self.watch_vars): variable = self.x2c_scope.get_variable(var, sfr=sfr) if variable is not None: - var_dict = self._get_watch_variable_as_dict(variable) + var_dict = self._get_watch_variable_as_dict(variable, sfr=sfr) self.watch_vars.append(var_dict) return var_dict @@ -267,7 +271,7 @@ def add_scope_var(self, var, sfr: bool = False): if not any(data["variable"].info.name == var for data in self.scope_vars): variable = self.x2c_scope.get_variable(var, sfr=sfr) if variable is not None: - var_dict = self._get_scope_variable_as_dict(variable) + var_dict = self._get_scope_variable_as_dict(variable, sfr=sfr) self.scope_vars.append(var_dict) self.x2c_scope.add_scope_channel(variable) return var_dict @@ -469,13 +473,50 @@ def connect(self, *args, **kwargs): self.x2c_scope = X2CScope(*args, **kwargs) def set_file(self, import_file): - """Import variables from ELF file. + """Import variables from a variable database file. Args: - import_file (str): Path to the ELF file. + import_file (str): Path to the import file. """ + self.variables_file = import_file self.x2c_scope.import_variables(import_file) + def get_export_filename(self, extension: str) -> str: + """Build a default export filename for the current variable database.""" + stem = Path(self.variables_file).stem if self.variables_file else "variables_list" + return stem + extension + + def get_selected_variables(self): + """Collect unique variables currently used by watch, scope, and dashboard views.""" + selected = [] + seen = set() + + for item in self.watch_vars: + variable = item.get("variable") + if variable is None: + continue + key = (variable.info.name, bool(item.get("sfr", False))) + if key not in seen: + seen.add(key) + selected.append(key) + + for item in self.scope_vars: + variable = item.get("variable") + if variable is None: + continue + key = (variable.info.name, bool(item.get("sfr", False))) + if key not in seen: + seen.add(key) + selected.append(key) + + for name, variable in self.dashboard_vars.items(): + key = (name, False) + if variable is not None and key not in seen: + seen.add(key) + selected.append(key) + + return selected + def list_variables(self): """List all available variables. @@ -496,6 +537,7 @@ def disconnect(self): """Disconnect from X2CScope.""" self.x2c_scope.disconnect() self.x2c_scope = None + self.variables_file = "" def is_connected(self): """Check if connected to X2CScope. diff --git a/pyx2cscope/gui/web/static/js/script.js b/pyx2cscope/gui/web/static/js/script.js index eaea6516..fe4a09d7 100644 --- a/pyx2cscope/gui/web/static/js/script.js +++ b/pyx2cscope/gui/web/static/js/script.js @@ -50,6 +50,23 @@ function disconnect(){ }); } +function exportVariables() { + const exportToggle = $('#exportVariablesToggle'); + if (exportToggle.attr('aria-disabled') === 'true') { + return; + } + + $('#x2cModalTitle').html('Export Variables'); + $('#x2cModalBody').html(` +

Export the variables currently used in Watch View, Scope View, and Dashboard.

+ + `); + $('#x2cModal').modal('show'); +} + function load_uart() { $.getJSON('/serial-ports', function(data) { uart = $('#port'); @@ -95,6 +112,7 @@ function setConnectState(status) { $("#btnDashboardView").prop("disabled", false); $("#btnConnect").prop("disabled", true); $("#btnConnect").html("Disconnect", true); + $('#exportVariablesToggle').removeClass('disabled text-white-50').attr('aria-disabled', 'false'); $('#connection-status').html('Connected'); $('#desktopTabs').removeClass('disabled'); $('#mobileTabs').removeClass('disabled'); @@ -112,6 +130,7 @@ function setConnectState(status) { $('#btnConnect').html('Connect'); $('#btnConnect').removeClass('btn-danger'); $('#btnConnect').addClass('btn-primary'); + $('#exportVariablesToggle').addClass('disabled text-white-50').attr('aria-disabled', 'true'); $('#setupView').removeClass('disabled'); $('#desktopTabs').addClass('disabled'); $('#mobileTabs').addClass('disabled'); @@ -125,6 +144,10 @@ function initSetupCard(){ if($('#btnConnect').html() === "Connect") connect(); else disconnect(); }); + $('#exportVariablesToggle').on('click', function(e) { + e.preventDefault(); + exportVariables(); + }); $('#connection-status').on('click', function() { if($('#connection-status').html() === "Disconnected") connect(); @@ -357,4 +380,4 @@ $(document).ready(function() { setConnectState(data.status); }); -}); \ No newline at end of file +}); diff --git a/pyx2cscope/gui/web/templates/index.html b/pyx2cscope/gui/web/templates/index.html index 2a552fea..a209e4b7 100644 --- a/pyx2cscope/gui/web/templates/index.html +++ b/pyx2cscope/gui/web/templates/index.html @@ -126,4 +126,4 @@ -{% endblock scripts %} \ No newline at end of file +{% endblock scripts %} diff --git a/pyx2cscope/gui/web/templates/navbar.html b/pyx2cscope/gui/web/templates/navbar.html index bf2b4444..b918107e 100644 --- a/pyx2cscope/gui/web/templates/navbar.html +++ b/pyx2cscope/gui/web/templates/navbar.html @@ -2,9 +2,12 @@

{{ title }} {{ version }}

-
\ No newline at end of file + diff --git a/pyx2cscope/gui/web/templates/setup.html b/pyx2cscope/gui/web/templates/setup.html index 66102411..d0839422 100644 --- a/pyx2cscope/gui/web/templates/setup.html +++ b/pyx2cscope/gui/web/templates/setup.html @@ -96,8 +96,8 @@
-
+
-
\ No newline at end of file +
diff --git a/pyx2cscope/gui/web/templates/welcome_content.html b/pyx2cscope/gui/web/templates/welcome_content.html index 47a877c4..e14c224e 100644 --- a/pyx2cscope/gui/web/templates/welcome_content.html +++ b/pyx2cscope/gui/web/templates/welcome_content.html @@ -6,7 +6,12 @@
Getting Started
settings Setup
-

Configure your interface, upload an ELF file, and click "Connect" to start monitoring your device.

+

Configure your interface, load an ELF or import file, and click "Connect" to start monitoring your device.

+
+ +
+
upload_file Export Variables
+

Use the export icon in the header to save the variables currently used in Watch View, Scope View, and Dashboard as YML or PKL.

Available Views
@@ -32,6 +37,7 @@
Tips
  • qr_code_2 Click QR code icons to generate scannable links for mobile access
  • open_in_new Click open icons to launch views in separate windows
  • help_outline Click the help icon in the header to toggle this card
  • +
  • upload_file Click the export icon in the header to download variables used by the active views
  • diff --git a/tests/test_parser.py b/tests/test_parser.py index 8be032e0..676f8017 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -155,3 +155,26 @@ def test_variable_export_import(self, mocker): os.remove("my_variables.yml") os.remove("qspin_foc_same54.yml") os.remove("my_single_variable.pkl") + + def test_sfr_export_import(self, mocker): + """Check exported SFR entries can be re-imported and resolved as registers.""" + fake_serial(mocker, 16) + x2c_scope = X2CScope(port="COM14") + x2c_scope.import_variables(self.elf_file_dspic33ak) + + sfr_list = x2c_scope.list_sfr() + assert sfr_list, "expected at least one SFR in the imported ELF" + + sfr_name = sfr_list[0] + x2c_scope.export_variables("my_sfr_variable", items=[(sfr_name, True)]) + assert os.path.exists("my_sfr_variable.yml") == True, "SFR export yaml file name not found" + + x2c_reloaded = X2CScope(port="COM14") + x2c_reloaded.import_variables(filename="my_sfr_variable.yml") + sfr_reloaded = x2c_reloaded.get_variable(sfr_name, sfr=True) + + assert sfr_reloaded is not None, "reloaded SFR should be available" + assert sfr_reloaded.info.name == sfr_name, "reloaded SFR name mismatch" + assert len(x2c_reloaded.list_sfr()) == 1, "import loaded more than one SFR" + + os.remove("my_sfr_variable.yml") diff --git a/tests/test_qt_gui.py b/tests/test_qt_gui.py index 76bed478..1fd5ddec 100644 --- a/tests/test_qt_gui.py +++ b/tests/test_qt_gui.py @@ -274,6 +274,38 @@ def test_connect_uart_creates_x2cscope( assert result is True + def test_connect_uart_imports_selected_file(self, connection_manager, mocker): + """Test UART connection always loads variables through import_variables.""" + mock_x2c = MagicMock() + mock_x2c.list_variables.return_value = [] + mocker.patch( + "pyx2cscope.gui.qt.controllers.connection_manager.X2CScope", + return_value=mock_x2c, + ) + + result = connection_manager.connect_uart( + port="COM1", baud_rate=115200, elf_file="firmware.elf" + ) + + assert result is True + mock_x2c.import_variables.assert_called_once_with("firmware.elf") + + def test_connect_tcp_imports_yml_after_connect(self, connection_manager, mocker): + """Test TCP connection loads YML imports after creating the transport.""" + mock_x2c = MagicMock() + mock_x2c.list_variables.return_value = [] + mocker.patch( + "pyx2cscope.gui.qt.controllers.connection_manager.X2CScope", + return_value=mock_x2c, + ) + + result = connection_manager.connect_tcp( + host="127.0.0.1", tcp_port=12666, elf_file="variables.yml" + ) + + assert result is True + mock_x2c.import_variables.assert_called_once_with("variables.yml") + def test_disconnect_clears_state(self, connection_manager): """Test disconnect clears connection state.""" connection_manager.disconnect() @@ -337,6 +369,25 @@ def test_setup_tab_creation(self, qt_application): assert tab is not None + def test_app_state_exports_selected_variables(self, qt_application): + """Test AppState exports only variables selected in watch and scope views.""" + from pyx2cscope.gui.qt.models.app_state import AppState, ScopeChannel + + app_state = AppState() + mock_x2c = MagicMock() + + mock_x2c.list_variables.return_value = ["watch.var", "scope.var"] + + app_state.set_x2cscope(mock_x2c) + app_state.add_live_watch_var() + app_state.update_live_watch_var_field(0, "name", "watch.var") + app_state.set_scope_channel(0, ScopeChannel(name="scope.var", sfr=True)) + + app_state.export_selected_variables("selected.yml") + + exported_items = mock_x2c.export_variables.call_args.kwargs["items"] + assert set(exported_items) == {("watch.var", False), ("scope.var", True)} + def test_scope_view_tab_creation(self, qt_application): """Test ScopeViewTab can be created.""" from pyx2cscope.gui.qt.models.app_state import AppState diff --git a/tests/test_web_gui.py b/tests/test_web_gui.py index 713dcf17..95918685 100644 --- a/tests/test_web_gui.py +++ b/tests/test_web_gui.py @@ -57,6 +57,7 @@ def test_index_route(self, flask_client): assert response.status_code == HTTP_OK assert b"html" in response.data.lower() + assert b"exportVariablesToggle" in response.data def test_serial_ports_route(self, flask_client, mocker): """Test serial-ports route returns list.""" @@ -112,6 +113,85 @@ def test_variables_route_not_connected(self, flask_client): assert "items" in data assert data["items"] == [] + def test_export_variables_route(self, flask_client, mocker): + """Test variable export route returns a downloadable file.""" + from pyx2cscope.gui.web.scope import web_scope + + mock_x2c = MagicMock() + original_x2c = web_scope.x2c_scope + original_file = web_scope.variables_file + original_watch = web_scope.watch_vars + original_scope = web_scope.scope_vars + original_dashboard = web_scope.dashboard_vars + + def write_export_file(filename, ext, items=None): + mode = "wb" if ext.value == ".pkl" else "w" + payload = b"pickle-data" if mode == "wb" else "yaml-data" + with open(filename, mode) as file: + file.write(payload) + + mock_x2c.export_variables.side_effect = write_export_file + mocker.patch.object(web_scope, "is_connected", return_value=True) + web_scope.x2c_scope = mock_x2c + web_scope.variables_file = "firmware.elf" + watch_var = MagicMock() + watch_var.info.name = "watch.var" + scope_var = MagicMock() + scope_var.info.name = "scope.var" + dashboard_var = MagicMock() + dashboard_var.info.name = "dashboard.var" + web_scope.watch_vars = [{"variable": watch_var, "sfr": True}] + web_scope.scope_vars = [{"variable": scope_var, "sfr": False}] + web_scope.dashboard_vars = {"dashboard.var": dashboard_var} + + try: + response = flask_client.get("/variables/export?ext=yml") + + assert response.status_code == HTTP_OK + assert response.headers["Content-Disposition"] == "attachment; filename=firmware.yml" + assert response.data == b"yaml-data" + assert mock_x2c.export_variables.call_args.kwargs["items"] == [ + ("watch.var", True), + ("scope.var", False), + ("dashboard.var", False), + ] + finally: + web_scope.x2c_scope = original_x2c + web_scope.variables_file = original_file + web_scope.watch_vars = original_watch + web_scope.scope_vars = original_scope + web_scope.dashboard_vars = original_dashboard + + def test_export_variables_route_requires_selected_variables(self, flask_client, mocker): + """Test export route fails when no view has selected variables.""" + from pyx2cscope.gui.web.scope import web_scope + + original_x2c = web_scope.x2c_scope + original_file = web_scope.variables_file + original_watch = web_scope.watch_vars + original_scope = web_scope.scope_vars + original_dashboard = web_scope.dashboard_vars + + mocker.patch.object(web_scope, "is_connected", return_value=True) + web_scope.x2c_scope = MagicMock() + web_scope.variables_file = "firmware.elf" + web_scope.watch_vars = [] + web_scope.scope_vars = [] + web_scope.dashboard_vars = {} + + try: + response = flask_client.get("/variables/export?ext=yml") + + assert response.status_code == 400 + data = json.loads(response.data) + assert "No variables are selected" in data["msg"] + finally: + web_scope.x2c_scope = original_x2c + web_scope.variables_file = original_file + web_scope.watch_vars = original_watch + web_scope.scope_vars = original_scope + web_scope.dashboard_vars = original_dashboard + class TestWatchViewRoutes: """Tests for watch view routes.""" @@ -358,6 +438,13 @@ def test_add_watch_var(self, web_scope_connected): assert result is not None assert len(web_scope_connected.watch_vars) == 1 + assert web_scope_connected.watch_vars[0]["sfr"] is False + + def test_add_watch_var_tracks_sfr_flag(self, web_scope_connected): + """Test adding watch SFR variable preserves its SFR flag.""" + web_scope_connected.add_watch_var("test_var", sfr=True) + + assert web_scope_connected.watch_vars[0]["sfr"] is True def test_add_watch_var_duplicate_prevented(self, web_scope_connected): """Test duplicate watch variables are not added.""" @@ -380,6 +467,13 @@ def test_add_scope_var(self, web_scope_connected): assert result is not None assert len(web_scope_connected.scope_vars) == 1 + assert web_scope_connected.scope_vars[0]["sfr"] is False + + def test_add_scope_var_tracks_sfr_flag(self, web_scope_connected): + """Test adding scope SFR variable preserves its SFR flag.""" + web_scope_connected.add_scope_var("test_var", sfr=True) + + assert web_scope_connected.scope_vars[0]["sfr"] is True def test_add_scope_var_max_limit(self, web_scope_connected): """Test scope variables can be added (max limit may not be enforced in WebScope).""" From 0ccd8082cfb02b93e5a36a4a8d2061baa6c2cb2b Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Wed, 15 Apr 2026 16:04:20 +0200 Subject: [PATCH 12/19] modernize packaging and add Python 3.14 support Migrate pyX2Cscope to a pip-first pyproject setup with setuptools and optional dev/docs/build extras, removing the root requirements and quality files. Update CI and docs to use editable installs with extras, and relax dependency constraints so the project installs and tests cleanly on Python 3.14. --- .github/workflows/buildexe.yml | 6 +- .github/workflows/documentation.yml | 10 ++- .github/workflows/release.yml | 15 +++-- README.md | 2 + doc/development.md | 3 +- doc/install.rst | 4 +- pyproject.toml | 81 +++++++++++++++--------- pyx2cscope/variable/variable_factory.py | 5 +- quality.txt | Bin 566 -> 0 bytes requirements.txt | Bin 346 -> 0 bytes tests/test_parser.py | 15 ++--- 11 files changed, 83 insertions(+), 58 deletions(-) delete mode 100644 quality.txt delete mode 100644 requirements.txt diff --git a/.github/workflows/buildexe.yml b/.github/workflows/buildexe.yml index 0035c024..b68f270b 100644 --- a/.github/workflows/buildexe.yml +++ b/.github/workflows/buildexe.yml @@ -20,8 +20,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r requirements.txt - pip install -r quality.txt + pip install -e ".[build]" - name: Build executable run: | @@ -56,8 +55,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r requirements.txt - pip install -r quality.txt + pip install -e ".[build]" sudo apt install libxcb-xinerama0 - name: Build executable diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 753b572c..4991e206 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -18,7 +18,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r quality.txt + pip install -e ".[dev]" - name: Code Format Check run: | @@ -35,7 +35,7 @@ jobs: # - name: Install dependencies # run: | # python -m pip install --upgrade pip -# pip install -r quality.txt +# pip install -e ".[dev]" # - name: Check code with ruff # run: | # ruff ./pyx2cscope @@ -72,8 +72,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r quality.txt - pip install -e . + pip install -e ".[dev]" - name: Run tests env: @@ -99,8 +98,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r quality.txt - pip install -e . + pip install -e ".[docs]" - name: Build documentation run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f1a0e9dd..c5f18f2e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,8 +20,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r quality.txt - pip install -e . + pip install -e ".[docs,build]" - name: Build documentation run: | @@ -33,9 +32,15 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./build/html - - name: Release to pypi with poetry + - name: Build package run: | - poetry config pypi-token.pypi ${{ secrets.PYX2CSCOPE_PYPI }} - poetry publish -vvv --build + python -m build + + - name: Release to pypi + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYX2CSCOPE_PYPI }} + run: | + python -m twine upload dist/* diff --git a/README.md b/README.md index 4893b17a..59fec4e4 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Detailed documentation is hosted at GitHub.io: ## Install +pyX2Cscope currently supports Python `3.10` to `3.14`. + Create a virtual environment and install pyx2cscope using the following commands (Windows): ``` python -m venv .venv diff --git a/doc/development.md b/doc/development.md index ac5f110f..e17f08c4 100644 --- a/doc/development.md +++ b/doc/development.md @@ -35,8 +35,7 @@ source .venv\bin\activate ## Installing dev requirements ```bash -pip install -r requirements.txt -pip install -r quality.txt +pip install -e ".[dev,docs,build]" ``` ## Running tests diff --git a/doc/install.rst b/doc/install.rst index 79e72d5d..8d56dce6 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -3,6 +3,8 @@ Installation Create a virtual environment and install pyx2cscope using the following commands (Windows): +pyX2Cscope currently supports Python ``3.10`` to ``3.14``. + .. code-block:: python python -m venv .venv @@ -50,4 +52,4 @@ pyX2Cscope with argument **-l** or **--log-level** .. code-block:: bash - pyx2cscope --log-level DEBUG \ No newline at end of file + pyx2cscope --log-level DEBUG diff --git a/pyproject.toml b/pyproject.toml index 78c9b8e3..0ff55022 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,41 +1,66 @@ [build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +requires = ["setuptools>=75", "wheel"] +build-backend = "setuptools.build_meta" -[tool.poetry] +[project] name = "pyx2cscope" version = "0.7.0" description = "python implementation of X2Cscope" +readme = "README.md" +requires-python = ">=3.10,<3.15" +license = "LicenseRef-Proprietary" authors = [ - "Yash Agarwal", - "Edras Pacola ", - "Christoph Baumgartner", - "Mark Wendler", + {name = "Yash Agarwal"}, + {name = "Edras Pacola", email = "edras.pacola@microchip.com"}, + {name = "Christoph Baumgartner"}, + {name = "Mark Wendler"}, +] +dependencies = [ + "pyserial>=3.5,<4.0", + "pyelftools>=0.31,<0.32", + "pyyaml>=6.0.1,<7.0.0", + "numpy>=1.26.0,<3.0.0", + "matplotlib>=3.7.2,<4.0.0", + "PyQt5>=5.15.9,<6.0.0", + "pyqtgraph>=0.13.7,<0.14.0", + "mchplnet==0.5.0", + "flask>=3.0.3,<4.0.0", + "flask-socketio>=5.3.4,<6.0.0", ] -readme = "README.md" -packages = [{include = "pyx2cscope"}] -license = "Proprietary" +[project.optional-dependencies] +dev = [ + "pre-commit==4.3.0", + "pylint==3.1.0", + "pytest==8.1.1", + "pytest-mock==3.14.0", + "pytest-qt==4.4.0", + "ruff==0.4.4", +] +docs = [ + "furo==2024.1.29", + "myst-parser==2.0.0", + "sphinx==7.2.6", + "sphinx-autoapi==3.0.0", + "sphinx-rtd-theme==2.0.0", +] +build = [ + "build>=1.2.2", + "pyinstaller>=6.11.0", + "requests==2.31.0", + "twine>=5.1.1", +] -homepage = "https://x2cscope.github.io/" -documentation = "https://x2cscope.github.io/pyx2cscope" -repository = "https://github.com/X2Cscope/pyx2cscope" +[project.urls] +Homepage = "https://x2cscope.github.io/" +Documentation = "https://x2cscope.github.io/pyx2cscope" +Repository = "https://github.com/X2Cscope/pyx2cscope" -[tool.poetry.scripts] -pyx2cscope = 'pyx2cscope.__main__:main' +[project.scripts] +pyx2cscope = "pyx2cscope.__main__:main" -[tool.poetry.dependencies] -python = "^3.10" -pyserial = "^3.5" -pyelftools = "^0.31" -pyyaml ="^6.0.1" -numpy = "^1.26.0" -matplotlib = "^3.7.2" -PyQt5 = "^5.15.9" -pyqtgraph = "^0.13.7" -mchplnet = "0.5.0" -flask = "^3.0.3" -flask-socketio = "^5.3.4" +[tool.setuptools.packages.find] +include = ["pyx2cscope*"] [tool.ruff] line-length = 120 @@ -50,5 +75,3 @@ lint.select = ["D"] lint.extend-select = ["I", "N", "F", "PL", "D"] exclude = ["mchplnet/*"] lint.ignore = ["PLR0913"] - - diff --git a/pyx2cscope/variable/variable_factory.py b/pyx2cscope/variable/variable_factory.py index b654c0c5..cc072fc4 100644 --- a/pyx2cscope/variable/variable_factory.py +++ b/pyx2cscope/variable/variable_factory.py @@ -188,15 +188,16 @@ def import_variables(self, filename: str): # clear any previous loaded variable self.parser.variable_map.clear() self.parser.register_map.clear() + imported_data = None if ext is FileType.ELF: self.parser = GenericParser(filename) if ext is FileType.PICKLE: with open(filename, 'rb') as file: - imported_data = pickle.load(file) + imported_data = pickle.loads(file.read()) if ext is FileType.YAML: with open(filename, 'r') as file: - imported_data = yaml.load(file, Loader=yaml.FullLoader) + imported_data = yaml.load(file.read(), Loader=yaml.FullLoader) if ext is not FileType.ELF: if isinstance(imported_data, dict) and "variables" in imported_data: diff --git a/quality.txt b/quality.txt deleted file mode 100644 index 27746401e678474c97ce725141c56561b3e65521..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 566 zcmZXR;ZB1<5QOJ9?}90`w)#Wgg;a>7RIYF)_T{bL9MF)O%R#a;J2Sg?`wi+T(Kft%n7TzY^OlP!5@Eo+lX~c0zEUPW7 zwObAz^+87@L5)KFk00RFFpl`1IW1f}@6epwGyJaV(gYLcx+mN)fw72!lezC@#yt5N z%hB#}IVIMlV2?+QT$fdXh2e}Bwln#RNyAfb?>Pq0hT{z0g*$g-Xs8c3yIz8n332*T zuX9Gfjq_Jb+2Jwh9rhkhao6{@BU*uP&*|te>!4?N%k~@U708K=j`O_kYv%;!dUn74 EAMSQn`v3p{ diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index f9e7311086ccb8df4b9601b3a09d06ad7e6dd669..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 346 zcmY+9u?~Vj5Jaao@gMvF2q!AB(9*<8jbDHS)OaB3Sg=9eVhCH@yqVekytnAE zgToXrEI4BropTH^Kufhljv5wA>NDzzGQC<-sp!A*vv_EV5Giwnsp)pivD6*s83$!j zG8zA|QVpIYrA=ClzWXl8sOZa?eF;wAAlfQu5%%mTNR@0_W20Gek#tRd+Y~tIHjPqp ivt$XCgo|(VA8}`AOS)%_=447mbdR|4f12#$l^9?7Rx~sK diff --git a/tests/test_parser.py b/tests/test_parser.py index 676f8017..23d0857d 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -116,8 +116,9 @@ def test_variable_enum_16(self, mocker, size6=6): assert variable.is_array() == False, "variable should not be an array" assert len(variable.info.valid_values) == size6, "enum size should be 3" - def test_variable_export_import(self, mocker): + def test_variable_export_import(self, mocker, tmp_path, monkeypatch): """Given a valid 32 bit elf file, check if export and import functions for variables are working.""" + monkeypatch.chdir(tmp_path) fake_serial(mocker, 32) x2c_scope = X2CScope(port="COM14") # try to import elf file instead of loading directly from the constructor @@ -141,6 +142,7 @@ def test_variable_export_import(self, mocker): assert variable.info.name == variable_reloaded.info.name, "variables don't have the same name" assert variable.info.address == variable_reloaded.info.address, "variables don't have the same address" assert variable.info.array_size == variable_reloaded.info.array_size, "variables don't have the same array size" + x2c_reloaded.disconnect() # load generated pickle file with single variable x2c_reloaded = X2CScope(port="COM14") @@ -150,14 +152,11 @@ def test_variable_export_import(self, mocker): assert variable.info.name == variable_reloaded.info.name, "variables don't have the same name" assert variable.info.address == variable_reloaded.info.address, "variables don't have the same address" assert variable.info.array_size == variable_reloaded.info.array_size, "variables don't have the same array size" + x2c_reloaded.disconnect() - # house keeping -> delete generated files - os.remove("my_variables.yml") - os.remove("qspin_foc_same54.yml") - os.remove("my_single_variable.pkl") - - def test_sfr_export_import(self, mocker): + def test_sfr_export_import(self, mocker, tmp_path, monkeypatch): """Check exported SFR entries can be re-imported and resolved as registers.""" + monkeypatch.chdir(tmp_path) fake_serial(mocker, 16) x2c_scope = X2CScope(port="COM14") x2c_scope.import_variables(self.elf_file_dspic33ak) @@ -176,5 +175,3 @@ def test_sfr_export_import(self, mocker): assert sfr_reloaded is not None, "reloaded SFR should be available" assert sfr_reloaded.info.name == sfr_name, "reloaded SFR name mismatch" assert len(x2c_reloaded.list_sfr()) == 1, "import loaded more than one SFR" - - os.remove("my_sfr_variable.yml") From 67a6905cd80c0855d96ff6cc6858a9b239888d60 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Wed, 15 Apr 2026 16:12:29 +0200 Subject: [PATCH 13/19] ruff check --- .../gui/qt/controllers/connection_manager.py | 1 + pyx2cscope/variable/variable_factory.py | 39 +++++++++++-------- tests/test_pyx2cscope_class.py | 4 +- tests/test_web_gui.py | 3 +- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/pyx2cscope/gui/qt/controllers/connection_manager.py b/pyx2cscope/gui/qt/controllers/connection_manager.py index 13112e5f..85c50860 100644 --- a/pyx2cscope/gui/qt/controllers/connection_manager.py +++ b/pyx2cscope/gui/qt/controllers/connection_manager.py @@ -1,6 +1,7 @@ """Connection management for the X2CScope device.""" import logging + import serial.tools.list_ports from PyQt5.QtCore import QObject, pyqtSignal diff --git a/pyx2cscope/variable/variable_factory.py b/pyx2cscope/variable/variable_factory.py index cc072fc4..24ea9d3c 100644 --- a/pyx2cscope/variable/variable_factory.py +++ b/pyx2cscope/variable/variable_factory.py @@ -3,9 +3,9 @@ import logging import os import pickle -from typing import Optional from dataclasses import asdict from enum import Enum +from typing import Optional import yaml @@ -65,6 +65,8 @@ class VariableFactory: _get_variable_instance: Creates a Variable instance from provided information. """ + _NAME_SFR_PAIR_LEN = 2 + def __init__(self, l_net: LNet, elf_path=None): """Initialize the VariableFactory with LNet instance and path to the ELF file. @@ -113,29 +115,34 @@ def _build_export_file_name(self, filename: Optional[str] = None, ext: FileType= def _resolve_export_item(self, item): """Resolve an export item to VariableInfo and its target map kind.""" - if isinstance(item, tuple) and len(item) == 2: + variable_info = None + is_register = False + + if isinstance(item, tuple) and len(item) == self._NAME_SFR_PAIR_LEN: name, sfr = item + is_register = bool(sfr) if isinstance(name, str): - return self.parser.get_var_info(name, sfr=bool(sfr)), bool(sfr) - return None, bool(sfr) - - if isinstance(item, Variable): + variable_info = self.parser.get_var_info(name, sfr=is_register) + elif isinstance(item, Variable): item = item.info.name if isinstance(item, VariableInfo): if self.parser.register_map.get(item.name) == item: - return item, True - if self.parser.variable_map.get(item.name) == item: - return item, False - return item, item.name in self.parser.register_map - - if isinstance(item, str): + variable_info = item + is_register = True + elif self.parser.variable_map.get(item.name) == item: + variable_info = item + else: + variable_info = item + is_register = item.name in self.parser.register_map + elif isinstance(item, str): if item in self.parser.variable_map: - return self.parser.variable_map.get(item), False - if item in self.parser.register_map: - return self.parser.register_map.get(item), True + variable_info = self.parser.variable_map.get(item) + elif item in self.parser.register_map: + variable_info = self.parser.register_map.get(item) + is_register = True - return None, False + return variable_info, is_register def export_variables(self, filename: Optional[str] = None, ext: FileType = FileType.YAML, items=None): """Store the variables registered on the elf file to a pickle file. diff --git a/tests/test_pyx2cscope_class.py b/tests/test_pyx2cscope_class.py index 315d1991..cdc744d2 100644 --- a/tests/test_pyx2cscope_class.py +++ b/tests/test_pyx2cscope_class.py @@ -9,6 +9,8 @@ from tests import data from tests.utils.serial_stub import fake_serial +LNET_SAMPLE_TIME_THIRD_SAMPLE = 2 + class TestPyX2CScope: """Tests related to the PyX2CScope class.""" @@ -86,7 +88,7 @@ def test_set_sample_time_uses_user_facing_factor(self, mocker): assert scope.scope_setup.sample_time_factor == 0 scope.set_sample_time(3) - assert scope.scope_setup.sample_time_factor == 2 + assert scope.scope_setup.sample_time_factor == LNET_SAMPLE_TIME_THIRD_SAMPLE scope.set_sample_time(0) assert scope.scope_setup.sample_time_factor == 0 diff --git a/tests/test_web_gui.py b/tests/test_web_gui.py index 95918685..282709ae 100644 --- a/tests/test_web_gui.py +++ b/tests/test_web_gui.py @@ -16,6 +16,7 @@ # HTTP status codes for test assertions HTTP_OK = 200 +HTTP_BAD_REQUEST = 400 HTTP_NOT_FOUND = 404 @@ -182,7 +183,7 @@ def test_export_variables_route_requires_selected_variables(self, flask_client, try: response = flask_client.get("/variables/export?ext=yml") - assert response.status_code == 400 + assert response.status_code == HTTP_BAD_REQUEST data = json.loads(response.data) assert "No variables are selected" in data["msg"] finally: From 6113a31ab6a7d0ca2751bc1eef5f73b12cf16cd4 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Thu, 16 Apr 2026 11:06:10 +0200 Subject: [PATCH 14/19] point to mchplnet 0.5.1 --- mchplnet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mchplnet b/mchplnet index fea6eefb..d950279f 160000 --- a/mchplnet +++ b/mchplnet @@ -1 +1 @@ -Subproject commit fea6eefbef72780a101f7283ebb2c0c3dfe33c74 +Subproject commit d950279f674939548130fc5078330bda3e5e553b From d39a42c2d006aba42819d0bfff544f7fa2e8aa94 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Thu, 16 Apr 2026 11:06:40 +0200 Subject: [PATCH 15/19] update github actions --- .github/workflows/buildexe.yml | 4 ++-- .github/workflows/documentation.yml | 14 ++++++++++---- .github/workflows/release.yml | 2 +- .gitignore | 1 + doc/development.md | 4 ++++ pyproject.toml | 8 +++++++- 6 files changed, 25 insertions(+), 8 deletions(-) diff --git a/.github/workflows/buildexe.yml b/.github/workflows/buildexe.yml index b68f270b..ef567d94 100644 --- a/.github/workflows/buildexe.yml +++ b/.github/workflows/buildexe.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.14' - name: Install dependencies run: | @@ -50,7 +50,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.14' - name: Install dependencies run: | diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 4991e206..5f4d59f8 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.14" - name: Install dependencies run: | @@ -31,7 +31,7 @@ jobs: # - name: Set up Python # uses: actions/setup-python@v5 # with: -# python-version: "3.10" +# python-version: "3.14" # - name: Install dependencies # run: | # python -m pip install --upgrade pip @@ -45,13 +45,16 @@ jobs: tests: runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.14"] steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: ${{ matrix.python-version }} - name: Install system dependencies for Qt run: | @@ -85,6 +88,9 @@ jobs: docs: runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.14"] steps: - name: Checkout repository @@ -93,7 +99,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: ${{ matrix.python-version }} - name: Install dependencies run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c5f18f2e..65e76140 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.14' - name: Install dependencies run: | diff --git a/.gitignore b/.gitignore index d08a1541..ef1a2588 100644 --- a/.gitignore +++ b/.gitignore @@ -104,6 +104,7 @@ celerybeat.pid # Environments .env .venv +.venv* env/ venv/ ENV/ diff --git a/doc/development.md b/doc/development.md index e17f08c4..64dd1d38 100644 --- a/doc/development.md +++ b/doc/development.md @@ -38,6 +38,10 @@ source .venv\bin\activate pip install -e ".[dev,docs,build]" ``` +## Publishing a release + +Package releases are handled by GitHub Actions as part of the maintainer release workflow. + ## Running tests ### ruff syntax check diff --git a/pyproject.toml b/pyproject.toml index 0ff55022..e0502b6f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ dependencies = [ "matplotlib>=3.7.2,<4.0.0", "PyQt5>=5.15.9,<6.0.0", "pyqtgraph>=0.13.7,<0.14.0", - "mchplnet==0.5.0", + "mchplnet==0.5.1", "flask>=3.0.3,<4.0.0", "flask-socketio>=5.3.4,<6.0.0", ] @@ -38,6 +38,7 @@ dev = [ "ruff==0.4.4", ] docs = [ + "astroid<4.0.0", "furo==2024.1.29", "myst-parser==2.0.0", "sphinx==7.2.6", @@ -75,3 +76,8 @@ lint.select = ["D"] lint.extend-select = ["I", "N", "F", "PL", "D"] exclude = ["mchplnet/*"] lint.ignore = ["PLR0913"] + +[tool.pytest.ini_options] +testpaths = ["tests"] +addopts = "--import-mode=importlib" +pythonpath = ["."] From 58e286fe06a2d33905e5d3157790f1ad1e6f0017 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Thu, 16 Apr 2026 13:20:59 +0200 Subject: [PATCH 16/19] add compatibility check --- doc/example.md | 24 ++++++++ doc/scripting.rst | 20 +++++++ pyx2cscope/examples/check_compatibility.py | 31 ++++++++++ pyx2cscope/parser/elf_parser.py | 19 ++++++ pyx2cscope/parser/generic_parser.py | 19 ++++++ pyx2cscope/variable/variable_factory.py | 67 ++++++++++++++++++++++ pyx2cscope/x2cscope.py | 4 ++ tests/test_install.py | 6 +- tests/test_parser.py | 18 +++--- tests/test_pyx2cscope_class.py | 47 +++++++++++++++ tests/utils/serial_stub.py | 31 +++++++--- 11 files changed, 267 insertions(+), 19 deletions(-) create mode 100644 pyx2cscope/examples/check_compatibility.py diff --git a/doc/example.md b/doc/example.md index 61a16cef..cbaf1641 100644 --- a/doc/example.md +++ b/doc/example.md @@ -287,6 +287,30 @@ with open(csv_file_path, mode="w", newline="") as file: logging.info(f"Data saved in {csv_file_path}") ```` +## Check ELF compatibility + +````python + +"""Check whether the loaded ELF file appears compatible with the connected target.""" + +from pyx2cscope.utils import get_com_port, get_elf_file_path +from pyx2cscope.x2cscope import X2CScope + + +x2c_scope = X2CScope(port=get_com_port()) + +try: + x2c_scope.import_variables(get_elf_file_path()) + + compatibility = x2c_scope.check_compatibility() + print("Compatibility report:") + for key, value in compatibility.items(): + print(f" {key}: {value}") +finally: + x2c_scope.disconnect() + +```` + for more visit the [pyX2Cscope example directory ](https://github.com/X2Cscope/pyx2cscope/tree/develop/pyx2cscope/examples) diff --git a/doc/scripting.rst b/doc/scripting.rst index 6c329c6b..1c2a50ab 100644 --- a/doc/scripting.rst +++ b/doc/scripting.rst @@ -511,6 +511,26 @@ Internally, LNET uses a 0-based value, but pyX2Cscope exposes this parameter as Additional information on how to change triggers, clear and change sample time, may be found on the API documentation. +ELF Compatibility Check +^^^^^^^^^^^^^^^^^^^^^^^ + +When an ELF file is loaded, pyX2Cscope performs a best-effort compatibility check against the +connected target and emits a warning if the MCU family appears to mismatch. + +You can also query this explicitly: + +.. code-block:: python + + compatibility = x2c_scope.check_compatibility() + print(compatibility) + +The returned dictionary reports whether the check could be performed and whether the loaded ELF +appears compatible with the connected target. The check is best-effort and uses the ELF target +description together with the target processor information reported by LNET. It can distinguish +common cases such as ARM-based targets, PIC32, generic dsPIC/PIC24, and dsPIC33A. + +See also the runnable example in ``pyx2cscope/examples/check_compatibility.py``. + Utility Functions ----------------- diff --git a/pyx2cscope/examples/check_compatibility.py b/pyx2cscope/examples/check_compatibility.py new file mode 100644 index 00000000..945e46d8 --- /dev/null +++ b/pyx2cscope/examples/check_compatibility.py @@ -0,0 +1,31 @@ +"""Check whether the loaded ELF file matches the connected target. + +This example connects to the target, loads variables from an ELF file, and +prints the compatibility report returned by ``check_compatibility()``. +""" + +from pyx2cscope.utils import get_com_port +from pyx2cscope.x2cscope import X2CScope + +x2c_scope = X2CScope(port=get_com_port()) +# this test assumes you have a dsPIC33CK256MP508 connected on UART + +try: + # this should be compatible + x2c_scope.import_variables("../../tests/data/mc_foc_sl_fip_dspic33ck_mclv48v300w.elf") + compatibility = x2c_scope.check_compatibility() + print("Compatibility report:") + for key, value in compatibility.items(): + print(f" {key}: {value}") + x2c_scope.disconnect() + + # this should be incompatible and generate a warning + x2c_scope.import_variables("../../tests/data/MC_FOC_DYNO_SAME54_MCLV2.elf") + compatibility = x2c_scope.check_compatibility() + print("Compatibility report:") + for key, value in compatibility.items(): + print(f" {key}: {value}") +finally: + x2c_scope.disconnect() + + diff --git a/pyx2cscope/parser/elf_parser.py b/pyx2cscope/parser/elf_parser.py index 618c27f1..417ec4de 100644 --- a/pyx2cscope/parser/elf_parser.py +++ b/pyx2cscope/parser/elf_parser.py @@ -11,6 +11,12 @@ from pyx2cscope.variable.variable import VariableInfo +ELF_MACHINE_TO_FAMILY = { + "EM_ARM": "arm", + "EM_DSPIC30F": "dspic", + "EM_MIPS": "pic32", +} + class ElfParser(ABC): """Abstract base class for parsing ELF files. @@ -40,6 +46,8 @@ def __init__(self, elf_path: str): self.elf_path = elf_path self.dwarf_info = {} self.elf_file = None + self.elf_machine = None + self.target_signature = None self.variable_map = {} self.register_map = {} self.symbol_table = {} @@ -89,6 +97,17 @@ def get_var_list(self) -> List[str]: """ return sorted(self.variable_map.keys(), key=lambda x: x.lower()) + def get_target_family(self) -> Optional[str]: + """Return the MCU family inferred from the ELF machine type, if known.""" + elf_machine = self.elf_machine + if elf_machine is None: + return None + return ELF_MACHINE_TO_FAMILY.get(elf_machine) + + def get_target_signature(self) -> Optional[str]: + """Return the best available ELF target signature for compatibility checks.""" + return self.target_signature or self.get_target_family() + @abstractmethod def _load_elf_file(self): """Load the ELF file according to the specific hardware architecture. diff --git a/pyx2cscope/parser/generic_parser.py b/pyx2cscope/parser/generic_parser.py index 6a3772ff..ed80e8c1 100644 --- a/pyx2cscope/parser/generic_parser.py +++ b/pyx2cscope/parser/generic_parser.py @@ -15,6 +15,13 @@ from pyx2cscope.parser.elf_parser import ElfParser from pyx2cscope.variable.variable import VariableInfo +TARGET_SIGNATURE_PATTERNS = ( + ("dspic33a", ("__DSPIC33A", "__33AK")), + ("arm", ("__PIC32C", "PIC32C/", "SAME", "__GENERIC_ARM_", "ARMV6", "ARMV7")), + ("pic32", ("__PIC32",)), + ("dspic", ("__DSPIC", "__PIC24", "__33CK", "__33CH", "__33EP", "__33FJ")), +) + class GenericParser(ElfParser): """Class for parsing ELF files compatible with 32-bit architectures.""" @@ -33,6 +40,7 @@ def _load_elf_file(self): try: self.stream = open(self.elf_path, "rb") self.elf_file = ELFFile(self.stream) + self.elf_machine = self.elf_file["e_machine"] self.dwarf_info = self.elf_file.get_dwarf_info() except IOError: raise Exception(f"Error loading ELF file: {self.elf_path}") @@ -170,11 +178,22 @@ def _extract_address(self, die_variable): def _load_symbol_table(self): """Loads symbol table entries into a dictionary for fast access.""" + all_symbol_names = [] for section in self.elf_file.iter_sections(): if isinstance(section, SymbolTableSection): for symbol in section.iter_symbols(): + all_symbol_names.append(symbol.name) if symbol["st_info"].type == "STT_OBJECT" or symbol["st_info"].bind == "STB_GLOBAL": self.symbol_table[symbol.name] = symbol["st_value"] + self.target_signature = self._infer_target_signature(all_symbol_names) + + def _infer_target_signature(self, symbol_names): + """Infer a more specific target signature from the ELF symbol table.""" + symbol_names = "\n".join(symbol_names).upper() + for signature, markers in TARGET_SIGNATURE_PATTERNS: + if any(marker in symbol_names for marker in markers): + return signature + return self.get_target_family() def _fetch_address_from_symtab(self, variable_name): """Fetches the address of a variable from the preloaded symbol table.""" diff --git a/pyx2cscope/variable/variable_factory.py b/pyx2cscope/variable/variable_factory.py index 24ea9d3c..bd6f84dc 100644 --- a/pyx2cscope/variable/variable_factory.py +++ b/pyx2cscope/variable/variable_factory.py @@ -3,6 +3,7 @@ import logging import os import pickle +import warnings from dataclasses import asdict from enum import Enum from typing import Optional @@ -66,6 +67,17 @@ class VariableFactory: """ _NAME_SFR_PAIR_LEN = 2 + _DEVICE_FAMILY_KEYWORDS = { + "arm": ("ARM",), + "pic32": ("PIC32",), + "dspic": ("DSPIC", "PIC24"), + } + _DEVICE_SIGNATURE_KEYWORDS = { + "dspic33a": ("DSPIC33A", "33AK"), + "arm": ("ARM",), + "pic32": ("PIC32",), + "dspic": ("DSPIC", "PIC24"), + } def __init__(self, l_net: LNet, elf_path=None): """Initialize the VariableFactory with LNet instance and path to the ELF file. @@ -94,6 +106,7 @@ def set_elf_file(self, elf_path: str): """ parser = GenericParser self.parser = parser(elf_path) + self._warn_if_incompatible(elf_path) def set_lnet_interface(self, lnet: LNet): """Set the LNet interface to be used for data communication. @@ -102,6 +115,59 @@ def set_lnet_interface(self, lnet: LNet): lnet (LNet): the LNet interface """ self.l_net = lnet + self.device_info = self.l_net.get_device_info() + + def _get_device_family(self) -> Optional[str]: + processor_id = str(getattr(self.device_info, "processor_id", "") or "") + for family, keywords in self._DEVICE_FAMILY_KEYWORDS.items(): + if any(keyword in processor_id for keyword in keywords): + return family + return None + + def _get_device_signature(self) -> Optional[str]: + processor_id = str(getattr(self.device_info, "processor_id", "") or "") + for signature, keywords in self._DEVICE_SIGNATURE_KEYWORDS.items(): + if any(keyword in processor_id for keyword in keywords): + return signature + return None + + def check_device_compatibility(self) -> dict: + """Check whether the loaded ELF appears compatible with the connected target.""" + file_family = self.parser.get_target_family() if hasattr(self.parser, "get_target_family") else None + file_signature = self.parser.get_target_signature() if hasattr(self.parser, "get_target_signature") else file_family + device_family = self._get_device_family() + device_signature = self._get_device_signature() or device_family + checked = bool(file_signature and device_signature) + compatible = (file_signature == device_signature) if checked else None + if compatible is False: + reason = "ELF file and connected target appear to describe different MCU targets." + elif checked: + reason = "ELF file appears compatible with the connected target." + else: + reason = "Compatibility could not be determined." + return { + "checked": checked, + "compatible": compatible, + "device_family": device_family, + "file_family": file_family, + "device_signature": device_signature, + "file_signature": file_signature, + "processor_id": str(getattr(self.device_info, "processor_id", "") or ""), + "elf_file": getattr(self.parser, "elf_path", ""), + "reason": reason, + } + + def _warn_if_incompatible(self, elf_path: str): + """Warn when the loaded ELF appears incompatible with the connected target.""" + compatibility = self.check_device_compatibility() + if compatibility["compatible"] is False: + warnings.warn( + ( + f"Loaded ELF '{elf_path}' appears incompatible with the connected target " + f"({compatibility['processor_id']})." + ), + stacklevel=2, + ) def _build_export_file_name(self, filename: Optional[str] = None, ext: FileType= FileType.YAML): if filename is None: @@ -199,6 +265,7 @@ def import_variables(self, filename: str): if ext is FileType.ELF: self.parser = GenericParser(filename) + self._warn_if_incompatible(filename) if ext is FileType.PICKLE: with open(filename, 'rb') as file: imported_data = pickle.loads(file.read()) diff --git a/pyx2cscope/x2cscope.py b/pyx2cscope/x2cscope.py index 9f31f1ed..cb3f763e 100644 --- a/pyx2cscope/x2cscope.py +++ b/pyx2cscope/x2cscope.py @@ -177,6 +177,10 @@ def import_variables(self, filename: str): """ self.variable_factory.import_variables(filename) + def check_compatibility(self) -> dict: + """Check whether the currently loaded ELF appears compatible with the connected target.""" + return self.variable_factory.check_device_compatibility() + def add_scope_channel(self, variable: Variable, trigger: bool = False) -> int: """Add a variable as a scope channel. diff --git a/tests/test_install.py b/tests/test_install.py index 8470bcb5..4923e61d 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -9,7 +9,7 @@ from mchplnet.services.frame_load_parameter import LoadScopeData from pyx2cscope.x2cscope import X2CScope from tests import data -from tests.utils.serial_stub import fake_serial +from tests.utils.serial_stub import DEVICE_PROFILE_ARM, fake_serial elf_file_16 = os.path.join( os.path.dirname(data.__file__), "mc_foc_sl_fip_dspic33ck_mclv48v300w.elf" @@ -36,12 +36,12 @@ def test_x2cscope_install_serial_16(mocker): def test_x2cscope_install_serial_32(mocker): """Using a fake serial interface with a 32 bit device, check the device_info and scope_data frames.""" - fake_serial(mocker, 32) + fake_serial(mocker, 32, device_profile=DEVICE_PROFILE_ARM) pyx2cscope = X2CScope(elf_file=elf_file_32, port="COM11") device_info: DeviceInfo = pyx2cscope.lnet.device_info assert device_info.uc_width == PROCESSOR_32_BIT_LENGTH, "wrong processor bit length" assert ( - device_info.processor_id == "__GENERIC_MICROCHIP_PIC32__" + device_info.processor_id == "__GENERIC_ARM_ARMV7__" ), "unknown processor" scope_data: LoadScopeData = pyx2cscope.lnet.scope_data assert scope_data.scope_state == 0, "wrong scope state value" diff --git a/tests/test_parser.py b/tests/test_parser.py index 23d0857d..c06b99ea 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -5,7 +5,7 @@ from pyx2cscope.variable.variable_factory import FileType from pyx2cscope.x2cscope import X2CScope from tests import data -from tests.utils.serial_stub import fake_serial +from tests.utils.serial_stub import DEVICE_PROFILE_ARM, DEVICE_PROFILE_DSPIC33A, fake_serial class TestParser: @@ -31,7 +31,7 @@ def test_variable_16_does_not_exist(self, mocker): def test_variable_32_does_not_exist(self, mocker): """Given a valid 32 bit elf file, check if an invalid variable outputs the expected behavior.""" - fake_serial(mocker, 16) + fake_serial(mocker, 32, device_profile=DEVICE_PROFILE_ARM) x2c_scope = X2CScope(port="COM14", elf_file=self.elf_file_32) variable = x2c_scope.get_variable("wrong_variable_name") assert variable is None @@ -47,7 +47,7 @@ def test_array_variable_16(self, mocker, array_size_test=4): def test_array_variable_32(self, mocker, array_size_test=255): """Given a valid 32 bit elf file, check if an array variable is read correctly.""" - fake_serial(mocker, 32) + fake_serial(mocker, 32, device_profile=DEVICE_PROFILE_ARM) x2c_scope = X2CScope(port="COM14", elf_file=self.elf_file_32) variable = x2c_scope.get_variable("bufferLNet") assert variable is not None, "variable name not found" @@ -69,7 +69,7 @@ def test_union_variable_16(self, mocker): def test_variable_dspic33ak(self, mocker, array_size_test=4900, address=22122): """Given a valid dspic33ak elf file, check if an array variable is read correctly.""" - fake_serial(mocker, 32) + fake_serial(mocker, 32, device_profile=DEVICE_PROFILE_DSPIC33A) x2c_scope = X2CScope(port="COM14") x2c_scope.import_variables(self.elf_file_dspic33ak) variable = x2c_scope.get_variable("measureInputs.current.Ia") @@ -84,7 +84,7 @@ def test_variable_dspic33ak(self, mocker, array_size_test=4900, address=22122): def test_nested_array_variable_32(self, mocker, array_size_test=3): """Given a valid 32 bit elf file, check if an array variable is read correctly.""" - fake_serial(mocker, 32) + fake_serial(mocker, 32, device_profile=DEVICE_PROFILE_ARM) x2c_scope = X2CScope(port="COM14", elf_file=self.elf_file_32) variable = x2c_scope.get_variable("mcFocI_ModuleData_gds.dOutput.duty") assert variable is not None, "variable name not found" @@ -93,7 +93,7 @@ def test_nested_array_variable_32(self, mocker, array_size_test=3): def test_variable_enum_32(self, mocker, size6=6, size3=3): """Given a valid dspic33ck elf file, check if an enum variable is read correctly.""" - fake_serial(mocker, 32) + fake_serial(mocker, 32, device_profile=DEVICE_PROFILE_ARM) x2c_scope = X2CScope(port="COM14", elf_file=self.elf_file_32) # test simple variable enum variable = x2c_scope.get_variable("nextGlobalState") @@ -108,7 +108,7 @@ def test_variable_enum_32(self, mocker, size6=6, size3=3): def test_variable_enum_16(self, mocker, size6=6): """Given a valid dspic33ck elf file, check if an enum variable is read correctly.""" - fake_serial(mocker, 32) + fake_serial(mocker, 16) x2c_scope = X2CScope(port="COM14", elf_file=self.elf_file_16) # test nested enum inside a structure variable = x2c_scope.get_variable("motor.apiData.motorStatus") @@ -119,7 +119,7 @@ def test_variable_enum_16(self, mocker, size6=6): def test_variable_export_import(self, mocker, tmp_path, monkeypatch): """Given a valid 32 bit elf file, check if export and import functions for variables are working.""" monkeypatch.chdir(tmp_path) - fake_serial(mocker, 32) + fake_serial(mocker, 32, device_profile=DEVICE_PROFILE_ARM) x2c_scope = X2CScope(port="COM14") # try to import elf file instead of loading directly from the constructor x2c_scope.import_variables(self.elf_file_32) @@ -157,7 +157,7 @@ def test_variable_export_import(self, mocker, tmp_path, monkeypatch): def test_sfr_export_import(self, mocker, tmp_path, monkeypatch): """Check exported SFR entries can be re-imported and resolved as registers.""" monkeypatch.chdir(tmp_path) - fake_serial(mocker, 16) + fake_serial(mocker, 32, device_profile=DEVICE_PROFILE_DSPIC33A) x2c_scope = X2CScope(port="COM14") x2c_scope.import_variables(self.elf_file_dspic33ak) diff --git a/tests/test_pyx2cscope_class.py b/tests/test_pyx2cscope_class.py index cdc744d2..be39c319 100644 --- a/tests/test_pyx2cscope_class.py +++ b/tests/test_pyx2cscope_class.py @@ -18,6 +18,12 @@ class TestPyX2CScope: elf_file = os.path.join( os.path.dirname(data.__file__), "mc_foc_sl_fip_dspic33ck_mclv48v300w.elf" ) + arm_elf_file = os.path.join( + os.path.dirname(data.__file__), "qspin_foc_same54.elf" + ) + dspic33a_elf_file = os.path.join( + os.path.dirname(data.__file__), "dsPIC33ak128mc106_foc.elf" + ) def test_missing_elf_file_16(self, mocker): """Check if the corresponding exception is raised in case of wrong 16 bit elf path.""" @@ -94,3 +100,44 @@ def test_set_sample_time_uses_user_facing_factor(self, mocker): assert scope.scope_setup.sample_time_factor == 0 finally: scope.disconnect() + + def test_incompatible_elf_emits_warning(self, mocker): + """Check mismatched ELF and target families generate a warning.""" + fake_serial(mocker, 16) + with warnings.catch_warnings(record=True) as captured: + warnings.simplefilter("always") + scope = X2CScope(elf_file=self.arm_elf_file, port="COM1") + try: + assert any("appears incompatible" in str(w.message) for w in captured) + finally: + scope.disconnect() + + def test_check_compatibility(self, mocker): + """Check the compatibility API reports a matching dsPIC ELF correctly.""" + fake_serial(mocker, 16) + scope = X2CScope(elf_file=self.elf_file, port="COM1") + try: + compatibility = scope.check_compatibility() + assert compatibility["checked"] is True + assert compatibility["compatible"] is True + assert compatibility["file_family"] == "dspic" + assert compatibility["device_family"] == "dspic" + assert compatibility["file_signature"] == "dspic" + finally: + scope.disconnect() + + def test_check_compatibility_detects_dspic33a_mismatch(self, mocker): + """Check the compatibility API distinguishes dsPIC33A from generic dsPIC targets.""" + fake_serial(mocker, 16) + with warnings.catch_warnings(record=True) as captured: + warnings.simplefilter("always") + scope = X2CScope(elf_file=self.dspic33a_elf_file, port="COM1") + try: + compatibility = scope.check_compatibility() + assert compatibility["checked"] is True + assert compatibility["compatible"] is False + assert compatibility["file_signature"] == "dspic33a" + assert compatibility["device_signature"] == "dspic" + assert any("appears incompatible" in str(w.message) for w in captured) + finally: + scope.disconnect() diff --git a/tests/utils/serial_stub.py b/tests/utils/serial_stub.py index cce6300a..443ddee7 100644 --- a/tests/utils/serial_stub.py +++ b/tests/utils/serial_stub.py @@ -9,6 +9,10 @@ BIT_LENGTH_16 = 16 BIT_LENGTH_32 = 32 +DEVICE_PROFILE_DSPIC = "dspic" +DEVICE_PROFILE_ARM = "arm" +DEVICE_PROFILE_PIC32 = "pic32" +DEVICE_PROFILE_DSPIC33A = "dspic33a" class FrameBuilder(LNetFrame): """FrameBuilder class to build LNet frames.""" @@ -66,13 +70,16 @@ def _check_frame_protocol(self): class SerialStub: """Fakes a serial connection for 16 and 32 bit devices.""" - def __init__(self, uc_width=BIT_LENGTH_16): + def __init__(self, uc_width=BIT_LENGTH_16, device_profile=None): """Constructor of the SerialStub class. Expected get_device_info and load_param bytestream are initialized here. """ self.delay_seconds = 0.2 # 200ms delay to make concurrency self.uc_width = uc_width + self.device_profile = device_profile or ( + DEVICE_PROFILE_DSPIC if uc_width == BIT_LENGTH_16 else DEVICE_PROFILE_PIC32 + ) self.data = bytearray() self.device_info = bytearray(b"\x55\x01\x01\x00\x57") self.load_param = bytearray(b"\x55\x03\x01\x11\x01\x00\x6b") @@ -146,18 +153,27 @@ def lnet_serial_read(self) -> bytearray: def _get_device_info(self): if self.data != self.device_info: raise ValueError("Wrong Device Info package format!") - if self.uc_width == BIT_LENGTH_16: + if self.device_profile == DEVICE_PROFILE_DSPIC: return bytearray( b"\x55.\x01\x00\x00\x05\x00\x01\x00\xff\x10\x82Nov2320231500\x00\x00\x00\x00" b"\x00\x00\xccJ\x14K\xc0\xff\xff\x01\x00\x00\x00\x00\x00\x00\xf4R\x00\x00\xba" ) - elif self.uc_width == BIT_LENGTH_32: + if self.device_profile == DEVICE_PROFILE_PIC32: return bytearray( b"\x55.\x01\x00\x00\x05\x00\x01\x00\xff \x82Mar 320191220Mar 320191220\x01" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00 T" ) - else: - raise ValueError("Mocker fake_serial: wrong uC width! should be either 16 or 32 bits") + if self.device_profile == DEVICE_PROFILE_ARM: + return bytearray( + b"\x55.\x01\x00\x00\x05\x00\x01\x00\xff\x10\x83Mar 320191220Mar 320191220\x01" + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00 T" + ) + if self.device_profile == DEVICE_PROFILE_DSPIC33A: + return bytearray( + b"\x55.\x01\x00\x00\x05\x00\x01\x00\xff@\x82Apr 120241200Apr 120241200\x01" + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00 T" + ) + raise ValueError("Mocker fake_serial: unsupported device profile") def _get_load_param(self) -> bytearray: if self.data != self.load_param: @@ -175,7 +191,7 @@ def _get_load_param(self) -> bytearray: else: raise ValueError("Mocker fake_serial: wrong uC width! should be either 16 or 32 bits") -def fake_serial(mocker, uc_width=BIT_LENGTH_16): +def fake_serial(mocker, uc_width=BIT_LENGTH_16, device_profile=None): """Fakes a serial port for 16/32 bit devices. The methods being faked by this function are start, read and write. @@ -183,10 +199,11 @@ def fake_serial(mocker, uc_width=BIT_LENGTH_16): Args: mocker: Mocker inheritance uc_width: bit size of the device to be mocked + device_profile: target profile to be mocked Return: None """ - serial_stub = SerialStub(uc_width=uc_width) + serial_stub = SerialStub(uc_width=uc_width, device_profile=device_profile) mocker.patch.object(LNetSerial, "start", serial_stub.lnet_serial_start) mocker.patch.object(LNetSerial, "write", serial_stub.lnet_serial_write) mocker.patch.object(LNetSerial, "read", serial_stub.lnet_serial_read) From 7312ef83bb8064cfef44907dfb3d987f15c3a136 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Thu, 16 Apr 2026 14:29:47 +0200 Subject: [PATCH 17/19] included SFR bits --- pyx2cscope/parser/elf_parser.py | 1 + pyx2cscope/parser/generic_parser.py | 100 +++++++++++++++++++++++++++- tests/test_parser.py | 46 +++++++++++++ tests/utils/serial_stub.py | 3 +- 4 files changed, 147 insertions(+), 3 deletions(-) diff --git a/pyx2cscope/parser/elf_parser.py b/pyx2cscope/parser/elf_parser.py index 417ec4de..fcfde3a5 100644 --- a/pyx2cscope/parser/elf_parser.py +++ b/pyx2cscope/parser/elf_parser.py @@ -51,6 +51,7 @@ def __init__(self, elf_path: str): self.variable_map = {} self.register_map = {} self.symbol_table = {} + self.absolute_symbol_table = {} self._load_elf_file() self._load_symbol_table() diff --git a/pyx2cscope/parser/generic_parser.py b/pyx2cscope/parser/generic_parser.py index ed80e8c1..3be4f6fb 100644 --- a/pyx2cscope/parser/generic_parser.py +++ b/pyx2cscope/parser/generic_parser.py @@ -5,6 +5,7 @@ import logging import math +import re from itertools import product from elftools.construct.lib import ListContainer @@ -21,6 +22,13 @@ ("pic32", ("__PIC32",)), ("dspic", ("__DSPIC", "__PIC24", "__33CK", "__33CH", "__33EP", "__33FJ")), ) +REGISTER_SYMBOL_PATTERN = re.compile(r"^[A-Z][A-Z0-9]*$") +FAMILY_REGISTER_BYTE_SIZE = { + "arm": 4, + "pic32": 4, + "dspic33a": 4, + "dspic": 2, +} class GenericParser(ElfParser): @@ -112,6 +120,40 @@ def _process_die(self, die): valid_values=member_data["valid_values"], ) + if self.is_sfr: + self._add_sfr_aliases(self.var_name, target_map) + + @staticmethod + def _get_sfr_alias_names(register_name: str, member_name: str) -> list[str]: + """Return alternate names for SFR bitfield members.""" + aliases = [] + if "." not in member_name: + return aliases + + member_leaf = member_name.split(".")[-1] + aliases.append(member_leaf) + + return aliases + + def _add_sfr_aliases(self, register_name: str, target_map: dict[str, VariableInfo]): + """Add convenience aliases for parsed SFR bitfield members.""" + register_entries = list(target_map.items()) + for member_name, variable_info in register_entries: + if not member_name.startswith(register_name + "."): + continue + for alias_name in self._get_sfr_alias_names(register_name, member_name): + if alias_name not in target_map: + target_map[alias_name] = VariableInfo( + name=alias_name, + type=variable_info.type, + byte_size=variable_info.byte_size, + bit_size=variable_info.bit_size, + bit_offset=variable_info.bit_offset, + address=variable_info.address, + array_size=variable_info.array_size, + valid_values=variable_info.valid_values, + ) + def _get_base_type_die(self, current_die): """Find the base type die regarding the current selected die, i.e. array_type.""" type_attr = current_die.attributes.get("DW_AT_type") @@ -183,8 +225,15 @@ def _load_symbol_table(self): if isinstance(section, SymbolTableSection): for symbol in section.iter_symbols(): all_symbol_names.append(symbol.name) - if symbol["st_info"].type == "STT_OBJECT" or symbol["st_info"].bind == "STB_GLOBAL": + if symbol.name: self.symbol_table[symbol.name] = symbol["st_value"] + if symbol["st_shndx"] == "SHN_ABS": + self.absolute_symbol_table[symbol.name] = { + "address": symbol["st_value"], + "size": symbol["st_size"], + "type": symbol["st_info"].type, + "bind": symbol["st_info"].bind, + } self.target_signature = self._infer_target_signature(all_symbol_names) def _infer_target_signature(self, symbol_names): @@ -197,7 +246,16 @@ def _infer_target_signature(self, symbol_names): def _fetch_address_from_symtab(self, variable_name): """Fetches the address of a variable from the preloaded symbol table.""" - return self.symbol_table.get(variable_name, None) + candidates = [variable_name] + if not variable_name.startswith("_"): + candidates.append("_" + variable_name) + else: + candidates.append(variable_name[1:]) + + for candidate in candidates: + if candidate in self.symbol_table: + return self.symbol_table[candidate] + return None def _find_actual_declaration(self, die_variable): """Find the actual declaration of an extern variable.""" @@ -421,6 +479,42 @@ def _map_registers(self) -> dict[str, VariableInfo]: """ return self.register_map + def _get_symbol_only_register_byte_size(self) -> int: + """Return a best-effort byte size for symbol-only SFR entries.""" + signature = self.get_target_signature() + family = self.get_target_family() + return FAMILY_REGISTER_BYTE_SIZE.get(signature, FAMILY_REGISTER_BYTE_SIZE.get(family, 2)) + + @staticmethod + def _get_symbol_only_register_type(byte_size: int) -> str: + """Return the variable type string for a symbol-only SFR entry.""" + type_by_size = { + 1: "unsigned char", + 2: "unsigned int", + 4: "unsigned long", + 8: "unsigned long long", + } + return type_by_size.get(byte_size, "unsigned int") + + def _map_symbol_only_registers(self): + """Populate missing SFRs from absolute symbol-table entries when DWARF lacks variables.""" + byte_size = self._get_symbol_only_register_byte_size() + for symbol_name, symbol_data in self.absolute_symbol_table.items(): + if not REGISTER_SYMBOL_PATTERN.fullmatch(symbol_name): + continue + if symbol_name in self.register_map: + continue + self.register_map[symbol_name] = VariableInfo( + name=symbol_name, + type=self._get_symbol_only_register_type(byte_size), + byte_size=byte_size, + bit_size=0, + bit_offset=0, + address=symbol_data["address"], + array_size=0, + valid_values={}, + ) + def _map_variables(self) -> dict[str, VariableInfo]: """Maps all variables in the ELF file.""" self.variable_map.clear() @@ -430,6 +524,8 @@ def _map_variables(self) -> dict[str, VariableInfo]: self.expression_parser = DWARFExprParser(die.cu.structs) self._process_die(die) + self._map_symbol_only_registers() + return self.variable_map diff --git a/tests/test_parser.py b/tests/test_parser.py index c06b99ea..bac11ac8 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -22,6 +22,52 @@ class TestParser: os.path.dirname(data.__file__), "dsPIC33ak128mc106_foc.elf" ) + def test_sfr_bitfield_aliases_dspic33ck(self, mocker): + """Check dsPIC33CK SFR bitfields are exposed with nested and flat aliases.""" + serial_stub = fake_serial(mocker, 16) + x2c_scope = X2CScope(port="COM14", elf_file=self.elf_file_16) + late_bit = x2c_scope.get_variable("LATE3", sfr=True) + late_bit_nested = x2c_scope.get_variable("LATEbits.LATE3", sfr=True) + + assert late_bit is not None + assert late_bit_nested is not None + assert late_bit.info.address == late_bit_nested.info.address + assert late_bit.info.bit_size == 1 + + serial_stub.mock_memory[late_bit.info.address] = 0 + late_bit.set_value(int("1")) + assert serial_stub.mock_memory[late_bit.info.address] == 0x0008 + assert late_bit.get_value() == 1 + + def test_sfr_bitfield_aliases_dspic33a(self, mocker): + """Check dsPIC33A SFR bitfields are exposed with nested and flat aliases.""" + fake_serial(mocker, 32, device_profile=DEVICE_PROFILE_DSPIC33A) + x2c_scope = X2CScope(port="COM14") + x2c_scope.import_variables(self.elf_file_dspic33ak) + + ansela_bit = x2c_scope.get_variable("ANSELA0", sfr=True) + ansela_bit_nested = x2c_scope.get_variable("ANSELAbits.ANSELA0", sfr=True) + + assert ansela_bit is not None + assert ansela_bit_nested is not None + assert ansela_bit.info.address == ansela_bit_nested.info.address + assert ansela_bit.info.bit_size == 1 + + def test_symbol_only_sfr_is_listed_with_address(self, mocker): + """Check symbol-only SFRs like DMA0CH are exposed with their absolute address.""" + fake_serial(mocker, 32, device_profile=DEVICE_PROFILE_DSPIC33A) + x2c_scope = X2CScope(port="COM14") + x2c_scope.import_variables(self.elf_file_dspic33ak) + + dma0ch = x2c_scope.get_variable("DMA0CH", sfr=True) + dma0stat = x2c_scope.get_variable("DMA0STAT", sfr=True) + + assert dma0ch is not None + assert dma0stat is not None + assert dma0ch.info.address == 8976 + assert dma0stat.info.address == 8984 + assert dma0ch.info.byte_size == 4 + def test_variable_16_does_not_exist(self, mocker): """Given a valid 16 bit elf file, check if an invalid variable outputs the expected behavior.""" fake_serial(mocker, 16) diff --git a/tests/utils/serial_stub.py b/tests/utils/serial_stub.py index 443ddee7..30912067 100644 --- a/tests/utils/serial_stub.py +++ b/tests/utils/serial_stub.py @@ -201,9 +201,10 @@ def fake_serial(mocker, uc_width=BIT_LENGTH_16, device_profile=None): uc_width: bit size of the device to be mocked device_profile: target profile to be mocked Return: - None + SerialStub: the configured serial stub instance """ serial_stub = SerialStub(uc_width=uc_width, device_profile=device_profile) mocker.patch.object(LNetSerial, "start", serial_stub.lnet_serial_start) mocker.patch.object(LNetSerial, "write", serial_stub.lnet_serial_write) mocker.patch.object(LNetSerial, "read", serial_stub.lnet_serial_read) + return serial_stub From 9f77b7fdbb972b5ac47f2e7f199e71bd13e95b70 Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Thu, 16 Apr 2026 15:07:06 +0200 Subject: [PATCH 18/19] fixed import/export of SFRs on GUIs --- pyx2cscope/gui/qt/tabs/scope_view_tab.py | 8 ++++++-- pyx2cscope/gui/qt/tabs/watch_view_tab.py | 4 ++++ pyx2cscope/gui/web/scope.py | 5 +++-- pyx2cscope/gui/web/static/js/dashboard_view.js | 7 ++++--- pyx2cscope/gui/web/static/js/script.js | 5 ++--- pyx2cscope/gui/web/templates/setup.html | 3 +-- pyx2cscope/gui/web/views/scope_view.py | 3 +-- pyx2cscope/gui/web/views/watch_view.py | 2 +- pyx2cscope/gui/web/ws_handlers.py | 3 ++- pyx2cscope/variable/variable.py | 2 +- 10 files changed, 25 insertions(+), 17 deletions(-) diff --git a/pyx2cscope/gui/qt/tabs/scope_view_tab.py b/pyx2cscope/gui/qt/tabs/scope_view_tab.py index 9b5b75cd..02401af4 100644 --- a/pyx2cscope/gui/qt/tabs/scope_view_tab.py +++ b/pyx2cscope/gui/qt/tabs/scope_view_tab.py @@ -495,12 +495,13 @@ def get_config(self) -> dict: "offset": [off.text() for off in self._offset_edits], "color": [cb.currentData() or list(self._colors.keys())[cb.currentIndex()] for cb in self._color_combos], "show": [cb.isChecked() for cb in self._visible_checkboxes], + "sfr": [self._app_state.get_scope_channel(i).sfr for i in range(len(self._var_line_edits))], "trigger_variable": self._trigger_variable, "trigger_level": self._trigger_level_edit.text(), "trigger_delay": self._trigger_delay_combo.currentText(), "trigger_edge": self._trigger_edge_combo.currentText(), "trigger_mode": self._trigger_mode_combo.currentText(), - "sample_time_factor": self._sample_time_factor_edit.text() or "1", + "sample_time_factor": self._sample_time_factor_edit.value(), "single_shot": self._single_shot_checkbox.isChecked(), } @@ -512,9 +513,12 @@ def load_config(self, config: dict): offsets = config.get("offset", []) colors = config.get("color", []) shows = config.get("show", []) + sfrs = config.get("sfr", []) for i, (le, var) in enumerate(zip(self._var_line_edits, variables)): le.setText(var) + sfr = sfrs[i] if i < len(sfrs) else False + self._app_state.update_scope_channel_field(i, "sfr", sfr) # Update app state with variable name self._app_state.update_scope_channel_field(i, "name", var) for i, (cb, trigger) in enumerate(zip(self._trigger_checkboxes, triggers)): @@ -539,5 +543,5 @@ def load_config(self, config: dict): self._trigger_delay_combo.setCurrentText(config.get("trigger_delay", "0")) self._trigger_edge_combo.setCurrentText(config.get("trigger_edge", "Rising")) self._trigger_mode_combo.setCurrentText(config.get("trigger_mode", "Disable")) - self._sample_time_factor_edit.setText(config.get("sample_time_factor", "1") or "1") + self._sample_time_factor_edit.setValue(int(config.get("sample_time_factor", 1))) self._single_shot_checkbox.setChecked(config.get("single_shot", False)) diff --git a/pyx2cscope/gui/qt/tabs/watch_view_tab.py b/pyx2cscope/gui/qt/tabs/watch_view_tab.py index 662ea245..45b95faa 100644 --- a/pyx2cscope/gui/qt/tabs/watch_view_tab.py +++ b/pyx2cscope/gui/qt/tabs/watch_view_tab.py @@ -334,6 +334,7 @@ def get_config(self) -> dict: "offsets": [off.text() for off in self._offset_edits], "scaled_values": [sv.text() for sv in self._scaled_value_edits], "live": [cb.isChecked() for cb in self._live_checkboxes], + "sfr": [self._app_state.get_live_watch_var(i).sfr for i in range(len(self._variable_edits))], } def load_config(self, config: dict): @@ -348,11 +349,14 @@ def load_config(self, config: dict): offsets = config.get("offsets", []) scaled_values = config.get("scaled_values", []) lives = config.get("live", []) + sfrs = config.get("sfr", []) for i, var in enumerate(variables): self._add_variable_row() if i < len(self._variable_edits): self._variable_edits[i].setText(var) + sfr = sfrs[i] if i < len(sfrs) else False + self._app_state.update_live_watch_var_field(i, "sfr", sfr) # Update app state with variable name self._app_state.update_live_watch_var_field(i, "name", var) if i < len(values) and i < len(self._value_edits): diff --git a/pyx2cscope/gui/web/scope.py b/pyx2cscope/gui/web/scope.py index 3c9b87ce..f7edf4d0 100644 --- a/pyx2cscope/gui/web/scope.py +++ b/pyx2cscope/gui/web/scope.py @@ -194,17 +194,18 @@ def watch_poll(self): return result # Dashboard variable methods - def add_dashboard_var(self, name): + def add_dashboard_var(self, name, sfr: bool = False): """Add a variable to the dashboard polling list. Args: name (str): Variable name to add. + sfr (bool): Whether to retrieve a peripheral register (SFR) instead of a firmware variable. Returns: bool: True if variable was added successfully. """ if name not in self.dashboard_vars: - variable = self.x2c_scope.get_variable(name) + variable = self.x2c_scope.get_variable(name, sfr=sfr) if variable is not None: self.dashboard_vars[name] = variable return True diff --git a/pyx2cscope/gui/web/static/js/dashboard_view.js b/pyx2cscope/gui/web/static/js/dashboard_view.js index 60e21f23..c6e7871a 100644 --- a/pyx2cscope/gui/web/static/js/dashboard_view.js +++ b/pyx2cscope/gui/web/static/js/dashboard_view.js @@ -326,7 +326,7 @@ function registerWidgetVariables(widget) { dashboardSocket.emit('add_dashboard_var', {var: varName}); }); } else if (widget.type !== 'label') { - dashboardSocket.emit('add_dashboard_var', {var: widget.variable}); + dashboardSocket.emit('add_dashboard_var', {var: widget.variable, sfr: widget.sfr || false}); } } @@ -470,8 +470,8 @@ function showWidgetConfig(type, editWidget = null) { // Initialize Select2 after modal is shown so dropdown renders correctly $('#widgetConfigModal').one('shown.bs.modal', function() { - // Reset SFR toggle for each new config session - $('#widgetSfrToggle').prop('checked', false); + // Restore SFR toggle from widget if editing, otherwise reset + $('#widgetSfrToggle').prop('checked', editWidget ? (editWidget.sfr || false) : false); if (widgetDef.requiresVariable && !widgetDef.requiresMultipleVariables) { $('#widgetVarName').select2(initWidgetVarSelect2()); @@ -519,6 +519,7 @@ function addDashboardWidget() { id: widgetIdCounter++, type: currentWidgetType, variable: varName, + sfr: $('#widgetSfrToggle').is(':checked'), icon: widgetDef.icon, x: 50, y: 50, diff --git a/pyx2cscope/gui/web/static/js/script.js b/pyx2cscope/gui/web/static/js/script.js index fe4a09d7..c741a31c 100644 --- a/pyx2cscope/gui/web/static/js/script.js +++ b/pyx2cscope/gui/web/static/js/script.js @@ -71,9 +71,8 @@ function load_uart() { $.getJSON('/serial-ports', function(data) { uart = $('#port'); uart.empty(); - uart.append(''); - // Add AUTO option for auto-detection - uart.append($('').val('AUTO').html('AUTO (Auto-detect)')); + // Add AUTO option as default selection + uart.append($('').val('AUTO').html('AUTO (Auto-detect)')); data.forEach(function(item) { uart.append($('').val(item).html(item)); }); diff --git a/pyx2cscope/gui/web/templates/setup.html b/pyx2cscope/gui/web/templates/setup.html index d0839422..856d82d6 100644 --- a/pyx2cscope/gui/web/templates/setup.html +++ b/pyx2cscope/gui/web/templates/setup.html @@ -15,8 +15,7 @@
    diff --git a/pyx2cscope/gui/web/views/scope_view.py b/pyx2cscope/gui/web/views/scope_view.py index 651fe648..6bba8b71 100644 --- a/pyx2cscope/gui/web/views/scope_view.py +++ b/pyx2cscope/gui/web/views/scope_view.py @@ -62,8 +62,7 @@ def load(): if isinstance(data, list) and data and isinstance(data[0], dict) and "variable" in data[0].keys(): web_scope.clear_scope_var() for item in data: - web_scope.clear_scope_var() - var = web_scope.add_scope_var(item["variable"]) + var = web_scope.add_scope_var(item["variable"], sfr=item.get("sfr", False)) if var is None: msg = "Variable " + item["variable"] + " is not available." else: diff --git a/pyx2cscope/gui/web/views/watch_view.py b/pyx2cscope/gui/web/views/watch_view.py index 0dab9dda..ff59fdbc 100644 --- a/pyx2cscope/gui/web/views/watch_view.py +++ b/pyx2cscope/gui/web/views/watch_view.py @@ -41,7 +41,7 @@ def load(): if isinstance(data, list) and data and isinstance(data[0], dict) and "variable" in data[0].keys(): web_scope.clear_watch_var() for item in data: - var = web_scope.add_watch_var(item["variable"]) + var = web_scope.add_watch_var(item["variable"], sfr=item.get("sfr", False)) if var is None: msg = "Variable " + item["variable"] + " is not available." else: diff --git a/pyx2cscope/gui/web/ws_handlers.py b/pyx2cscope/gui/web/ws_handlers.py index 6fdc91b2..ad44a6ee 100644 --- a/pyx2cscope/gui/web/ws_handlers.py +++ b/pyx2cscope/gui/web/ws_handlers.py @@ -220,8 +220,9 @@ def handle_add_dashboard_var(data): data (dict): Dictionary containing the variable name. """ var = data.get("var") + sfr = bool(data.get("sfr", False)) if var: - web_scope.add_dashboard_var(var) + web_scope.add_dashboard_var(var, sfr=sfr) @socketio.on("remove_dashboard_var", namespace="/dashboard") def handle_remove_dashboard_var(data): diff --git a/pyx2cscope/variable/variable.py b/pyx2cscope/variable/variable.py index b4cad58b..02b87194 100644 --- a/pyx2cscope/variable/variable.py +++ b/pyx2cscope/variable/variable.py @@ -166,7 +166,7 @@ def _set_bit_value(self, value: Number): shift = (8 * self.info.byte_size) - (self.info.bit_offset + self.info.bit_size) mask = ((1 << self.info.bit_size) - 1) << shift current_data &= ~mask - return current_data | ((value << shift) & mask) + return current_data | ((int(value) << shift) & mask) def get_value(self): """Get the stored value from the MCU. From 3ebfb438fa6e4c89c08ac6fb69557d180ae9dceb Mon Sep 17 00:00:00 2001 From: Edras Pacola Date: Thu, 16 Apr 2026 15:12:54 +0200 Subject: [PATCH 19/19] fixed linter --- tests/test_parser.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/test_parser.py b/tests/test_parser.py index bac11ac8..3c285055 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -11,6 +11,11 @@ class TestParser: """Parser related unit tests.""" + LATE3_BIT_MASK = 0x0008 + DMA0CH_ADDRESS = 8976 + DMA0STAT_ADDRESS = 8984 + DMA0CH_BYTE_SIZE = 4 + elf_file_16 = os.path.join( os.path.dirname(data.__file__), "MCAF_ZSMT_dsPIC33CK.elf" ) @@ -36,7 +41,7 @@ def test_sfr_bitfield_aliases_dspic33ck(self, mocker): serial_stub.mock_memory[late_bit.info.address] = 0 late_bit.set_value(int("1")) - assert serial_stub.mock_memory[late_bit.info.address] == 0x0008 + assert serial_stub.mock_memory[late_bit.info.address] == self.LATE3_BIT_MASK assert late_bit.get_value() == 1 def test_sfr_bitfield_aliases_dspic33a(self, mocker): @@ -64,9 +69,9 @@ def test_symbol_only_sfr_is_listed_with_address(self, mocker): assert dma0ch is not None assert dma0stat is not None - assert dma0ch.info.address == 8976 - assert dma0stat.info.address == 8984 - assert dma0ch.info.byte_size == 4 + assert dma0ch.info.address == self.DMA0CH_ADDRESS + assert dma0stat.info.address == self.DMA0STAT_ADDRESS + assert dma0ch.info.byte_size == self.DMA0CH_BYTE_SIZE def test_variable_16_does_not_exist(self, mocker): """Given a valid 16 bit elf file, check if an invalid variable outputs the expected behavior."""