diff --git a/getSymbol.py b/getSymbol.py new file mode 100644 index 0000000..8b7ec84 --- /dev/null +++ b/getSymbol.py @@ -0,0 +1,35 @@ +import pyocd +from elftools.elf.elffile import ELFFile +import logging +import time + +# Replace 'your_elf_file.elf' with the path to your ELF file +elf_file_path = 'max32655.elf' + +# Replace 'your_symbol_name' with the symbol name you want to retrieve the address for +symbol_name = 'testVal' + + + +# Connect to the target with your probe +with pyocd.target.get_device_count() as session: + if session > 0: + with pyocd.target.Session() as target: + try: + # Load the ELF file onto the target + target.load_binary(elf_file_path) + + # Get the address of the symbol + address = target.get_symbol_address(symbol_name) + + if address is not None: + logger.info(f"The address of '{symbol_name}' is 0x{address:08X}") + else: + logger.info(f"Symbol '{symbol_name}' not found.") + + except Exception as e: + logger.warning(f"Error while connecting to the probe: {e}") + else: + logger.info("No probe found!") + +# Rest of your code (variable monitoring, etc.) goes here... diff --git a/main.py b/main.py index a9b741b..7704dbd 100644 --- a/main.py +++ b/main.py @@ -205,7 +205,7 @@ def openCloseRightBox(): self.watch_vars_chart_container.setLayout(self.watch_vars_chart_layout) self.ui.insights_scroll_area.setWidget(self.watch_vars_chart_container) - + self.ui.stats_frame.hide() # SHOW APP self.show() diff --git a/main.ui b/main.ui index bac20ca..b89aa4a 100644 --- a/main.ui +++ b/main.ui @@ -7,7 +7,7 @@ <rect> <x>0</x> <y>0</y> - <width>1558</width> + <width>1503</width> <height>857</height> </rect> </property> @@ -1836,7 +1836,7 @@ p, li { white-space: pre-wrap; } <string notr="true">background: transparent;</string> </property> <property name="currentIndex"> - <number>3</number> + <number>2</number> </property> <widget class="QWidget" name="home"> <property name="styleSheet"> @@ -2533,7 +2533,7 @@ QHeaderView::section:vertical <rect> <x>0</x> <y>0</y> - <width>424</width> + <width>274</width> <height>218</height> </rect> </property> @@ -3282,6 +3282,157 @@ QPushButton:pressed{ <enum>QFrame::Raised</enum> </property> <layout class="QVBoxLayout" name="verticalLayout_37"> + <property name="topMargin"> + <number>0</number> + </property> + <item> + <widget class="QFrame" name="stats_frame"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>250</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">border: 2px solid rgb(52, 59, 72); +border-radius: 5px; +</string> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QVBoxLayout" name="verticalLayout_39" stretch="1,8"> + <property name="leftMargin"> + <number>9</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <item> + <widget class="QFrame" name="frame_4"> + <property name="styleSheet"> + <string notr="true"> border: 0px solid rgb(52, 59, 72);</string> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <widget class="QLabel" name="titleLeftApp_2"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>160</width> + <height>20</height> + </rect> + </property> + <property name="font"> + <font> + <family>Segoe UI</family> + <pointsize>10</pointsize> + <weight>50</weight> + <italic>false</italic> + <bold>false</bold> + </font> + </property> + <property name="styleSheet"> + <string notr="true"> border: 0px solid rgb(52, 59, 72); + border-radius: 5px; +</string> + </property> + <property name="text"> + <string>Connection stats</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </widget> + </item> + <item> + <widget class="QFrame" name="frame_15"> + <property name="styleSheet"> + <string notr="true"> border: 0px solid rgb(52, 59, 72);</string> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QVBoxLayout" name="verticalLayout_40"> + <property name="spacing"> + <number>10</number> + </property> + <item> + <widget class="QLabel" name="lbl_rx_data_count"> + <property name="text"> + <string>RX Data Count:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lbl_rx_data_crc_err"> + <property name="text"> + <string>RX Data CRC ERR:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lbl_rx_data_timeout"> + <property name="text"> + <string>RX Data Timeout:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lbl_tx_data_count"> + <property name="text"> + <string>TX Data Count:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lbl_tx_data_err"> + <property name="text"> + <string>TX Data ERR:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lbl_PER"> + <property name="styleSheet"> + <string notr="true"/> + </property> + <property name="text"> + <string>PER : </string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_5"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> <item> <widget class="QScrollArea" name="insights_scroll_area"> <property name="widgetResizable"> @@ -3292,8 +3443,8 @@ QPushButton:pressed{ <rect> <x>0</x> <y>0</y> - <width>558</width> - <height>571</height> + <width>533</width> + <height>286</height> </rect> </property> </widget> @@ -3461,7 +3612,7 @@ QPushButton:pressed{ <property name="frameShadow"> <enum>QFrame::Raised</enum> </property> - <layout class="QVBoxLayout" name="verticalLayout_28"> + <layout class="QVBoxLayout" name="verticalLayout_28" stretch="2"> <property name="spacing"> <number>15</number> </property> @@ -3502,7 +3653,7 @@ QPushButton:pressed{ <rect> <x>0</x> <y>0</y> - <width>792</width> + <width>570</width> <height>584</height> </rect> </property> @@ -4111,9 +4262,15 @@ margin: 0px;</string> </item> <item> <widget class="AnimatedToggle" name="graph_enabled"> + <property name="minimumSize"> + <size> + <width>84</width> + <height>0</height> + </size> + </property> <property name="maximumSize"> <size> - <width>99999</width> + <width>84</width> <height>999999</height> </size> </property> @@ -4162,6 +4319,9 @@ margin: 0px;</string> </item> <item> <widget class="QFrame" name="elfSettings"> + <property name="enabled"> + <bool>true</bool> + </property> <property name="minimumSize"> <size> <width>0</width> @@ -4171,7 +4331,7 @@ margin: 0px;</string> <property name="maximumSize"> <size> <width>16777215</width> - <height>9999</height> + <height>999</height> </size> </property> <property name="styleSheet"> @@ -4435,6 +4595,73 @@ QPushButton:pressed{ </property> </widget> </item> + <item> + <widget class="QFrame" name="frame_14"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>50</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>99999</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">border: 2px solid rgb(52, 59, 72); +color: rgb(255, 255, 255); +border-radius: 5px; </string> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_21" stretch="4,2"> + <item> + <widget class="QLabel" name="label_8"> + <property name="styleSheet"> + <string notr="true"> + border: 0px solid rgb(52, 59, 72); +</string> + </property> + <property name="text"> + <string>Connection stats</string> + </property> + </widget> + </item> + <item> + <widget class="AnimatedToggle" name="connection_stats_enable"> + <property name="minimumSize"> + <size> + <width>84</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>84</width> + <height>999999</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">border: 0px solid rgb(52, 59, 72); +</string> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> <item> <spacer name="verticalSpacer_4"> <property name="orientation"> diff --git a/max32655.elf b/max32655.elf new file mode 100755 index 0000000..8f8aa22 Binary files /dev/null and b/max32655.elf differ diff --git a/modules/btn_callbacks.py b/modules/btn_callbacks.py index 8d834d1..442e269 100644 --- a/modules/btn_callbacks.py +++ b/modules/btn_callbacks.py @@ -290,7 +290,7 @@ def handle_checkbox_state_change(state, var_name, address, address_dict, main_wi address_dict[var_name] = {"address": address, "watched_row_position": watched_row_position, "graphed": False} # TODO make user chose from a drop down - address_dict[var_name]['var_type'] = 'float' + address_dict[var_name]['var_type'] = 'None' else: @@ -637,6 +637,21 @@ def start_ota(main_window): return main_window.connectedDevice.device_ota_update_start.emit(main_window.connectedDevice , main_window.fileName, main_window.fileLen, main_window.fileCrc32) +def btn_hide_core_regs(main_window): + main_window.var_watcher.symbolName = 'bbConnStats' + +def enable_connection_stats(main_window): + logger = logging.getLogger("PDexLogger") + if main_window.ui.connection_stats_enable.isChecked(): + main_window.var_watcher.getConnStats = True + main_window.ui.stats_frame.show() + logger.info("Getting connection stats") + else: + main_window.var_watcher.getConnStats = False + logger.info("Not getting connection stats") + main_window.ui.stats_frame.hide() + + def register_button_callbacks(main_window): logger = logging.getLogger("PDexLogger") try: @@ -653,7 +668,9 @@ def register_button_callbacks(main_window): main_window.var_watcher.core_regs_tuple.connect(main_window.get_core_regs_handler) main_window.ui.btn_refreshCoreRegs.clicked.connect(lambda: get_core_regs(main_window)) # graphing checkbox callbacks - main_window.ui.graph_enabled.stateChanged.connect(lambda: disable_graphing(main_window)) + main_window.ui.graph_enabled.stateChanged.connect(lambda: disable_graphing(main_window)) + main_window.ui.btn_hideCoreRegs.clicked.connect(lambda: btn_hide_core_regs(main_window)) + main_window.ui.connection_stats_enable.stateChanged.connect(lambda: enable_connection_stats(main_window)) #register slot/signal for disconnecting from device main_window.ui.btn_clear_logs.clicked.connect(lambda: clear_logs(main_window)) diff --git a/modules/elf_insights.py b/modules/elf_insights.py index 08e630f..73270c3 100644 --- a/modules/elf_insights.py +++ b/modules/elf_insights.py @@ -5,7 +5,7 @@ import logging import time import sys - +import struct from PySide6.QtCore import QThread class ExtractGlobalVariablesThread(QThread): @@ -47,8 +47,8 @@ def run(self): # if exit_early is true then exit the thread if self.exit_early: return - # TODO make this a user setting, possibly slider to select sample rate - time.sleep(0.005) + + time.sleep(0.001) self.logger.info("Finished extracting global variables") @@ -56,12 +56,17 @@ def run(self): class MonitoringThread(QThread): signal_update_variable = Signal(str, object) # Signal to update the variable value var_monitor_active = Signal(bool) + monitor_active = False exit_early = False logger = logging.getLogger("PDexLogger") getCoreRegs = False core_regs_tuple = Signal(zip) - + symbolName = None + getConnStats = False + connStatsAddress = None + #make a signal to update the connection stats as list + connStatValues = Signal(list) def __init__(self, address_dict): super().__init__() self.address_dict = address_dict #vars_watched_dict from main.py @@ -143,6 +148,74 @@ def monitor_variables(self, target, addresses): if self.getCoreRegs is True: self.print_core_registers(target) self.getCoreRegs = False + + if self.getConnStats is True: + if self.connStatsAddress is None: + try: + self.connStatsAddress = self.get_symbol_address_from_elf('/home/eddie/projects/BLE-PyDex/max32655.elf', 'bbConnStats') + except Exception as e: + self.logger.setLevel(logging.WARNING) + self.logger.warning("Error while monitoring variables: %s", e) + self.logger.setLevel(logging.INFO) + if self.connStatsAddress is not None: + #print address in hex + # print("0x{:08x}".format(address)) + data = self.read_struct_from_memory(target,self.connStatsAddress, 20) + # Define the format string for the struct + # The format string corresponds to the data types and order in the struct + format_string = '<IIIII' # Use '<' for little-endian byte order + + # Unpack the binary data into a tuple + struct_byes = bytes(data) + struct_data = struct.unpack(format_string, struct_byes) + + # Now, struct_data contains the values according to the struct's meaning + rxData, rxDataCrc, rxDataTimeout, txData, errData= struct_data + # check for division by zero + if (rxDataCrc + rxDataTimeout) != 0 and (rxData +rxDataCrc + rxDataTimeout) != 0: + #if none of the stats are zero then we are connected + per = (rxDataCrc + rxDataTimeout) / (rxData +rxDataCrc + rxDataTimeout) + else: + per = 0 + #conver PER to percent + per = per * 100 + #only 2 decimal places + per = round(per, 2) + + self.connStatValues.emit([rxData, rxDataCrc, rxDataTimeout, txData, errData, per]) + + + + if self.symbolName is not None: + address = self.get_symbol_address_from_elf('/home/eddie/projects/BLE-PyDex/max32655.elf', self.symbolName) + if address is not None: + #print address in hex + # print("0x{:08x}".format(address)) + data = self.read_struct_from_memory(target,address, 20) + # Define the format string for the struct + # The format string corresponds to the data types and order in the struct + format_string = '<IIIIIHHHH' # Use '<' for little-endian byte order + + # Unpack the binary data into a tuple + struct_byes = bytes(data) + struct_data = struct.unpack(format_string, struct_byes) + + # Now, struct_data contains the values according to the struct's meaning + rxData, rxDataCrc, rxDataTimeout, txData, errData= struct_data + + # Print the values + print(f"rxData: {rxData}") + print(f"rxDataCrc: {rxDataCrc}") + print(f"rxDataTimeout: {rxDataTimeout}") + print(f"txData: {txData}") + print(f"errData: {errData}") + + + print(data) + else: + self.logger.warning("Symbol '%s' not found in ELF file.", self.symbolName) + self.symbolName = None + # TODO make this use the slider value time.sleep(0.010) # Adjust the refresh rate as needed except Exception as e: self.logger.setLevel(logging.WARNING) @@ -157,7 +230,26 @@ def monitor_variables(self, target, addresses): self.exit_early = False monitor_active = False - + def get_symbol_address_from_elf(self, elf_path, symbol_name): + try: + with open(elf_path, 'rb') as elf_file: + elf = ELFFile(elf_file) + for section in elf.iter_sections(): + if section.name == '.symtab': + symbol_table = section + for symbol in symbol_table.iter_symbols(): + if symbol.name == symbol_name: + return symbol['st_value'] + except Exception as e: + self.logger.warning("Error while getting symbol address from ELF: %s", e) + return None + def read_struct_from_memory(self, target, address, struct_size): + try: + data = target.read_memory_block8(address, struct_size) + return data + except Exception as e: + self.logger.warning("Error while reading struct from memory: %s", e) + return None def mass_erase(self): pass diff --git a/modules/slots.py b/modules/slots.py index 661eadd..429852f 100644 --- a/modules/slots.py +++ b/modules/slots.py @@ -80,6 +80,16 @@ def device_disconnected_cb(interface): # clean up gui elements interface.cleanUp.emit("dummy data") +def update_connection_stats(interface, stats): + interface.ui.lbl_rx_data_count.setText("RX Data Count: " + str(stats[0])) + interface.ui.lbl_rx_data_crc_err.setText("RX Data CRC Error: " + str(stats[1])) + interface.ui.lbl_rx_data_timeout.setText("RX Data Timeout: " + str(stats[2])) + interface.ui.lbl_tx_data_count.setText("TX Data Count: " + str(stats[3])) + interface.ui.lbl_tx_data_err.setText("TX Data Error: " + str(stats[4])) + interface.ui.lbl_PER.setText("PER: " + str(stats[5]) + "%") + + + def init_signals_and_slots(interface): interface.bleScanner.discovered_devices.connect(lambda device : update_discovered_devices(interface,device)) @@ -89,6 +99,9 @@ def init_signals_and_slots(interface): # show Gatt explorer when connected interface.connectedDevice.connection_established.connect(lambda: interface.stacked_widget_show_connected()) + #singal/slot for connection stats + interface.var_watcher.connStatValues.connect(lambda stats: update_connection_stats(interface, stats)) + diff --git a/modules/ui_main.py b/modules/ui_main.py index 0d2f1ad..99bcd58 100644 --- a/modules/ui_main.py +++ b/modules/ui_main.py @@ -32,7 +32,7 @@ class Ui_MainWindow(object): def setupUi(self, MainWindow): if not MainWindow.objectName(): MainWindow.setObjectName(u"MainWindow") - MainWindow.resize(1558, 857) + MainWindow.resize(1503, 857) MainWindow.setMinimumSize(QSize(940, 560)) MainWindow.setMouseTracking(True) self.styleSheet = QWidget(MainWindow) @@ -1423,7 +1423,7 @@ def setupUi(self, MainWindow): self.scrollArea.setWidgetResizable(True) self.scrollAreaWidgetContents = QWidget() self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents") - self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 424, 218)) + self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 274, 218)) self.scrollAreaWidgetContents.setStyleSheet(u" QScrollBar:vertical {\n" " border: none;\n" " background: rgb(52, 59, 72);\n" @@ -1761,12 +1761,91 @@ def setupUi(self, MainWindow): self.insights_graphing_frame.setFrameShadow(QFrame.Raised) self.verticalLayout_37 = QVBoxLayout(self.insights_graphing_frame) self.verticalLayout_37.setObjectName(u"verticalLayout_37") + self.verticalLayout_37.setContentsMargins(-1, 0, -1, -1) + self.stats_frame = QFrame(self.insights_graphing_frame) + self.stats_frame.setObjectName(u"stats_frame") + self.stats_frame.setMinimumSize(QSize(0, 250)) + self.stats_frame.setStyleSheet(u"border: 2px solid rgb(52, 59, 72);\n" +"border-radius: 5px; \n" +"") + self.stats_frame.setFrameShape(QFrame.StyledPanel) + self.stats_frame.setFrameShadow(QFrame.Raised) + self.verticalLayout_39 = QVBoxLayout(self.stats_frame) + self.verticalLayout_39.setObjectName(u"verticalLayout_39") + self.verticalLayout_39.setContentsMargins(9, 0, -1, -1) + self.frame_4 = QFrame(self.stats_frame) + self.frame_4.setObjectName(u"frame_4") + self.frame_4.setStyleSheet(u" border: 0px solid rgb(52, 59, 72);") + self.frame_4.setFrameShape(QFrame.StyledPanel) + self.frame_4.setFrameShadow(QFrame.Raised) + self.titleLeftApp_2 = QLabel(self.frame_4) + self.titleLeftApp_2.setObjectName(u"titleLeftApp_2") + self.titleLeftApp_2.setGeometry(QRect(10, 10, 160, 20)) + self.titleLeftApp_2.setFont(font) + self.titleLeftApp_2.setStyleSheet(u" border: 0px solid rgb(52, 59, 72);\n" +" border-radius: 5px; \n" +"") + self.titleLeftApp_2.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop) + + self.verticalLayout_39.addWidget(self.frame_4) + + self.frame_15 = QFrame(self.stats_frame) + self.frame_15.setObjectName(u"frame_15") + self.frame_15.setStyleSheet(u" border: 0px solid rgb(52, 59, 72);") + self.frame_15.setFrameShape(QFrame.StyledPanel) + self.frame_15.setFrameShadow(QFrame.Raised) + self.verticalLayout_40 = QVBoxLayout(self.frame_15) + self.verticalLayout_40.setSpacing(10) + self.verticalLayout_40.setObjectName(u"verticalLayout_40") + self.lbl_rx_data_count = QLabel(self.frame_15) + self.lbl_rx_data_count.setObjectName(u"lbl_rx_data_count") + + self.verticalLayout_40.addWidget(self.lbl_rx_data_count) + + self.lbl_rx_data_crc_err = QLabel(self.frame_15) + self.lbl_rx_data_crc_err.setObjectName(u"lbl_rx_data_crc_err") + + self.verticalLayout_40.addWidget(self.lbl_rx_data_crc_err) + + self.lbl_rx_data_timeout = QLabel(self.frame_15) + self.lbl_rx_data_timeout.setObjectName(u"lbl_rx_data_timeout") + + self.verticalLayout_40.addWidget(self.lbl_rx_data_timeout) + + self.lbl_tx_data_count = QLabel(self.frame_15) + self.lbl_tx_data_count.setObjectName(u"lbl_tx_data_count") + + self.verticalLayout_40.addWidget(self.lbl_tx_data_count) + + self.lbl_tx_data_err = QLabel(self.frame_15) + self.lbl_tx_data_err.setObjectName(u"lbl_tx_data_err") + + self.verticalLayout_40.addWidget(self.lbl_tx_data_err) + + self.lbl_PER = QLabel(self.frame_15) + self.lbl_PER.setObjectName(u"lbl_PER") + self.lbl_PER.setStyleSheet(u"") + + self.verticalLayout_40.addWidget(self.lbl_PER) + + self.verticalSpacer_5 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) + + self.verticalLayout_40.addItem(self.verticalSpacer_5) + + + self.verticalLayout_39.addWidget(self.frame_15) + + self.verticalLayout_39.setStretch(0, 1) + self.verticalLayout_39.setStretch(1, 8) + + self.verticalLayout_37.addWidget(self.stats_frame) + self.insights_scroll_area = QScrollArea(self.insights_graphing_frame) self.insights_scroll_area.setObjectName(u"insights_scroll_area") self.insights_scroll_area.setWidgetResizable(True) self.scrollAreaWidgetContents_3 = QWidget() self.scrollAreaWidgetContents_3.setObjectName(u"scrollAreaWidgetContents_3") - self.scrollAreaWidgetContents_3.setGeometry(QRect(0, 0, 558, 571)) + self.scrollAreaWidgetContents_3.setGeometry(QRect(0, 0, 533, 286)) self.insights_scroll_area.setWidget(self.scrollAreaWidgetContents_3) self.verticalLayout_37.addWidget(self.insights_scroll_area) @@ -1888,11 +1967,12 @@ def setupUi(self, MainWindow): self.scrollArea_2.setWidgetResizable(True) self.scrollAreaWidgetContents_2 = QWidget() self.scrollAreaWidgetContents_2.setObjectName(u"scrollAreaWidgetContents_2") - self.scrollAreaWidgetContents_2.setGeometry(QRect(0, 0, 792, 584)) + self.scrollAreaWidgetContents_2.setGeometry(QRect(0, 0, 570, 584)) self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2) self.verticalLayout_28.addWidget(self.scrollArea_2) + self.verticalLayout_28.setStretch(0, 2) self.horizontalLayout_18.addWidget(self.scroll_Area_2_frame) @@ -2203,7 +2283,8 @@ def setupUi(self, MainWindow): self.graph_enabled = AnimatedToggle(self.frame) self.graph_enabled.setObjectName(u"graph_enabled") - self.graph_enabled.setMaximumSize(QSize(99999, 999999)) + self.graph_enabled.setMinimumSize(QSize(84, 0)) + self.graph_enabled.setMaximumSize(QSize(84, 999999)) self.graph_enabled.setChecked(True) self.horizontalLayout_10.addWidget(self.graph_enabled) @@ -2232,8 +2313,9 @@ def setupUi(self, MainWindow): self.elfSettings = QFrame(self.contentSettings) self.elfSettings.setObjectName(u"elfSettings") + self.elfSettings.setEnabled(True) self.elfSettings.setMinimumSize(QSize(0, 0)) - self.elfSettings.setMaximumSize(QSize(16777215, 9999)) + self.elfSettings.setMaximumSize(QSize(16777215, 999)) self.elfSettings.setStyleSheet(u"text-align: center;") self.elfSettings.setFrameShape(QFrame.NoFrame) self.elfSettings.setFrameShadow(QFrame.Raised) @@ -2412,6 +2494,40 @@ def setupUi(self, MainWindow): self.verticalLayout_29.addWidget(self.btn_showCoreRegs) + self.frame_14 = QFrame(self.elfSettings) + self.frame_14.setObjectName(u"frame_14") + self.frame_14.setMinimumSize(QSize(0, 50)) + self.frame_14.setMaximumSize(QSize(16777215, 99999)) + self.frame_14.setStyleSheet(u"border: 2px solid rgb(52, 59, 72);\n" +"color: rgb(255, 255, 255);\n" +"border-radius: 5px; ") + self.frame_14.setFrameShape(QFrame.StyledPanel) + self.frame_14.setFrameShadow(QFrame.Raised) + self.horizontalLayout_21 = QHBoxLayout(self.frame_14) + self.horizontalLayout_21.setObjectName(u"horizontalLayout_21") + self.label_8 = QLabel(self.frame_14) + self.label_8.setObjectName(u"label_8") + self.label_8.setStyleSheet(u"\n" +" border: 0px solid rgb(52, 59, 72);\n" +"") + + self.horizontalLayout_21.addWidget(self.label_8) + + self.connection_stats_enable = AnimatedToggle(self.frame_14) + self.connection_stats_enable.setObjectName(u"connection_stats_enable") + self.connection_stats_enable.setMinimumSize(QSize(84, 0)) + self.connection_stats_enable.setMaximumSize(QSize(84, 999999)) + self.connection_stats_enable.setStyleSheet(u"border: 0px solid rgb(52, 59, 72);\n" +"") + self.connection_stats_enable.setChecked(False) + + self.horizontalLayout_21.addWidget(self.connection_stats_enable) + + self.horizontalLayout_21.setStretch(0, 4) + self.horizontalLayout_21.setStretch(1, 2) + + self.verticalLayout_29.addWidget(self.frame_14) + self.verticalSpacer_4 = QSpacerItem(20, 97, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_29.addItem(self.verticalSpacer_4) @@ -2484,7 +2600,7 @@ def setupUi(self, MainWindow): self.retranslateUi(MainWindow) self.scanSlider.valueChanged.connect(self.label_scan_timeout_value.setNum) - self.stackedWidget.setCurrentIndex(3) + self.stackedWidget.setCurrentIndex(2) self.rssi_gatt_expolrer.setCurrentIndex(0) @@ -2571,6 +2687,13 @@ def retranslateUi(self, MainWindow): ___qtablewidgetitem5.setText(QCoreApplication.translate("MainWindow", u"Name", None)); ___qtablewidgetitem6 = self.tbl_vars_watched.horizontalHeaderItem(1) ___qtablewidgetitem6.setText(QCoreApplication.translate("MainWindow", u"Value", None)); + self.titleLeftApp_2.setText(QCoreApplication.translate("MainWindow", u"Connection stats", None)) + self.lbl_rx_data_count.setText(QCoreApplication.translate("MainWindow", u"RX Data Count:", None)) + self.lbl_rx_data_crc_err.setText(QCoreApplication.translate("MainWindow", u"RX Data CRC ERR:", None)) + self.lbl_rx_data_timeout.setText(QCoreApplication.translate("MainWindow", u"RX Data Timeout:", None)) + self.lbl_tx_data_count.setText(QCoreApplication.translate("MainWindow", u"TX Data Count:", None)) + self.lbl_tx_data_err.setText(QCoreApplication.translate("MainWindow", u"TX Data ERR:", None)) + self.lbl_PER.setText(QCoreApplication.translate("MainWindow", u"PER : ", None)) ___qtreewidgetitem = self.gatt_treeView.headerItem() ___qtreewidgetitem.setText(0, QCoreApplication.translate("MainWindow", u"Gatt Tree", None)); self.btn_disconnect.setText(QCoreApplication.translate("MainWindow", u"Disconnect", None)) @@ -2597,6 +2720,8 @@ def retranslateUi(self, MainWindow): self.btn_load_elf.setText(QCoreApplication.translate("MainWindow", u"Load Elf", None)) self.btn_monitor.setText(QCoreApplication.translate("MainWindow", u"Start Monitoring", None)) self.btn_showCoreRegs.setText(QCoreApplication.translate("MainWindow", u"Show Core Regs", None)) + self.label_8.setText(QCoreApplication.translate("MainWindow", u"Connection stats", None)) + self.connection_stats_enable.setText("") self.creditsLabel.setText(QCoreApplication.translate("MainWindow", u"By: Edwin Amaya", None)) self.version.setText(QCoreApplication.translate("MainWindow", u"v2.0.0", None)) # retranslateUi